vibespot 1.6.5 → 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +24 -3
  2. package/assets/whats-new.json +27 -0
  3. package/dist/index.js +579 -681
  4. package/dist/index.js.map +1 -1
  5. package/package.json +8 -5
  6. package/ui/chat.js +671 -9
  7. package/ui/dashboard.js +53 -12
  8. package/ui/docs/index.html +57 -2
  9. package/ui/email-preview.js +1 -5
  10. package/ui/escape-html.js +14 -0
  11. package/ui/field-editor.js +6 -12
  12. package/ui/field-save.js +82 -0
  13. package/ui/index.html +10 -4
  14. package/ui/inline-edit.js +116 -570
  15. package/ui/plan.js +22 -13
  16. package/ui/preview-agent.js +1050 -0
  17. package/ui/preview.js +248 -265
  18. package/ui/section-controls.js +16 -622
  19. package/ui/setup.js +73 -20
  20. package/ui/styles.css +424 -0
  21. package/ui/upload-panel.js +7 -8
  22. package/ui/whats-new.js +249 -0
  23. package/assets/readme/00-hero-banner.png +0 -0
  24. package/assets/readme/00-hero-banner.svg +0 -59
  25. package/assets/readme/01-vibe-coding-hero.png +0 -0
  26. package/assets/readme/02-plan-mode.png +0 -0
  27. package/assets/readme/03-figma-import.png +0 -0
  28. package/assets/readme/04-multi-page-sites.png +0 -0
  29. package/assets/readme/05-inline-wysiwyg.png +0 -0
  30. package/assets/readme/06-hubspot-upload.png +0 -0
  31. package/ui/docs/screenshots/brand-kit-preview.png +0 -0
  32. package/ui/docs/screenshots/content-type-dropdown.png +0 -0
  33. package/ui/docs/screenshots/editor-full-layout.png +0 -0
  34. package/ui/docs/screenshots/inline-wysiwyg-editing.png +0 -0
  35. package/ui/docs/screenshots/module-overview-slideout.png +0 -0
  36. package/ui/docs/screenshots/multi-page-tree.png +0 -0
  37. package/ui/docs/screenshots/onboarding-walkthrough.png +0 -0
  38. package/ui/docs/screenshots/split-pane-view.png +0 -0
  39. package/ui/docs/screenshots/visual-controls-toolbar.png +0 -0
  40. package/ui/docs/screenshots/workspace-tabs.png +0 -0
package/dist/index.js CHANGED
@@ -1,12 +1,5 @@
1
- var dg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{for(var n in t)dg(e,n,{get:t[n],enumerable:!0})};import Av from"path";import{fileURLToPath as $v}from"url";var y=N(()=>{"use strict"});import fn from"chalk";function At(e){return Ha?fn:fn.hex(e)}var pt,Ha,I,gt=N(()=>{"use strict";y();pt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Ha=!!process.env.NO_COLOR;I={accent:At(pt.accent),accentBright:At(pt.accentBright),success:At(pt.success),info:At(pt.info),warn:At(pt.warn),error:At(pt.error),muted:At(pt.muted),vibes:At(pt.vibes),heading:Ha?fn.bold:fn.bold.hex(pt.accent),command:At(pt.accentBright),dim:fn.dim,bold:fn.bold}});import{readFileSync as Pi,writeFileSync as ug,mkdirSync as Ua,existsSync as Vs}from"fs";import{dirname as Ga,join as _t}from"path";import{fileURLToPath as mg}from"url";function P(e){return Pi(e,"utf-8")}function B(e,t){Ua(Ga(e),{recursive:!0}),ug(e,t,"utf-8")}function x(e){return Vs(e)}function Re(e){Ua(e,{recursive:!0})}function bn(e){let t=[_t(yn,"../../assets",e),_t(yn,"../assets",e),_t(process.cwd(),"assets",e)];for(let n of t)if(Vs(n))return n;throw new Error(`Asset not found: ${e}`)}function Sn(){if(hn)return hn;let e=[_t(yn,"../../package.json"),_t(yn,"../package.json"),_t(process.cwd(),"package.json")];for(let t of e)if(Vs(t))try{let n=JSON.parse(Pi(t,"utf-8"));if(n.name==="vibespot"&&n.version)return hn=n.version,hn}catch{}return hn="dev",hn}function Wa(){if(Ks)return Ks;let e=[_t(yn,"../../CHANGELOG.md"),_t(yn,"../CHANGELOG.md"),_t(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Vs(t))try{return Ks=Pi(t,"utf-8"),Ks}catch{}return""}var yn,hn,Ks,oe=N(()=>{"use strict";y();yn=Ga(mg(import.meta.url));hn="";Ks=""});import{execSync as Ka,execFileSync as pg}from"child_process";function ie(e,t={}){try{return{stdout:Ka(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Z(e,t={}){try{return{stdout:pg("git",e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Va(e,t={}){try{return Ka(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var Qt=N(()=>{"use strict";y()});var qa={};Ge(qa,{addHubSpotAccount:()=>Xn,getActiveHubSpotAccount:()=>Ht,getApiKeyForEngine:()=>Fe,getConfigDir:()=>hg,getHubSpotPak:()=>Le,isCliToolEnabled:()=>st,loadConfig:()=>R,maskApiKey:()=>Ys,removeHubSpotAccount:()=>Ni,saveConfig:()=>Y,setActiveHubSpotAccount:()=>Ri,setCliToolEnabled:()=>Oi});import{join as za}from"path";import{homedir as gg}from"os";import{chmodSync as fg}from"fs";function R(){let e={};if(x(zs))try{e=JSON.parse(P(zs)),e.aiEngine==="api"&&(e.aiEngine="anthropic-api")}catch{e={}}return process.env.VIBESPOT_AI_ENGINE&&!e.aiEngine&&(e.aiEngine=process.env.VIBESPOT_AI_ENGINE),process.env.ANTHROPIC_API_KEY&&!e.anthropicApiKey&&(e.anthropicApiKey=process.env.ANTHROPIC_API_KEY),process.env.OPENAI_API_KEY&&!e.openaiApiKey&&(e.openaiApiKey=process.env.OPENAI_API_KEY),(process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)&&!e.geminiApiKey&&(e.geminiApiKey=process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY),process.env.LANGDOCK_API_KEY&&!e.langdockApiKey&&(e.langdockApiKey=process.env.LANGDOCK_API_KEY),process.env.LANGDOCK_BASE_URL&&!e.langdockBaseUrl&&(e.langdockBaseUrl=process.env.LANGDOCK_BASE_URL),process.env.LANGDOCK_PROVIDER&&!e.langdockProvider&&(e.langdockProvider=process.env.LANGDOCK_PROVIDER),process.env.FIGMA_TOKEN&&!e.figmaToken&&(e.figmaToken=process.env.FIGMA_TOKEN),process.env.VIBESPOT_AGENTIC_MODE!==void 0&&e.agenticMode===void 0&&(e.agenticMode=process.env.VIBESPOT_AGENTIC_MODE==="true"),process.env.LANGFUSE_PUBLIC_KEY&&!e.langfusePublicKey&&(e.langfusePublicKey=process.env.LANGFUSE_PUBLIC_KEY),process.env.LANGFUSE_SECRET_KEY&&!e.langfuseSecretKey&&(e.langfuseSecretKey=process.env.LANGFUSE_SECRET_KEY),process.env.LANGFUSE_BASE_URL&&!e.langfuseBaseUrl&&(e.langfuseBaseUrl=process.env.LANGFUSE_BASE_URL),process.env.LANGFUSE_ENABLED!==void 0&&e.langfuseEnabled===void 0&&(e.langfuseEnabled=process.env.LANGFUSE_ENABLED==="true"),e}function Fe(e,t){let n=t||R();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;case"langdock-api":return n.langdockApiKey||process.env.LANGDOCK_API_KEY;default:return}}function Ys(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function Y(e){let n={...R(),...e};if(B(zs,JSON.stringify(n,null,2)),process.platform!=="win32")try{fg(zs,384)}catch{}}function hg(){return Ya}function Ht(){let e=R();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function Xn(e,t,n,s){let i=R().hubspotAccounts||[],r=i.findIndex(l=>l.portalId===t),a={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};r>=0?i[r]=a:i.push(a),Y({hubspotAccounts:i,activeHubSpotAccount:t})}function Ni(e){let t=R(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),Y(s)}function Ri(e){Y({activeHubSpotAccount:e})}function Le(){return Ht()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function st(e){return R().enabledCLITools?.includes(e)??!1}function Oi(e,t){let n=R(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),Y({enabledCLITools:[...s]})}var Ya,zs,ee=N(()=>{"use strict";y();oe();Ya=za(gg(),".vibespot"),zs=za(Ya,"config.json")});var ji={};Ge(ji,{OAUTH_EXTRA_HEADERS:()=>Zn,OAUTH_SYSTEM_PREFIX:()=>xn,clearOAuthTokens:()=>Zs,getOAuthTokenInfo:()=>en,getValidAccessToken:()=>Di,hasValidOAuthToken:()=>Ze,saveInitialToken:()=>Fi});import{join as yg}from"path";import{homedir as bg}from"os";import{chmodSync as Sg,unlinkSync as vg}from"fs";function Xs(){if(!x(vn))return null;try{return JSON.parse(P(vn))}catch{return null}}function Xa(e){if(B(vn,JSON.stringify(e,null,2)),process.platform!=="win32")try{Sg(vn,384)}catch{}}async function kg(e){let t=await fetch(wg,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:xg})});if(!t.ok)throw Zs(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Xa({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Fi(e,t=""){Xa({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Ze(){let e=Xs();return e?e.expires_at>Date.now():!1}async function Di(){let e=Xs();if(!e)return null;if(e.expires_at-Date.now()>Cg)return e.access_token;if(e.refresh_token){qs||(qs=kg(e.refresh_token).finally(()=>{qs=null}));try{await qs}catch{return null}return Xs()?.access_token??null}return e.access_token}function en(){let e=Xs();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function Zs(){if(x(vn))try{vg(vn)}catch{}}var xg,wg,vn,Cg,Zn,xn,qs,$t=N(()=>{"use strict";y();oe();xg="9d1c250a-e61b-44d9-88ed-5944d1962f5e",wg="https://console.anthropic.com/v1/oauth/token",vn=yg(bg(),".vibespot","claude-oauth.json"),Cg=300*1e3,Zn={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},xn="You are Claude Code, Anthropic's official CLI for Claude.";qs=null});import{join as Qs}from"path";import{homedir as eo}from"os";import{readFileSync as Za,existsSync as to,readdirSync as Tg}from"fs";function Qn(){let e=ie("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:ie(`${tn} node`).stdout}}function es(){let e=ie("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:ie(`${tn} git`).stdout}}function ft(){let e=ie("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:ie(`${tn} hs`).stdout}}function kn(){let e=ie("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Qs(eo(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(to(t)){let o=Tg(t);(o.some(r=>r.includes("credentials")||r.includes("auth")||r.includes("token")||r===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:ie(`${tn} claude`).stdout,authenticated:n,authDetail:s}}function ts(e){try{let t=Qs(eo(),".hscli","config.yml");if(!to(t))return"na1";let n=Za(t,"utf-8"),s=n.indexOf(`accountId: ${e}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let r=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!r)return"na1";if(r[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function ht(){let e=ie("hs accounts list",{timeout:Qa});if(!e.success||!e.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let t=[],n="",s="",o=e.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=e.stdout.split(`
2
- `);for(let r of i){let a=r.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(a&&!/Account ID/i.test(r)&&!/^-+$/.test(r.trim())&&!/^Name\s/i.test(r.trim())){let l=a[1].trim(),c=a[2].trim(),d=a[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Tn(){let e=ie("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Qs(eo(),".config","gcloud","application_default_credentials.json"),n=to(t),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:e.stdout,path:ie(`${tn} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function An(){let e=ie("codex --version");if(!e.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=!!process.env.OPENAI_API_KEY,n=!1;try{let i=Qs(eo(),".codex","auth.json");to(i)&&(n=Za(i,"utf-8").length>10)}catch{}let s=t||n,o=n?"Authenticated (OAuth)":t?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:e.stdout,path:ie(`${tn} codex`).stdout,authenticated:s,authDetail:o}}function no(){let e=ie("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
3
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:ie(`${tn} gh`).stdout}}function so(){let e=ie("gh auth status 2>&1",{timeout:Qa});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 el(){return!!process.env.ANTHROPIC_API_KEY}function oo(e){return parseInt(e.split(".")[0],10)>=18}function tl(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function Ag(){let e=R(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Ht();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function wn(e,...t){if(e)return{configured:!0,masked:Ys(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:Ys(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function Li(e){return{anthropic:wn(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:wn(e.openaiApiKey,"OPENAI_API_KEY"),gemini:wn(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:wn(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:wn(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:wn(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function Ji(e){let t=[];return e.claudeCode&&t.push("claude-code"),e.claudeOAuth&&t.push("claude-oauth"),e.apiKeys.anthropic.configured&&t.push("anthropic-api"),e.apiKeys.openai.configured&&t.push("openai-api"),e.geminiCli&&t.push("gemini-cli"),e.apiKeys.gemini.configured&&t.push("gemini-api"),e.codexCli&&t.push("codex-cli"),e.apiKeys.langdock.configured&&t.push("langdock-api"),t}function Bi(e,t){if(e==="cli"){if(!t)return{name:"HubSpot CLI",found:!1,version:"",path:"",authenticated:!1,portalName:"",portalId:"",dataCenter:"na1",accounts:[],uploadMode:"cli"};let n=ft(),s=n.found?ht():{authenticated:!1,portalName:"",portalId:"",accounts:[]},o=s.portalId?ts(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...Ag()}}function nl(){let e=R(),t=e.hubspotUploadMode||"api",n=Li(e),s={authenticated:Ze(),expiresAt:en()?.expiresAt},o=r=>({name:r,found:!1,version:"",path:"",authenticated:!1,authDetail:"Not scanned"}),i=r=>({name:r,found:!1,version:"",path:""});return{tools:{node:i("Node.js"),git:i("Git"),hubspot:Bi(t,!1),github:{...i("GitHub CLI"),authenticated:!1,username:""},claudeCode:o("Claude Code"),claudeOAuth:s,geminiCli:o("Gemini CLI"),codexCli:o("OpenAI Codex CLI")},apiKeys:n,activeEngine:e.aiEngine||null,availableEngines:Ji({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:st("claude-code"),geminiCli:st("gemini-cli"),codexCli:st("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function sl(){let e=R(),t=Li(e),n={authenticated:Ze(),expiresAt:en()?.expiresAt},s=st("claude-code")?kn():{...Cn,name:"Claude Code"},o=st("gemini-cli")?Tn():{...Cn,name:"Gemini CLI"},i=st("codex-cli")?An():{...Cn,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:i,claudeOAuth:n,availableEngines:Ji({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:i.found&&i.authenticated})}}function ol(){let t=R().hubspotUploadMode||"api",n=no(),s=n.found?so():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:Bi(t,!0)}}function io(){let e=R(),t=e.hubspotUploadMode||"api",n=Qn(),s=es(),o=Bi(t,!0),i=no(),r=i.found?so():{authenticated:!1,username:""},a={authenticated:Ze(),expiresAt:en()?.expiresAt},l=st("claude-code")?kn():{...Cn,name:"Claude Code"},c=st("gemini-cli")?Tn():{...Cn,name:"Gemini CLI"},d=st("codex-cli")?An():{...Cn,name:"OpenAI Codex CLI"},u=Li(e);return{tools:{node:n,git:s,hubspot:o,github:{...i,...r},claudeCode:l,claudeOAuth:a,geminiCli:c,codexCli:d},apiKeys:u,activeEngine:e.aiEngine||null,availableEngines:Ji({apiKeys:u,claudeOAuth:a.authenticated,claudeCode:l.found&&l.authenticated,geminiCli:c.found&&c.authenticated,codexCli:d.found&&d.authenticated}),enabledCLITools:e.enabledCLITools||[],scanned:!0}}var tn,Qa,Cn,nn=N(()=>{"use strict";y();Qt();ee();$t();tn=process.platform==="win32"?"where":"which",Qa=4e3;Cn={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as _g}from"fs";import{basename as $g}from"path";async function rl(e){let t=il.get(e);if(t&&t.expiresAt-Date.now()>Ig)return t;let n=await fetch(`${Et}/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 il.set(e,o),o}async function _n(e){let{accessToken:t}=await rl(e);return{Authorization:`Bearer ${t}`}}function ro(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function Pg(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Ng(e){return new Promise(t=>setTimeout(t,e))}async function ns(e,t){let n=`HTTP ${e.status}`,s,o;try{let i=await e.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let r=i.errors[0];o=r.message||JSON.stringify(r)}}catch{try{let i=await e.text();i&&(n=i.slice(0,500))}catch{}}return{status:e.status,message:t?`${n} (${t})`:n,category:s,detail:o}}async function ss(e,t,n=Eg){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=Mg*Math.pow(2,s);await Ng(i);continue}return o}return fetch(e,t)}async function ao(e){let t=await rl(e),n=`${Et}/account-info/v3/details`,s=await ss(n,{headers:await _n(e)});if(!s.ok){let a=await ns(s);throw new Error(`Failed to get account info: ${a.message}`)}let o=await s.json(),i=String(o.portalId||t.hubId||""),r=t.hubName||o.uiDomain||i;return{portalId:i,portalName:r,dataCenter:Pg(e)}}async function al(e,t,n){let s=_g(n),o=$g(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${Et}/cms/v3/source-code/published/content/${ro(t)}`,l=await ss(a,{method:"PUT",headers:await _n(e),body:i});if(!l.ok){let c=await ns(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function Hi(e,t){let n=`${Et}/cms/v3/source-code/published/content/${ro(t)}`,s=await ss(n,{method:"DELETE",headers:await _n(e)});if(!s.ok&&s.status!==404){let o=await ns(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function ll(e,t){let n=`${Et}/cms/v3/source-code/published/content/${ro(t)}`,s=await ss(n,{method:"GET",headers:await _n(e)});if(!s.ok){let i=await ns(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function lo(e,t){let n=`${Et}/cms/v3/source-code/published/metadata/${ro(t)}`,s=await ss(n,{method:"GET",headers:await _n(e)});if(s.status===404)return null;if(!s.ok){let o=await ns(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function cl(e){let t=await _n(e),n=[`${Et}/cms/v3/source-code/published/metadata`,`${Et}/cms/v3/source-code/published/metadata/`,`${Et}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let i=await o.json(),r=i.children||i.objects||(Array.isArray(i)?i:null);if(r&&r.length>0)return r.filter(a=>a.folder)}}catch{}return[]}var Et,Eg,Mg,Ig,il,sn=N(()=>{"use strict";y();Et="https://api.hubapi.com",Eg=3,Mg=1e3,Ig=300*1e3,il=new Map});import*as ae from"@clack/prompts";function Ui(e){ae.isCancel(e)&&(ae.cancel(I.muted("Operation cancelled.")),process.exit(0))}async function ge(e){ae.intro(I.heading(e))}async function fe(e){ae.outro(I.success(e))}async function yt(e,t){ae.note(e,t?I.heading(t):void 0)}async function Se(e){let t=e.validate,n=await ae.text({message:I.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:t?s=>t(s??""):void 0});return Ui(n),n}async function Me(e){let t=await ae.confirm({message:I.accent(e.message),initialValue:e.initialValue??!0});return Ui(t),t}async function Mt(e){let t=await ae.select({message:I.accent(e.message),options:e.options});return Ui(t),t}async function De(){let e=ae.spinner();return{start:t=>e.start(I.muted(t)),stop:t=>e.stop(I.success(t)),message:t=>e.message(I.muted(t))}}function D(e){ae.log.info(e)}function G(e){ae.log.success(I.success(e))}function se(e){ae.log.warn(I.warn(e))}function V(e){ae.log.error(I.error(e))}var Qe=N(()=>{"use strict";y();gt()});import{readdirSync as Gi,statSync as Rg}from"fs";import{join as he,basename as Wi,extname as Og}from"path";function dl(e){return typeof e!="string"||e.length===0||e.length>2048||/[\s;&|`$()<>\\]/.test(e)?!1:!!(/^https?:\/\/[^\s]+$/.test(e)||/^git@[\w.-]+:[\w./~+-]+$/.test(e))}function ul(e){let t=[],n=[he(e,"src/components/landing"),he(e,"src/components/sections"),he(e,"src/components"),he(e,"src/pages"),he(e,"app/components"),he(e,"components")];for(let s of n)if(x(s))try{let o=Gi(s);for(let i of o){let r=he(s,i);if(!Rg(r).isFile())continue;let l=Og(i);if(![".tsx",".jsx"].includes(l))continue;let c=Wi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=P(r),u=Fg(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function Fg(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 ml(e){let t=[he(e,"src/index.css"),he(e,"src/globals.css"),he(e,"src/app/globals.css"),he(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!x(o))continue;let i=P(o),r=i.match(/--[\w-]+:/g);r&&(n+=r.length);let a=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(a)for(let c of a){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function pl(e){let t=[],n=he(e,"src/hooks");if(x(n))try{let o=Gi(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=he(e,"src/components/landing");if(x(s))try{let o=Gi(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=P(he(s,i));/carousel|embla|swiper/i.test(r)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(r)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(r)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(r)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function gl(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!dl(e))throw new Error(`Refusing to clone unsafe source URL: ${e}. Only http(s):// and git@host:path URLs without shell metacharacters are allowed.`);n=!0;let l=Wi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",l),!x(t)){let c=Z(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!x(t))throw new Error(`Directory not found: ${t}`);let s=ul(t),o=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:i,fonts:r}=ml(t),a=pl(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function uo(){await ge("Source Project");let e=await Se({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){dl(e)||(V("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let h=Wi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",h),x(t))G(`Using existing clone: ${I.dim(t)}`);else{let f=await De();f.start("Cloning repository..."),Z(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${I.dim(t)}`)}}else t=e,x(t)||(V(`Directory not found: ${t}`),process.exit(1)),G(`Using local source: ${I.dim(t)}`);let s=await De();s.start("Analyzing project structure...");let o=ul(t),i=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:r,fonts:a}=ml(t),l=pl(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(se("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${I.dim(`${f+1}.`)} ${I.bold(h.name)} ${I.muted(`\u2014 ${h.description}`)}`).join(`
4
- `),d=i?`Tailwind + custom CSS (${r} variables)`:`Custom CSS (${r} variables)`,u=a.length>0?a.join(", "):"System fonts",m=l.join(", ");return await yt(`${c}
5
-
6
- CSS: ${d}
7
- JS: ${m}
8
- Font: ${u}`,`${o.length} components detected`),await Me({message:"Does this look right?"})||(V("Please adjust your source directory and try again."),process.exit(0)),await fe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var mo=N(()=>{"use strict";y();Qt();oe();Qe();gt()});var fl={};Ge(fl,{addEmailTemplateToTheme:()=>$n,createThemeScaffold:()=>is});import{mkdirSync as It,writeFileSync as os}from"fs";import{join as We}from"path";function is(e,t){It(e,{recursive:!0}),It(We(e,"templates"),{recursive:!0}),It(We(e,"modules"),{recursive:!0}),It(We(e,"css"),{recursive:!0}),It(We(e,"js"),{recursive:!0}),It(We(e,"images"),{recursive:!0}),It(We(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};os(We(e,"theme.json"),JSON.stringify(n,null,2)+`
9
- `),os(We(e,"fields.json"),`[]
1
+ var Yf=Object.defineProperty;var j=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ve=(e,t)=>{for(var n in t)Yf(e,n,{get:t[n],enumerable:!0})};import Ok from"path";import{fileURLToPath as Dk}from"url";var y=j(()=>{"use strict"});import{readFileSync as di,writeFileSync as Xf,mkdirSync as Il,existsSync as mo}from"fs";import{dirname as Ml,join as It}from"path";import{fileURLToPath as Zf}from"url";function I(e){return di(e,"utf-8")}function U(e,t){Il(Ml(e),{recursive:!0}),Xf(e,t,"utf-8")}function w(e){return mo(e)}function $e(e){Il(e,{recursive:!0})}function Kt(e){let t=[It(Pn,"../../assets",e),It(Pn,"../assets",e),It(process.cwd(),"assets",e)];for(let n of t)if(mo(n))return n;throw new Error(`Asset not found: ${e}`)}function Mt(){if(_n)return _n;let e=[It(Pn,"../../package.json"),It(Pn,"../package.json"),It(process.cwd(),"package.json")];for(let t of e)if(mo(t))try{let n=JSON.parse(di(t,"utf-8"));if(n.name==="vibespot"&&n.version)return _n=n.version,_n}catch{}return _n="dev",_n}function $l(){if(po)return po;let e=[It(Pn,"../../CHANGELOG.md"),It(Pn,"../CHANGELOG.md"),It(process.cwd(),"CHANGELOG.md")];for(let t of e)if(mo(t))try{return po=di(t,"utf-8"),po}catch{}return""}var Pn,_n,po,ae=j(()=>{"use strict";y();Pn=Ml(Zf(import.meta.url));_n="";po=""});import{execSync as Rl,execFileSync as Nl}from"child_process";function Se(e,t={}){try{return{stdout:Rl(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),r=(s.stderr??"").toString().trim();return{stdout:o,stderr:r,success:!1}}}function ee(e,t={}){try{return{stdout:Nl("git",e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),r=(s.stderr??"").toString().trim();return{stdout:o,stderr:r,success:!1}}}function cs(e,t,n={}){try{return{stdout:Nl(e,t,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,shell:process.platform==="win32",...n}).toString().trim(),stderr:"",success:!0}}catch(s){let o=s,r=(o.stdout??"").toString().trim(),i=(o.stderr??"").toString().trim();return{stdout:r,stderr:i,success:!1}}}function Ol(e,t={}){try{return Rl(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var on=j(()=>{"use strict";y()});var Dl={};Ve(Dl,{addHubSpotAccount:()=>us,getActiveHubSpotAccount:()=>Vt,getApiKeyForEngine:()=>De,getConfigDir:()=>sh,getHubSpotPak:()=>Je,isCliToolEnabled:()=>rt,loadConfig:()=>$,maskApiKey:()=>fo,removeHubSpotAccount:()=>fi,saveConfig:()=>Y,setActiveHubSpotAccount:()=>hi,setCliToolEnabled:()=>yi});import{join as gi}from"path";import{homedir as Qf}from"os";import{chmodSync as ui,mkdirSync as eh,renameSync as th,writeFileSync as nh}from"fs";function mi(){if(process.platform!=="win32"){try{ui(ds,Fl)}catch{}try{ui(go,pi)}catch{}}}function $(){let e={};if(w(go))try{mi(),e=JSON.parse(I(go)),e.aiEngine==="api"&&(e.aiEngine="anthropic-api")}catch{e={}}return process.env.VIBESPOT_AI_ENGINE&&!e.aiEngine&&(e.aiEngine=process.env.VIBESPOT_AI_ENGINE),process.env.ANTHROPIC_API_KEY&&!e.anthropicApiKey&&(e.anthropicApiKey=process.env.ANTHROPIC_API_KEY),process.env.OPENAI_API_KEY&&!e.openaiApiKey&&(e.openaiApiKey=process.env.OPENAI_API_KEY),(process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)&&!e.geminiApiKey&&(e.geminiApiKey=process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY),process.env.LANGDOCK_API_KEY&&!e.langdockApiKey&&(e.langdockApiKey=process.env.LANGDOCK_API_KEY),process.env.LANGDOCK_BASE_URL&&!e.langdockBaseUrl&&(e.langdockBaseUrl=process.env.LANGDOCK_BASE_URL),process.env.LANGDOCK_PROVIDER&&!e.langdockProvider&&(e.langdockProvider=process.env.LANGDOCK_PROVIDER),process.env.FIGMA_TOKEN&&!e.figmaToken&&(e.figmaToken=process.env.FIGMA_TOKEN),process.env.VIBESPOT_AGENTIC_MODE!==void 0&&e.agenticMode===void 0&&(e.agenticMode=process.env.VIBESPOT_AGENTIC_MODE==="true"),process.env.LANGFUSE_PUBLIC_KEY&&!e.langfusePublicKey&&(e.langfusePublicKey=process.env.LANGFUSE_PUBLIC_KEY),process.env.LANGFUSE_SECRET_KEY&&!e.langfuseSecretKey&&(e.langfuseSecretKey=process.env.LANGFUSE_SECRET_KEY),process.env.LANGFUSE_BASE_URL&&!e.langfuseBaseUrl&&(e.langfuseBaseUrl=process.env.LANGFUSE_BASE_URL),process.env.LANGFUSE_ENABLED!==void 0&&e.langfuseEnabled===void 0&&(e.langfuseEnabled=process.env.LANGFUSE_ENABLED==="true"),e}function De(e,t){let n=t||$();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;case"langdock-api":return n.langdockApiKey||process.env.LANGDOCK_API_KEY;default:return}}function fo(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function Y(e){let n={...$(),...e},s=JSON.stringify(n,null,2);eh(ds,{recursive:!0,mode:Fl}),mi();let o=gi(ds,`.config.json.${process.pid}.${Date.now()}.tmp`);if(nh(o,s,{encoding:"utf-8",mode:pi,flag:"w"}),process.platform!=="win32")try{ui(o,pi)}catch{}th(o,go),mi()}function sh(){return ds}function Vt(){let e=$();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function us(e,t,n,s){let r=$().hubspotAccounts||[],i=r.findIndex(l=>l.portalId===t),a={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};i>=0?r[i]=a:r.push(a),Y({hubspotAccounts:r,activeHubSpotAccount:t})}function fi(e){let t=$(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),Y(s)}function hi(e){Y({activeHubSpotAccount:e})}function Je(){return Vt()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function rt(e){return $().enabledCLITools?.includes(e)??!1}function yi(e,t){let n=$(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),Y({enabledCLITools:[...s]})}var ds,go,pi,Fl,te=j(()=>{"use strict";y();ae();ds=gi(Qf(),".vibespot"),go=gi(ds,"config.json"),pi=384,Fl=448});var Ci={};Ve(Ci,{OAUTH_EXTRA_HEADERS:()=>ms,OAUTH_SYSTEM_PREFIX:()=>In,clearOAuthTokens:()=>ps,getOAuthTokenInfo:()=>rn,getValidAccessToken:()=>ki,hasValidOAuthToken:()=>Qe,saveInitialToken:()=>wi});import{join as xi}from"path";import{homedir as oh}from"os";import{chmodSync as bi,mkdirSync as rh,renameSync as ih,unlinkSync as ah,writeFileSync as lh}from"fs";function vi(){if(process.platform!=="win32"){try{bi(yo,jl)}catch{}try{bi(En,Si)}catch{}}}function ph(e){if(!e||typeof e!="object")return null;let t=e;return typeof t.access_token!="string"||!t.access_token||typeof t.refresh_token!="string"||typeof t.expires_at!="number"||!Number.isFinite(t.expires_at)?null:{access_token:t.access_token,refresh_token:t.refresh_token,expires_at:t.expires_at}}function bo(){if(!w(En))return null;try{return vi(),ph(JSON.parse(I(En)))}catch{return null}}function Ll(e){rh(yo,{recursive:!0,mode:jl}),vi();let t=xi(yo,`.claude-oauth.json.${process.pid}.${Date.now()}.tmp`);if(lh(t,JSON.stringify(e,null,2),{encoding:"utf-8",mode:Si,flag:"w"}),process.platform!=="win32")try{bi(t,Si)}catch{}ih(t,En),vi()}async function mh(e){let t=await fetch(dh,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:ch})});if(!t.ok)throw ps(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();if(typeof n.access_token!="string"||!n.access_token)throw ps(),new Error("Claude OAuth refresh returned an invalid token payload. Please re-authenticate in Settings.");let s=typeof n.expires_in=="number"&&Number.isFinite(n.expires_in)?n.expires_in:28800;Ll({access_token:n.access_token,refresh_token:typeof n.refresh_token=="string"?n.refresh_token:e,expires_at:Date.now()+s*1e3})}function wi(e,t=""){Ll({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Qe(){let e=bo();return e?e.expires_at>Date.now():!1}async function ki(){let e=bo();if(!e)return null;if(e.expires_at-Date.now()>uh)return e.access_token;if(e.refresh_token){ho||(ho=mh(e.refresh_token).finally(()=>{ho=null}));try{await ho}catch{return null}return bo()?.access_token??null}return e.access_token}function rn(){let e=bo();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function ps(){if(w(En))try{ah(En)}catch{}}var ch,dh,yo,En,uh,Si,jl,ms,In,ho,$t=j(()=>{"use strict";y();ae();ch="9d1c250a-e61b-44d9-88ed-5944d1962f5e",dh="https://console.anthropic.com/v1/oauth/token",yo=xi(oh(),".vibespot"),En=xi(yo,"claude-oauth.json"),uh=300*1e3,Si=384,jl=448,ms={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},In="You are Claude Code, Anthropic's official CLI for Claude.";ho=null});import{readFileSync as hh}from"fs";import{basename as yh}from"path";import{createHash as bh}from"crypto";function wh(e){return bh("sha256").update(e).digest("hex")}function kh(e=Date.now()){for(let[t,n]of ln)n.expiresAt-e<=Vl&&ln.delete(t)}function Ch(){for(;ln.size>xh;){let e=ln.keys().next().value;if(!e)return;ln.delete(e)}}async function zl(e){kh();let t=wh(e),n=ln.get(t);if(n&&n.expiresAt-Date.now()>Vl)return n;let s=await fetch(`${Rt}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:e})});if(!s.ok){let i=await s.text().catch(()=>"");throw new Error(s.status===401||s.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${s.status}): ${i.slice(0,200)}`)}let o=await s.json();if(typeof o.oauthAccessToken!="string"||!o.oauthAccessToken||typeof o.expiresAtMillis!="number"||!Number.isFinite(o.expiresAtMillis)||o.expiresAtMillis<=Date.now())throw new Error("Token exchange returned an invalid token payload");let r={accessToken:o.oauthAccessToken,expiresAt:o.expiresAtMillis,hubId:typeof o.hubId=="number"?o.hubId:Number(o.hubId||0),hubName:typeof o.hubName=="string"?o.hubName:""};return ln.set(t,r),Ch(),r}async function Fn(e){let{accessToken:t}=await zl(e);return{Authorization:`Bearer ${t}`}}function Ao(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function Th(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Ah(e){return new Promise(t=>setTimeout(t,e))}async function ys(e,t){let n=`HTTP ${e.status}`,s,o;try{let r=await e.json();if(r.message&&typeof r.message=="string"&&(n=r.message),r.category&&typeof r.category=="string"&&(s=r.category),r.errors&&Array.isArray(r.errors)&&r.errors.length>0){let i=r.errors[0];o=i.message||JSON.stringify(i)}}catch{try{let r=await e.text();r&&(n=r.slice(0,500))}catch{}}return{status:e.status,message:t?`${n} (${t})`:n,category:s,detail:o}}async function bs(e,t,n=Sh){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let r=vh*Math.pow(2,s);await Ah(r);continue}return o}return fetch(e,t)}async function _o(e){let t=await zl(e),n=`${Rt}/account-info/v3/details`,s=await bs(n,{headers:await Fn(e)});if(!s.ok){let a=await ys(s);throw new Error(`Failed to get account info: ${a.message}`)}let o=await s.json(),r=String(o.portalId||t.hubId||""),i=t.hubName||o.uiDomain||r;return{portalId:r,portalName:i,dataCenter:Th(e)}}async function ql(e,t,n){let s=hh(n),o=yh(n),r=new FormData,i=new Blob([s]);r.append("file",i,o);let a=`${Rt}/cms/v3/source-code/published/content/${Ao(t)}`,l=await bs(a,{method:"PUT",headers:await Fn(e),body:r});if(!l.ok){let c=await ys(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function Pi(e,t){let n=`${Rt}/cms/v3/source-code/published/content/${Ao(t)}`,s=await bs(n,{method:"DELETE",headers:await Fn(e)});if(!s.ok&&s.status!==404){let o=await ys(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Yl(e,t){let n=`${Rt}/cms/v3/source-code/published/content/${Ao(t)}`,s=await bs(n,{method:"GET",headers:await Fn(e)});if(!s.ok){let r=await ys(s,t);throw new Error(`Failed to download ${t}: ${r.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Po(e,t){let n=`${Rt}/cms/v3/source-code/published/metadata/${Ao(t)}`,s=await bs(n,{method:"GET",headers:await Fn(e)});if(s.status===404)return null;if(!s.ok){let o=await ys(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Xl(e){let t=await Fn(e),n=[`${Rt}/cms/v3/source-code/published/metadata`,`${Rt}/cms/v3/source-code/published/metadata/`,`${Rt}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let r=await o.json(),i=r.children||r.objects||(Array.isArray(r)?r:null);if(i&&i.length>0)return i.filter(a=>a.folder)}}catch{}return[]}var Rt,Sh,vh,Vl,xh,ln,cn=j(()=>{"use strict";y();Rt="https://api.hubapi.com",Sh=3,vh=1e3,Vl=300*1e3,xh=25,ln=new Map});var sc={};Ve(sc,{addEmailTemplateToTheme:()=>jn,createThemeScaffold:()=>vs});import{mkdirSync as Ot,writeFileSync as Ss}from"fs";import{join as ze}from"path";function vs(e,t){Ot(e,{recursive:!0}),Ot(ze(e,"templates"),{recursive:!0}),Ot(ze(e,"modules"),{recursive:!0}),Ot(ze(e,"css"),{recursive:!0}),Ot(ze(e,"js"),{recursive:!0}),Ot(ze(e,"images"),{recursive:!0}),Ot(ze(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};Ss(ze(e,"theme.json"),JSON.stringify(n,null,2)+`
2
+ `),Ss(ze(e,"fields.json"),`[]
10
3
  `);let s=`<!--
11
4
  templateType: page
12
5
  isAvailableForNewContent: false
@@ -22,7 +15,7 @@ var dg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
22
15
  %}
23
16
  {% end_dnd_area %}
24
17
  {% endblock body %}
25
- `;os(We(e,"templates","home.html"),s);let o=`<!--
18
+ `;Ss(ze(e,"templates","home.html"),s);let o=`<!--
26
19
  templateType: none
27
20
  isAvailableForNewContent: false
28
21
  label: Base Layout
@@ -45,7 +38,7 @@ var dg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
45
38
  {{ standard_footer_includes }}
46
39
  </body>
47
40
  </html>
48
- `;It(We(e,"templates","layouts"),{recursive:!0}),os(We(e,"templates","layouts","base.html"),o)}function $n(e,t){let n=`<!--
41
+ `;Ot(ze(e,"templates","layouts"),{recursive:!0}),Ss(ze(e,"templates","layouts","base.html"),o)}function jn(e,t){let n=`<!--
49
42
  templateType: email
50
43
  isAvailableForNewContent: true
51
44
  label: ${t} Email Template
@@ -84,8 +77,8 @@ var dg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
84
77
  {{ standard_footer_includes }}
85
78
  </body>
86
79
  </html>
87
- `;It(We(e,"templates"),{recursive:!0}),os(We(e,"templates","email.html"),n)}var rs=N(()=>{"use strict";y()});var yl={};Ge(yl,{fetchTheme:()=>as});import{mkdirSync as hl,writeFileSync as Dg}from"fs";import{join as jg,dirname as Lg}from"path";async function Ki(e,t){let n=await lo(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let i of o){let r=typeof i=="string"?i:i.name;if(!r)continue;let a=`${t}/${r}`;if(typeof i=="string")s.push(...await Ki(e,a));else{let l=i;l.folder?s.push(...await Ki(e,l.path||a)):s.push(l.path||a)}}return s}async function Jg(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function as(e,t,n,s={}){let o=s.concurrency??5,i=await Ki(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);hl(n,{recursive:!0}),await Jg(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=jg(n,a);hl(Lg(l),{recursive:!0});let c=await ll(e,r);Dg(l,c),s.onFile?.(a)})}var po=N(()=>{"use strict";y();sn()});function Ut(e){let t=bl.get(e);if(t!==void 0)return t;try{t=P(bn(e))}catch{t=""}return bl.set(e,t),t}function ye(){return Ut("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function cs(){return Ut("design-guide.md")}function Vi(){return Ut("content-guide.md")}function Je(){return Ut("hubspot-rules.md")}function zi(){return Ut("humanify-guide.md")}function Sl(){return Ut("email-rules.md")}function vl(){return Ut("blog-rules.md")}function Yi(e){let t=Ut("page-types.md");if(!t)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[e];if(!s)return"";let o=t.indexOf(s);if(o<0)return"";let i=t.indexOf(`
88
- ## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function xl(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
80
+ `;Ot(ze(e,"templates"),{recursive:!0}),Ss(ze(e,"templates","email.html"),n)}var xs=j(()=>{"use strict";y()});import{join as Ih,resolve as Mo,dirname as Mh,sep as $h}from"path";function He(e){return String(e||"").trim().toLowerCase().replace(/['"]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function ws(e){return!e||e==="."||e===".."?!1:!/[/\\\0]/.test(e)}function dn(e,t){let n=Mo(e);if(!ws(`${t}.module`))throw new Error(`Unsafe module name rejected: ${JSON.stringify(t)}`);let s=Mo(n,`${t}.module`);if(Mh(s)!==n||!s.endsWith(".module"))throw new Error(`Unsafe module name rejected: ${JSON.stringify(t)}`);return s}function Ln(e,t){if(t.includes("\0"))throw new Error(`Unsafe path rejected: ${JSON.stringify(t)}`);let n=Ih(e,t),s=Mo(e),o=Mo(n);if(o!==s&&!o.startsWith(s+$h))throw new Error(`Path escapes target directory: ${JSON.stringify(t)}`);return n}var wt=j(()=>{"use strict";y()});var rc={};Ve(rc,{fetchTheme:()=>ks});import{mkdirSync as oc,writeFileSync as Rh}from"fs";import{dirname as Nh}from"path";async function $i(e,t){let n=await Po(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let r of o){let i=typeof r=="string"?r:r.name;if(!i)continue;let a=`${t}/${i}`;if(typeof r=="string")s.push(...await $i(e,a));else{let l=r;l.folder?s.push(...await $i(e,l.path||a)):s.push(l.path||a)}}return s}async function Oh(e,t,n){let s=0;async function o(){for(;s<e.length;){let i=s++;await n(e[i])}}let r=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(r)}async function ks(e,t,n,s={}){let o=s.concurrency??5,r=await $i(e,t);if(r.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);oc(n,{recursive:!0}),await Oh(r,o,async i=>{let a=i.startsWith(t+"/")?i.slice(t.length+1):i,l=Ln(n,a);oc(Nh(l),{recursive:!0});let c=await Yl(e,i);Rh(l,c),s.onFile?.(a)})}var $o=j(()=>{"use strict";y();wt();cn()});function zt(e){let t=ic.get(e);if(t!==void 0)return t;try{t=I(Kt(e))}catch{t=""}return ic.set(e,t),t}function Ce(){return zt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function No(){return zt("design-guide.md")}function ac(){return zt("content-guide.md")}function et(){return zt("hubspot-rules.md")}function lc(){return zt("humanify-guide.md")}function cc(){return zt("email-rules.md")}function dc(){return zt("blog-rules.md")}function uc(e){let t=zt("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 r=t.indexOf(`
81
+ ## `,o+s.length);return r>=0?t.slice(o,r).trim():t.slice(o).trim()}function pc(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
89
82
 
90
83
  ## Rules
91
84
  Follow the conversion guide below EXACTLY. Key rules:
@@ -102,10 +95,10 @@ Follow the conversion guide below EXACTLY. Key rules:
102
95
  - Convert React hooks to vanilla JS (no React, no npm packages)
103
96
 
104
97
  ## HubSpot CMS Rules
105
- ${Je()}
98
+ ${et()}
106
99
 
107
100
  ## Conversion Guide
108
- ${e}`}function wl(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
101
+ ${e}`}function mc(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
109
102
 
110
103
  Return a JSON object with these keys:
111
104
  - fieldsJson: complete fields.json content (as JSON string)
@@ -120,7 +113,7 @@ ${n}
120
113
  React component source:
121
114
  ${e}
122
115
 
123
- Return ONLY valid JSON, no markdown fences.`}function Cl(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
116
+ Return ONLY valid JSON, no markdown fences.`}function gc(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
124
117
 
125
118
  Extract the design system from the source CSS and Tailwind config below.
126
119
  Use the class prefix ".${n}-" for all custom classes.
@@ -144,7 +137,7 @@ ${e}
144
137
  Tailwind config:
145
138
  ${t}
146
139
 
147
- Return ONLY the CSS content, no markdown fences.`}function kl(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
140
+ Return ONLY the CSS content, no markdown fences.`}function fc(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
148
141
 
149
142
  Convert the React hooks and interactive components below to plain JavaScript.
150
143
  Use the class prefix "${n}-" to match the CSS.
@@ -162,7 +155,7 @@ ${e}
162
155
  Interactive component sources:
163
156
  ${t}
164
157
 
165
- Return ONLY the JavaScript content, no markdown fences.`}function Tl(e,t,n){return`Create a HubSpot page template that assembles these modules:
158
+ Return ONLY the JavaScript content, no markdown fences.`}function hc(e,t,n){return`Create a HubSpot page template that assembles these modules:
166
159
 
167
160
  ${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
168
161
  `)}
@@ -177,30 +170,27 @@ Template requirements:
177
170
  - Each module in its own dnd_section with padding zeroed and full_width=true
178
171
  - dnd_area label: "${t} Landing Page"
179
172
 
180
- Return ONLY the template HTML content, no markdown fences.`}var bl,Ke=N(()=>{"use strict";y();oe();bl=new Map});import{appendFileSync as Wg,mkdirSync as Kg,readdirSync as Vg,unlinkSync as zg}from"fs";import{join as Qi}from"path";import{homedir as Yg}from"os";function Xg(){if(!Xi)try{Kg(ho,{recursive:!0}),Xi=!0}catch{}}function Zg(){if(!Zi){Zi=!0;try{let e=Date.now()-qg*864e5;for(let t of Vg(ho)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{zg(Qi(ho,t))}catch{}}}catch{}}}function Qg(){let t=new Date().toISOString().slice(0,10);return Qi(ho,`vibespot-${t}.log`)}function ef(){return new Date().toISOString().slice(11,23)}function qi(e,t){if(Xg(),!!Xi){Zi||Zg();try{Wg(Qg(),`${ef()} ${e} ${t}
181
- `)}catch{}}}var ho,qg,Xi,Zi,M,le=N(()=>{"use strict";y();ho=Qi(Yg(),".vibespot","logs"),qg=7,Xi=!1,Zi=!1;M={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),qi("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),qi("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),qi("ERROR",o)}}});function nf(e){let t=(e||"").toLowerCase();return tf.find(n=>t.includes(n.match))}function ds(e,t){let n=nf(e);if(!n)return;let s=n.cacheReadPerM??n.inputPerM*.1,o=n.cacheWritePerM??n.inputPerM*1.25,i=(t.inputTokens??0)*n.inputPerM,r=(t.outputTokens??0)*n.outputPerM,a=(t.cacheReadTokens??0)*s,l=(t.cacheCreationTokens??0)*o,c={total:(i+r+a+l)/1e6};return t.inputTokens!=null&&(c.input=i/1e6),t.outputTokens!=null&&(c.output=r/1e6),t.cacheReadTokens&&(c.cache_read_input_tokens=a/1e6),t.cacheCreationTokens&&(c.cache_creation_input_tokens=l/1e6),c}function et(e){if(e)return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_input_tokens??void 0,cacheCreationTokens:e.cache_creation_input_tokens??void 0}}function En(e){if(!e)return;let t=e.prompt_tokens_details?.cached_tokens??0,n=e.prompt_tokens;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.completion_tokens,totalTokens:e.total_tokens,cacheReadTokens:t||void 0}}function Mn(e){if(!e)return;let t=e.cachedContentTokenCount??0,n=e.promptTokenCount;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.candidatesTokenCount,totalTokens:e.totalTokenCount,cacheReadTokens:t||void 0}}function _l(e){let t={};return e.inputTokens!=null&&(t.input=e.inputTokens),e.outputTokens!=null&&(t.output=e.outputTokens),e.cacheReadTokens&&(t.cache_read_input_tokens=e.cacheReadTokens),e.cacheCreationTokens&&(t.cache_creation_input_tokens=e.cacheCreationTokens),e.totalTokens!=null&&(t.total=e.totalTokens),t}var tf,on=N(()=>{"use strict";y();tf=[{match:"claude-opus-4",inputPerM:15,outputPerM:75},{match:"claude-sonnet-4",inputPerM:3,outputPerM:15},{match:"claude-haiku-4",inputPerM:1,outputPerM:5},{match:"claude-3-7-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-haiku",inputPerM:.8,outputPerM:4},{match:"claude-3-opus",inputPerM:15,outputPerM:75},{match:"gpt-5.5",inputPerM:5,outputPerM:30},{match:"gpt-5.4",inputPerM:2.5,outputPerM:15},{match:"gpt-5.3",inputPerM:1.75,outputPerM:14},{match:"gpt-4o-mini",inputPerM:.15,outputPerM:.6},{match:"gpt-4o",inputPerM:2.5,outputPerM:10},{match:"gpt-4.1-nano",inputPerM:.1,outputPerM:.4},{match:"gpt-4.1-mini",inputPerM:.4,outputPerM:1.6},{match:"gpt-4.1",inputPerM:2,outputPerM:8},{match:"gemini-2.5-pro",inputPerM:1.25,outputPerM:10},{match:"gemini-2.5-flash",inputPerM:.3,outputPerM:2.5},{match:"gemini-2.0-flash",inputPerM:.1,outputPerM:.4},{match:"gemini-1.5-pro",inputPerM:1.25,outputPerM:5},{match:"gemini-1.5-flash",inputPerM:.075,outputPerM:.3}]});import{AsyncLocalStorage as sf}from"async_hooks";function of(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function rf(e){return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,cacheReadTokens:e.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens,totalTokens:e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens,costUsd:e.costUsd,calls:e.calls,costComplete:e.unpricedCalls===0}}async function er(e){let t=of();return{result:await $l.run(t,e),cost:rf(t)}}function El(e,t){if(!t)return;let n=$l.getStore();if(!n)return;n.inputTokens+=t.inputTokens??0,n.outputTokens+=t.outputTokens??0,n.cacheReadTokens+=t.cacheReadTokens??0,n.cacheCreationTokens+=t.cacheCreationTokens??0,n.calls+=1;let s=ds(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}var $l,tr=N(()=>{"use strict";y();on();$l=new sf});import{randomUUID as Pt}from"crypto";import{AsyncLocalStorage as af}from"async_hooks";function Pl(){let e=R(),t=e.langfusePublicKey||process.env.LANGFUSE_PUBLIC_KEY,n=e.langfuseSecretKey||process.env.LANGFUSE_SECRET_KEY;if(!(e.langfuseEnabled===!0||process.env.LANGFUSE_ENABLED==="true")||!t||!n)return null;let o=(e.langfuseBaseUrl||process.env.LANGFUSE_BASE_URL||lf).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function yo(){return Pl()!==null}function ms(e,t=cf){if(typeof e=="string")return e.length>t?e.slice(0,t)+`\u2026[+${e.length-t} chars]`:e;try{let n=JSON.stringify(e);if(n&&n.length>t)return n.slice(0,t)+`\u2026[+${n.length-t} chars]`}catch{return"[unserializable]"}return e}async function tt(e,t){if(!yo())return t();let n=Pt();Gt.push({id:Pt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},...e.userId?{userId:e.userId}:{},...e.input!==void 0?{input:ms(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await us.run({traceId:n,sessionId:e.sessionId},t)}finally{await Nl()}}function nr(e){if(!yo())return;let t=us.getStore();t?.traceId&&Gt.push({id:Pt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:t.traceId,timestamp:new Date().toISOString(),output:ms(e)}})}async function te(e,t,n){let s=us.getStore();if(!yo()||!s?.traceId)return t();let o=Pt(),i=s.spanId,r=new Date,a,l;try{return await us.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{Gt.push({id:Pt(),type:"span-create",timestamp:new Date().toISOString(),body:{id:o,traceId:s.traceId,name:e,startTime:r.toISOString(),endTime:new Date().toISOString(),...i?{parentObservationId:i}:{},...n?.input!==void 0?{input:ms(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function df(e){if(yo())try{let t=us.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Pt(),o=!0,Gt.push({id:Pt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let i=e.usage?_l(e.usage):void 0,r=e.usage?ds(e.model,e.usage):void 0;Gt.push({id:Pt(),type:"generation-create",timestamp:new Date().toISOString(),body:{id:Pt(),traceId:n,...s?{parentObservationId:s}:{},name:e.name,model:e.model,startTime:(e.startTime??new Date).toISOString(),endTime:(e.endTime??new Date).toISOString(),...e.input!==void 0?{input:ms(e.input,Ml)}:{},...e.output!==void 0?{output:ms(e.output,Ml)}:{},...i?{usageDetails:i}:{},...r?{costDetails:r}:{},...e.level?{level:e.level}:{},...e.statusMessage?{statusMessage:e.statusMessage}:{},...e.promptName?{promptName:e.promptName,...e.promptVersion!=null?{promptVersion:e.promptVersion}:{}}:{},metadata:{...e.engine?{engine:e.engine}:{},...e.metadata??{}}}}),o&&await Nl()}catch(t){M.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function St(e){let{engine:t,model:n,name:s,usage:o,startTime:i,endTime:r}=e,a=r.getTime()-i.getTime(),l=o?ds(n,o):void 0;if(o&&M.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),Il.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:i,endTime:r,durationMs:a};for(let d of Il)try{d(c)}catch{}}El(n,o),df({name:s,model:n,engine:t,input:e.input,output:e.output,usage:o,startTime:i,endTime:r,level:e.level,statusMessage:e.statusMessage,metadata:e.metadata,promptName:e.promptName,promptVersion:e.promptVersion})}async function Nl(){let e=Pl();if(!e||Gt.length===0)return;let t=Gt;Gt=[];try{let n=Buffer.from(`${e.publicKey}:${e.secretKey}`).toString("base64"),s=await fetch(`${e.baseUrl}/api/public/ingestion`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Basic ${n}`},body:JSON.stringify({batch:t})});if(!s.ok&&s.status!==207){let o=await s.text().catch(()=>"");M.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else M.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){M.warn("langfuse",`ingestion failed: ${n.message}`)}}var lf,cf,Ml,us,Gt,Il,Be=N(()=>{"use strict";y();ee();le();on();tr();lf="https://cloud.langfuse.com",cf=24e3,Ml=2e5,us=new af,Gt=[],Il=new Set});import{join as me}from"path";import{readdirSync as it,rmSync as wf}from"fs";function ko(e){let t=[];for(let n of e){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),/dnd.area.*only.*have.*name.*main/i.test(s)&&(o=!0),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function To(e){let t=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(e)&&t.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(e)&&t.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(e)){let n=e.match(/field.*?(\w+)\s+has an invalid/i);t.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(e)){let n=e.match(/file '([^']+)'/i);t.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(e)&&t.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),/dnd.area.*only.*have.*name.*main/i.test(e)&&t.push({file:"templates/email.html",message:'Dnd area can only have name "main"',fixable:!0}),t}function Ao(e){let t=[];return Ll(e)&&t.push("textarea \u2192 text"),Jl(e)&&t.push("name \u2192 item_name"),Bl(e)&&t.push("now() \u2192 local_dt"),Hl(e)&&t.push("Removed HubDB templates"),Ul(e)&&t.push("Fixed link field defaults"),Gl(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),Cf(e)&&t.push("Stripped CDN @import statements"),Kl(e)&&t.push('dnd_area \u2192 "main" in email templates'),Vl(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function jl(e,t){return t.message.includes("textarea")?Ll(e):t.message.includes("reserved field name")?Jl(e):t.message.includes("now()")?Bl(e):t.message.includes("HubDB")?Hl(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?Ul(e):t.message.includes("invalid format")&&t.message.includes("color")?Gl(e):t.message.includes("dnd")||t.message.includes("Dnd area")?Kl(e):t.message.includes("dnd_area_stylesheet")?Vl(e):!1}function Ll(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),B(o,i),t=!0)}return t}function Jl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),B(o,i),t=!0)}return t}function Bl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"module.html");if(!x(o))continue;let i=P(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),B(o,i),t=!0)}return t}function Hl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(wf(o),t=!0)}return t}function Ul(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));zl(i)&&(B(o,JSON.stringify(i,null,2)+`
182
- `),t=!0)}catch{}}return t}function Cf(e){let t=!1,n=me(e,"css");if(x(n))for(let o of it(n)){if(!o.endsWith(".css"))continue;let i=me(n,o),r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(B(i,a),t=!0)}let s=me(e,"modules");if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.css");if(!x(i))continue;let r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(B(i,a),t=!0)}if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.html");if(!x(i))continue;let r=P(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(B(i,a),t=!0)}return t}function Gl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));Wl(i)&&(B(o,JSON.stringify(i,null,2)+`
183
- `),t=!0)}catch{}}return t}function Wl(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"&&!kf(i)){let r=Tf(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&Wl(s.children)&&(t=!0)}return t}function kf(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function Tf(e){let t=e.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(t)return{hex:`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`};let n=e.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),r=Math.min(255,parseInt(n[2])),a=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=e.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function Kl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i))continue;let r=i.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');r!==i&&(B(o,r),t=!0)}return t}function Vl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i)||i.includes("dnd_area_stylesheet"))continue;let r=i.replace(/(\{\{\s*standard_header_includes\s*\}\})/,`$1
184
- {{ dnd_area_stylesheet }}`);r!==i&&(B(o,r),t=!0)}return t}function zl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&zl(s.children)&&(t=!0)}return t}var _o=N(()=>{"use strict";y();oe()});import{readdirSync as Af}from"fs";import{join as _f,relative as $f}from"path";function Yl(e){let t=[];for(let n of Af(e,{withFileTypes:!0})){if(Ef.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=_f(e,n.name);n.isDirectory()?t.push(...Yl(s)):n.isFile()&&t.push(s)}return t}async function Mf(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function $o(e,t,n,s={}){let o=s.concurrency??5,i=Yl(t),r=i.length,a=0,l=0,c=[];return await Mf(i,o,async d=>{let u=$f(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await al(e,m,d);if(g.success)a++,s.onFileComplete?.(u);else{l++;let h={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(h),s.onFileError?.(u,h)}s.onProgress?.(a+l,r)}),{success:l===0,uploaded:a,failed:l,total:r,errors:c}}var Ef,sr=N(()=>{"use strict";y();sn();sn();Ef=new Set([".git","node_modules",".vibespot",".DS_Store"])});var oc=N(()=>{"use strict";y()});import{existsSync as Nt,writeFileSync as Rf,mkdirSync as Of}from"fs";import{join as vt}from"path";function rc(e){return/^[0-9a-f]{4,40}$/i.test(e)}function ac(e){return Number.isInteger(e)&&e>0&&e<1e3}function rt(){return Eo!==null||(Eo=Z(["--version"]).success),Eo}function Mo(e){if(!rt())return!1;if(Nt(vt(e,".git")))return ic(e),!0;let t=Z(["init"],{cwd:e});return t.success?(Ff(e),ic(e),Z(["add","-A"],{cwd:e}),Z(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function ic(e){let t=vt(e,".vibespot");Nt(t)||Of(t,{recursive:!0})}function Ff(e){let t=vt(e,".gitignore");Rf(t,[".vibespot/","node_modules/",""].join(`
185
- `),"utf-8")}function rn(e,t){if(!rt()||!Nt(vt(e,".git"))||(Z(["add","-A"],{cwd:e}),Z(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=Z(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=Z(["rev-parse","--short","HEAD"],{cwd:e});return i.success?i.stdout:null}function ir(e,t,n,s){if(!rt()||!Nt(vt(e,".git")))return null;for(let u of s){let m=vt(e,u);Nt(m)&&Z(["add","--",u],{cwd:e})}if(Z(["diff","--cached","--quiet"],{cwd:e}).success)return null;let i=`[${t}] `,r=72-i.length,a=n.length>r?n.slice(0,r-3)+"...":n,l=i+a,c=Z(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=Z(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function lc(e){let t=[],n=null;for(let s of e.split(`
186
- `)){let o=s.trimEnd();if(o.startsWith("COMMIT|")){n&&t.push(n);let i=o.slice(7).split("|");if(i.length<4){n=null;continue}let r=parseInt(i[3],10)*1e3;n={hash:i[0],fullHash:i[1],message:i[2],timestamp:r,date:new Date(r).toISOString(),changedFiles:[],changedModules:[]}}else o&&n&&n.changedFiles.push(o)}n&&t.push(n);for(let s of t){if(!s.changedFiles)continue;let o=new Set;for(let i of s.changedFiles){let r=i.match(/^modules\/([^/]+)\.module(?:\/|$)/);r&&o.add(r[1])}s.changedModules=[...o]}return t}function cc(e,t=50){if(!rt())return[];if(!Nt(vt(e,".git")))return[];if(!ac(t))return[];let n=Z(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:lc(n.stdout)}function dc(e,t,n=50){if(!rt())return[];if(!Nt(vt(e,".git")))return[];if(!ac(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=Z(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:lc(o.stdout)}function uc(e,t){if(!rt())return{success:!1,error:"Git not available"};if(!Nt(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!rc(t))return{success:!1,error:"Invalid commit hash"};let n=Z(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=Z(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=Z(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return Z(["commit","-m",r],{cwd:e}),{success:!0}}function mc(e,t,n,s){if(!rt())return{success:!1,error:"Git not available"};if(!Nt(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!rc(n))return{success:!1,error:"Invalid commit hash"};let o=Z(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=Z(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)Z(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};Z(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return Z(["commit","-m",c],{cwd:e}),{success:!0}}var Eo,Pn=N(()=>{"use strict";y();Qt();Eo=null});import{readFileSync as Df,existsSync as gc,writeFileSync as jf,mkdirSync as Lf,rmSync as Jf}from"fs";import{join as Io}from"path";function an(e){let t=C();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e.plan)}function at(){let e=C();if(!e)return;let t=ke();if(!t){if(e.modules.length===0)return;let n={modules:e.modules,moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,template:e.template,messages:e.messages,plan:e.brandAssets?.plan};t=Rt("landing_page",`${e.themeName} Landing Page`),e.activeTemplateId=t.id,e.modules=n.modules,e.moduleOrder=n.moduleOrder,e.sharedCss=n.sharedCss,e.sharedJs=n.sharedJs,e.template=n.template,e.messages=n.messages,e.brandAssets&&(e.brandAssets.plan=n.plan)}t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.plan=e.brandAssets?.plan}function lt(e,t,n){let s=C();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),at(),Hf()}function fc(e){let t=C();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),L())}function hc(e){let t=C();if(!t)return;if(e.calls===0)return t.costTotal;let n=t.costTotal??{costUsd:0,totalTokens:0,generations:0,costComplete:!0},s={costUsd:n.costUsd+e.costUsd,totalTokens:n.totalTokens+e.totalTokens,generations:n.generations+1,costComplete:n.costComplete&&e.costComplete};return t.costTotal=s,t.updatedAt=Date.now(),s}function pc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function Bf(e,t){let n=pc(e),s=pc(t);if(n===s)return!0;if(n.length<4||s.length<4)return!1;let o=n.length<=s.length?n:s,i=n.length<=s.length?s:n;return i.includes(o)?o.length/i.length>=.8:!1}function He(e){let t=C();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let i=t.modules.find(r=>Bf(r.moduleName,n.moduleName));i&&M.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${i.moduleName}" \u2014 adding as a new module. This usually indicates the Module Planner re-named an existing module. Check the prompt's "preserve existing names" rule.`),t.modules.push(n),t.moduleOrder.some(r=>r.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),at()}}function Wt(e){let t=C();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),at())}function yc(e){let t=C();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=Io(t.themePath,"modules",`${e}.module`);gc(n)&&Jf(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),at()}}function bc(e){let t=C();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),at())}function Sc(e,t,n){let s=C();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);wc(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),at()}catch{}}function ve(){let e=C();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Hf(){let e=C();if(e)try{let t=Io(e.themePath,".vibespot");Lf(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};jf(Io(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function vc(e){let t=Io(e,".vibespot","chat.json");if(!gc(t))return[];try{let n=JSON.parse(Df(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function xc(e){let t=C();if(t){for(let n of t.templates)n.sharedCss=e.sharedCss,n.sharedJs=e.sharedJs;t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs;for(let n of e.pages){let s=e.pageLabels.get(n.pageId),o=s?.label||n.pageId,i=s?.pageType||"website_page",r=t.templates.find(a=>a.id===n.templateId);r||(r=Rt(i,o),r.id=n.templateId,r.templateFile=`templates/${n.templateId}.html`),r.modules=n.modules,r.moduleOrder=n.moduleOrder,r.sharedCss=e.sharedCss,r.sharedJs=e.sharedJs}e.pages.length>0&&fs(e.pages[0].templateId),t.updatedAt=Date.now()}}function wc(e,t,n){let s=t.split("."),o=s[0],i=e.find(r=>r.name===o);i&&(s.length===1?i.default=n:i.children&&wc(i.children,s.slice(1).join("."),n))}var gs=N(()=>{"use strict";y();hs();Kt();le()});import{existsSync as Po,rmSync as No}from"fs";import{join as Nn}from"path";function Ro(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function ke(){let e=C();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function fs(e){let t=C();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,an(n),t.updatedAt=Date.now(),!0):!1}function Rt(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=n==="email",a=`${i?"email":e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:t,pageType:e,contentMode:n,templateFile:i?"templates/email.html":e==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,an(l),s.updatedAt=Date.now(),l}function Cc(e,t){let n=C();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:a,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${a}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[],plan:s.plan};return n.templates.push(l),n.activeTemplateId=a,an(l),n.updatedAt=Date.now(),l}function kc(e){let t=C();if(!t||!Array.isArray(e)||e.length===0)return!1;let n=new Map(t.templates.map(i=>[i.id,i])),s=new Set,o=[];for(let i of e){let r=n.get(i);!r||s.has(i)||(o.push(r),s.add(i))}for(let i of t.templates)s.has(i.id)||o.push(i);return o.length!==t.templates.length?!1:(t.templates=o,t.updatedAt=Date.now(),!0)}function Tc(e,t){let n=C();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function Ac(e,t=!1){let n=C();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Nn(n.themePath,"templates"),r=`${o.id}.html`,a=Nn(i,r);if(Po(a)&&No(a,{force:!0}),o.pageType==="blog_post"){let l=Nn(i,`${o.id}-listing.html`);Po(l)&&No(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let a of n.templates)for(let l of a.modules)i.add(l.moduleName);for(let a of n.modules)i.add(a.moduleName);let r=o.modules.map(a=>a.moduleName).filter(a=>!i.has(a));if(n.themePath&&r.length>0){let a=Nn(n.themePath,"modules");for(let l of r){let c=Nn(a,`${l}.module`);Po(c)&&No(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?fs(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[],n.brandAssets&&delete n.brandAssets.plan)),o.plan&&n.themePath&&!n.templates.some(r=>!!r.plan)){let r=Nn(n.themePath,".vibespot","plan.md");Po(r)&&No(r,{force:!0})}return n.updatedAt=Date.now(),!0}function Ot(){let e=C();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of e.modules)t.has(n.moduleName)||t.set(n.moduleName,{module:n,usedIn:[]});return Array.from(t.values())}var Kt=N(()=>{"use strict";y();hs();gs()});import{readFileSync as xt,readdirSync as dr,existsSync as Ie,writeFileSync as ys,mkdirSync as Oo,rmSync as rr,renameSync as ar,cpSync as Uf}from"fs";import{join as pe,dirname as _c}from"path";import{homedir as Gf}from"os";function Fo(){if(Rn)return Rn;try{return Ie(lr)?(Rn=JSON.parse(xt(lr,"utf-8")),Rn):cr()}catch{return cr()}}function Do(e){Rn=e;try{Oo(de,{recursive:!0}),ys(lr,JSON.stringify(e),"utf-8")}catch{}}function cr(){if(!Ie(de))return[];let e=[];for(let t of dr(de).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(xt(pe(de,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length,pageCount:s.filter(o=>o.contentMode!=="email").length,emailCount:s.filter(o=>o.contentMode==="email").length,hasBrandAssets:!!(n.brandAssets&&(n.brandAssets.styleguide||n.brandAssets.brandvoice||n.brandAssets.brandKit)),isImported:!!n.isImported})}catch{}return Rn=e,Do(e),e}function $c(e){let t=Fo(),n=e.templates||[],s={id:e.id,themeName:e.themeName,updatedAt:e.updatedAt,moduleCount:n.reduce((i,r)=>i+(r.modules?.length||0),0),templateCount:n.length,pageCount:n.filter(i=>i.contentMode!=="email").length,emailCount:n.filter(i=>i.contentMode==="email").length,hasBrandAssets:!!(e.brandAssets&&(e.brandAssets.styleguide||e.brandAssets.brandvoice||e.brandAssets.brandKit)),isImported:!!e.isImported},o=t.findIndex(i=>i.id===e.id);o>=0?t[o]=s:t.push(s),Do(t)}function Wf(e){let t=Fo().filter(n=>n.id!==e);Do(t)}function Kf(e){let t=Fo().filter(n=>n.themeName!==e);Do(t)}function C(){return Ue}function Ec(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function On(e,t,n={}){let s={id:Ec(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Ue=s,Mo(e),s}function L(){if(!Ue)return;Oo(de,{recursive:!0});let e=pe(de,`${Ue.id}.json`);ys(e,JSON.stringify(Ue,null,2),"utf-8"),$c(Ue)}function jo(e){let t=pe(de,e+".json");if(!Ie(t))return null;try{let n=JSON.parse(xt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Ro(n),n.brandAssets?.plan&&n.templates?.length>0){let s=n.templates.find(o=>o.id===n.activeTemplateId)||n.templates[0];s.plan||(s.plan=n.brandAssets.plan)}return Ue=n,n}catch{return null}}function Fn(){return Ie(de)?Fo():[]}function Mc(e,t=!1){let n=pe(de,e+".json"),s="";if(t)try{let o=JSON.parse(xt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ie(o.themePath)&&rr(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(xt(n,"utf-8")).themeName||""}catch{}try{Ie(n)&&rr(n)}catch{}if(s&&Ie(de)){for(let o of dr(de).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(xt(pe(de,o),"utf-8")).themeName===s&&rr(pe(de,o))}catch{}Kf(s)}else Wf(e);Ue?.id===e&&(Ue=null)}function Ic(e,t){let n=pe(de,e+".json");if(!Ie(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(xt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,r=pe(_c(i),t);if(Ie(i)){if(Ie(r))return{ok:!1,error:"A project with that name already exists"};try{ar(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=pe(r,"css",`${o}-theme.css`),l=pe(r,"css",`${t}-theme.css`);if(Ie(a))try{ar(a,l)}catch{}let c=pe(r,"js",`${o}-animations.js`),d=pe(r,"js",`${t}-animations.js`);if(Ie(c))try{ar(c,d)}catch{}let u=pe(r,"theme.json");if(Ie(u))try{let m=JSON.parse(xt(u,"utf-8"));m.label=t,m.name=t,ys(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ie(de))for(let a of dr(de).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(xt(pe(de,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),ys(pe(de,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Ue&&Ue.themeName===o&&(Ue.themeName=t,Ue.themePath=r,Ue.updatedAt=Date.now()),cr(),{ok:!0}}function Pc(e){let t=pe(de,e+".json");if(!Ie(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(xt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=_c(n.themePath),i=`${s}-copy`,r=1;for(;Ie(pe(o,i));)r++,i=`${s}-copy-${r}`;let a=pe(o,i);if(Ie(n.themePath))try{Uf(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else Oo(a,{recursive:!0});let l=Ec(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return Oo(de,{recursive:!0}),ys(pe(de,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),$c(c),{ok:!0,newName:i,newSessionId:l}}var de,lr,Rn,Ue,hs=N(()=>{"use strict";y();Pn();Kt();de=pe(Gf(),".vibespot","sessions"),lr=pe(de,"_index.json"),Rn=null;Ue=null});import{readFileSync as Vf,readdirSync as Oc,statSync as ur}from"fs";import{createHash as zf}from"crypto";import{join as be,relative as Yf}from"path";function Bo(e){let t=[];if(!x(e))return vh(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=Dn(e),s=hh(e),o=bh(e),i=Sh(e),r=eh(e);Object.keys(n.cssVariables).length===0&&t.push({severity:"info",rule:"design.cssVariables.empty",message:"No :root CSS custom properties found in theme CSS.",fix:"Run with --apply-tokens to seed a :root block from inferred palette/typography."}),n.palette.length===0&&t.push({severity:"info",rule:"design.palette.empty",message:"Could not infer a colour palette from the theme CSS."}),s.orphanModules.length>0&&t.push({severity:"warning",rule:"modules.orphan",message:`${s.orphanModules.length} module(s) are not referenced by any template: ${s.orphanModules.join(", ")}`,fix:"Either reference these modules from a template or remove them."}),s.templates.length===0&&s.modules.length>0&&t.push({severity:"warning",rule:"templates.missing",message:"Theme has modules but no page templates wiring them together.",fix:"Add a templates/<name>.html that includes the modules via dnd_module."});for(let l of o)t.push({severity:"info",rule:"field.unsupported-pattern",file:`modules/${l.module}.module/fields.json`,message:`${l.module}.${l.field}: ${l.reason}`,fix:"vibeSpot will preserve this field as-is. Edit it in HubSpot if changes are needed."});for(let l of i)t.push({severity:"warning",rule:"roundtrip.preserve-pattern",file:l.file,message:`${l.pattern}: ${l.detail}`,fix:"vibeSpot avoids modifying this. Don't ask the AI to refactor it."});r.hasSnapshot&&r.filesChanged>0&&t.push({severity:"info",rule:"roundtrip.snapshot.diff",message:`${r.filesChanged} file(s) differ from the imported theme snapshot.`,fix:"Review report.roundTripDiff before re-uploading if you need to preserve imported files exactly."});let a=i.filter(l=>l.pattern==="hubl.macro").length;return{themePath:e,designTokens:n,graph:s,fieldFlags:o,roundTripRisks:i,roundTripDiff:r,findings:t,summary:{moduleCount:s.modules.length,templateCount:s.templates.length,orphanCount:s.orphanModules.length,paletteSize:n.palette.length,cssVarCount:Object.keys(n.cssVariables).length,customMacroCount:a,roundTripChangedCount:r.filesChanged}}}function bs(e){let t=[];for(let[n,s]of Object.entries(e.cssVariables))t.push(` ${n}: ${s};`);return Object.keys(e.cssVariables).length===0&&(e.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;t.push(` --color-${o}: ${n.value};`)}),e.fontFamilies[0]&&t.push(` --font-family-base: ${e.fontFamilies[0]};`),e.fontFamilies[1]&&t.push(` --font-family-heading: ${e.fontFamilies[1]};`)),t.length===0?"":`:root {
173
+ Return ONLY the template HTML content, no markdown fences.`}var ic,tt=j(()=>{"use strict";y();ae();ic=new Map});import{appendFileSync as Bh,mkdirSync as Jh,readdirSync as Hh,unlinkSync as Uh}from"fs";import{join as Fi}from"path";import{homedir as Gh}from"os";function Kh(){if(!Ni)try{Jh(Fo,{recursive:!0}),Ni=!0}catch{}}function Vh(){if(!Oi){Oi=!0;try{let e=Date.now()-Wh*864e5;for(let t of Hh(Fo)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{Uh(Fi(Fo,t))}catch{}}}catch{}}}function zh(){let t=new Date().toISOString().slice(0,10);return Fi(Fo,`vibespot-${t}.log`)}function qh(){return new Date().toISOString().slice(11,23)}function Ri(e,t){if(Kh(),!!Ni){Oi||Vh();try{Bh(zh(),`${qh()} ${e} ${t}
174
+ `)}catch{}}}var Fo,Wh,Ni,Oi,A,re=j(()=>{"use strict";y();Fo=Fi(Gh(),".vibespot","logs"),Wh=7,Ni=!1,Oi=!1;A={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),Ri("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),Ri("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),Ri("ERROR",o)}}});function Xh(e){let t=(e||"").toLowerCase();return Yh.find(n=>t.includes(n.match))}function Ts(e,t){let n=Xh(e);if(!n)return;let s=n.cacheReadPerM??n.inputPerM*.1,o=n.cacheWritePerM??n.inputPerM*1.25,r=(t.inputTokens??0)*n.inputPerM,i=(t.outputTokens??0)*n.outputPerM,a=(t.cacheReadTokens??0)*s,l=(t.cacheCreationTokens??0)*o,c={total:(r+i+a+l)/1e6};return t.inputTokens!=null&&(c.input=r/1e6),t.outputTokens!=null&&(c.output=i/1e6),t.cacheReadTokens&&(c.cache_read_input_tokens=a/1e6),t.cacheCreationTokens&&(c.cache_creation_input_tokens=l/1e6),c}function nt(e){if(e)return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_input_tokens??void 0,cacheCreationTokens:e.cache_creation_input_tokens??void 0}}function Bn(e){if(!e)return;let t=e.prompt_tokens_details?.cached_tokens??0,n=e.prompt_tokens;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.completion_tokens,totalTokens:e.total_tokens,cacheReadTokens:t||void 0}}function Jn(e){if(!e)return;let t=e.cachedContentTokenCount??0,n=e.promptTokenCount;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.candidatesTokenCount,totalTokens:e.totalTokenCount,cacheReadTokens:t||void 0}}function bc(e){let t={};return e.inputTokens!=null&&(t.input=e.inputTokens),e.outputTokens!=null&&(t.output=e.outputTokens),e.cacheReadTokens&&(t.cache_read_input_tokens=e.cacheReadTokens),e.cacheCreationTokens&&(t.cache_creation_input_tokens=e.cacheCreationTokens),e.totalTokens!=null&&(t.total=e.totalTokens),t}var Yh,un=j(()=>{"use strict";y();Yh=[{match:"claude-opus-4",inputPerM:15,outputPerM:75},{match:"claude-sonnet-4",inputPerM:3,outputPerM:15},{match:"claude-haiku-4",inputPerM:1,outputPerM:5},{match:"claude-3-7-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-haiku",inputPerM:.8,outputPerM:4},{match:"claude-3-opus",inputPerM:15,outputPerM:75},{match:"gpt-5.5",inputPerM:5,outputPerM:30},{match:"gpt-5.4",inputPerM:2.5,outputPerM:15},{match:"gpt-5.3",inputPerM:1.75,outputPerM:14},{match:"gpt-4o-mini",inputPerM:.15,outputPerM:.6},{match:"gpt-4o",inputPerM:2.5,outputPerM:10},{match:"gpt-4.1-nano",inputPerM:.1,outputPerM:.4},{match:"gpt-4.1-mini",inputPerM:.4,outputPerM:1.6},{match:"gpt-4.1",inputPerM:2,outputPerM:8},{match:"gemini-2.5-pro",inputPerM:1.25,outputPerM:10},{match:"gemini-2.5-flash",inputPerM:.3,outputPerM:2.5},{match:"gemini-2.0-flash",inputPerM:.1,outputPerM:.4},{match:"gemini-1.5-pro",inputPerM:1.25,outputPerM:5},{match:"gemini-1.5-flash",inputPerM:.075,outputPerM:.3}]});import{AsyncLocalStorage as Zh}from"async_hooks";function Qh(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function Sc(e){return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,cacheReadTokens:e.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens,totalTokens:e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens,costUsd:e.costUsd,calls:e.calls,costComplete:e.unpricedCalls===0}}async function Do(e){let t=Qh();return{result:await Di.run(t,e),cost:Sc(t)}}function vc(e,t){if(!t)return;let n=Di.getStore();if(!n)return;n.inputTokens+=t.inputTokens??0,n.outputTokens+=t.outputTokens??0,n.cacheReadTokens+=t.cacheReadTokens??0,n.cacheCreationTokens+=t.cacheCreationTokens??0,n.calls+=1;let s=Ts(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}function xc(){let e=Di.getStore();return e?Sc(e):null}var Di,jo=j(()=>{"use strict";y();un();Di=new Zh});import{randomUUID as Ft}from"crypto";import{AsyncLocalStorage as ey}from"async_hooks";function Cc(){let e=$(),t=e.langfusePublicKey||process.env.LANGFUSE_PUBLIC_KEY,n=e.langfuseSecretKey||process.env.LANGFUSE_SECRET_KEY;if(!(e.langfuseEnabled===!0||process.env.LANGFUSE_ENABLED==="true")||!t||!n)return null;let o=(e.langfuseBaseUrl||process.env.LANGFUSE_BASE_URL||ty).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function Lo(){return Cc()!==null}function _s(e,t=ny){if(typeof e=="string")return e.length>t?e.slice(0,t)+`\u2026[+${e.length-t} chars]`:e;try{let n=JSON.stringify(e);if(n&&n.length>t)return n.slice(0,t)+`\u2026[+${n.length-t} chars]`}catch{return"[unserializable]"}return e}async function qe(e,t){if(!Lo())return t();let n=Ft();qt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},...e.userId?{userId:e.userId}:{},...e.input!==void 0?{input:_s(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await As.run({traceId:n,sessionId:e.sessionId},t)}finally{Tc()}}function Bo(e){if(!Lo())return;let t=As.getStore();t?.traceId&&qt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:t.traceId,timestamp:new Date().toISOString(),output:_s(e)}})}async function ce(e,t,n){let s=As.getStore();if(!Lo()||!s?.traceId)return t();let o=Ft(),r=s.spanId,i=new Date,a,l;try{return await As.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{qt.push({id:Ft(),type:"span-create",timestamp:new Date().toISOString(),body:{id:o,traceId:s.traceId,name:e,startTime:i.toISOString(),endTime:new Date().toISOString(),...r?{parentObservationId:r}:{},...n?.input!==void 0?{input:_s(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function sy(e){if(Lo())try{let t=As.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Ft(),o=!0,qt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let r=e.usage?bc(e.usage):void 0,i=e.usage?Ts(e.model,e.usage):void 0;qt.push({id:Ft(),type:"generation-create",timestamp:new Date().toISOString(),body:{id:Ft(),traceId:n,...s?{parentObservationId:s}:{},name:e.name,model:e.model,startTime:(e.startTime??new Date).toISOString(),endTime:(e.endTime??new Date).toISOString(),...e.input!==void 0?{input:_s(e.input,wc)}:{},...e.output!==void 0?{output:_s(e.output,wc)}:{},...r?{usageDetails:r}:{},...i?{costDetails:i}:{},...e.level?{level:e.level}:{},...e.statusMessage?{statusMessage:e.statusMessage}:{},...e.promptName?{promptName:e.promptName,...e.promptVersion!=null?{promptVersion:e.promptVersion}:{}}:{},metadata:{...e.engine?{engine:e.engine}:{},...e.metadata??{}}}}),o&&await Tc()}catch(t){A.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function Ct(e){let{engine:t,model:n,name:s,usage:o,startTime:r,endTime:i}=e,a=i.getTime()-r.getTime(),l=o?Ts(n,o):void 0;if(o&&A.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),kc.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:r,endTime:i,durationMs:a};for(let d of kc)try{d(c)}catch{}}vc(n,o),sy({name:s,model:n,engine:t,input:e.input,output:e.output,usage:o,startTime:r,endTime:i,level:e.level,statusMessage:e.statusMessage,metadata:e.metadata,promptName:e.promptName,promptVersion:e.promptVersion})}async function Tc(){let e=Cc();if(!e||qt.length===0)return;let t=qt;qt=[];try{let n=Buffer.from(`${e.publicKey}:${e.secretKey}`).toString("base64"),s=await fetch(`${e.baseUrl}/api/public/ingestion`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Basic ${n}`},body:JSON.stringify({batch:t}),signal:AbortSignal.timeout(oy)});if(!s.ok&&s.status!==207){let o=await s.text().catch(()=>"");A.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else A.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){A.warn("langfuse",`ingestion failed: ${n.message}`)}}var ty,ny,wc,As,qt,kc,oy,Ue=j(()=>{"use strict";y();te();re();un();jo();ty="https://cloud.langfuse.com",ny=24e3,wc=2e5,As=new ey,qt=[],kc=new Set;oy=1e4});var _c=j(()=>{"use strict";y()});import{existsSync as Dt,writeFileSync as ay,mkdirSync as ly}from"fs";import{join as Tt}from"path";function Ec(e){return/^[0-9a-f]{4,40}$/i.test(e)}function Ic(e){return Number.isInteger(e)&&e>0&&e<1e3}function at(){return Ho!==null||(Ho=ee(["--version"]).success),Ho}function Uo(e){if(!at())return!1;if(Dt(Tt(e,".git")))return Pc(e),!0;let t=ee(["init"],{cwd:e});return t.success?(cy(e),Pc(e),ee(["add","-A"],{cwd:e}),ee(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Pc(e){let t=Tt(e,".vibespot");Dt(t)||ly(t,{recursive:!0})}function cy(e){let t=Tt(e,".gitignore");ay(t,[".vibespot/","node_modules/",""].join(`
175
+ `),"utf-8")}function pn(e,t){if(!at()||!Dt(Tt(e,".git"))||(ee(["add","-A"],{cwd:e}),ee(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=ee(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let r=ee(["rev-parse","--short","HEAD"],{cwd:e});return r.success?r.stdout:null}function ji(e,t,n,s){if(!at()||!Dt(Tt(e,".git")))return null;for(let u of s){let p=Tt(e,u);Dt(p)&&ee(["add","--",u],{cwd:e})}if(ee(["diff","--cached","--quiet"],{cwd:e}).success)return null;let r=`[${t}] `,i=72-r.length,a=n.length>i?n.slice(0,i-3)+"...":n,l=r+a,c=ee(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=ee(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function Mc(e){let t=[],n=null;for(let s of e.split(`
176
+ `)){let o=s.trimEnd();if(o.startsWith("COMMIT|")){n&&t.push(n);let r=o.slice(7).split("|");if(r.length<4){n=null;continue}let i=parseInt(r[3],10)*1e3;n={hash:r[0],fullHash:r[1],message:r[2],timestamp:i,date:new Date(i).toISOString(),changedFiles:[],changedModules:[]}}else o&&n&&n.changedFiles.push(o)}n&&t.push(n);for(let s of t){if(!s.changedFiles)continue;let o=new Set;for(let r of s.changedFiles){let i=r.match(/^modules\/([^/]+)\.module(?:\/|$)/);i&&o.add(i[1])}s.changedModules=[...o]}return t}function $c(e,t=50){if(!at())return[];if(!Dt(Tt(e,".git")))return[];if(!Ic(t))return[];let n=ee(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:Mc(n.stdout)}function Rc(e,t,n=50){if(!at())return[];if(!Dt(Tt(e,".git")))return[];if(!Ic(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=ee(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:Mc(o.stdout)}function Nc(e,t){if(!at())return{success:!1,error:"Git not available"};if(!Dt(Tt(e,".git")))return{success:!1,error:"Not a git repo"};if(!Ec(t))return{success:!1,error:"Invalid commit hash"};let n=ee(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=ee(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,r=ee(["checkout",t,"--","."],{cwd:e});if(!r.success)return{success:!1,error:`Checkout failed: ${r.stderr}`};let i=`Rollback to: ${o}`.slice(0,72);return ee(["commit","-m",i],{cwd:e}),{success:!0}}function Oc(e,t,n,s){if(!at())return{success:!1,error:"Git not available"};if(!Dt(Tt(e,".git")))return{success:!1,error:"Not a git repo"};if(!Ec(n))return{success:!1,error:"Invalid commit hash"};let o=ee(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let r=ee(["log","--format=%s","-1",n],{cwd:e}),i=r.success?r.stdout:n,a=0;for(let d of s)ee(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};ee(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${i}`.slice(0,72);return ee(["commit","-m",c],{cwd:e}),{success:!0}}var Ho,Hn=j(()=>{"use strict";y();on();Ho=null});import{readFileSync as dy,existsSync as Dc,writeFileSync as uy,mkdirSync as py,rmSync as my}from"fs";import{join as Go}from"path";function mn(e){let t=x();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e.plan)}function lt(){let e=x();if(!e)return;let t=xe();if(!t){if(e.modules.length===0)return;let n={modules:e.modules,moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,template:e.template,messages:e.messages,plan:e.brandAssets?.plan};t=jt("landing_page",`${e.themeName} Landing Page`),e.activeTemplateId=t.id,e.modules=n.modules,e.moduleOrder=n.moduleOrder,e.sharedCss=n.sharedCss,e.sharedJs=n.sharedJs,e.template=n.template,e.messages=n.messages,e.brandAssets&&(e.brandAssets.plan=n.plan)}t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.plan=e.brandAssets?.plan}function ct(e,t,n){let s=x();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),lt(),fy()}function jc(e){let t=x();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),D())}function Lc(e){let t=x();if(!t)return;if(e.calls===0)return t.costTotal;let n=t.costTotal??{costUsd:0,totalTokens:0,generations:0,costComplete:!0},s={costUsd:n.costUsd+e.costUsd,totalTokens:n.totalTokens+e.totalTokens,generations:n.generations+1,costComplete:n.costComplete&&e.costComplete};return t.costTotal=s,t.updatedAt=Date.now(),s}function Fc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function gy(e,t){let n=Fc(e),s=Fc(t);if(n===s)return!0;if(n.length<4||s.length<4)return!1;let o=n.length<=s.length?n:s,r=n.length<=s.length?s:n;return r.includes(o)?o.length/r.length>=.8:!1}function Ge(e){let t=x();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(r=>r.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let r=t.modules.find(i=>gy(i.moduleName,n.moduleName));r&&A.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${r.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(i=>i.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),lt()}}function Yt(e){let t=x();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),lt())}function Bc(e){let t=x();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)try{let n=dn(Go(t.themePath,"modules"),e);Dc(n)&&my(n,{recursive:!0,force:!0})}catch{A.warn("session-state","Refusing to delete module with unsafe name",{name:e})}t.updatedAt=Date.now(),lt()}}function Jc(e){let t=x();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),lt())}function Hc(e,t,n){let s=x();if(!s)return;let o=s.modules.find(r=>r.moduleName===e);if(o)try{let r=JSON.parse(o.fieldsJson);Wc(r,t,n),o.fieldsJson=JSON.stringify(r,null,2),s.updatedAt=Date.now(),lt()}catch{}}function pe(){let e=x();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 fy(){let e=x();if(e)try{let t=Go(e.themePath,".vibespot");py(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};uy(Go(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Uc(e){let t=Go(e,".vibespot","chat.json");if(!Dc(t))return[];try{let n=JSON.parse(dy(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Gc(e){let t=x();if(t){for(let n of t.templates)n.sharedCss=e.sharedCss,n.sharedJs=e.sharedJs;t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs;for(let n of e.pages){let s=e.pageLabels.get(n.pageId),o=s?.label||n.pageId,r=s?.pageType||"website_page",i=t.templates.find(a=>a.id===n.templateId);i||(i=jt(r,o),i.id=n.templateId,i.templateFile=`templates/${n.templateId}.html`),i.modules=n.modules,i.moduleOrder=n.moduleOrder,i.sharedCss=e.sharedCss,i.sharedJs=e.sharedJs}e.pages.length>0&&Es(e.pages[0].templateId),t.updatedAt=Date.now()}}function Wc(e,t,n){let s=t.split("."),o=s[0],r=e.find(i=>i.name===o);r&&(s.length===1?r.default=n:r.children&&Wc(r.children,s.slice(1).join("."),n))}var Ps=j(()=>{"use strict";y();Is();Xt();re();wt()});import{existsSync as Wo,rmSync as Ko}from"fs";import{join as Ms}from"path";function Vo(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=x();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function Es(e){let t=x();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,mn(n),t.updatedAt=Date.now(),!0):!1}function jt(e,t,n){let s=x();if(!s)throw new Error("No active session");let o=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),r=n==="email",a=`${r?"email":e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:t,pageType:e,contentMode:n,templateFile:r?"templates/email.html":e==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,mn(l),s.updatedAt=Date.now(),l}function Kc(e,t){let n=x();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,r=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${r}`,l={id:a,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${a}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[],plan:s.plan};return n.templates.push(l),n.activeTemplateId=a,mn(l),n.updatedAt=Date.now(),l}function Vc(e){let t=x();if(!t||!Array.isArray(e)||e.length===0)return!1;let n=new Map(t.templates.map(r=>[r.id,r])),s=new Set,o=[];for(let r of e){let i=n.get(r);!i||s.has(r)||(o.push(i),s.add(r))}for(let r of t.templates)s.has(r.id)||o.push(r);return o.length!==t.templates.length?!1:(t.templates=o,t.updatedAt=Date.now(),!0)}function zc(e,t){let n=x();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 qc(e,t=!1){let n=x();if(!n)return!1;let s=n.templates.findIndex(r=>r.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let r=Ms(n.themePath,"templates"),i=`${o.id}.html`,a=Ms(r,i);if(Wo(a)&&Ko(a,{force:!0}),o.pageType==="blog_post"){let l=Ms(r,`${o.id}-listing.html`);Wo(l)&&Ko(l,{force:!0})}}if(t&&o.modules.length>0){let r=new Set;for(let a of n.templates)for(let l of a.modules)r.add(l.moduleName);for(let a of n.modules)r.add(a.moduleName);let i=o.modules.map(a=>a.moduleName).filter(a=>!r.has(a));if(n.themePath&&i.length>0){let a=Ms(n.themePath,"modules");for(let l of i){let c;try{c=dn(a,l)}catch{continue}Wo(c)&&Ko(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?Es(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[],n.brandAssets&&delete n.brandAssets.plan)),o.plan&&n.themePath&&!n.templates.some(i=>!!i.plan)){let i=Ms(n.themePath,".vibespot","plan.md");Wo(i)&&Ko(i,{force:!0})}return n.updatedAt=Date.now(),!0}function Lt(){let e=x();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of e.modules)t.has(n.moduleName)||t.set(n.moduleName,{module:n,usedIn:[]});return Array.from(t.values())}var Xt=j(()=>{"use strict";y();Is();Ps();wt()});import{readFileSync as dt,readdirSync as qo,existsSync as Te,writeFileSync as $s,mkdirSync as zo,rmSync as Li,renameSync as Bi,cpSync as hy}from"fs";import{join as ue,dirname as Xc,resolve as Yc}from"path";import{homedir as yy}from"os";function Yo(){if(Un)return Un;try{return Te(Ji)?(Un=JSON.parse(dt(Ji,"utf-8")),Un):Hi()}catch{return Hi()}}function Xo(e){Un=e;try{zo(oe,{recursive:!0}),$s(Ji,JSON.stringify(e),"utf-8")}catch{}}function Hi(){if(!Te(oe))return[];let e=[];for(let t of qo(oe).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(dt(ue(oe,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,r)=>o+(r.modules?.length||0),0),templateCount:s.length,pageCount:s.filter(o=>o.contentMode!=="email").length,emailCount:s.filter(o=>o.contentMode==="email").length,hasBrandAssets:!!(n.brandAssets&&(n.brandAssets.styleguide||n.brandAssets.brandvoice||n.brandAssets.brandKit)),isImported:!!n.isImported})}catch{}return Un=e,Xo(e),e}function Zc(e){let t=Yo(),n=e.templates||[],s={id:e.id,themeName:e.themeName,updatedAt:e.updatedAt,moduleCount:n.reduce((r,i)=>r+(i.modules?.length||0),0),templateCount:n.length,pageCount:n.filter(r=>r.contentMode!=="email").length,emailCount:n.filter(r=>r.contentMode==="email").length,hasBrandAssets:!!(e.brandAssets&&(e.brandAssets.styleguide||e.brandAssets.brandvoice||e.brandAssets.brandKit)),isImported:!!e.isImported},o=t.findIndex(r=>r.id===e.id);o>=0?t[o]=s:t.push(s),Xo(t)}function by(e){let t=Yo().filter(n=>n.id!==e);Xo(t)}function Sy(e){let t=Yo().filter(n=>n.themeName!==e);Xo(t)}function x(){return We}function Qc(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Gn(e,t,n={}){let s={id:Qc(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return We=s,Uo(e),s}function D(){if(!We)return;zo(oe,{recursive:!0});let e=ue(oe,`${We.id}.json`);$s(e,JSON.stringify(We,null,2),"utf-8"),Zc(We)}function Rs(e){let t=ue(oe,e+".json");if(!Te(t))return null;try{let n=JSON.parse(dt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Vo(n),n.brandAssets?.plan&&n.templates?.length>0){let s=n.templates.find(o=>o.id===n.activeTemplateId)||n.templates[0];s.plan||(s.plan=n.brandAssets.plan)}return We=n,n}catch{return null}}function ed(e){if(!Te(oe))return null;let t=Yc(e),n=null,s=-1;for(let o of qo(oe).filter(r=>r.endsWith(".json")&&r!=="_index.json"))try{let r=JSON.parse(dt(ue(oe,o),"utf-8"));if(!r.id||!r.themePath||Yc(r.themePath)!==t)continue;let i=typeof r.updatedAt=="number"?r.updatedAt:0;i>s&&(s=i,n=r.id)}catch{}return n}function Wn(){return Te(oe)?Yo():[]}function td(e,t=!1){let n=ue(oe,e+".json"),s="";if(t)try{let o=JSON.parse(dt(n,"utf-8"));s=o.themeName||"",o.themePath&&Te(o.themePath)&&Li(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(dt(n,"utf-8")).themeName||""}catch{}try{Te(n)&&Li(n)}catch{}if(s&&Te(oe)){for(let o of qo(oe).filter(r=>r.endsWith(".json")&&r!=="_index.json"))try{JSON.parse(dt(ue(oe,o),"utf-8")).themeName===s&&Li(ue(oe,o))}catch{}Sy(s)}else by(e);We?.id===e&&(We=null)}function nd(e,t){let n=ue(oe,e+".json");if(!Te(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(dt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let r=s.themePath,i=ue(Xc(r),t);if(Te(r)){if(Te(i))return{ok:!1,error:"A project with that name already exists"};try{Bi(r,i)}catch(p){return{ok:!1,error:`Failed to rename folder: ${p instanceof Error?p.message:String(p)}`}}let a=ue(i,"css",`${o}-theme.css`),l=ue(i,"css",`${t}-theme.css`);if(Te(a))try{Bi(a,l)}catch{}let c=ue(i,"js",`${o}-animations.js`),d=ue(i,"js",`${t}-animations.js`);if(Te(c))try{Bi(c,d)}catch{}let u=ue(i,"theme.json");if(Te(u))try{let p=JSON.parse(dt(u,"utf-8"));p.label=t,p.name=t,$s(u,JSON.stringify(p,null,2),"utf-8")}catch{}}if(Te(oe))for(let a of qo(oe).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(dt(ue(oe,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=i,l.updatedAt=Date.now(),$s(ue(oe,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return We&&We.themeName===o&&(We.themeName=t,We.themePath=i,We.updatedAt=Date.now()),Hi(),{ok:!0}}function sd(e){let t=ue(oe,e+".json");if(!Te(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(dt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=Xc(n.themePath),r=`${s}-copy`,i=1;for(;Te(ue(o,r));)i++,r=`${s}-copy-${i}`;let a=ue(o,r);if(Te(n.themePath))try{hy(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else zo(a,{recursive:!0});let l=Qc(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:r,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return zo(oe,{recursive:!0}),$s(ue(oe,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Zc(c),{ok:!0,newName:r,newSessionId:l}}var oe,Ji,Un,We,Is=j(()=>{"use strict";y();Hn();Xt();oe=ue(yy(),".vibespot","sessions"),Ji=ue(oe,"_index.json"),Un=null;We=null});import{readFileSync as vy,readdirSync as id,statSync as Ui}from"fs";import{createHash as xy}from"crypto";import{join as be,relative as wy}from"path";function er(e){let t=[];if(!w(e))return Vy(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=Qt(e),s=Uy(e),o=Wy(e),r=Ky(e),i=_y(e);Object.keys(n.cssVariables).length===0&&t.push({severity:"info",rule:"design.cssVariables.empty",message:"No :root CSS custom properties found in theme CSS.",fix:"Run with --apply-tokens to seed a :root block from inferred palette/typography."}),n.palette.length===0&&t.push({severity:"info",rule:"design.palette.empty",message:"Could not infer a colour palette from the theme CSS."}),s.orphanModules.length>0&&t.push({severity:"warning",rule:"modules.orphan",message:`${s.orphanModules.length} module(s) are not referenced by any template: ${s.orphanModules.join(", ")}`,fix:"Either reference these modules from a template or remove them."}),s.templates.length===0&&s.modules.length>0&&t.push({severity:"warning",rule:"templates.missing",message:"Theme has modules but no page templates wiring them together.",fix:"Add a templates/<name>.html that includes the modules via dnd_module."});for(let l of o)t.push({severity:"info",rule:"field.unsupported-pattern",file:`modules/${l.module}.module/fields.json`,message:`${l.module}.${l.field}: ${l.reason}`,fix:"vibeSpot will preserve this field as-is. Edit it in HubSpot if changes are needed."});for(let l of r)t.push({severity:"warning",rule:"roundtrip.preserve-pattern",file:l.file,message:`${l.pattern}: ${l.detail}`,fix:"vibeSpot avoids modifying this. Don't ask the AI to refactor it."});i.hasSnapshot&&i.filesChanged>0&&t.push({severity:"info",rule:"roundtrip.snapshot.diff",message:`${i.filesChanged} file(s) differ from the imported theme snapshot.`,fix:"Review report.roundTripDiff before re-uploading if you need to preserve imported files exactly."});let a=r.filter(l=>l.pattern==="hubl.macro").length;return{themePath:e,designTokens:n,graph:s,fieldFlags:o,roundTripRisks:r,roundTripDiff:i,findings:t,summary:{moduleCount:s.modules.length,templateCount:s.templates.length,orphanCount:s.orphanModules.length,paletteSize:n.palette.length,cssVarCount:Object.keys(n.cssVariables).length,customMacroCount:a,roundTripChangedCount:i.filesChanged}}}function gn(e){let t=[];for(let[n,s]of Object.entries(e.cssVariables))t.push(` ${n}: ${s};`);return Object.keys(e.cssVariables).length===0&&(e.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;t.push(` --color-${o}: ${n.value};`)}),e.fontFamilies[0]&&t.push(` --font-family-base: ${e.fontFamilies[0]};`),e.fontFamilies[1]&&t.push(` --font-family-heading: ${e.fontFamilies[1]};`)),t.length===0?"":`:root {
187
177
  ${t.join(`
188
178
  `)}
189
179
  }
190
- `}function Ho(e,t){let n=be(e,"css");if(x(n))try{for(let r of Oc(n))if(r.endsWith("-theme.css"))return null}catch{}let s=Dn(e),o=bs(s);if(!o)return null;let i=be(n,`${t}-theme.css`);return B(i,o),i}function Ss(e){return be(e,qf)}function Zf(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:jc(e)}}function mr(e,t){let n=Zf(e,t),s=Ss(e);return B(s,JSON.stringify(n,null,2)+`
191
- `),s}function Fc(e){let t=Ss(e);return x(t)?null:mr(e)}function Qf(e){let t=Ss(e);if(!x(t))return null;try{let n=JSON.parse(P(t));return wh(n)?n:null}catch{return null}}function eh(e){let t=Ss(e),n=Qf(e);if(!n)return{hasSnapshot:!1,snapshotPath:t,filesChanged:0,added:0,modified:0,deleted:0,files:[]};let s=new Map(n.files.map(d=>[d.path,d])),o=jc(e),i=new Map(o.map(d=>[d.path,d])),r=[];for(let d of n.files){let u=i.get(d.path);u?u.sha256!==d.sha256&&r.push({file:d.path,status:"modified",beforeSha256:d.sha256,afterSha256:u.sha256,beforeSize:d.size,afterSize:u.size,beforeLines:Jo(d.text),afterLines:Jo(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:Jo(d.text)})}for(let d of o)s.has(d.path)||r.push({file:d.path,status:"added",afterSha256:d.sha256,afterSize:d.size,afterLines:Jo(d.text)});r.sort((d,u)=>d.file.localeCompare(u.file));let a=r.filter(d=>d.status==="added").length,l=r.filter(d=>d.status==="modified").length,c=r.filter(d=>d.status==="deleted").length;return{hasSnapshot:!0,snapshotPath:t,filesChanged:r.length,added:a,modified:l,deleted:c,files:r}}function Dn(e){let t=fh(e),n={},s=new Map,o=new Map,i=new Set,r=new Set,a=new Set,l=new Set,c=new Set;for(let u of t){let m;try{m=P(u)}catch{continue}let g,h=new RegExp(ch.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(dh.source,"g"),S;for(;(S=b.exec(f))!==null;){let v=S[1].trim(),w=S[2].trim();n[v]||(n[v]=w);let $=w.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if($){let j=Nc($[0]);o.set(j,v)}}}for(let f of[th,nh,sh]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let v=Nc(S[0]);v&&s.set(v,(s.get(v)??0)+1)}}Lo(m,oh,i,mh),Lo(m,ih,r,f=>f.trim()),uh(m,a),Lo(m,ah,l,f=>f.trim()),Lo(m,lh,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!gh(u)).sort((u,m)=>m[1]-u[1]).slice(0,12).map(([u,m])=>({value:u,count:m,varName:o.get(u)}));return{cssVariables:n,palette:d,fontFamilies:[...i].slice(0,8),fontSizes:[...r].slice(0,16),spacing:[...a].slice(0,16),radii:[...l].slice(0,8),shadows:[...c].slice(0,8)}}function Lo(e,t,n,s){let o=new RegExp(t.source,"g"),i;for(;(i=o.exec(e))!==null;){let r=s(i[1]);r&&!r.startsWith("var(")&&n.add(r)}}function uh(e,t){let n=new RegExp(rh.source,"g"),s;for(;(s=n.exec(e))!==null;){let o=s[1].trim();if(!o.startsWith("var("))for(let i of o.split(/\s+/))/^-?\d+(\.\d+)?(rem|em|px|%)$/.test(i)&&t.add(i)}}function mh(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function Nc(e){let t=e.trim().toLowerCase();if(t.startsWith("#")){if(/^#[0-9a-f]{3}$/.test(t)){let[,n,s,o]=t.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);return`#${n}${n}${s}${s}${o}${o}`}return t}return t.replace(/\s+/g,"")}function gh(e){return ph.has(e)}function fh(e){let t=[],n=be(e,"css");if(x(n))for(let o of Vt(n))o.endsWith(".css")&&t.push(be(n,o));let s=be(e,"modules");if(x(s))for(let o of Vt(s)){if(!o.endsWith(".module"))continue;let i=be(s,o,"module.css");x(i)&&t.push(i)}return t}function hh(e){let t=be(e,"modules"),n=be(e,"templates"),s=new Set,o=new Map;if(x(t))for(let c of Vt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,x(be(t,c,"module.js")))}let i=[],r=new Map;if(x(n))for(let c of Vt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=be(n,c),u;try{u=ur(d)}catch{continue}if(!u.isFile())continue;let m;try{m=P(d)}catch{continue}let g=pr(m);for(let f of g){let b=r.get(f)??new Set;b.add(c),r.set(f,b)}let h=c.replace(/\.html$/,"");i.push({id:h,file:`templates/${c}`,modules:Ch(g)})}let a=[...s].sort().map(c=>({name:c,templates:[...r.get(c)??[]].sort(),hasJs:o.get(c)??!1})),l=a.filter(c=>c.templates.length===0).map(c=>c.name);return{templates:i,modules:a,orphanModules:l}}function pr(e){let t=[],n=/{%\s*dnd_module\b[\s\S]*?%}/g,s;for(;(s=n.exec(e))!==null;){let o=s[0].match(/\bpath\s*=\s*["']([^"']+)["']/);if(!o)continue;let i=o[1].match(/(?:^|\/)modules\/(.+)$/);if(!i)continue;let r=i[1].replace(/\.module$/,"");r&&t.push(r)}return t}function bh(e){let t=[],n=be(e,"modules");if(!x(n))return t;for(let s of Vt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=be(n,s,"fields.json");if(!x(i))continue;let r;try{r=JSON.parse(P(i))}catch{continue}Array.isArray(r)&&Dc(r,o,t,0)}return t}function Dc(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)",a=typeof i.type=="string"?i.type:"";if(a==="group"&&s>=1&&n.push({module:t,field:r,reason:"deeply nested group (>1 level)"}),(a==="group"||a==="module")&&i.occurrence){let l=i.occurrence;l.max!==void 0&&l.max!==1&&n.push({module:t,field:r,reason:"repeater (occurrence) field"})}(a==="hubdb_table"||a==="hubdbtable")&&n.push({module:t,field:r,reason:"HubDB-backed field"}),(a==="crm_object"||a==="crm_object_property")&&n.push({module:t,field:r,reason:"CRM object field"}),a==="embed"&&typeof i.embed=="object"&&n.push({module:t,field:r,reason:"rich embed field"}),a&&!yh.has(a)&&a!=="module"&&n.push({module:t,field:r,reason:`field type "${a}" not in vibeSpot's generation set`}),i.visibility&&typeof i.visibility=="object"&&n.push({module:t,field:r,reason:"conditional visibility rule"}),Array.isArray(i.children)&&Dc(i.children,t,n,s+1)}}function Sh(e){let t=[],n=be(e,"modules");if(x(n))for(let i of Vt(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=be(n,i,"module.html");x(a)&&Rc(a,e,r,t);let l=be(n,i,"module.js");if(x(l))try{P(l).trim().length>0&&t.push({file:gr(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=be(e,"templates");if(x(s))for(let i of Vt(s)){if(!i.endsWith(".html"))continue;let r=be(s,i);if(!x(r))continue;let a;try{a=ur(r)}catch{continue}a.isFile()&&Rc(r,e,i,t)}let o=be(e,"import_modules.json");return x(o)&&t.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),t}function Rc(e,t,n,s){let o;try{o=P(e)}catch{return}let i=gr(t,e);/{%\s*macro\s+\w+/.test(o)&&s.push({file:i,pattern:"hubl.macro",detail:`${n}: contains custom HubL {% macro %}`}),/{%\s*raw\s*%}/.test(o)&&s.push({file:i,pattern:"hubl.raw",detail:`${n}: contains {% raw %} block`});let r=/{%\s*include\s+["']([^"']+)["']/g,a;for(;(a=r.exec(o))!==null;){let l=a[1];!l.startsWith("../modules/")&&!l.startsWith("./modules/")&&!l.includes("/layouts/")&&s.push({file:i,pattern:"hubl.include",detail:`${n}: includes partial "${l}" outside modules/`})}}function vh(e,t){let n={hasSnapshot:!1,snapshotPath:Ss(e),filesChanged:0,added:0,modified:0,deleted:0,files:[]};return{themePath:e,designTokens:{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]},graph:{templates:[],modules:[],orphanModules:[]},fieldFlags:[],roundTripRisks:[],roundTripDiff:n,findings:t,summary:{moduleCount:0,templateCount:0,orphanCount:0,paletteSize:0,cssVarCount:0,customMacroCount:0,roundTripChangedCount:0}}}function jc(e){let t=[];function n(s){for(let o of Vt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=be(s,o),r;try{r=ur(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=gr(e,i),l=Vf(i),c={path:a,sha256:zf("sha256").update(l).digest("hex"),size:l.length};xh(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function xh(e){let t=e.lastIndexOf(".");return t<0?!1:Xf.has(e.slice(t).toLowerCase())}function wh(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version!==1||typeof t.createdAt!="string"||!Array.isArray(t.files)?!1:t.files.every(n=>{if(typeof n!="object"||n===null)return!1;let s=n;return typeof s.path=="string"&&typeof s.sha256=="string"&&typeof s.size=="number"&&(s.text===void 0||typeof s.text=="string")})}function Jo(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Vt(e){try{return Oc(e)}catch{return[]}}function gr(e,t){return Yf(e,t).split("\\").join("/")}function Ch(e){return[...new Set(e)]}var qf,Xf,th,nh,sh,oh,ih,rh,ah,lh,ch,dh,ph,yh,Uo=N(()=>{"use strict";y();oe();qf=".vibespot/import-snapshot.json",Xf=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);th=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,nh=/\brgba?\([^)]+\)/g,sh=/\bhsla?\([^)]+\)/g,oh=/font-family\s*:\s*([^;}\n]+)/g,ih=/font-size\s*:\s*([^;}\n]+)/g,rh=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,ah=/border-radius\s*:\s*([^;}\n]+)/g,lh=/box-shadow\s*:\s*([^;}\n]+)/g,ch=/:root\s*\{([\s\S]*?)\}/g,dh=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;ph=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);yh=new Set(["text","richtext","image","url","boolean","choice","number","color","icon","link","menu","video","form","cta","blog","tag","page","email","logo","embed","alignment","border","spacing","font","background","gradient","textalignment","group"])});import{readFileSync as fr,readdirSync as xs,existsSync as xe,writeFileSync as Ye,mkdirSync as vs,rmSync as Lc}from"fs";import{join as U}from"path";function we(e){try{return fr(e,"utf-8")}catch{return""}}function Bc(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 kh(e,t){let n=we(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o=/templateType:\s*email\b/i.test(n),i="landing_page",r;o?(i="module_only",r="email"):s.startsWith("bp-")?i="blog_post":s.startsWith("wp-")?i="website_page":s.startsWith("mo-")&&(i="module_only");let a=s,l=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);l&&(a=l[1].trim());let c=pr(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function Th(e,t,n,s,o){if(!xe(e))return[];let i=[],r=xs(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=U(e,a),c=kh(l,a);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let g=t.get(m);g&&(d.push(g),u.push(m))}i.push({id:c.id,label:c.label,pageType:c.pageType,contentMode:c.contentMode,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:c.contentMode==="email"?"":n,sharedJs:c.contentMode==="email"?"":s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function Go(e){let t=C();if(!t)return;let n=vc(e);n.length>0&&t.messages.length===0&&(t.messages=n),Mo(e),Fc(e);let s=U(e,"modules");if(!xe(s))return;let o=xs(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let v=U(s,S.name),w=S.name.replace(/\.module$/,""),$={moduleName:w,fieldsJson:we(U(v,"fields.json")),metaJson:we(U(v,"meta.json")),moduleHtml:we(U(v,"module.html")),moduleCss:we(U(v,"module.css")),moduleJs:we(U(v,"module.js"))||void 0};$.fieldsJson&&$.moduleHtml&&(t.modules.push($),t.moduleOrder.push(w))}let i=U(e,"css"),r=U(e,"js"),a="",l="";if(xe(i)){let S=xs(i).filter(v=>v.endsWith("-theme.css"));S.length>0&&(a=we(U(i,S[0])),t.sharedCss=a)}if(xe(r)){let S=xs(r).filter(v=>v.endsWith("-animations.js"));S.length>0&&(l=we(U(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=Dn(e),v=bs(S);v&&(t.sharedCss=v,a=v)}let c=U(e,".vibespot","styleguide.md"),d=U(e,".vibespot","brandvoice.md"),u=U(e,".vibespot","theme-context.md"),m=U(e,".vibespot","plan.md"),g=U(e,".vibespot","brand-kit.json");if((xe(c)||xe(d)||xe(u)||xe(m)||xe(g))&&(t.brandAssets||(t.brandAssets={}),xe(c)&&(t.brandAssets.styleguide=we(c)),xe(d)&&(t.brandAssets.brandvoice=we(d)),xe(u)&&(t.brandAssets.themeContext=we(u)),xe(m)&&(t.brandAssets.plan=we(m)),xe(g)))try{t.brandAssets.brandKit=JSON.parse(we(g))}catch{}let h=U(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=Th(h,f,a,l,t.messages);if(b.length>0){t.templates=b,t.activeTemplateId=b[0].id,t.brandAssets?.plan&&!b[0].plan&&(b[0].plan=t.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let v=new Set(t.moduleOrder),w=S.filter($=>v.has($));for(let $ of t.moduleOrder)w.includes($)||w.push($);t.moduleOrder=w}an(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),Ro(t)}function Te(){let e=C();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=U(t,"modules");vs(s,{recursive:!0});for(let l of n.values())vs(U(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=U(s,`${l.moduleName}.module`);Ye(U(c,"fields.json"),l.fieldsJson,"utf-8"),Ye(U(c,"meta.json"),l.metaJson,"utf-8"),Ye(U(c,"module.html"),l.moduleHtml,"utf-8"),Ye(U(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ye(U(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=U(t,"css");vs(l,{recursive:!0}),Ye(U(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=U(t,"js");vs(l,{recursive:!0}),Ye(U(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=U(t,"templates");vs(o,{recursive:!0});let i=U(o,"home.html");(e.templates.length>0||e.modules.length>0)&&xe(i)&&Lc(i,{force:!0});let a=new Set;if(e.templates.length>0)for(let l of e.templates){if(l.contentMode==="email"){if(l.modules.length===0)continue;let m=Eh(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ye(U(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||$h(l),d=Jc(c,l.label,l.pageType),u=`${l.id}.html`;Ye(U(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(Mh(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||Ih(),c=Jc(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ye(U(o,d),c,"utf-8"),a.add(d)}try{for(let l of xs(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&Lc(U(o,l),{force:!0})}catch{}Ah(),_h()}function Hc(){let e=C();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",Go(e.themePath),e.updatedAt=Date.now(),at())}function Uc(){let e=C();if(!e)return;let t=ke();if(!t)return;let n=e.themePath,s=U(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=U(s,`${o}.module`);if(!xe(i))continue;let r={moduleName:o,fieldsJson:we(U(i,"fields.json")),metaJson:we(U(i,"meta.json")),moduleHtml:we(U(i,"module.html")),moduleCss:we(U(i,"module.css")),moduleJs:we(U(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=U(n,t.templateFile);xe(o)&&(t.template=we(o))}an(t),e.updatedAt=Date.now()}function Ah(){let e=C();if(!e)return;let t=U(e.themePath,"templates","layouts","base.html");if(xe(t))try{let n=fr(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+`
180
+ `}function tr(e,t){let n=be(e,"css");if(w(n))try{for(let i of id(n))if(i.endsWith("-theme.css"))return null}catch{}let s=Qt(e),o=gn(s);if(!o)return null;let r=be(n,`${t}-theme.css`);return U(r,o),r}function Ns(e){return be(e,ky)}function Ty(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:cd(e)}}function Gi(e,t){let n=Ty(e,t),s=Ns(e);return U(s,JSON.stringify(n,null,2)+`
181
+ `),s}function ad(e){let t=Ns(e);return w(t)?null:Gi(e)}function Ay(e){let t=Ns(e);if(!w(t))return null;try{let n=JSON.parse(I(t));return qy(n)?n:null}catch{return null}}function _y(e){let t=Ns(e),n=Ay(e);if(!n)return{hasSnapshot:!1,snapshotPath:t,filesChanged:0,added:0,modified:0,deleted:0,files:[]};let s=new Map(n.files.map(d=>[d.path,d])),o=cd(e),r=new Map(o.map(d=>[d.path,d])),i=[];for(let d of n.files){let u=r.get(d.path);u?u.sha256!==d.sha256&&i.push({file:d.path,status:"modified",beforeSha256:d.sha256,afterSha256:u.sha256,beforeSize:d.size,afterSize:u.size,beforeLines:Qo(d.text),afterLines:Qo(u.text)}):i.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:Qo(d.text)})}for(let d of o)s.has(d.path)||i.push({file:d.path,status:"added",afterSha256:d.sha256,afterSize:d.size,afterLines:Qo(d.text)});i.sort((d,u)=>d.file.localeCompare(u.file));let a=i.filter(d=>d.status==="added").length,l=i.filter(d=>d.status==="modified").length,c=i.filter(d=>d.status==="deleted").length;return{hasSnapshot:!0,snapshotPath:t,filesChanged:i.length,added:a,modified:l,deleted:c,files:i}}function Qt(e){let t=Hy(e),n={},s=new Map,o=new Map,r=new Set,i=new Set,a=new Set,l=new Set,c=new Set;for(let u of t){let p;try{p=I(u)}catch{continue}let g,f=new RegExp(Fy.source,"g");for(;(g=f.exec(p))!==null;){let h=g[1],b=new RegExp(Dy.source,"g"),S;for(;(S=b.exec(h))!==null;){let v=S[1].trim(),k=S[2].trim();n[v]||(n[v]=k);let _=k.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if(_){let M=od(_[0]);o.set(M,v)}}}for(let h of[Py,Ey,Iy]){let b=new RegExp(h.source,"g"),S;for(;(S=b.exec(p))!==null;){let v=od(S[0]);v&&s.set(v,(s.get(v)??0)+1)}}Zo(p,My,r,Ly),Zo(p,$y,i,h=>h.trim()),jy(p,a),Zo(p,Ny,l,h=>h.trim()),Zo(p,Oy,c,h=>h.trim())}let d=[...s.entries()].filter(([u])=>!Jy(u)).sort((u,p)=>p[1]-u[1]).slice(0,12).map(([u,p])=>({value:u,count:p,varName:o.get(u)}));return{cssVariables:n,palette:d,fontFamilies:[...r].slice(0,8),fontSizes:[...i].slice(0,16),spacing:[...a].slice(0,16),radii:[...l].slice(0,8),shadows:[...c].slice(0,8)}}function Zo(e,t,n,s){let o=new RegExp(t.source,"g"),r;for(;(r=o.exec(e))!==null;){let i=s(r[1]);i&&!i.startsWith("var(")&&n.add(i)}}function jy(e,t){let n=new RegExp(Ry.source,"g"),s;for(;(s=n.exec(e))!==null;){let o=s[1].trim();if(!o.startsWith("var("))for(let r of o.split(/\s+/))/^-?\d+(\.\d+)?(rem|em|px|%)$/.test(r)&&t.add(r)}}function Ly(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function od(e){let t=e.trim().toLowerCase();if(t.startsWith("#")){if(/^#[0-9a-f]{3}$/.test(t)){let[,n,s,o]=t.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);return`#${n}${n}${s}${s}${o}${o}`}return t}return t.replace(/\s+/g,"")}function Jy(e){return By.has(e)}function Hy(e){let t=[],n=be(e,"css");if(w(n))for(let o of Zt(n))o.endsWith(".css")&&t.push(be(n,o));let s=be(e,"modules");if(w(s))for(let o of Zt(s)){if(!o.endsWith(".module"))continue;let r=be(s,o,"module.css");w(r)&&t.push(r)}return t}function Uy(e){let t=be(e,"modules"),n=be(e,"templates"),s=new Set,o=new Map;if(w(t))for(let c of Zt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,w(be(t,c,"module.js")))}let r=[],i=new Map;if(w(n))for(let c of Zt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=be(n,c),u;try{u=Ui(d)}catch{continue}if(!u.isFile())continue;let p;try{p=I(d)}catch{continue}let g=Wi(p);for(let h of g){let b=i.get(h)??new Set;b.add(c),i.set(h,b)}let f=c.replace(/\.html$/,"");r.push({id:f,file:`templates/${c}`,modules:Yy(g)})}let a=[...s].sort().map(c=>({name:c,templates:[...i.get(c)??[]].sort(),hasJs:o.get(c)??!1})),l=a.filter(c=>c.templates.length===0).map(c=>c.name);return{templates:r,modules:a,orphanModules:l}}function Wi(e){let t=[],n=/{%\s*dnd_module\b[\s\S]*?%}/g,s;for(;(s=n.exec(e))!==null;){let o=s[0].match(/\bpath\s*=\s*["']([^"']+)["']/);if(!o)continue;let r=o[1].match(/(?:^|\/)modules\/(.+)$/);if(!r)continue;let i=r[1].replace(/\.module$/,"");i&&t.push(i)}return t}function Wy(e){let t=[],n=be(e,"modules");if(!w(n))return t;for(let s of Zt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),r=be(n,s,"fields.json");if(!w(r))continue;let i;try{i=JSON.parse(I(r))}catch{continue}Array.isArray(i)&&ld(i,o,t,0)}return t}function ld(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let r=o,i=typeof r.name=="string"?r.name:"(unnamed)",a=typeof r.type=="string"?r.type:"";if(a==="group"&&s>=1&&n.push({module:t,field:i,reason:"deeply nested group (>1 level)"}),(a==="group"||a==="module")&&r.occurrence){let l=r.occurrence;l.max!==void 0&&l.max!==1&&n.push({module:t,field:i,reason:"repeater (occurrence) field"})}(a==="hubdb_table"||a==="hubdbtable")&&n.push({module:t,field:i,reason:"HubDB-backed field"}),(a==="crm_object"||a==="crm_object_property")&&n.push({module:t,field:i,reason:"CRM object field"}),a==="embed"&&typeof r.embed=="object"&&n.push({module:t,field:i,reason:"rich embed field"}),a&&!Gy.has(a)&&a!=="module"&&n.push({module:t,field:i,reason:`field type "${a}" not in vibeSpot's generation set`}),r.visibility&&typeof r.visibility=="object"&&n.push({module:t,field:i,reason:"conditional visibility rule"}),Array.isArray(r.children)&&ld(r.children,t,n,s+1)}}function Ky(e){let t=[],n=be(e,"modules");if(w(n))for(let r of Zt(n)){if(!r.endsWith(".module"))continue;let i=r.replace(/\.module$/,""),a=be(n,r,"module.html");w(a)&&rd(a,e,i,t);let l=be(n,r,"module.js");if(w(l))try{I(l).trim().length>0&&t.push({file:Ki(e,l),pattern:"module.js.custom",detail:`${i}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=be(e,"templates");if(w(s))for(let r of Zt(s)){if(!r.endsWith(".html"))continue;let i=be(s,r);if(!w(i))continue;let a;try{a=Ui(i)}catch{continue}a.isFile()&&rd(i,e,r,t)}let o=be(e,"import_modules.json");return w(o)&&t.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),t}function rd(e,t,n,s){let o;try{o=I(e)}catch{return}let r=Ki(t,e);/{%\s*macro\s+\w+/.test(o)&&s.push({file:r,pattern:"hubl.macro",detail:`${n}: contains custom HubL {% macro %}`}),/{%\s*raw\s*%}/.test(o)&&s.push({file:r,pattern:"hubl.raw",detail:`${n}: contains {% raw %} block`});let i=/{%\s*include\s+["']([^"']+)["']/g,a;for(;(a=i.exec(o))!==null;){let l=a[1];!l.startsWith("../modules/")&&!l.startsWith("./modules/")&&!l.includes("/layouts/")&&s.push({file:r,pattern:"hubl.include",detail:`${n}: includes partial "${l}" outside modules/`})}}function Vy(e,t){let n={hasSnapshot:!1,snapshotPath:Ns(e),filesChanged:0,added:0,modified:0,deleted:0,files:[]};return{themePath:e,designTokens:{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]},graph:{templates:[],modules:[],orphanModules:[]},fieldFlags:[],roundTripRisks:[],roundTripDiff:n,findings:t,summary:{moduleCount:0,templateCount:0,orphanCount:0,paletteSize:0,cssVarCount:0,customMacroCount:0,roundTripChangedCount:0}}}function cd(e){let t=[];function n(s){for(let o of Zt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let r=be(s,o),i;try{i=Ui(r)}catch{continue}if(i.isDirectory()){n(r);continue}if(!i.isFile())continue;let a=Ki(e,r),l=vy(r),c={path:a,sha256:xy("sha256").update(l).digest("hex"),size:l.length};zy(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function zy(e){let t=e.lastIndexOf(".");return t<0?!1:Cy.has(e.slice(t).toLowerCase())}function qy(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version!==1||typeof t.createdAt!="string"||!Array.isArray(t.files)?!1:t.files.every(n=>{if(typeof n!="object"||n===null)return!1;let s=n;return typeof s.path=="string"&&typeof s.sha256=="string"&&typeof s.size=="number"&&(s.text===void 0||typeof s.text=="string")})}function Qo(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Zt(e){try{return id(e)}catch{return[]}}function Ki(e,t){return wy(e,t).split("\\").join("/")}function Yy(e){return[...new Set(e)]}var ky,Cy,Py,Ey,Iy,My,$y,Ry,Ny,Oy,Fy,Dy,By,Gy,Os=j(()=>{"use strict";y();ae();ky=".vibespot/import-snapshot.json",Cy=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);Py=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Ey=/\brgba?\([^)]+\)/g,Iy=/\bhsla?\([^)]+\)/g,My=/font-family\s*:\s*([^;}\n]+)/g,$y=/font-size\s*:\s*([^;}\n]+)/g,Ry=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,Ny=/border-radius\s*:\s*([^;}\n]+)/g,Oy=/box-shadow\s*:\s*([^;}\n]+)/g,Fy=/:root\s*\{([\s\S]*?)\}/g,Dy=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;By=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);Gy=new Set(["text","richtext","image","url","boolean","choice","number","color","icon","link","menu","video","form","cta","blog","tag","page","email","logo","embed","alignment","border","spacing","font","background","gradient","textalignment","group"])});import{readFileSync as Vi,readdirSync as Ds,existsSync as we,writeFileSync as Ye,mkdirSync as Fs,rmSync as dd}from"fs";import{join as q}from"path";function ke(e){try{return Vi(e,"utf-8")}catch{return""}}function nr(e,t){return ws(t)?q(e,t):(A.warn("session-disk","Skipping template with unsafe filename",{filename:t}),null)}function pd(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 Xy(e,t){let n=ke(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o=/templateType:\s*email\b/i.test(n),r="landing_page",i;o?(r="module_only",i="email"):s.startsWith("bp-")||/templateType:\s*blog_post\b/i.test(n)?r="blog_post":s.startsWith("wp-")?r="website_page":s.startsWith("mo-")&&(r="module_only");let a=s,l=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);l&&(a=l[1].trim());let c=Wi(n);return{id:s,label:a,pageType:r,contentMode:i,moduleNames:c,templateContent:n,filename:t}}function Zy(e,t,n,s,o){if(!we(e))return[];let r=[],i=Ds(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of i){let l=q(e,a),c=Xy(l,a);if(!c||c.moduleNames.length===0&&r.length>0)continue;let d=[],u=[];for(let p of c.moduleNames){let g=t.get(p);g&&(d.push(g),u.push(p))}r.push({id:c.id,label:c.label,pageType:c.pageType,contentMode:c.contentMode,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:c.contentMode==="email"?"":n,sharedJs:c.contentMode==="email"?"":s,template:c.templateContent,messages:r.length===0?[...o]:[]})}return r}function sr(e){let t=x();if(!t)return;let n=Uc(e);n.length>0&&t.messages.length===0&&(t.messages=n),Uo(e),ad(e);let s=q(e,"modules");if(!we(s))return;let o=Ds(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let v=q(s,S.name),k=S.name.replace(/\.module$/,""),_={moduleName:k,fieldsJson:ke(q(v,"fields.json")),metaJson:ke(q(v,"meta.json")),moduleHtml:ke(q(v,"module.html")),moduleCss:ke(q(v,"module.css")),moduleJs:ke(q(v,"module.js"))||void 0};_.fieldsJson&&_.moduleHtml&&(t.modules.push(_),t.moduleOrder.push(k))}let r=q(e,"css"),i=q(e,"js"),a="",l="";if(we(r)){let S=Ds(r).filter(v=>v.endsWith("-theme.css"));S.length>0&&(a=ke(q(r,S[0])),t.sharedCss=a)}if(we(i)){let S=Ds(i).filter(v=>v.endsWith("-animations.js"));S.length>0&&(l=ke(q(i,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=Qt(e),v=gn(S);v&&(t.sharedCss=v,a=v)}let c=q(e,".vibespot","styleguide.md"),d=q(e,".vibespot","brandvoice.md"),u=q(e,".vibespot","theme-context.md"),p=q(e,".vibespot","plan.md"),g=q(e,".vibespot","brand-kit.json");if((we(c)||we(d)||we(u)||we(p)||we(g))&&(t.brandAssets||(t.brandAssets={}),we(c)&&(t.brandAssets.styleguide=ke(c)),we(d)&&(t.brandAssets.brandvoice=ke(d)),we(u)&&(t.brandAssets.themeContext=ke(u)),we(p)&&(t.brandAssets.plan=ke(p)),we(g)))try{t.brandAssets.brandKit=JSON.parse(ke(g))}catch{}let f=q(e,"templates"),h=new Map(t.modules.map(S=>[S.moduleName,S])),b=Zy(f,h,a,l,t.messages);if(b.length>0){t.templates=b,t.activeTemplateId=b[0].id,t.brandAssets?.plan&&!b[0].plan&&(b[0].plan=t.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let v=new Set(t.moduleOrder),k=S.filter(_=>v.has(_));for(let _ of t.moduleOrder)k.includes(_)||k.push(_);t.moduleOrder=k}mn(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),Vo(t)}function Ae(){let e=x();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let c of e.templates)for(let d of c.modules)n.set(d.moduleName,d);for(let c of e.modules)n.set(c.moduleName,c);let s=q(t,"modules"),o=[];for(let c of n.values())try{o.push({mod:c,modDir:dn(s,c.moduleName)})}catch{A.warn("session-disk","Skipping module with unsafe name",{name:c.moduleName})}Fs(s,{recursive:!0});for(let{modDir:c}of o)Fs(c,{recursive:!0});for(let{mod:c,modDir:d}of o)Ye(q(d,"fields.json"),c.fieldsJson,"utf-8"),Ye(q(d,"meta.json"),c.metaJson,"utf-8"),Ye(q(d,"module.html"),c.moduleHtml,"utf-8"),Ye(q(d,"module.css"),c.moduleCss,"utf-8"),c.moduleJs&&Ye(q(d,"module.js"),c.moduleJs,"utf-8");if(e.sharedCss){let c=q(t,"css");Fs(c,{recursive:!0}),Ye(q(c,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let c=q(t,"js");Fs(c,{recursive:!0}),Ye(q(c,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let r=q(t,"templates");Fs(r,{recursive:!0});let i=q(r,"home.html");(e.templates.length>0||e.modules.length>0)&&we(i)&&dd(i,{force:!0});let l=new Set;if(e.templates.length>0)for(let c of e.templates){if(c.contentMode==="email"){if(c.modules.length===0)continue;let f=nb(c),h=c.templateFile?c.templateFile.replace("templates/",""):"email.html",b=nr(r,h);if(!b)continue;Ye(b,f,"utf-8"),l.add(h);continue}if(c.pageType==="module_only"||c.modules.length===0)continue;let d=c.template||tb(c),u=ud(d,c.label,c.pageType),p=`${c.id}.html`,g=nr(r,p);g&&(Ye(g,u,"utf-8"),l.add(p),c.pageType==="blog_post"&&(sb(r,c),l.add(`${c.id}-listing.html`)))}else if(e.modules.length>0){let c=e.template||ob(),d=ud(c,`${e.themeName} Landing Page`),u=`lp-${e.themeName}.html`,p=nr(r,u);p&&(Ye(p,d,"utf-8"),l.add(u))}try{for(let c of Ds(r))c.startsWith("lp-")&&c.endsWith(".html")&&!l.has(c)&&dd(q(r,c),{force:!0})}catch{}Qy(),eb()}function md(){let e=x();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",sr(e.themePath),e.updatedAt=Date.now(),lt())}function gd(){let e=x();if(!e)return;let t=xe();if(!t)return;let n=e.themePath,s=q(n,"modules");t.modules=[];for(let o of t.moduleOrder){let r;try{r=dn(s,o)}catch{A.warn("session-disk","Skipping module with unsafe name",{name:o});continue}if(!we(r))continue;let i={moduleName:o,fieldsJson:ke(q(r,"fields.json")),metaJson:ke(q(r,"meta.json")),moduleHtml:ke(q(r,"module.html")),moduleCss:ke(q(r,"module.css")),moduleJs:ke(q(r,"module.js"))||void 0};i.fieldsJson&&i.moduleHtml&&t.modules.push(i)}if(t.templateFile)try{let o=Ln(n,t.templateFile);we(o)&&(t.template=ke(o))}catch{A.warn("session-disk","Skipping template file outside theme",{templateFile:t.templateFile})}mn(t),e.updatedAt=Date.now()}function Qy(){let e=x();if(!e)return;let t=q(e.themePath,"templates","layouts","base.html");if(we(t))try{let n=Vi(t,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
192
182
  {% if template_js %}
193
183
  {{ require_js(get_asset_url(template_js)) }}
194
184
  {% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
195
185
  {{ require_js(get_asset_url(template_js)) }}
196
186
  {% endif %}
197
- {{ standard_footer_includes }}`),Ye(t,n,"utf-8")}catch{}}function _h(){let e=C();if(!e)return;let t=U(e.themePath,"theme.json");if(xe(t))try{let n=JSON.parse(fr(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ye(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Jc(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
187
+ {{ standard_footer_includes }}`),Ye(t,n,"utf-8")}catch{}}function eb(){let e=x();if(!e)return;let t=q(e.themePath,"theme.json");if(we(t))try{let n=JSON.parse(Vi(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ye(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function ud(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
198
188
  templateType: ${n==="blog_post"?"blog_post":"page"}
199
189
  isAvailableForNewContent: true
200
190
  label: "${t}"
201
191
  -->
202
- `+e}function $h(e){if(e.modules.length===0)return"";let n=C().themeName,o=Bc(e).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
203
- {% dnd_module path="../modules/${r.moduleName}.module" %}
192
+ `+e}function tb(e){if(e.modules.length===0)return"";let n=x().themeName,o=pd(e).map(i=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
193
+ {% dnd_module path="../modules/${i.moduleName}.module" %}
204
194
  {% end_dnd_module %}
205
195
  {% end_dnd_section %}`).join(`
206
196
 
@@ -230,7 +220,7 @@ ${o}
230
220
 
231
221
  {% block footer %}
232
222
  {% endblock footer %}
233
- `}function Eh(e){let n=Bc(e).map(s=>` {% dnd_section %}
223
+ `}function nb(e){let n=pd(e).map(s=>` {% dnd_section %}
234
224
  {% dnd_module path="../modules/${s.moduleName}.module" %}
235
225
  {% end_dnd_module %}
236
226
  {% end_dnd_section %}`).join(`
@@ -277,7 +267,7 @@ ${n}
277
267
  {{ standard_footer_includes }}
278
268
  </body>
279
269
  </html>
280
- `}function Mh(e,t){let n=`<!--
270
+ `}function sb(e,t){let n=`<!--
281
271
  templateType: blog_listing
282
272
  isAvailableForNewContent: true
283
273
  label: "${t.label} - Listing"
@@ -302,7 +292,7 @@ ${n}
302
292
  {% endif %}
303
293
  </div>
304
294
  {% endblock body %}
305
- `;Ye(U(e,`${t.id}-listing.html`),n,"utf-8")}function Ih(){let e=C();if(!e||e.modules.length===0)return"";let t=e.themeName,s=ve().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
295
+ `,s=nr(e,`${t.id}-listing.html`);s&&Ye(s,n,"utf-8")}function ob(){let e=x();if(!e||e.modules.length===0)return"";let t=e.themeName,s=pe().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
306
296
  {% dnd_module path="../modules/${o.moduleName}.module" %}
307
297
  {% end_dnd_module %}
308
298
  {% end_dnd_section %}`).join(`
@@ -333,163 +323,11 @@ ${s}
333
323
 
334
324
  {% block footer %}
335
325
  {% endblock footer %}
336
- `}var hr=N(()=>{"use strict";y();hs();gs();Kt();Pn();Uo()});var Gc=N(()=>{"use strict";y();oc();hs();gs();hr();Kt()});var Ce=N(()=>{"use strict";y();Gc()});function ln(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]=ln(n.children):t[n.name]=n.default??"";return t}function Ln(e,t){let n=e;return n=Jh(n),n=zc(n,t),n=Yc(n,t),n=qc(n,t),n=Hh(n),n}function Sr(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
337
- `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
338
- `),s=e.renderedModules.join(`
339
- `);return`<!DOCTYPE html>
340
- <html lang="en">
341
- <head>
342
- <meta charset="utf-8">
343
- <meta name="viewport" content="width=device-width, initial-scale=1">
344
- ${t}
345
- <style>
346
- html{scroll-behavior:smooth}
347
- .vsp-img-wrap{position:relative;display:inline-block}
348
- .vsp-img-badge{position:absolute;top:8px;right:8px;background:rgba(0,0,0,.75);color:#fff;font:500 11px/1 -apple-system,sans-serif;padding:5px 8px;border-radius:4px;pointer-events:none;opacity:.85;white-space:nowrap;z-index:10}
349
- </style>
350
- </head>
351
- <body>
352
- ${s}
353
- ${n}
354
- <script>
355
- // Anchor link handler \u2014 smooth scroll to module sections
356
- document.addEventListener('click',function(e){
357
- var a=e.target.closest('a[href^="#"]');
358
- if(!a)return;
359
- var id=a.getAttribute('href').slice(1);
360
- if(!id)return;
361
- var el=document.getElementById(id);
362
- if(el){
363
- e.preventDefault();
364
- el.scrollIntoView({behavior:'smooth',block:'start'});
365
- }
366
- });
367
- // Placeholder image badges
368
- document.querySelectorAll('img').forEach(function(img){
369
- var src=img.src||img.getAttribute('src')||'';
370
- if(src.indexOf('placehold')!==-1){
371
- var w=document.createElement('span');
372
- w.className='vsp-img-wrap';
373
- img.parentNode.insertBefore(w,img);
374
- w.appendChild(img);
375
- var b=document.createElement('span');
376
- b.className='vsp-img-badge';
377
- b.textContent='Placeholder \u2014 replace in HubSpot';
378
- w.appendChild(b);
379
- }
380
- });
381
- </script>
382
- </body>
383
- </html>`}function Jh(e){return e=e.replace(Ph,""),e=e.replace(Nh,""),e=e.replace(Rh,""),Wc.lastIndex=0,e=e.replace(Wc,(t,n)=>`/theme-assets/${n}`),Kc.lastIndex=0,e=e.replace(Kc,""),e=e.replace(Oh,""),e=e.replace(Fh,""),e=e.replace(Dh,""),e=e.replace(jh,""),e=e.replace(Lh,""),e}function zc(e,t){let n=e,s=0;for(;s<30;){s++;let o=Bh(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Uh(r,t),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let h={...t,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},f=zc(a,h);return f=Yc(f,h),f=qc(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Bh(e){let t=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=t.exec(e);if(!s)return null;let o=s[1],i=s[2],r=s.index+s[0].length;n.lastIndex=r;let a=1,l;for(;(l=n.exec(e))!==null;)if(l[1].startsWith("for"))a++;else if(a--,a===0){let c=e.slice(r,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function Yc(e,t){let n=e,s=0;for(;yr.test(n)&&s<50;)s++,n=n.replace(yr,(o,i,r)=>{let a=r.split(/\{%[-\s]*else\s*-?%\}/),l=a[0],c=a[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(jn(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(jn(m,t))return g}return c}return jn(i,t)?l:c}),yr.lastIndex=0;return n}function qc(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Gh(t,r);for(let c=1;c<i.length;c++)a=Zc(a,i[c].trim());if(a==null)return"";if(typeof a=="object")return JSON.stringify(a);let l=String(a);return l=l.replace(/\\n/g," ").replace(/\n/g," "),l})}function Hh(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Uh(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Vc(n[1],t),i=Vc(n[2],t),r=[];for(let a=o;a<i;a++)r.push(a);return r}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=zt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return zt(t,e)}function Vc(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=zt(t,o);for(let r=1;r<s.length;r++)i=Zc(i,s[r].trim());return Number(i)||0}function zt(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 Gh(e,t){let n=t.match(/^(.+?)\s*([*/])\s*([\d.]+)$/);if(n){let s=zt(e,n[1].trim());if(s==null||s==="")return"";let o=Number(s);if(Number.isNaN(o))return"";let i=Number(n[3]);return n[2]==="/"?i===0?"":o/i:o*i}return zt(e,t)}function jn(e,t){let n=e.trim();if(n.startsWith("not "))return!jn(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>jn(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>jn(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=zt(t,s[1].trim()),r=s[2],a=s[3].trim();switch(typeof a=="string"&&a.startsWith('"')&&a.endsWith('"')||typeof a=="string"&&a.startsWith("'")&&a.endsWith("'")?a=a.slice(1,-1):isNaN(Number(a))?a=zt(t,a):a=Number(a),r){case"==":return i==a;case"!=":return i!=a;case">":return Number(i)>Number(a);case"<":return Number(i)<Number(a);case">=":return Number(i)>=Number(a);case"<=":return Number(i)<=Number(a)}}let o=zt(t,n);return Xc(o)}function Xc(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function Zc(e,t){let n=e==null?"":String(e),s=t.match(/^(\w+)\((.*)\)$/),o=s?s[1]:t,i=s?s[2].replace(/^["']|["']$/g,""):void 0;switch(o){case"escape":case"e":return n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");case"lower":return n.toLowerCase();case"upper":return n.toUpperCase();case"capitalize":return n.charAt(0).toUpperCase()+n.slice(1);case"trim":return n.trim();case"truncate":if(i){let r=parseInt(i,10);return n.length>r?n.slice(0,r)+"...":n}return n;case"default":return Xc(e)?e:i??"";case"length":return Array.isArray(e)?e.length:n.length;case"join":return Array.isArray(e)?e.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));case"convert_rgb":{let r=br(e);return r?Kh(r):""}default:return e}}function br(e){if(e==null)return null;if(typeof e=="string"){let t=e.match(/#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})(?![0-9a-fA-F])/);return t?Wh(t[1]):null}if(typeof e=="object"){let t=e;if(typeof t.color=="string")return br(t.color);if(typeof t.hex=="string")return br(t.hex)}return null}function Wh(e){let t=e.toLowerCase();return t.length===3?t.split("").map(n=>n+n).join(""):t}function Kh(e){let t=parseInt(e.slice(0,2),16),n=parseInt(e.slice(2,4),16),s=parseInt(e.slice(4,6),16);return`${t}, ${n}, ${s}`}var Ph,Nh,Rh,Wc,Kc,Oh,Fh,Dh,jh,Lh,yr,vr=N(()=>{"use strict";y();Ph=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Nh=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,Rh=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,Wc=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Kc=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Oh=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Fh=/\{%[-\s]*module\b.*?%\}/gs,Dh=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,jh=/\{#.*?#\}/gs,Lh=/\{\{[-\s]*content\.\w+.*?\}\}/gs,yr=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Wo={};Ge(Wo,{buildModulePreviewHtml:()=>Cr,buildPreviewHtml:()=>wr});function Vh(e){if(Jn()==="email")return!0;for(let t of e)try{let n=JSON.parse(t.metaJson);if(Array.isArray(n.host_template_types)&&n.host_template_types.includes("EMAIL"))return!0}catch{}return!1}function zh(e){if(!e)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let t=(a,l)=>{for(let c of a){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=e.match(d);if(u)return u[1].trim()}return l},n=t(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=t(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=t(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=t(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),r=t(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:r}}function xr(e,t){if(!Array.isArray(t))return e;let n=new Map;for(let o of t)n.set(o.name,o.type);let s=e;return s=s.replace(/(<([a-zA-Z]\w*)(\s[^>]*)?>)\s*(\{\{\s*module\.(\w+)(?:\.\w+)*(?:\|[^}]*)?\s*\}\})\s*(<\/\2>)/g,(o,i,r,a,l,c,d)=>{if(i.includes("data-vs-field"))return o;let u=n.get(c)||"text";return`${i.replace(/>$/,` data-vs-field="${c}" data-vs-type="${u}">`)}${l}${d}`}),s=s.replace(/(<img\b)([^>]*?)\bsrc\s*=\s*["']\{\{\s*module\.(\w+)\.src\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-field")?o:o.replace("<img",`<img data-vs-field="${a}" data-vs-type="image"`)),s=s.replace(/(<a\b)([^>]*?)\bhref\s*=\s*["']\{\{\s*module\.(\w+)\.url\.href\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-link")?o:o.replace("<a",`<a data-vs-link="${a}"`)),s}function wr(){let e=C();if(!e)return Qc();let t=ve(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return Qc();if(Vh(t))return Yh(t,n);let s=[],o=[],i=[],r=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d,u=[];try{let f=JSON.parse(c.fieldsJson);u=Array.isArray(f)?f:[],d={module:ln(u)}}catch{d={module:{}}}let m=xr(c.moduleHtml,u),g=Ln(m,d),h=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${h}" data-module="${c.moduleName}">${g}</div>`),r.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let a=zh(e.sharedCss);for(let c of n)if(!r.has(c)){let d=c.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module vibespot-module--pending" id="${d}" data-module="${c}">
384
- <div class="vibespot-placeholder">
385
- <div class="vibespot-placeholder__name">${c}</div>
386
- </div>
387
- </div>`)}let l=`body{background:${a.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${a.surface};border:1px dashed ${a.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${a.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return Sr({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function Qc(){return`<!DOCTYPE html>
388
- <html lang="en">
389
- <head>
390
- <meta charset="utf-8">
391
- <meta name="viewport" content="width=device-width, initial-scale=1">
392
- <style>
393
- * { margin: 0; padding: 0; box-sizing: border-box; }
394
- body {
395
- min-height: 100vh;
396
- display: flex;
397
- align-items: center;
398
- justify-content: center;
399
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
400
- background: #0f0f14;
401
- color: #888;
402
- }
403
- .welcome {
404
- text-align: center;
405
- padding: 2rem;
406
- }
407
- .welcome__wave {
408
- font-size: 4rem;
409
- margin-bottom: 1.2rem;
410
- opacity: 0.4;
411
- animation: float 3s ease-in-out infinite;
412
- }
413
- @keyframes float {
414
- 0%, 100% { transform: translateY(0); }
415
- 50% { transform: translateY(-6px); }
416
- }
417
- .welcome__title {
418
- font-size: 1.4rem;
419
- font-weight: 600;
420
- color: #bbb;
421
- letter-spacing: 0.5px;
422
- margin-bottom: 0.4rem;
423
- }
424
- .welcome__sub {
425
- font-size: 1rem;
426
- color: #666;
427
- font-weight: 300;
428
- }
429
- </style>
430
- </head>
431
- <body>
432
- <div class="welcome">
433
- <div class="welcome__wave">\u224B</div>
434
- <div class="welcome__title">vibeSpot</div>
435
- <div class="welcome__sub">Build Something Great</div>
436
- </div>
437
- </body>
438
- </html>`}function Cr(e){let t=C();if(!t)return"";let n;for(let a of t.templates)if(n=a.modules.find(l=>l.moduleName===e),n)break;if(n||(n=t.modules.find(a=>a.moduleName===e)),!n)return"";let s,o=[];try{let a=JSON.parse(n.fieldsJson);o=Array.isArray(a)?a:[],s={module:ln(o)}}catch{s={module:{}}}let i=xr(n.moduleHtml,o),r=Ln(i,s);return Sr({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${r}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}function Yh(e,t){let n=[],s=new Set;for(let i of e){let r,a=[];try{let u=JSON.parse(i.fieldsJson);a=Array.isArray(u)?u:[],r={module:ln(a)}}catch{r={module:{}}}let l=xr(i.moduleHtml,a),c=Ln(l,r),d=i.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module" id="${d}" data-module="${i.moduleName}">${c}</div>`),s.add(i.moduleName)}for(let i of t)if(!s.has(i)){let r=i.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module vibespot-module--pending" id="${r}" data-module="${i}">
439
- <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="max-width:600px;margin:0 auto;">
440
- <tr><td style="padding:40px 30px;text-align:center;background-color:#ffffff;border:1px dashed #ddd;">
441
- <p style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#999;">${i}</p>
442
- </td></tr>
443
- </table>
444
- </div>`)}return`<!DOCTYPE html>
445
- <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
446
- <head>
447
- <meta charset="utf-8">
448
- <meta name="viewport" content="width=device-width, initial-scale=1">
449
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
450
- <title>Email Preview</title>
451
- <style>
452
- html, body { margin: 0; padding: 0; overflow-x: hidden; }
453
- body {
454
- background-color: #e8e8e8;
455
- font-family: Arial, Helvetica, sans-serif;
456
- -webkit-font-smoothing: antialiased;
457
- }
458
- .vibespot-email-wrapper {
459
- padding: 30px 20px;
460
- background-color: #e8e8e8;
461
- min-height: 100vh;
462
- }
463
- .vibespot-module { margin: 0 auto; max-width: 600px; }
464
- .vibespot-module--pending table { opacity: 0.6; }
465
- html { scroll-behavior: smooth; }
466
- img { max-width: 100% !important; height: auto !important; }
467
- table { max-width: 100% !important; }
468
- td { word-break: break-word; }
469
- @media screen and (max-width: 620px) {
470
- .vibespot-email-wrapper { padding: 10px 8px; }
471
- table[width] { width: 100% !important; }
472
- img[width] { width: 100% !important; height: auto !important; }
473
- }
474
- </style>
475
- </head>
476
- <body>
477
- <div class="vibespot-email-wrapper">
478
- ${n.join(`
479
- `)}
480
- </div>
481
- <script>
482
- document.addEventListener('click', function(e) {
483
- var a = e.target.closest('a[href^="#"]');
484
- if (a) { e.preventDefault(); var t = document.querySelector(a.getAttribute('href')); if (t) t.scrollIntoView({ behavior: 'smooth' }); }
485
- });
486
- </script>
487
- </body>
488
- </html>`}var ws=N(()=>{"use strict";y();vr();Ce();Cs()});function ct(e){try{return JSON.parse(e)}catch{}let t=e,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(t)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let r=parseInt(i[1],10);if(r<=n)return null;n=r;let a=Math.max(0,r-5),c=t.slice(a,r+1).lastIndexOf('"');if(c===-1)return null;let d=a+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function ks(e){let t=e.indexOf('"modules"');if(t===-1)return null;let n=e.indexOf("[",t);if(n===-1)return null;let s=-1,o=0,i=!1,r=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(r){r=!1;continue}if(u==="\\"){r=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=e.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ct(c)}function kr(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 ed(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{M.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ct(s[1]);if(!i||typeof i!="object")throw M.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let r=i;r.modules&&Array.isArray(r.modules)&&(He({modules:r.modules.map(a=>kr(a)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(i){M.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let r=ct(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(He({modules:a.modules.map(l=>kr(l)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(r){M.warn("parse","Failed to parse JSON module block",{error:r instanceof Error?r.message:String(r)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){M.info("parse","Detected truncated response (odd fence count), attempting salvage");let r=e.lastIndexOf("```"),a=e.slice(r+3);a=a.replace(/^[\w-]*\s*\n?/,"");let l=ks(a);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(M.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),He({modules:c.modules.map(d=>kr(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){M.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),r=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(i||r){let a=i?"Module changes could not be applied \u2014 the AI response contained invalid JSON. Try sending your request again.":"The AI described modules but did not include the required structured data. Try sending your request again.";M.warn("parse",a),t&&t(a)}}}var Ko=N(()=>{"use strict";y();Ce();le()});function Hn(){let e=C();return e?{pageType:ke()?.pageType,brandAssets:e.brandAssets}:{}}function nd(e,t,n=!1,s,o){let r=[{type:"text",text:Xh(t,n)}];if(n){let l=`## HubSpot CMS Rules
489
- ${Je()}
326
+ `}var zi=j(()=>{"use strict";y();Is();Ps();Xt();Hn();re();wt();Os()});var fd=j(()=>{"use strict";y();_c();Is();Ps();zi();Xt()});var me=j(()=>{"use strict";y();fd()});function Vn(){let e=x();return e?{pageType:xe()?.pageType,brandAssets:e.brandAssets}:{}}function qi(e,t,n=!1,s,o){let i=[{type:"text",text:ib(t,n)}];if(n){let l=`## HubSpot CMS Rules
327
+ ${et()}
490
328
 
491
329
  ## Conversion Guide Reference
492
- ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
330
+ ${e}`;i.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}else{let l=`## Design Quality
493
331
  - Use modern, clean design with proper spacing and typography
494
332
  - Include responsive CSS (mobile breakpoint at 767px)
495
333
  - Add scroll animation classes where appropriate
@@ -512,22 +350,22 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
512
350
  This makes elements appear after 3 seconds if JS never adds the .visible class. Once JS runs normally and adds .visible, the animation is cancelled.
513
351
 
514
352
  ## Design Guide
515
- ${cs()}
353
+ ${No()}
516
354
 
517
355
  ## Content & Copywriting Guide
518
- ${Vi()}
356
+ ${ac()}
519
357
 
520
358
  ## HubSpot CMS Rules
521
- ${Je()}
359
+ ${et()}
522
360
 
523
361
  ## Conversion Guide Reference
524
- ${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=qh(s,o);return a&&r.push({type:"text",text:a}),r.push({type:"text",text:"## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory."}),r}function qh(e,t){let n=[];if(e){let s=Yi(e);s&&n.push(`## Page Type Context
362
+ ${e}`;i.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=rb(s,o);return a&&i.push({type:"text",text:a}),i.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."}),i}function rb(e,t){let n=[];if(e){let s=uc(e);s&&n.push(`## Page Type Context
525
363
  ${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
526
364
  ${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
527
- ${t.brandvoice}`),t?.humanify!==!1){let s=zi();s&&n.push(`## Anti-AI Copy Rules (Humanify)
365
+ ${t.brandvoice}`),t?.humanify!==!1){let s=lc();s&&n.push(`## Anti-AI Copy Rules (Humanify)
528
366
  ${s}`)}return n.join(`
529
367
 
530
- `)}function Xh(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
368
+ `)}function ib(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
531
369
 
532
370
  ## Your Role
533
371
  You generate native HubSpot CMS modules directly from user descriptions. Every module you create is immediately compatible with HubSpot's drag-and-drop page editor.
@@ -606,241 +444,265 @@ The current template's modules are listed in page order in the user message. Thi
606
444
  - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
607
445
  - **Remove**: When the user asks to remove a section, omit it from the output.
608
446
  - **Preserve**: Always include ALL modules you want to keep (modified + unchanged) in your output. Modules omitted from the output will be removed from the page.
609
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function Ts(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
610
-
611
- ## Your Role
612
- You generate native HubSpot CMS modules directly from user descriptions. Every module you create is immediately compatible with HubSpot's drag-and-drop page editor.
613
-
614
- ## Output Format \u2014 CRITICAL
615
- You MUST include a \`\`\`vibespot-modules code block with ALL module data as JSON. This is the ONLY way modules get created. A text summary, table, or description of modules does NOT work \u2014 you must output the actual JSON.
616
-
617
- \`\`\`vibespot-modules
618
- {
619
- "modules": [
620
- {
621
- "moduleName": "Hero",
622
- "fieldsJson": "...",
623
- "metaJson": "...",
624
- "moduleHtml": "...",
625
- "moduleCss": "...",
626
- "moduleJs": null
627
- }
628
- ],
629
- "sharedCss": "...",
630
- "sharedJs": "..."
631
- }
632
- \`\`\`
633
-
634
- NEVER respond with only a text summary. The vibespot-modules JSON block is mandatory.
635
-
636
- ## Rules
637
- - fieldsJson, metaJson must be valid JSON strings
638
- - moduleHtml uses HubL template syntax ({{ module.field_name }})
639
- - moduleCss is vanilla CSS (no Tailwind, no Sass)
640
- - moduleJs is optional vanilla JS (wrapped in IIFE)
641
- - NEVER use CDN imports (@import url(), <link> to external CDNs like Google Fonts, cdnjs, unpkg, jsdelivr)
642
- - For fonts, use system font stacks with good fallbacks. Define them as CSS custom properties in sharedCss:
643
- --font-heading: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
644
- --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
645
- --font-mono: 'SF Mono', SFMono-Regular, Consolas, monospace;
646
- - All assets must be self-contained \u2014 no external HTTP requests in CSS or HTML
647
- - Use "type": "text" (NEVER "textarea" \u2014 it's deprecated)
648
- - NEVER use "name": "name" (reserved) \u2014 use "item_name" instead
649
- - NEVER put literal \\n newline sequences in field default values \u2014 use plain text without line breaks
650
- - Wrap style fields in a "styles" group with "tab": "STYLE"
651
- - All CSS classes must use a unique prefix "${t}-" to avoid theme conflicts
652
- - Use BEM naming: ${t}-module__element--modifier
653
- - metaJson must include: host_template_types: ["PAGE"], is_available_for_new_content: true
654
- - For repeater groups, use "occurrence": { "min": 0, "max": 100 } and iterate with {% for %}
655
- - Color fields: type "color", default { "color": "#hex", "opacity": 100 }
656
- - Link fields: type "link", default { "url": { "href": "#", "type": "EXTERNAL" }, "open_in_new_tab": false, "no_follow": false }
657
- - Image fields: type "image", default { "src": "https://placehold.co/800x600/1a1a2e/ffffff?text=Replace+in+HubSpot", "alt": "Placeholder image", "width": 800, "height": 600 }
658
-
659
- ## Images & Media
660
- - Users can upload images that get placed in the theme's assets/ folder automatically
661
- - When the user uploads an image and wants it on the page, reference it with: {{ get_asset_url("${t}/assets/filename.ext") }}
662
- - IMPORTANT: get_asset_url() paths must include the theme name prefix "${t}/" because HubSpot resolves from the Design Manager root
663
- - For background images with uploaded assets: style="background-image: url('{{ get_asset_url(\\"${t}/assets/filename.ext\\") }}')"
664
- - For images without an uploaded asset, use image fields (type "image") with placehold.co defaults
665
- - ALWAYS use image fields (type "image") so users can swap images in the page editor
666
- - Use placehold.co URLs as defaults so the preview looks complete (e.g. https://placehold.co/800x600/1a1a2e/ffffff?text=Hero+Image)
667
- - In module.html, render images with: <img src="{{ module.field_name.src }}" alt="{{ module.field_name.alt }}" width="{{ module.field_name.width }}" height="{{ module.field_name.height }}">
668
- - For background images in CSS, use inline styles: style="background-image: url('{{ module.field_name.src }}')"
669
- - Size placeholders appropriately for their context (hero: 1920x800, cards: 600x400, icons: 200x200, avatars: 150x150)
670
- - If the user's intent is ambiguous (design reference vs page asset), ask them to clarify
671
-
672
- ## Navigation & Anchor Links
673
- - For anchor links, add an id attribute directly on the module's root element in module.html:
674
- <section id="pricing" class="..."> (NOT on an external wrapper \u2014 HubSpot's dnd system strips those)
675
- - The id should be the moduleName lowercased with spaces replaced by hyphens (e.g. "Pricing Cards" \u2192 id="pricing-cards")
676
- - For navigation/menu modules, use anchor links that match these ids: e.g. href="#features"
677
- - Always include smooth scrolling behavior in navigation link clicks
678
- - For nav modules, make menu items editable via a repeater group with "label" (text) and "anchor" (text) fields
679
-
680
- ## When modifying existing modules
681
- The current template's modules are listed in page order in the user message. This sequence forms the page narrative.
682
-
683
- - **Modify**: When the user references an existing module by name or describes changes to existing content, update that module's code. Keep the moduleName unchanged.
684
- - **Add**: When the user asks for a new section, create a new module and insert it at the narratively correct position. Consider the page flow: navigation \u2192 hero \u2192 content sections \u2192 social proof \u2192 CTA \u2192 footer.
685
- - **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
686
- - **Remove**: When the user asks to remove a section, omit it from the output.
687
- - **Preserve**: Always include ALL modules you want to keep (modified + unchanged) in your output. Modules omitted from the output will be removed from the page.
688
- - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,r=s?Yi(s):"",a=r?`
689
-
690
- ## Page Type Context
691
- ${r}`:"",l="";if(o?.styleguide&&(l+=`
692
-
693
- ## Brand Style Guide
694
- ${o.styleguide}`),o?.brandvoice&&(l+=`
695
-
696
- ## Brand Voice
697
- ${o.brandvoice}`),o?.humanify!==!1){let d=zi();d&&(l+=`
698
-
699
- ## Anti-AI Copy Rules (Humanify)
700
- ${d}`)}let c="\n\n## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory.";return n?i+a+l+`
701
-
702
- ## HubSpot CMS Rules
703
- ${Je()}
704
-
705
- ## Conversion Guide Reference
706
- ${e}`+c:i+a+l+`
707
-
708
- ## Design Quality
709
- - Use modern, clean design with proper spacing and typography
710
- - Include responsive CSS (mobile breakpoint at 767px)
711
- - Add scroll animation classes where appropriate
712
- - Use CSS custom properties for the design system
713
- - Make content editable through fields.json (headlines, text, colors, images, links)
714
-
715
- ## Scroll Animation CSS Fallback (IMPORTANT)
716
- When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include a CSS-only fallback animation in sharedCss that auto-reveals elements after a delay. This ensures content is visible even if the JS file fails to load:
717
- \`\`\`css
718
- @keyframes scroll-animate-fallback {
719
- to { opacity: 1; transform: none; }
720
- }
721
- .scroll-animate {
722
- animation: scroll-animate-fallback 0.1s 3s forwards;
723
- }
724
- .scroll-animate.visible {
725
- animation: none;
726
- }
727
- \`\`\`
728
- This makes elements appear after 3 seconds if JS never adds the .visible class. Once JS runs normally and adds .visible, the animation is cancelled.
447
+ - **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function js(e,t,n=!1,s,o){return qi(e,t,n,s,o).map(r=>r.text).join(`
729
448
 
730
- ## Design Guide
731
- ${cs()}
732
-
733
- ## Content & Copywriting Guide
734
- ${Vi()}
735
-
736
- ## HubSpot CMS Rules
737
- ${Je()}
738
-
739
- ## Conversion Guide Reference
740
- ${e}`+c}function Bn(e,t){return e.length<=t?e:e.slice(0,t)+`
741
- /* \u2026truncated ${e.length-t} chars to fit the context budget\u2026 */`}function As(){let e=C(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
449
+ `)}function Kn(e,t){return e.length<=t?e:e.slice(0,t)+`
450
+ /* \u2026truncated ${e.length-t} chars to fit the context budget\u2026 */`}function Ls(){let e=x(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
742
451
 
743
452
  ## Page Narrative (module sequence)
744
453
  `),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
745
- `);for(let d=0;d<s;d++)t.push(`${d+1}. ${n[d].moduleName}
454
+ `);for(let g=0;g<s;g++)t.push(`${g+1}. ${n[g].moduleName}
746
455
  `);t.push(`
747
456
  When the user asks to modify this page, decide whether to MODIFY existing modules, ADD new ones at the right narrative position, REARRANGE the sequence, or REMOVE sections. Always include ALL modules you want to keep in your output.
748
457
  `),t.push(`
749
458
  ## Current Module State
750
- `);let a=0,l=!1,c=Math.max(2e3,Math.floor(td/Math.max(s,1)));for(let d=0;d<s;d++){let u=n[d];if(l){t.push(`
751
- ### ${d+1}/${s}: ${u.moduleName}.module \u2014 (source omitted to fit context budget; ask to edit it specifically to load its source)
752
- `);continue}let m=`
753
- ### ${d+1}/${s}: ${u.moduleName}.module
459
+ `);let a=0,l=!1,u=Math.max(s,1)*4+2,p=Math.max(2e3,Math.floor(hd/u));for(let g=0;g<s;g++){let f=n[g];if(l){t.push(`
460
+ ### ${g+1}/${s}: ${f.moduleName}.module \u2014 (source omitted to fit context budget; ask to edit it specifically to load its source)
461
+ `);continue}let h=`
462
+ ### ${g+1}/${s}: ${f.moduleName}.module
754
463
  **fields.json:**
755
464
  \`\`\`json
756
- ${Bn(u.fieldsJson,c)}
465
+ ${Kn(f.fieldsJson,p)}
757
466
  \`\`\`
758
467
  **module.html:**
759
468
  \`\`\`html
760
- ${Bn(u.moduleHtml,c)}
469
+ ${Kn(f.moduleHtml,p)}
761
470
  \`\`\`
762
471
  **module.css:**
763
472
  \`\`\`css
764
- ${Bn(u.moduleCss,c)}
473
+ ${Kn(f.moduleCss,p)}
765
474
  \`\`\`
766
- `+(u.moduleJs?`**module.js:**
475
+ `+(f.moduleJs?`**module.js:**
767
476
  \`\`\`js
768
- ${Bn(u.moduleJs,c)}
477
+ ${Kn(f.moduleJs,p)}
769
478
  \`\`\`
770
- `:"");a+=m.length,t.push(m),a>td&&(l=!0)}e.sharedCss&&t.push(`
479
+ `:"");a+=h.length,t.push(h),a>hd&&(l=!0)}e.sharedCss&&t.push(`
771
480
  ### Shared CSS
772
481
  \`\`\`css
773
- ${Bn(e.sharedCss,c)}
482
+ ${Kn(e.sharedCss,p)}
774
483
  \`\`\`
775
484
  `),e.sharedJs&&t.push(`
776
485
  ### Shared JS
777
486
  \`\`\`js
778
- ${Bn(e.sharedJs,c)}
487
+ ${Kn(e.sharedJs,p)}
779
488
  \`\`\`
780
- `)}let o=Ot(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
489
+ `)}let o=Lt(),r=new Set(e.modules.map(a=>a.moduleName)),i=o.filter(a=>!r.has(a.module.moduleName));if(i.length>0){t.push(`
781
490
 
782
491
  ## Available modules in this theme (reusable)
783
- `);for(let a of r)t.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
492
+ `);for(let a of i)t.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
784
493
  `);t.push(`
785
494
  The user can ask to reuse any of these modules by name.
786
- `)}return t.join("")}function Tr(e,t){let n=C(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===e&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=As(),r="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(r=`
495
+ `)}return t.join("")}function Yi(e,t){let n=x(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===e&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),r=Ls(),i="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(i=`
787
496
 
788
497
  ## Available Theme Assets
789
498
  These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
790
499
  ${d.map(u=>`- ${u.filename} (${u.originalName}) \u2192 get_asset_url("${n.themeName}/assets/${u.filename}")`).join(`
791
- `)}`)}let a=e;i&&(a+=`
500
+ `)}`)}let a=e;r&&(a+=`
792
501
 
793
502
  ---
794
- ${i}`),r&&(a+=r),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let l=t&&t.length>0;if(l)for(let d of t)d.type==="document"&&d.extractedText&&(a+=`
503
+ ${r}`),i&&(a+=i),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let l=t&&t.length>0;if(l)for(let d of t)d.type==="document"&&d.extractedText&&(a+=`
795
504
 
796
505
  ---
797
506
  [Attached document: ${d.originalName}]
798
507
  ${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(a+=`
799
508
 
800
- [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?t.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:a}),o.push({role:"user",content:d})}else o.push({role:"user",content:a});return o}var td,sd=N(()=>{"use strict";y();Ke();Ce();td=2e5});import{spawn as id}from"child_process";import{mkdtempSync as Zh}from"fs";import{tmpdir as od}from"os";import{join as Qh}from"path";async function rd(){return Ar||(Ar=(await import("@anthropic-ai/sdk")).default),Ar}function ad(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
509
+ [Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?t.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:a}),o.push({role:"user",content:d})}else o.push({role:"user",content:a});return o}var hd,yd=j(()=>{"use strict";y();tt();me();hd=2e5});import{spawn as Sd}from"child_process";import{mkdtempSync as ab}from"fs";import{tmpdir as bd}from"os";import{join as lb}from"path";async function vd(){return Xi||(Xi=(await import("@anthropic-ai/sdk")).default),Xi}function pb(e){for(let[t,n]of ub)if(t.test(e))return Math.min(cb,n);return db}function xd(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
801
510
  [Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
802
511
 
803
512
  ---
804
513
  [Attached document: ${n.originalName}]
805
- ${n.extractedText}`);return t.join("")}async function ld(e,t,n,s,o,i,r,a="anthropic-api"){for(let l=0;;l++){let c=new Date;try{let d="",u=0,m=i||(()=>{});m(je[0]);let g=setInterval(()=>{u++,m(je[Math.min(u,je.length-1)])},6e3),h=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});try{for await(let b of h)if(b.type==="content_block_delta"&&b.delta.type==="text_delta"){let S=b.delta.text;d+=S,o(S)}}finally{clearInterval(g)}let f;try{f=et((await h.finalMessage()).usage)}catch{}St({engine:a,model:s,name:"vibe-chat",input:{system:t,messages:n},output:d,usage:f,startTime:c,endTime:new Date}),r&&r(d);return}catch(d){let u=d.status,m=d.error?.type;if(!(u===429||m==="rate_limit_error"||d instanceof Error&&d.message.includes("429"))||l>=_r.length)throw d;let h=_r[l];M.warn("ai-engine",`Rate limited (429), attempt ${l+1}/${_r.length} \u2014 waiting ${h}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${h}s...`),await new Promise(f=>setTimeout(f,h*1e3)),i&&i("Retrying...")}}}function cd(e,t,n){let s=ye(),i=C().modules.length>0,r=Tr(e,n),a=Hn(),l=nd(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function $r(e,t,n,s,o,i,r,a,l){let c=await rd(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:m}=cd(e,n,a);M.info("anthropic","API call",{model:s,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:u.length}),await ld(d,m,u,s,o,i,r)}async function dd(e,t,n,s,o,i,r){let a=await Di();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await rd(),c=new l({authToken:a,defaultHeaders:Zn}),{messages:d,systemBlocks:u}=cd(e,t,r),m=[{type:"text",text:xn},...u];M.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await ld(c,m,d,n,s,o,i,"claude-oauth")}async function Er(e,t,n,s,o,i,r,a,l){let c=ye(),d=C().modules.length>0,u=Tr(e,a),m=Hn(),g=u.map(T=>typeof T.content=="string"?T:{role:T.role,content:T.content.map(k=>k.type==="text"?{type:"text",text:k.text}:{type:"image_url",image_url:{url:`data:${k.source.media_type};base64,${k.source.data}`}})}),h=Ts(c,n,d,m.pageType,m.brandAssets),f=l||"https://api.openai.com/v1/chat/completions",b=!/\/mistral(\/|$|\?)/.test(f),S=new Date,v=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,...b?{stream_options:{include_usage:!0}}:{},messages:[{role:"system",content:h},...g]})});if(!v.ok){let T=await v.text();throw new Error(`API error (${v.status}): ${T}`)}let w=0,$=i||(()=>{});$(je[0]);let j=setInterval(()=>{w++,$(je[Math.min(w,je.length-1)])},6e3),J="",K,H=v.body.getReader(),X=new TextDecoder,F="";try{for(;;){let{done:T,value:k}=await H.read();if(T)break;F+=X.decode(k,{stream:!0});let E=F.split(`
806
- `);F=E.pop()||"";for(let O of E){if(!O.startsWith("data: "))continue;let re=O.slice(6).trim();if(re==="[DONE]")break;try{let _e=JSON.parse(re),z=_e.choices?.[0]?.delta?.content;z&&(J+=z,o(z)),_e.usage&&(K=_e.usage)}catch{}}}}finally{clearInterval(j)}St({engine:"openai-api",model:s,name:"vibe-chat",input:{system:h,messages:g},output:J,usage:En(K),startTime:S,endTime:new Date}),r&&r(J)}async function Mr(e,t,n,s,o,i,r,a,l){let c=ye(),d=C(),u=d.modules.length>0,m=As(),g=Hn(),h=[];for(let O of d.messages.slice(-20))h.push({role:O.role==="assistant"?"model":"user",parts:[{text:O.content}]});let f=m?`${e}
514
+ ${n.extractedText}`);return t.join("")}async function wd(e,t,n,s,o,r,i,a="anthropic-api"){for(let l=0;;l++){let c=new Date;try{let d="",u=0,p=r||(()=>{});p(Le[0]);let g=setInterval(()=>{u++,p(Le[Math.min(u,Le.length-1)])},6e3),f=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});try{for await(let b of f)if(b.type==="content_block_delta"&&b.delta.type==="text_delta"){let S=b.delta.text;d+=S,o(S)}}finally{clearInterval(g)}let h;try{h=nt((await f.finalMessage()).usage)}catch{}Ct({engine:a,model:s,name:"vibe-chat",input:{system:t,messages:n},output:d,usage:h,startTime:c,endTime:new Date}),i&&i(d);return}catch(d){let u=d.status,p=d.error?.type;if(!(u===429||p==="rate_limit_error"||d instanceof Error&&d.message.includes("429"))||l>=Zi.length)throw d;let f=Zi[l];A.warn("ai-engine",`Rate limited (429), attempt ${l+1}/${Zi.length} \u2014 waiting ${f}s`),r&&r(`Rate limited by Anthropic API \u2014 retrying in ${f}s...`),await new Promise(h=>setTimeout(h,f*1e3)),r&&r("Retrying...")}}}function kd(e,t,n){let s=Ce(),r=x().modules.length>0,i=Yi(e,n),a=Vn(),l=qi(s,t,r,a.pageType,a.brandAssets);return{messages:i,systemBlocks:l,conversionGuide:s,editMode:r}}async function Qi(e,t,n,s,o,r,i,a,l){let c=await vd(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:p}=kd(e,n,a);A.info("anthropic","API call",{model:s,systemBlockCount:p.length,cachedBlocks:p.filter(g=>g.cache_control).length,messageCount:u.length}),await wd(d,p,u,s,o,r,i)}async function Cd(e,t,n,s,o,r,i){let a=await ki();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await vd(),c=new l({authToken:a,defaultHeaders:ms}),{messages:d,systemBlocks:u}=kd(e,t,i),p=[{type:"text",text:In},...u];A.info("anthropic-oauth","API call",{model:n,systemBlockCount:p.length,cachedBlocks:p.filter(g=>g.cache_control).length,messageCount:d.length}),await wd(c,p,d,n,s,o,r,"claude-oauth")}async function ea(e,t,n,s,o,r,i,a,l){let c=Ce(),d=x().modules.length>0,u=Yi(e,a),p=Vn(),g=u.map(P=>typeof P.content=="string"?P:{role:P.role,content:P.content.map(F=>F.type==="text"?{type:"text",text:F.text}:{type:"image_url",image_url:{url:`data:${F.source.media_type};base64,${F.source.data}`}})}),f=js(c,n,d,p.pageType,p.brandAssets),h=l||"https://api.openai.com/v1/chat/completions",b=!/\/mistral(\/|$|\?)/.test(h),S=new Date,v=await fetch(h,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:pb(s),stream:!0,...b?{stream_options:{include_usage:!0}}:{},messages:[{role:"system",content:f},...g]})});if(!v.ok){let P=await v.text();throw new Error(`API error (${v.status}): ${P}`)}let k=0,_=r||(()=>{});_(Le[0]);let M=setInterval(()=>{k++,_(Le[Math.min(k,Le.length-1)])},6e3),R="",J,O=v.body.getReader(),V=new TextDecoder,H="";try{for(;;){let{done:P,value:F}=await O.read();if(P)break;H+=V.decode(F,{stream:!0});let z=H.split(`
515
+ `);H=z.pop()||"";for(let L of z){if(!L.startsWith("data: "))continue;let W=L.slice(6).trim();if(W==="[DONE]")break;try{let _e=JSON.parse(W),Be=_e.choices?.[0]?.delta?.content;Be&&(R+=Be,o(Be)),_e.usage&&(J=_e.usage)}catch{}}}}finally{clearInterval(M)}Ct({engine:"openai-api",model:s,name:"vibe-chat",input:{system:f,messages:g},output:R,usage:Bn(J),startTime:S,endTime:new Date}),i&&i(R)}async function ta(e,t,n,s,o,r,i,a,l){let c=Ce(),d=x(),u=d.modules.length>0,p=Ls(),g=Vn(),f=[];for(let W of d.messages.slice(-20))f.push({role:W.role==="assistant"?"model":"user",parts:[{text:W.content}]});let h=p?`${e}
807
516
 
808
517
  ---
809
- ${m}`:e;if(r?.length)for(let O of r)O.type==="document"&&O.extractedText&&(f+=`
518
+ ${p}`:e;if(i?.length)for(let W of i)W.type==="document"&&W.extractedText&&(h+=`
810
519
 
811
520
  ---
812
- [Attached document: ${O.originalName}]
813
- ${O.extractedText}`),O.type==="image"&&O.usage==="asset"&&O.assetPath&&(f+=`
814
-
815
- [Uploaded image: ${O.originalName} \u2192 available as get_asset_url("${O.assetPath}")]`);let b=[];if(r?.length)for(let O of r)O.type==="image"&&O.base64&&b.push({inlineData:{mimeType:O.mimeType,data:O.base64}});b.push({text:f}),h.push({role:"user",parts:b});let S=l||"gemini-2.5-flash",v=a||`https://generativelanguage.googleapis.com/v1beta/models/${S}:streamGenerateContent?alt=sse&key=${t}`,w=Ts(c,n,u,g.pageType,g.brandAssets),$=new Date,j=await fetch(v,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:w}]},contents:h,generationConfig:{maxOutputTokens:48e3}})});if(!j.ok){let O=await j.text();throw new Error(`Gemini API error (${j.status}): ${O}`)}let J=0,K=o||(()=>{});K(je[0]);let H=setInterval(()=>{J++,K(je[Math.min(J,je.length-1)])},6e3),X="",F,T=j.body.getReader(),k=new TextDecoder,E="";try{for(;;){let{done:O,value:re}=await T.read();if(O)break;E+=k.decode(re,{stream:!0});let _e=E.split(`
816
- `);E=_e.pop()||"";for(let z of _e){if(!z.startsWith("data: "))continue;let ue=z.slice(6).trim();try{let ne=JSON.parse(ue),$e=ne.candidates?.[0]?.content?.parts?.[0]?.text;$e&&(X+=$e,s($e)),ne.usageMetadata&&(F=ne.usageMetadata)}catch{}}}}finally{clearInterval(H)}St({engine:"gemini-api",model:S,name:"vibe-chat",input:{system:w,contents:h},output:X,usage:Mn(F),startTime:$,endTime:new Date}),i&&i(X)}function ey(){if(_s)return _s;try{_s=Zh(Qh(od(),"vibespot-claude-"))}catch{_s=od()}return _s}function ty(e){return/prompt is too long|exceed\w*\s+(the\s+)?(maximum\s+)?context|too many (input )?tokens|200000|context window/i.test(e)?"This request exceeded the model's 200k-token context window. vibeSpot isolates the Claude Code CLI from your MCP servers and project memory, so this usually means the page state itself is too large. Try: removing or splitting very large modules, starting a fresh theme, or switching to the Anthropic API engine in AI Settings (isolated per-request, no ambient context).":e}function Pr(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=id("claude",e,{stdio:["pipe","pipe","pipe"],env:r,cwd:ey()}),l="",c="",d="",u=!1,m=null,g=w=>{u||(u=!0,w())},h=w=>{try{if(w.type==="assistant"&&w.message?.content){for(let $ of w.message.content)if($.type==="text"&&typeof $.text=="string"){let j=$.text;l+=j,n.onChunk&&n.onChunk(j)}else if($.type==="tool_use"){let j=$;j.name&&n.onToolUse&&n.onToolUse(j.name,j.input)}}w.type==="result"&&(m=w,!l&&typeof w.result=="string"&&(l=w.result,n.onChunk&&n.onChunk(w.result))),n.onEvent&&n.onEvent(w)}catch{}};a.stdout.on("data",w=>{d+=w.toString();let $;for(;($=d.indexOf(`
817
- `))>=0;){let j=d.slice(0,$).trim();if(d=d.slice($+1),!!j)try{h(JSON.parse(j))}catch{}}}),a.stderr.on("data",w=>{c+=w.toString()}),a.on("error",w=>g(()=>i(new Error(`claude failed to start: ${w.message}`)))),a.on("close",w=>{if(d.trim()){try{h(JSON.parse(d.trim()))}catch{}d=""}g(()=>{if(w!==0||m&&m.is_error){let j=`${c}
818
- ${l}`,J=ty(j);i(J!==j?new Error(J):new Error(`claude exited with code ${w}.
819
- `+(c?`Stderr: ${c.slice(0,500)}
820
- `:"")+(l?`Output: ${l.slice(0,500)}`:"No output")))}else o(l)})}),a.stdin.on("error",()=>{}),a.stdin.write(t)?a.stdin.end():a.stdin.once("drain",()=>a.stdin.end());let b=s||6e5,S=Math.round(b/6e4),v=setTimeout(()=>{a.kill(),g(()=>i(new Error(`claude (stream-json) timed out after ${S} minutes.
821
- `+(c?`Stderr: ${c.slice(0,500)}
822
- `:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(v))})}function Nr(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=id(e,t,{stdio:["pipe","pipe","pipe"],env:a}),c="",d="",u=!1,m=S=>{u||(u=!0,S())};l.stdout.on("data",S=>{let v=S.toString();c+=v,s&&s(v)}),l.stderr.on("data",S=>{d+=S.toString()}),l.on("error",S=>m(()=>r(new Error(`${e} failed to start: ${S.message}`)))),l.on("close",S=>{m(()=>{S!==0?r(new Error(`${e} exited with code ${S}.
521
+ [Attached document: ${W.originalName}]
522
+ ${W.extractedText}`),W.type==="image"&&W.usage==="asset"&&W.assetPath&&(h+=`
523
+
524
+ [Uploaded image: ${W.originalName} \u2192 available as get_asset_url("${W.assetPath}")]`);let b=[];if(i?.length)for(let W of i)W.type==="image"&&W.base64&&b.push({inlineData:{mimeType:W.mimeType,data:W.base64}});b.push({text:h}),f.push({role:"user",parts:b});let S=l||"gemini-2.5-flash",v=!!a,k=a||`https://generativelanguage.googleapis.com/v1beta/models/${S}:streamGenerateContent?alt=sse&key=${t}`,_=js(c,n,u,g.pageType,g.brandAssets),M=new Date,R=await fetch(k,{method:"POST",headers:{"Content-Type":"application/json",...v?{Authorization:`Bearer ${t}`}:{}},body:JSON.stringify({systemInstruction:{parts:[{text:_}]},contents:f,generationConfig:{maxOutputTokens:48e3}})});if(!R.ok){let W=await R.text();throw new Error(`Gemini API error (${R.status}): ${W}`)}let J=0,O=o||(()=>{});O(Le[0]);let V=setInterval(()=>{J++,O(Le[Math.min(J,Le.length-1)])},6e3),H="",P,F=R.body.getReader(),z=new TextDecoder,L="";try{for(;;){let{done:W,value:_e}=await F.read();if(W)break;L+=z.decode(_e,{stream:!0});let Be=L.split(`
525
+ `);L=Be.pop()||"";for(let yt of Be){if(!yt.startsWith("data: "))continue;let ot=yt.slice(6).trim();try{let ie=JSON.parse(ot),Tn=ie.candidates?.[0]?.content?.parts?.[0]?.text;Tn&&(H+=Tn,s(Tn)),ie.usageMetadata&&(P=ie.usageMetadata)}catch{}}}}finally{clearInterval(V)}Ct({engine:"gemini-api",model:S,name:"vibe-chat",input:{system:_,contents:f},output:H,usage:Jn(P),startTime:M,endTime:new Date}),r&&r(H)}function mb(){if(Bs)return Bs;try{Bs=ab(lb(bd(),"vibespot-claude-"))}catch{Bs=bd()}return Bs}function gb(e){return/prompt is too long|exceed\w*\s+(the\s+)?(maximum\s+)?context|too many (input )?tokens|200000|context window/i.test(e)?"This request exceeded the model's 200k-token context window. vibeSpot isolates the Claude Code CLI from your MCP servers and project memory, so this usually means the page state itself is too large. Try: removing or splitting very large modules, starting a fresh theme, or switching to the Anthropic API engine in AI Settings (isolated per-request, no ambient context).":e}function sa(e,t,n={},s,o){return new Promise((r,i)=>{if(o?.aborted){i(or("claude"));return}let a={...process.env};delete a.CLAUDECODE;let l=Sd("claude",e,{stdio:["pipe","pipe","pipe"],env:a,cwd:mb()}),c="",d="",u="",p=!1,g=null,f=M=>{p||(p=!0,M())},h=M=>{try{if(M.type==="assistant"&&M.message?.content){for(let R of M.message.content)if(R.type==="text"&&typeof R.text=="string"){let J=R.text;c+=J,n.onChunk&&n.onChunk(J)}else if(R.type==="tool_use"){let J=R;J.name&&n.onToolUse&&n.onToolUse(J.name,J.input)}}M.type==="result"&&(g=M,!c&&typeof M.result=="string"&&(c=M.result,n.onChunk&&n.onChunk(M.result))),n.onEvent&&n.onEvent(M)}catch{}};l.stdout.on("data",M=>{u+=M.toString();let R;for(;(R=u.indexOf(`
526
+ `))>=0;){let J=u.slice(0,R).trim();if(u=u.slice(R+1),!!J)try{h(JSON.parse(J))}catch{}}}),l.stderr.on("data",M=>{d+=M.toString()}),l.on("error",M=>f(()=>i(new Error(`claude failed to start: ${M.message}`)))),l.on("close",M=>{if(u.trim()){try{h(JSON.parse(u.trim()))}catch{}u=""}f(()=>{if(M!==0||g&&g.is_error){let J=`${d}
527
+ ${c}`,O=gb(J);i(O!==J?new Error(O):new Error(`claude exited with code ${M}.
823
528
  `+(d?`Stderr: ${d.slice(0,500)}
824
- `:"")+(c?`Output: ${c.slice(0,500)}`:"No output"))):i(c)})}),l.stdin.on("error",()=>{}),l.stdin.write(n)?l.stdin.end():l.stdin.once("drain",()=>l.stdin.end());let h=o||6e5,f=Math.round(h/6e4),b=setTimeout(()=>{l.kill(),m(()=>r(new Error(`${e} timed out after ${f} minutes.
529
+ `:"")+(c?`Output: ${c.slice(0,500)}`:"No output")))}else r(c)})}),l.stdin.on("error",()=>{}),l.stdin.write(t)?l.stdin.end():l.stdin.once("drain",()=>l.stdin.end());let S=s||6e5,v=Math.round(S/6e4),k=setTimeout(()=>{l.kill(),f(()=>i(new Error(`claude (stream-json) timed out after ${v} minutes.
825
530
  `+(d?`Stderr: ${d.slice(0,500)}
826
- `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function ud(e,t,n,s,o,i){let r=ye(),a=R(),l=C().modules.length>0,c=Hn(),d=Ts(r,t,l,c.pageType,c.brandAssets);d+=`
531
+ `:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},S),_=()=>{l.kill(),f(()=>i(or("claude")))};o?.addEventListener("abort",_,{once:!0}),l.on("close",()=>{clearTimeout(k),o?.removeEventListener("abort",_)})})}function or(e){let t=new Error(`${e} aborted (generation cancelled)`);return t.name="AbortError",t}function Js(e,t,n,s,o,r,i){return new Promise((a,l)=>{if(r?.aborted){l(or(e));return}let c={...process.env};delete c.CLAUDECODE;let d=Sd(e,t,{stdio:["pipe","pipe","pipe"],env:c,...i?.cwd?{cwd:i.cwd}:{},...i?.shell?{shell:!0}:{}}),u="",p="",g=!1,f=_=>{g||(g=!0,_())};d.stdout.on("data",_=>{let M=_.toString();u+=M,s&&s(M)}),d.stderr.on("data",_=>{p+=_.toString()}),d.on("error",_=>f(()=>l(new Error(`${e} failed to start: ${_.message}`)))),d.on("close",_=>{f(()=>{_!==0?l(new Error(`${e} exited with code ${_}.
532
+ `+(p?`Stderr: ${p.slice(0,500)}
533
+ `:"")+(u?`Output: ${u.slice(0,500)}`:"No output"))):a(u)})}),d.stdin.on("error",()=>{}),d.stdin.write(n)?d.stdin.end():d.stdin.once("drain",()=>d.stdin.end());let b=o||6e5,S=Math.round(b/6e4),v=setTimeout(()=>{d.kill(),f(()=>l(new Error(`${e} timed out after ${S} minutes.
534
+ `+(p?`Stderr: ${p.slice(0,500)}
535
+ `:"")+`Partial output (${u.length} chars): ${u.slice(0,500)}`)))},b),k=()=>{d.kill(),f(()=>l(or(e)))};r?.addEventListener("abort",k,{once:!0}),d.on("close",()=>{clearTimeout(v),r?.removeEventListener("abort",k)})})}async function Td(e,t,n,s,o,r){let i=Ce(),a=$(),l=x().modules.length>0,c=Vn(),d=js(i,t,l,c.pageType,c.brandAssets);d+=`
827
536
 
828
537
  ## User Request
829
- `+e,d+=As(),d+=ad(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print",...Ir];a.claudeCodeModel&&u.push("--model",a.claudeCodeModel),a.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let m=0,g=s||(()=>{});g(je[0]);let h=setInterval(()=>{m++;let f=je[Math.min(m,je.length-1)];g(f)},6e3);try{let f=await Pr(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(ny(b,S))}});o&&o(f)}finally{clearInterval(h)}}function ny(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 Rr(e,t,n,s,o,i,r){let a=ye(),l=C().modules.length>0,c=Hn(),d=Ts(a,n,l,c.pageType,c.brandAssets);d+=`
538
+ `+e,d+=Ls(),d+=xd(r),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print",...na];a.claudeCodeModel&&u.push("--model",a.claudeCodeModel),a.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let p=0,g=s||(()=>{});g(Le[0]);let f=setInterval(()=>{p++;let h=Le[Math.min(p,Le.length-1)];g(h)},6e3);try{let h=await sa(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(fb(b,S))}});o&&o(h)}finally{clearInterval(f)}}function fb(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 oa(e,t,n,s,o,r,i){let a=Ce(),l=x().modules.length>0,c=Vn(),d=js(a,n,l,c.pageType,c.brandAssets);d+=`
830
539
 
831
540
  ## User Request
832
- `+t,d+=As(),d+=ad(r),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;e==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,h=o||(()=>{});h(je[0]);let f=setInterval(()=>{g++;let b=je[Math.min(g,je.length-1)];h(b)},6e3);try{let b=await Nr(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Ar,je,_r,Ir,_s,Or=N(()=>{"use strict";y();Ke();ee();$t();Ce();sd();le();Be();on();Ar=null;je=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],_r=[10,20,40,60,120];Ir=["--strict-mcp-config"],_s=null});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function W(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function qe(e,t,n){W(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Xe=N(()=>{"use strict";y()});import{createWriteStream as sy,mkdirSync as md,existsSync as Fr,readFileSync as Dr}from"fs";import{join as cn,extname as oy}from"path";import{randomUUID as iy}from"crypto";import ry from"busboy";function dy(e,t){if(gd.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return cy[n]??t}function uy(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function my(e,t){if(!Fr(cn(e,t)))return t;let n=oy(t),s=t.slice(0,-n.length||void 0),o=1;for(;Fr(cn(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function py(e){let{PDFParse:t}=await import("pdf-parse"),n=Dr(e),s=new t({data:n});try{return(await s.getText()).text}finally{await s.destroy()}}async function gy(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function fy(e){return Dr(e,"utf-8")}function fd(e,t){let n=C();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],r=0,a=[],l=ry({headers:e.headers,limits:{fileSize:ay,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=dy(m,g);if(!gd.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=pd.has(h),b=uy(m),S=iy(),v,w;f?(v=cn(n.themePath,"assets"),md(v,{recursive:!0}),w=my(v,b)):(v=cn(n.themePath,".vibespot","uploads"),md(v,{recursive:!0}),w=`${S}-${b}`);let $=cn(v,w),j=sy($),J=0,K=!1;d.on("data",H=>{J+=H.length}),d.on("limit",()=>{K=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(j),a.push(new Promise(H=>{j.on("finish",()=>{if(!K){let X={id:S,filename:w,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:J,addedAt:new Date().toISOString()};o.push(X),fc(X)}H()}),j.on("error",()=>{i.push(`Failed to write: ${m}`),H()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=cn(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await py(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await gy(d):c.extractedText=fy(d),M.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){M.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(r===0){p(t,400,{error:"No files uploaded"});return}p(t,200,{files:o.map(c=>({id:c.id,filename:c.filename,originalName:c.originalName,type:c.type,usage:c.usage,size:c.size})),errors:i.length>0?i:void 0})}),l.on("error",c=>{M.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Vo(e){let t=C();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=cn(t.themePath,"assets",s.filename);Fr(i)&&(o.base64=Dr(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 ay,pd,ly,gd,cy,jr=N(()=>{"use strict";y();Xe();Ce();le();ay=10*1024*1024,pd=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),ly=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),gd=new Set([...pd,...ly]),cy={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var wd={};Ge(wd,{LANGDOCK_BASE_URLS:()=>$s,callAgent:()=>Pe,callAgentAPI:()=>xd,isAgenticCapable:()=>Ms,isCLIEngine:()=>Gn,resolveThinkingBudget:()=>Un});async function zo(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>=Lr.length)throw s;let a=Lr[n];M.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${Lr.length} \u2014 waiting ${a}s`),t&&t(`Rate limited \u2014 retrying in ${a}s...`),await new Promise(l=>setTimeout(l,a*1e3)),t&&t("Retrying...")}}function Es(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 Sd(){return Jr||(Jr=(await import("@anthropic-ai/sdk")).default),Jr}async function hd(e,t,n,s,o,i){let r=await Sd(),a=new r({apiKey:e,...s?{defaultHeaders:s}:{},...i?{baseURL:i}:{}}),l=n.messages,c=n.systemPrompt;if(n.systemBlocks?c=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(c=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let d={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return zo(async()=>{let u=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,tools:[d],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),m=et(u.usage);for(let h of u.content)if(h.type==="tool_use")return{type:"structured",data:Es(h.input),usage:m};return{type:"text",text:u.content.filter(h=>h.type==="text").map(h=>h.text).join(""),usage:m}},n.onStatus)}return zo(async()=>{let d="",u=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let g of u)g.type==="content_block_delta"&&g.delta.type==="text_delta"&&(d+=g.delta.text,n.onChunk&&n.onChunk(g.delta.text));let m;try{m=et((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:m}},n.onStatus)}async function hy(e,t,n){let s=await Sd(),o=new s({authToken:e,defaultHeaders:Zn}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:xn},...n.systemBlocks]:r=[{type:"text",text:xn},{type:"text",text:n.systemPrompt}],n.structuredOutput){let a={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return zo(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),c=et(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:Es(u.input),usage:c};return{type:"text",text:l.content.filter(u=>u.type==="text").map(u=>u.text).join(""),usage:c}},n.onStatus)}return zo(async()=>{let a="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let d of l)d.type==="content_block_delta"&&d.delta.type==="text_delta"&&(a+=d.delta.text,n.onChunk&&n.onChunk(d.delta.text));let c;try{c=et((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus)}function Br(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"?Br(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Br(t.items)),t}async function yd(e,t,n,s){let o=[{role:"system",content:n.systemPrompt},...n.messages.map(u=>({role:u.role,content:typeof u.content=="string"?u.content:u.content.map(m=>({type:"text",text:m.text}))}))],i={model:t,max_completion_tokens:n.maxTokens||16e3,messages:o};n.structuredOutput&&(i.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!1,schema:Br(n.structuredOutput.schema)}});let a=await fetch(s||"https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(i)});if(!a.ok){let u=await a.text(),m=a.status;if(m===429){let g=new Error(`OpenAI rate limit: ${u}`);throw g.status=429,g}throw new Error(`OpenAI API error (${m}): ${u}`)}let l=await a.json(),c=l.choices?.[0]?.message?.content||"",d=En(l.usage);if(n.structuredOutput)try{return{type:"structured",data:Es(JSON.parse(c)),usage:d}}catch{return M.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:c,usage:d}}return{type:"text",text:c,usage:d}}async function bd(e,t,n,s){let o=t||"gemini-2.5-flash",i=n.messages.map(m=>({role:m.role==="assistant"?"model":"user",parts:typeof m.content=="string"?[{text:m.content}]:m.content.map(g=>({text:g.text}))})),r={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:i,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`,l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok){let m=await l.text(),g=l.status;if(g===429){let h=new Error(`Gemini rate limit: ${m}`);throw h.status=429,h}throw new Error(`Gemini API error (${g}): ${m}`)}let c=await l.json(),d=c.candidates?.[0]?.content?.parts?.[0]?.text||"",u=Mn(c.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:Es(JSON.parse(d)),usage:u}}catch{return M.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:d,usage:u}}return{type:"text",text:d,usage:u}}function yy(e,t,n){switch(e){case"claude-code":{let s=["--print",...Ir];return t&&s.push("--model",t),n?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":{let s=[];return t&&s.push("-m",t),{bin:"gemini",args:s}}case"codex-cli":{let s=["exec","--full-auto"];return t&&s.push("-m",t),{bin:"codex",args:s}}default:throw new Error(`Not a CLI engine: ${e}`)}}function by(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(`
541
+ `+t,d+=Ls(),d+=xd(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,p;e==="gemini"?(u="gemini",p=[]):(u="codex",p=["exec","--full-auto"]);let g=0,f=o||(()=>{});f(Le[0]);let h=setInterval(()=>{g++;let b=Le[Math.min(g,Le.length-1)];f(b)},6e3);try{let b=await Js(u,p,d,S=>{s(S)});r&&r(b)}finally{clearInterval(h)}}var Xi,cb,db,ub,Le,Zi,na,Bs,rr=j(()=>{"use strict";y();tt();te();$t();me();yd();re();Ue();un();Xi=null;cb=48e3,db=16384,ub=[[/^gpt-5/i,128e3],[/^(o1|o3|o4)/i,1e5],[/^gpt-4\.1/i,32768],[/^gpt-4o/i,16384],[/^(gpt-4-turbo|gpt-4-\d|gpt-3\.5)/i,4096]];Le=["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..."],Zi=[10,20,40,60,120];na=["--strict-mcp-config"],Bs=null});function fn(e){let t={},n=new Map;for(let s of e)if(n.set(s.name,s.type),s.type==="group"&&s.occurrence&&Array.isArray(s.default))t[s.name]=s.children?Gb(s.default,s.children):s.default;else if(s.type==="group"&&s.children){let o=fn(s.children);Ub(n,s.name,o),t[s.name]=o}else t[s.name]=s.default??"";return eu(t,n),t}function Yn(e,t){let n=e;return n=Hb(n),n=su(n,t),n=ou(n,t),n=ru(n,t),n=Xb(n),n}function aa(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${lu(o)}</style>`).join(`
542
+ `),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${cu(o)}</script>`).join(`
543
+ `),s=e.renderedModules.join(`
544
+ `);return`<!DOCTYPE html>
545
+ <html lang="en">
546
+ <head>
547
+ <meta charset="utf-8">
548
+ <meta name="viewport" content="width=device-width, initial-scale=1">
549
+ ${t}
550
+ <style>
551
+ html{scroll-behavior:smooth}
552
+ .vsp-img-wrap{position:relative;display:inline-block}
553
+ .vsp-img-badge{position:absolute;top:8px;right:8px;background:rgba(0,0,0,.75);color:#fff;font:500 11px/1 -apple-system,sans-serif;padding:5px 8px;border-radius:4px;pointer-events:none;opacity:.85;white-space:nowrap;z-index:10}
554
+ </style>
555
+ </head>
556
+ <body>
557
+ ${s}
558
+ ${n}
559
+ <script>
560
+ // Anchor link handler \u2014 smooth scroll to module sections
561
+ document.addEventListener('click',function(e){
562
+ var a=e.target.closest('a[href^="#"]');
563
+ if(!a)return;
564
+ var id=a.getAttribute('href').slice(1);
565
+ if(!id)return;
566
+ var el=document.getElementById(id);
567
+ if(el){
568
+ e.preventDefault();
569
+ el.scrollIntoView({behavior:'smooth',block:'start'});
570
+ }
571
+ });
572
+ // Placeholder image badges
573
+ document.querySelectorAll('img').forEach(function(img){
574
+ var src=img.src||img.getAttribute('src')||'';
575
+ if(src.indexOf('placehold')!==-1){
576
+ var w=document.createElement('span');
577
+ w.className='vsp-img-wrap';
578
+ img.parentNode.insertBefore(w,img);
579
+ w.appendChild(img);
580
+ var b=document.createElement('span');
581
+ b.className='vsp-img-badge';
582
+ b.textContent='Placeholder \u2014 replace in HubSpot';
583
+ w.appendChild(b);
584
+ }
585
+ });
586
+ </script>
587
+ </body>
588
+ </html>`}function Hb(e){return e=e.replace(Nb,""),e=e.replace(Ob,""),e=e.replace(Fb,""),qd.lastIndex=0,e=e.replace(qd,(t,n)=>`/theme-assets/${n}`),Yd.lastIndex=0,e=e.replace(Yd,""),e=e.replace(Db,""),e=e.replace(jb,""),e=e.replace(Lb,""),e=e.replace(Bb,""),e=e.replace(Jb,""),e}function eu(e,t){Object.defineProperty(e,Qd,{value:t,enumerable:!1,configurable:!1})}function Ub(e,t,n){let s=nu(n);if(s)for(let[o,r]of s)e.set(`${t}.${o}`,r)}function Gb(e,t){return e.map(n=>{if(n===null||typeof n!="object"||Array.isArray(n))return n;let s={...n},o=tu(t);return eu(s,o),s})}function tu(e,t=""){let n=new Map;for(let s of e){let o=t?`${t}.${s.name}`:s.name;if(n.set(o,s.type),s.type==="group"&&s.children){let r=tu(s.children,o);for(let[i,a]of r)n.set(i,a)}}return n}function nu(e){if(!(e===null||typeof e!="object"))return e[Qd]}function su(e,t){let n=e,s=0;for(;s<30;){s++;let o=Wb(n);if(!o)break;let{varName:r,iterExpr:i,body:a,start:l,end:c}=o,d=Zb(i,t),u="";Array.isArray(d)&&(u=d.map((p,g)=>{let f={...t,[r]:p,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},h=su(a,f);return h=ou(h,f),h=ru(h,f),h}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Wb(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],r=s[2],i=s.index+s[0].length;n.lastIndex=i;let a=1,l;for(;(l=n.exec(e))!==null;)if(l[1].startsWith("for"))a++;else if(a--,a===0){let c=e.slice(i,l.index);return{varName:o,iterExpr:r,body:c,start:s.index,end:l.index+l[0].length}}return null}function ou(e,t){let n=e,s=0,o=Kb(e);for(;s<o;){s++;let r=Vb(n);if(!r)break;let i=zb(r.condition,r.body,t);n=n.slice(0,r.start)+i+n.slice(r.end)}return n}function Kb(e){let t=e.match(/\{%[-\s]*if\s+/g);return t?t.length:0}function Vb(e){let t=[];fr.lastIndex=0;let n;for(;(n=fr.exec(e))!==null;){let s=n[1].trim();if(s.startsWith("if "))t.push({condition:n[2].trim(),start:n.index,bodyStart:n.index+n[0].length});else if(s==="endif"&&t.length>0){let o=t.pop();return{condition:o.condition,body:e.slice(o.bodyStart,n.index),start:o.start,end:n.index+n[0].length}}}return null}function zb(e,t,n){let s=[],o=e,r=0,i=0;fr.lastIndex=0;let a;for(;(a=fr.exec(t))!==null;){let l=a[1].trim();if(l.startsWith("if ")){i++;continue}if(l==="endif"){i=Math.max(0,i-1);continue}i>0||(l.startsWith("elif ")||l==="else")&&(s.push({condition:o,body:t.slice(r,a.index)}),o=l==="else"?null:a[3].trim(),r=a.index+a[0].length)}s.push({condition:o,body:t.slice(r)});for(let l of s)if(l.condition===null||gr(l.condition,n))return l.body;return""}function ru(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s,o)=>{let r=s.trim(),i=qb(e,o),a=r.split("|"),l=a[0].trim(),c=Qb(t,l),d=!1,u=!1;for(let g=1;g<a.length;g++){let f=a[g].trim(),h=eS(f);c=au(c,f),h==="escape"||h==="e"?d=!0:h==="safe"&&(u=!0)}if(c==null)return"";typeof c=="object"&&(c=JSON.stringify(c));let p=String(c);return p=p.replace(/\\n/g," ").replace(/\n/g," "),d?p:i==="style"?lu(p):i==="script"?tS(p):i==="htmlText"&&(u||Yb(t,l))?lS(p):la(p)})}function qb(e,t){let n=e.slice(0,t),s=n.toLowerCase().lastIndexOf("<script"),o=n.toLowerCase().lastIndexOf("</script");if(s>o)return"script";let r=n.toLowerCase().lastIndexOf("<style"),i=n.toLowerCase().lastIndexOf("</style");if(r>i)return"style";let a=n.lastIndexOf("<"),l=n.lastIndexOf(">");return a>l?"htmlTag":"htmlText"}function Yb(e,t){let n=t.split(".");if(n.length<2)return!1;let s=e,o="";for(let r=0;r<n.length;r++){if(s===null||typeof s!="object")return!1;let i=nu(s);if(i){o=n.slice(r).join(".");let a=i.get(o);return a==="richtext"||a==="html"}s=s[n[r]]}return!1}function Xb(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Zb(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Xd(n[1],t),r=Xd(n[2],t),i=[];for(let a=o;a<r;a++)i.push(a);return i}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=en(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return en(t,e)}function Xd(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let r=en(t,o);for(let i=1;i<s.length;i++)r=au(r,s[i].trim());return Number(r)||0}function en(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 Qb(e,t){let n=t.match(/^(.+?)\s*([*/])\s*([\d.]+)$/);if(n){let s=en(e,n[1].trim());if(s==null||s==="")return"";let o=Number(s);if(Number.isNaN(o))return"";let r=Number(n[3]);return n[2]==="/"?r===0?"":o/r:o*r}return en(e,t)}function gr(e,t){let n=e.trim();if(n.startsWith("not "))return!gr(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(r=>gr(r,t));if(n.includes(" or "))return n.split(" or ").some(r=>gr(r,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let r=en(t,s[1].trim()),i=s[2],a=s[3].trim();switch(typeof a=="string"&&a.startsWith('"')&&a.endsWith('"')||typeof a=="string"&&a.startsWith("'")&&a.endsWith("'")?a=a.slice(1,-1):isNaN(Number(a))?a=en(t,a):a=Number(a),i){case"==":return r==a;case"!=":return r!=a;case">":return Number(r)>Number(a);case"<":return Number(r)<Number(a);case">=":return Number(r)>=Number(a);case"<=":return Number(r)<=Number(a)}}let o=en(t,n);return iu(o)}function iu(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function au(e,t){let n=e==null?"":String(e),s=t.match(/^(\w+)\((.*)\)$/),o=s?s[1]:t,r=s?s[2].replace(/^["']|["']$/g,""):void 0;switch(o){case"escape":case"e":return la(n);case"safe":return e;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(r){let i=parseInt(r,10);return n.length>i?n.slice(0,i)+"...":n}return n;case"default":return iu(e)?e:r??"";case"length":return Array.isArray(e)?e.length:n.length;case"join":return Array.isArray(e)?e.join(r??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));case"convert_rgb":{let i=ia(e);return i?yS(i):""}default:return e}}function eS(e){let t=e.match(/^(\w+)(?:\(.*\))?$/);return t?t[1]:e}function la(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;")}function lu(e){return e.replace(/<\/style/gi,"<\\/style")}function cu(e){return e.replace(/<\/script/gi,"<\\/script")}function tS(e){return cu(e).replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/'/g,"\\'").replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029")}function lS(e){let t="",n=0,s=null;for(;n<e.length;){let o=e.indexOf("<",n);if(o===-1){s||(t+=e.slice(n));break}s||(t+=e.slice(n,o));let r=cS(e,o);if(r===-1){s||(t+="&lt;"),n=o+1;continue}let i=e.slice(o,r+1),a=dS(i);if(n=r+1,!!a){if(s){a.closing&&a.tagName===s&&(s=null);continue}if(nS.has(a.tagName)){a.closing||(s=a.tagName);continue}if(sS.has(a.tagName)){if(a.closing){aS.has(a.tagName)||(t+=`</${a.tagName}>`);continue}t+=pS(a)}}}return t.replace(/<\/style/gi,"<\\/style").replace(/<\/script/gi,"<\\/script")}function cS(e,t){let n=null;for(let s=t+1;s<e.length;s++){let o=e[s];if(n){o===n&&(n=null);continue}if(o==='"'||o==="'"){n=o;continue}if(o===">")return s}return-1}function dS(e){if(e.startsWith("<!--"))return null;let t=e.slice(1,-1).trim();if(!t||t.startsWith("!")||t.startsWith("?"))return null;let n=t.startsWith("/");n&&(t=t.slice(1).trimStart());let s=t.match(/^([A-Za-z][A-Za-z0-9:-]*)/);if(!s)return null;let o=s[1].toLowerCase(),r=n?[]:uS(t.slice(s[0].length));return{tagName:o,closing:n,attrs:r}}function uS(e){let t=[],n=0;for(;n<e.length;){for(;n<e.length&&/[\s/]/.test(e[n]);)n++;if(n>=e.length)break;let s=n;for(;n<e.length&&!/[\s/=]/.test(e[n]);)n++;let o=e.slice(s,n);if(!o){n++;continue}for(;n<e.length&&/\s/.test(e[n]);)n++;let r=null;if(e[n]==="="){for(n++;n<e.length&&/\s/.test(e[n]);)n++;let i=e[n];if(i==='"'||i==="'"){n++;let a=n;for(;n<e.length&&e[n]!==i;)n++;r=e.slice(a,n),e[n]===i&&n++}else{let a=n;for(;n<e.length&&!/\s/.test(e[n]);)n++;r=e.slice(a,n)}}t.push({name:o.toLowerCase(),value:r})}return t}function pS(e){let t=e.attrs.map(n=>mS(e.tagName,n)).filter(n=>!!n).map(n=>n.value===null?n.name:`${n.name}="${la(n.value)}"`).join(" ");return t?`<${e.tagName} ${t}>`:`<${e.tagName}>`}function mS(e,t){let n=t.name;if(!n||n.startsWith("on")||n==="style")return null;let s=rS[e];return oS.has(n)||n.startsWith("aria-")||n.startsWith("data-")||!!s?.has(n)?iS.has(n)&&t.value!==null&&!gS(t.value)?{name:n,value:"#"}:e==="a"&&n==="target"&&t.value==="_blank"?t:n==="target"?null:t:null}function gS(e){let n=fS(e).trim().replace(/[\u0000-\u001F\u007F\s]+/g,"").toLowerCase();if(n.startsWith("#")||n.startsWith("/")||n.startsWith("./")||n.startsWith("../"))return!0;if(n.startsWith("data:"))return/^data:image\/(?:gif|jpe?g|png|webp);/i.test(n);let s=n.match(/^([a-z][a-z0-9+.-]*):/);return s?["http","https","mailto","tel"].includes(s[1]):!0}function fS(e){let t={amp:"&",colon:":",gt:">",lt:"<",newline:`
589
+ `,quot:'"',tab:" "};return e.replace(/&(#x[\da-f]+|#\d+|[a-z]+);?/gi,(n,s)=>{let o=s.toLowerCase();if(o.startsWith("#x")){let r=parseInt(o.slice(2),16);return Zd(r)?String.fromCodePoint(r):n}if(o.startsWith("#")){let r=parseInt(o.slice(1),10);return Zd(r)?String.fromCodePoint(r):n}return t[o]??n})}function Zd(e){return Number.isInteger(e)&&e>=0&&e<=1114111}function ia(e){if(e==null)return null;if(typeof e=="string"){let t=e.match(/#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})(?![0-9a-fA-F])/);return t?hS(t[1]):null}if(typeof e=="object"){let t=e;if(typeof t.color=="string")return ia(t.color);if(typeof t.hex=="string")return ia(t.hex)}return null}function hS(e){let t=e.toLowerCase();return t.length===3?t.split("").map(n=>n+n).join(""):t}function yS(e){let t=parseInt(e.slice(0,2),16),n=parseInt(e.slice(2,4),16),s=parseInt(e.slice(4,6),16);return`${t}, ${n}, ${s}`}var Qd,Nb,Ob,Fb,qd,Yd,Db,jb,Lb,Bb,Jb,fr,nS,sS,oS,rS,iS,aS,ca=j(()=>{"use strict";y();Qd=Symbol("hublFieldTypes");Nb=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Ob=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,Fb=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,qd=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Yd=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Db=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,jb=/\{%[-\s]*module\b.*?%\}/gs,Lb=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Bb=/\{#.*?#\}/gs,Jb=/\{\{[-\s]*content\.\w+.*?\}\}/gs,fr=/\{%[-\s]*(if\s+([\s\S]*?)|elif\s+([\s\S]*?)|else|endif)\s*-?%\}/g;nS=new Set(["script","style","iframe","object","embed"]),sS=new Set(["a","abbr","b","blockquote","br","cite","code","dd","del","details","div","dl","dt","em","figcaption","figure","h1","h2","h3","h4","h5","h6","hr","i","img","ins","li","mark","ol","p","pre","q","s","small","span","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","u","ul"]),oS=new Set(["class","dir","id","lang","role","title"]),rS={a:new Set(["href","name","rel","target"]),blockquote:new Set(["cite"]),del:new Set(["cite","datetime"]),details:new Set(["open"]),img:new Set(["alt","decoding","height","loading","src","title","width"]),ins:new Set(["cite","datetime"]),q:new Set(["cite"]),td:new Set(["colspan","headers","rowspan"]),th:new Set(["colspan","headers","rowspan","scope"])},iS=new Set(["cite","href","src"]),aS=new Set(["br","hr","img"])});function tn(){return du}function uu(e){du=e}function pu(){return hr}function mu(e){hr=e}function gu(e){hr===e&&(hr=null)}var du,hr,hn=j(()=>{"use strict";y();du="page";hr=null});var yr={};Ve(yr,{buildModulePreviewHtml:()=>ua,buildPreviewHtml:()=>Us});function bS(e){if(tn()==="email")return!0;for(let t of e)try{let n=JSON.parse(t.metaJson);if(Array.isArray(n.host_template_types)&&n.host_template_types.includes("EMAIL"))return!0}catch{}return!1}function SS(e){if(!e)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let t=(a,l)=>{for(let c of a){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=e.match(d);if(u)return u[1].trim()}return l},n=t(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=t(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=t(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),r=t(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),i=t(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:r,border:i}}function da(e,t){if(!Array.isArray(t))return e;let n=new Map;for(let o of t)n.set(o.name,o.type);let s=e;return s=s.replace(/(<([a-zA-Z]\w*)(\s[^>]*)?>)\s*(\{\{\s*module\.(\w+)(?:\.\w+)*(?:\|[^}]*)?\s*\}\})\s*(<\/\2>)/g,(o,r,i,a,l,c,d)=>{if(r.includes("data-vs-field"))return o;let u=n.get(c)||"text";return`${r.replace(/>$/,` data-vs-field="${c}" data-vs-type="${u}">`)}${l}${d}`}),s=s.replace(/(<img\b)([^>]*?)\bsrc\s*=\s*["']\{\{\s*module\.(\w+)\.src\s*\}\}["']([^>]*?>)/g,(o,r,i,a)=>o.includes("data-vs-field")?o:o.replace("<img",`<img data-vs-field="${a}" data-vs-type="image"`)),s=s.replace(/(<a\b)([^>]*?)\bhref\s*=\s*["']\{\{\s*module\.(\w+)\.url\.href\s*\}\}["']([^>]*?>)/g,(o,r,i,a)=>o.includes("data-vs-link")?o:o.replace("<a",`<a data-vs-link="${a}"`)),s}function Us(){let e=x();if(!e)return fu();let t=pe(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return fu();if(bS(t))return vS(t,n);let s=[],o=[],r=[],i=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d,u=[];try{let h=JSON.parse(c.fieldsJson);u=Array.isArray(h)?h:[],d={module:fn(u)}}catch{d={module:{}}}let p=da(c.moduleHtml,u),g=Yn(p,d),f=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${f}" data-module="${c.moduleName}">${g}</div>`),i.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&r.push(c.moduleJs)}let a=SS(e.sharedCss);for(let c of n)if(!i.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}">
590
+ <div class="vibespot-placeholder">
591
+ <div class="vibespot-placeholder__name">${c}</div>
592
+ </div>
593
+ </div>`)}let l=`body{background:${a.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${a.surface};border:1px dashed ${a.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${a.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return aa({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:r})}function fu(){return`<!DOCTYPE html>
594
+ <html lang="en">
595
+ <head>
596
+ <meta charset="utf-8">
597
+ <meta name="viewport" content="width=device-width, initial-scale=1">
598
+ <style>
599
+ * { margin: 0; padding: 0; box-sizing: border-box; }
600
+ body {
601
+ min-height: 100vh;
602
+ display: flex;
603
+ align-items: center;
604
+ justify-content: center;
605
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
606
+ background: #0f0f14;
607
+ color: #888;
608
+ }
609
+ .welcome {
610
+ text-align: center;
611
+ padding: 2rem;
612
+ }
613
+ .welcome__wave {
614
+ font-size: 4rem;
615
+ margin-bottom: 1.2rem;
616
+ opacity: 0.4;
617
+ animation: float 3s ease-in-out infinite;
618
+ }
619
+ @keyframes float {
620
+ 0%, 100% { transform: translateY(0); }
621
+ 50% { transform: translateY(-6px); }
622
+ }
623
+ .welcome__title {
624
+ font-size: 1.4rem;
625
+ font-weight: 600;
626
+ color: #bbb;
627
+ letter-spacing: 0.5px;
628
+ margin-bottom: 0.4rem;
629
+ }
630
+ .welcome__sub {
631
+ font-size: 1rem;
632
+ color: #666;
633
+ font-weight: 300;
634
+ }
635
+ </style>
636
+ </head>
637
+ <body>
638
+ <div class="welcome">
639
+ <div class="welcome__wave">\u224B</div>
640
+ <div class="welcome__title">vibeSpot</div>
641
+ <div class="welcome__sub">Build Something Great</div>
642
+ </div>
643
+ </body>
644
+ </html>`}function ua(e){let t=x();if(!t)return"";let n;for(let a of t.templates)if(n=a.modules.find(l=>l.moduleName===e),n)break;if(n||(n=t.modules.find(a=>a.moduleName===e)),!n)return"";let s,o=[];try{let a=JSON.parse(n.fieldsJson);o=Array.isArray(a)?a:[],s={module:fn(o)}}catch{s={module:{}}}let r=da(n.moduleHtml,o),i=Yn(r,s);return aa({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${i}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}function vS(e,t){let n=[],s=new Set;for(let r of e){let i,a=[];try{let u=JSON.parse(r.fieldsJson);a=Array.isArray(u)?u:[],i={module:fn(a)}}catch{i={module:{}}}let l=da(r.moduleHtml,a),c=Yn(l,i),d=r.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module" id="${d}" data-module="${r.moduleName}">${c}</div>`),s.add(r.moduleName)}for(let r of t)if(!s.has(r)){let i=r.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module vibespot-module--pending" id="${i}" data-module="${r}">
645
+ <table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="max-width:600px;margin:0 auto;">
646
+ <tr><td style="padding:40px 30px;text-align:center;background-color:#ffffff;border:1px dashed #ddd;">
647
+ <p style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#999;">${r}</p>
648
+ </td></tr>
649
+ </table>
650
+ </div>`)}return`<!DOCTYPE html>
651
+ <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
652
+ <head>
653
+ <meta charset="utf-8">
654
+ <meta name="viewport" content="width=device-width, initial-scale=1">
655
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
656
+ <title>Email Preview</title>
657
+ <style>
658
+ html, body { margin: 0; padding: 0; overflow-x: hidden; }
659
+ body {
660
+ background-color: #e8e8e8;
661
+ font-family: Arial, Helvetica, sans-serif;
662
+ -webkit-font-smoothing: antialiased;
663
+ }
664
+ .vibespot-email-wrapper {
665
+ padding: 30px 20px;
666
+ background-color: #e8e8e8;
667
+ min-height: 100vh;
668
+ }
669
+ .vibespot-module { margin: 0 auto; max-width: 600px; }
670
+ .vibespot-module--pending table { opacity: 0.6; }
671
+ html { scroll-behavior: smooth; }
672
+ img { max-width: 100% !important; height: auto !important; }
673
+ table { max-width: 100% !important; }
674
+ td { word-break: break-word; }
675
+ @media screen and (max-width: 620px) {
676
+ .vibespot-email-wrapper { padding: 10px 8px; }
677
+ table[width] { width: 100% !important; }
678
+ img[width] { width: 100% !important; height: auto !important; }
679
+ }
680
+ </style>
681
+ </head>
682
+ <body>
683
+ <div class="vibespot-email-wrapper">
684
+ ${n.join(`
685
+ `)}
686
+ </div>
687
+ <script>
688
+ document.addEventListener('click', function(e) {
689
+ var a = e.target.closest('a[href^="#"]');
690
+ if (a) { e.preventDefault(); var t = document.querySelector(a.getAttribute('href')); if (t) t.scrollIntoView({ behavior: 'smooth' }); }
691
+ });
692
+ </script>
693
+ </body>
694
+ </html>`}var Xn=j(()=>{"use strict";y();ca();me();hn()});function m(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function G(e,t,n={}){let s=n.maxBytes??xS,o=[],r=0,i=!1;e.on("data",a=>{if(!i){if(r+=a.length,r>s){i=!0,o.length=0,n.res&&!n.res.headersSent?(e.pause(),n.res.writeHead(413,{"Content-Type":"application/json",Connection:"close"}),n.res.end(JSON.stringify({error:"Request body too large"}))):e.destroy();return}o.push(a)}}),e.on("end",()=>{i||t(Buffer.concat(o).toString("utf-8"))})}function Ze(e,t,n){G(e,s=>{try{n(JSON.parse(s||"{}"))}catch{m(t,400,{error:"Invalid JSON in request body"})}},{res:t})}var xS,Re=j(()=>{"use strict";y();xS=5*1024*1024});import{homedir as BS}from"os";function N(e){return(e instanceof Error?e.message:String(e)).split(BS()).join("~").replace(JS,"~")}var JS,At=j(()=>{"use strict";y();JS=/(?:\/(?:home|Users)\/|[A-Za-z]:\\Users\\)[^\s/\\'")\]]+/g});function pt(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 r=/position (\d+)/.exec(o.message);if(!r)return null;let i=parseInt(r[1],10);if(i<=n)return null;n=i;let a=Math.max(0,i-5),c=t.slice(a,i+1).lastIndexOf('"');if(c===-1)return null;let d=a+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function Gs(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,r=!1,i=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(i){i=!1;continue}if(u==="\\"){i=!0;continue}if(u==='"'){r=!r;continue}r||(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 pt(c)}function Au(e){return typeof e=="string"?e.trim()?e:null:e==null?null:JSON.stringify(e,null,2)}function HS(e){let t=typeof e.moduleName=="string"?e.moduleName.trim():"",n=Au(e.fieldsJson),s=Au(e.metaJson);return!t||n===null||s===null?null:{moduleName:t,fieldsJson:n,metaJson:s,moduleHtml:String(e.moduleHtml||""),moduleCss:String(e.moduleCss||""),moduleJs:e.moduleJs?String(e.moduleJs):void 0}}function ya(e,t){let n=[],s=0;for(let o of e){let r=o&&typeof o=="object"?HS(o):null;if(r)n.push(r);else{s++;let i=o&&typeof o=="object"?o.moduleName:void 0;A.warn("parse","Dropping malformed module (missing name/fieldsJson/metaJson)",{moduleName:i})}}return s>0&&t&&t(`${s} module(s) in the AI response were incomplete and skipped. Try sending your request again.`),n}function _u(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 r=pt(s[1]);if(!r||typeof r!="object")throw A.warn("parse","tryParseJSON returned non-object",{result:typeof r}),new Error("Invalid JSON after repair");let i=r;if(i.modules&&Array.isArray(i.modules)){let a=ya(i.modules,t);a.length>0&&(Ge({modules:a,sharedCss:i.sharedCss!==void 0?String(i.sharedCss):void 0,sharedJs:i.sharedJs!==void 0?String(i.sharedJs):void 0}),n=!0)}}catch(r){A.warn("parse","Failed to parse vibespot-modules block",{error:r instanceof Error?r.message:String(r)})}if(!n){let r=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=r.exec(e))!==null;)if(s[1].includes('"modules"'))try{let i=pt(s[1]);if(!i||typeof i!="object")throw new Error("Invalid JSON after repair");let a=i;if(a.modules&&Array.isArray(a.modules)){let l=ya(a.modules,t);l.length>0&&(Ge({modules:l,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 JSON module block",{error:i instanceof Error?i.message:String(i)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){A.info("parse","Detected truncated response (odd fence count), attempting salvage");let i=e.lastIndexOf("```"),a=e.slice(i+3);a=a.replace(/^[\w-]*\s*\n?/,"");let l=Gs(a);if(l){let c=l;if(c.modules&&Array.isArray(c.modules)&&c.modules.length>0){let d=ya(c.modules,t);d.length>0&&(A.info("parse","Salvaged modules from truncated response",{count:d.length}),Ge({modules: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 r=e.includes("vibespot-modules")||e.includes('"modules"'),i=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(r||i){let a=r?"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",a),t&&t(a)}}}var Sr=j(()=>{"use strict";y();me();re()});import{createWriteStream as US,mkdirSync as Pu,existsSync as ba,readFileSync as Sa}from"fs";import{join as yn,extname as GS}from"path";import{randomUUID as WS}from"crypto";import KS from"busboy";function YS(e,t){if(Iu.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return qS[n]??t}function XS(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function ZS(e,t){if(!ba(yn(e,t)))return t;let n=GS(t),s=t.slice(0,-n.length||void 0),o=1;for(;ba(yn(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function QS(e){let{PDFParse:t}=await import("pdf-parse"),n=Sa(e),s=new t({data:n});try{return(await s.getText()).text}finally{await s.destroy()}}async function ev(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function tv(e){return Sa(e,"utf-8")}function Mu(e,t){let n=x();if(!n){m(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){m(t,400,{error:"Expected multipart/form-data"});return}let o=[],r=[],i=0,a=[],l=KS({headers:e.headers,limits:{fileSize:VS,files:10}});l.on("file",(c,d,u)=>{let{filename:p,mimeType:g}=u;i++;let f=YS(p,g);if(!Iu.has(f)){r.push(`Unsupported file type: ${p} (${g})`),d.resume();return}let h=Eu.has(f),b=XS(p),S=WS(),v,k;h?(v=yn(n.themePath,"assets"),Pu(v,{recursive:!0}),k=ZS(v,b)):(v=yn(n.themePath,".vibespot","uploads"),Pu(v,{recursive:!0}),k=`${S}-${b}`);let _=yn(v,k),M=US(_),R=0,J=!1;d.on("data",O=>{R+=O.length}),d.on("limit",()=>{J=!0,r.push(`File too large (>10MB): ${p}`)}),d.pipe(M),a.push(new Promise(O=>{M.on("finish",()=>{if(!J){let V={id:S,filename:k,originalName:p,type:h?"image":"document",usage:h?"asset":"context",mimeType:f,size:R,addedAt:new Date().toISOString()};o.push(V),jc(V)}O()}),M.on("error",()=>{r.push(`Failed to write: ${p}`),O()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=yn(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await QS(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await ev(d):c.extractedText=tv(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(i===0){m(t,400,{error:"No files uploaded"});return}m(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:r.length>0?r:void 0})}),l.on("error",c=>{A.error("upload",`Busboy error: ${c}`),m(t,500,{error:"Upload failed"})}),e.pipe(l)}function vr(e){let t=x();return t?.assets?e.map(n=>{let s=t.assets.find(r=>r.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 r=yn(t.themePath,"assets",s.filename);ba(r)&&(o.base64=Sa(r).toString("base64")),o.assetPath=`${t.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var VS,Eu,zS,Iu,qS,va=j(()=>{"use strict";y();Re();me();re();VS=10*1024*1024,Eu=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),zS=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),Iu=new Set([...Eu,...zS]),qS={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});function Ws(e){if(e instanceof Ie)return!0;let t=e?.name;if(t==="AbortError"||t==="APIUserAbortError")return!0;let n=e instanceof Error?e.message:"";return/\baborted\b/i.test(n)}function xr(e,t){let n=0,s=[];return t&&t.addEventListener("abort",()=>{for(;s.length>0;)s.shift().reject(new Ie)},{once:!0}),async function(r){if(t?.aborted)throw new Ie;if(n>=e&&(await new Promise((i,a)=>s.push({resolve:i,reject:a})),t?.aborted))throw new Ie;n++;try{return await r()}finally{n--,s.length>0&&s.shift().resolve()}}}var Ie,Qn=j(()=>{"use strict";y();Ie=class extends Error{aborted=!0;constructor(t="Pipeline aborted"){super(t),this.name="PipelineAbortError"}}});var ju={};Ve(ju,{LANGDOCK_BASE_URLS:()=>Ks,callAgent:()=>Ne,callAgentAPI:()=>Du,isAgenticCapable:()=>zs,isCLIEngine:()=>ns,resolveThinkingBudget:()=>ts});function nv(e,t){return new Promise(n=>{let s=setTimeout(()=>{t?.removeEventListener("abort",o),n()},e),o=()=>{clearTimeout(s),n()};t?.addEventListener("abort",o,{once:!0})})}async function es(e,t,n){for(let s=0;;s++)try{return await e()}catch(o){let r=o.status,i=o.error?.type;if(!(r===429||i==="rate_limit_error"||o instanceof Error&&o.message.includes("429"))||s>=xa.length)throw o;let l=xa[s];if(A.warn("agent-adapter",`Rate limited (429), attempt ${s+1}/${xa.length} \u2014 waiting ${l}s`),t&&t(`Rate limited \u2014 retrying in ${l}s...`),await nv(l*1e3,n),n?.aborted)throw new Ie;t&&t("Retrying...")}}function Vs(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 Ou(){return wa||(wa=(await import("@anthropic-ai/sdk")).default),wa}async function $u(e,t,n,s,o,r){let i=await Ou(),a=new i({apiKey:e,...s?{defaultHeaders:s}:{},...r?{baseURL:r}:{}}),l=n.messages,c=n.systemPrompt;if(n.systemBlocks?c=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(c=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let d={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return es(async()=>{let u=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,tools:[d],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal}),p=nt(u.usage);for(let f of u.content)if(f.type==="tool_use")return{type:"structured",data:Vs(f.input),usage:p};return{type:"text",text:u.content.filter(f=>f.type==="text").map(f=>f.text).join(""),usage:p}},n.onStatus,n.signal)}return es(async()=>{let d="",u=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal});for await(let g of u)g.type==="content_block_delta"&&g.delta.type==="text_delta"&&(d+=g.delta.text,n.onChunk&&n.onChunk(g.delta.text));let p;try{p=nt((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:p}},n.onStatus,n.signal)}async function sv(e,t,n){let s=await Ou(),o=new s({authToken:e,defaultHeaders:ms}),r=n.messages,i;if(n.systemBlocks?i=[{type:"text",text:In},...n.systemBlocks]:i=[{type:"text",text:In},{type:"text",text:n.systemPrompt}],n.structuredOutput){let a={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return es(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:i,messages:r,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal}),c=nt(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:Vs(u.input),usage:c};return{type:"text",text:l.content.filter(u=>u.type==="text").map(u=>u.text).join(""),usage:c}},n.onStatus,n.signal)}return es(async()=>{let a="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:i,messages:r,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}},{signal:n.signal});for await(let d of l)d.type==="content_block_delta"&&d.delta.type==="text_delta"&&(a+=d.delta.text,n.onChunk&&n.onChunk(d.delta.text));let c;try{c=nt((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus,n.signal)}function ka(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"?ka(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=ka(t.items)),t}async function Ru(e,t,n,s){let o=[{role:"system",content:n.systemPrompt},...n.messages.map(a=>({role:a.role,content:typeof a.content=="string"?a.content:a.content.map(l=>({type:"text",text:l.text}))}))],r={model:t,max_completion_tokens:n.maxTokens||16e3,messages:o};n.structuredOutput&&(r.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!1,schema:ka(n.structuredOutput.schema)}});let i=s||"https://api.openai.com/v1/chat/completions";return es(async()=>{let a=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(r),signal:n.signal});if(!a.ok){let u=await a.text(),p=a.status;if(p===429){let g=new Error(`OpenAI rate limit: ${u}`);throw g.status=429,g}throw new Error(`OpenAI API error (${p}): ${u}`)}let l=await a.json(),c=l.choices?.[0]?.message?.content||"",d=Bn(l.usage);if(n.structuredOutput)try{return{type:"structured",data:Vs(JSON.parse(c)),usage:d}}catch{return A.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:c,usage:d}}return{type:"text",text:c,usage:d}},n.onStatus,n.signal)}async function Nu(e,t,n,s){let o=t||"gemini-2.5-flash",r=n.messages.map(c=>({role:c.role==="assistant"?"model":"user",parts:typeof c.content=="string"?[{text:c.content}]:c.content.map(d=>({text:d.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:r,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=!!s,l=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`;return es(async()=>{let c=await fetch(l,{method:"POST",headers:{"Content-Type":"application/json",...a?{Authorization:`Bearer ${e}`}:{}},body:JSON.stringify(i),signal:n.signal});if(!c.ok){let g=await c.text(),f=c.status;if(f===429){let h=new Error(`Gemini rate limit: ${g}`);throw h.status=429,h}throw new Error(`Gemini API error (${f}): ${g}`)}let d=await c.json(),u=d.candidates?.[0]?.content?.parts?.[0]?.text||"",p=Jn(d.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:Vs(JSON.parse(u)),usage:p}}catch{return A.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:u,usage:p}}return{type:"text",text:u,usage:p}},n.onStatus,n.signal)}function ov(e,t,n){switch(e){case"claude-code":{let s=["--print",...na];return t&&s.push("--model",t),n?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":{let s=[];return t&&s.push("-m",t),{bin:"gemini",args:s}}case"codex-cli":{let s=["exec","--full-auto"];return t&&s.push("-m",t),{bin:"codex",args:s}}default:throw new Error(`Not a CLI engine: ${e}`)}}function rv(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(r=>r.text).join(`
833
695
  `);t.push(`
834
696
 
835
697
  ## ${s}
836
- ${o}`)}if(e.structuredOutput){let n=vd(e.structuredOutput.schema);t.push(`
698
+ ${o}`)}if(e.structuredOutput){let n=Fu(e.structuredOutput.schema);t.push(`
837
699
 
838
700
  ## Output Format \u2014 CRITICAL
839
701
  Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
840
702
 
841
703
  The JSON must match this structure:
842
- ${n}`)}return t.join("")}function vd(e,t=0){let n=" ".repeat(t),s=e.properties,o=e.required||[];if(!s)return`${n}${JSON.stringify(e)}`;let i=["{"];for(let[r,a]of Object.entries(s)){let l=o.includes(r)?" (required)":"",c=a.type||"any",d=a.description?` \u2014 ${a.description}`:"",u=a.enum?` [${a.enum.join(", ")}]`:"";if(c==="array"&&a.items){let m=a.items.type||"object";i.push(`${n} "${r}": ${c}<${m}>${l}${d}${u}`)}else c==="object"&&a.properties?i.push(`${n} "${r}": ${vd(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
843
- `)}function Sy(e){let t=e.trim(),n=ct(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let a=s[1].trim(),l=ct(a);if(l&&typeof l=="object")return l;let c=ks(a);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let a=t.slice(o,i+1),l=ct(a);if(l&&typeof l=="object")return l;let c=ks(a);if(c&&typeof c=="object")return c}let r=ks(t);return r&&typeof r=="object"?r:null}async function vy(e,t,n){let{bin:s,args:o}=yy(e,t,n),i=by(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Pr(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=xy(c,d);n.onStatus(u)}})}else r=await Nr(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=Sy(r);return a?{type:"structured",data:Es(a)}:(M.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function xy(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 xd(e,t,n,s){M.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length});let o=new Date,i=await(async()=>{switch(e){case"anthropic-api":return hd(t,n,s);case"claude-oauth":{let{getValidAccessToken:r}=await Promise.resolve().then(()=>($t(),ji)),a=await r();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return hy(a,n,s)}case"openai-api":return yd(t,n,s);case"gemini-api":return bd(t,n,s);case"langdock-api":{let r=R(),a=r.langdockProvider||"anthropic",l=r.langdockBaseUrl;switch(a){case"openai":case"mistral":{let c=l||$s[a];return yd(t,n,s,`${c}/v1/chat/completions`)}case"google":{let c=l||$s.google;return bd(t,n,s,`${c}/v1beta/models/${n}:generateContent`)}default:{let c=l||$s.anthropic;return hd(t,n,s,void 0,void 0,c)}}}default:throw new Error(`Unsupported API engine: ${e}`)}})();return Cy(e,n,s,i,o,new Date),i}function Cy(e,t,n,s,o,i){St({engine:e,model:t,name:n.structuredOutput?.name||"generation",input:{system:n.systemPrompt,messages:n.messages},output:s.type==="structured"?s.data:s.text,usage:s.usage,startTime:o,endTime:i,metadata:{structured:!!n.structuredOutput,systemPromptLength:n.systemPrompt.length,...n.prompt?.source?{promptSource:n.prompt.source}:{}},...n.prompt?{promptName:n.prompt.name,promptVersion:n.prompt.version}:{}})}async function Pe(e,t,n,s){return wy.has(e)?xd(e,t,n,s):(M.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),vy(e,n,s))}function Un(e){if(e==="langdock-api"){if((R().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=R();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Ms(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="langdock-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function Gn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var $s,Xk,Lr,Jr,wy,dt=N(()=>{"use strict";y();Or();Ko();ee();$t();le();on();Be();$s={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},Xk=$s.anthropic,Lr=[10,20,40,60,120];Jr=null;wy=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});var Hr,Cd=N(()=>{"use strict";y();Hr={"intent-analyzer":{version:2,placeholders:["themeName","contextData"],template:`You are the Intent Analyzer for vibeSpot, a HubSpot CMS builder that generates pages, email templates, and blog templates.
704
+ ${n}`)}return t.join("")}function Fu(e,t=0){let n=" ".repeat(t),s=e.properties,o=e.required||[];if(!s)return`${n}${JSON.stringify(e)}`;let r=["{"];for(let[i,a]of Object.entries(s)){let l=o.includes(i)?" (required)":"",c=a.type||"any",d=a.description?` \u2014 ${a.description}`:"",u=a.enum?` [${a.enum.join(", ")}]`:"";if(c==="array"&&a.items){let p=a.items.type||"object";r.push(`${n} "${i}": ${c}<${p}>${l}${d}${u}`)}else c==="object"&&a.properties?r.push(`${n} "${i}": ${Fu(a,t+1)}${l}${d}`):r.push(`${n} "${i}": ${c}${l}${d}${u}`)}return r.push(`${n}}`),r.join(`
705
+ `)}function iv(e){let t=e.trim(),n=pt(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let a=s[1].trim(),l=pt(a);if(l&&typeof l=="object")return l;let c=Gs(a);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),r=t.lastIndexOf("}");if(o!==-1&&r>o){let a=t.slice(o,r+1),l=pt(a);if(l&&typeof l=="object")return l;let c=Gs(a);if(c&&typeof c=="object")return c}let i=Gs(t);return i&&typeof i=="object"?i:null}async function av(e,t,n){let{bin:s,args:o}=ov(e,t,n),r=rv(n),i;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];i=await sa(l,r,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=lv(c,d);n.onStatus(u)}},void 0,n.signal)}else i=await Js(s,o,r,n.onChunk,void 0,n.signal);if(!n.structuredOutput)return{type:"text",text:i};let a=iv(i);return a?{type:"structured",data:Vs(a)}:(A.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:i.slice(0,500),outputLength:i.length}),{type:"text",text:i})}function lv(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 Du(e,t,n,s){A.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length});let o=new Date,r=await(async()=>{switch(e){case"anthropic-api":return $u(t,n,s);case"claude-oauth":{let{getValidAccessToken:i}=await Promise.resolve().then(()=>($t(),Ci)),a=await i();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return sv(a,n,s)}case"openai-api":return Ru(t,n,s);case"gemini-api":return Nu(t,n,s);case"langdock-api":{let i=$(),a=i.langdockProvider||"anthropic",l=i.langdockBaseUrl;switch(a){case"openai":case"mistral":{let c=l||Ks[a];return Ru(t,n,s,`${c}/v1/chat/completions`)}case"google":{let c=l||Ks.google;return Nu(t,n,s,`${c}/v1beta/models/${n}:generateContent`)}default:{let c=l||Ks.anthropic;return $u(t,n,s,void 0,void 0,c)}}}default:throw new Error(`Unsupported API engine: ${e}`)}})();return dv(e,n,s,r,o,new Date),r}function dv(e,t,n,s,o,r){Ct({engine:e,model:t,name:n.structuredOutput?.name||"generation",input:{system:n.systemPrompt,messages:n.messages},output:s.type==="structured"?s.data:s.text,usage:s.usage,startTime:o,endTime:r,metadata:{structured:!!n.structuredOutput,systemPromptLength:n.systemPrompt.length,...n.prompt?.source?{promptSource:n.prompt.source}:{}},...n.prompt?{promptName:n.prompt.name,promptVersion:n.prompt.version}:{}})}async function Ne(e,t,n,s){if(s.signal?.aborted)throw new Ie;return cv.has(e)?Du(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}),av(e,n,s))}function ts(e){if(e==="langdock-api"){if(($().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=$();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function zs(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="langdock-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function ns(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Ks,jP,xa,wa,cv,mt=j(()=>{"use strict";y();rr();Sr();te();$t();re();un();Ue();Qn();Ks={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},jP=Ks.anthropic,xa=[10,20,40,60,120];wa=null;cv=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});var Ca,Lu=j(()=>{"use strict";y();Ca={"intent-analyzer":{version:2,placeholders:["themeName","contextData"],template:`You are the Intent Analyzer for vibeSpot, a HubSpot CMS builder that generates pages, email templates, and blog templates.
844
706
 
845
707
  Your job: classify the user's request, determine the content type (page, email, or blog), and plan which modules need work. You do NOT generate module code \u2014 you only plan. Think like a product strategist: read past the literal words to the outcome the user actually wants, then scope the smallest set of changes that delivers it.
846
708
 
@@ -1176,9 +1038,9 @@ Every style/color field you reference in CSS must ship a complete default value.
1176
1038
  - Include smooth scroll behavior in nav click handlers, and respect prefers-reduced-motion
1177
1039
 
1178
1040
  ## metaJson Template
1179
- { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`}}});function Ay(){if(kd!==void 0)return kd;if(Is!==void 0)return Is;try{let e=JSON.parse(P(bn(Ty)));Is=e&&typeof e=="object"&&e.prompts?e:null}catch{Is=null}return Is}function _y(e){let t=new Set;for(let n of e.matchAll(Td))t.add(n[1]);return[...t]}function Ad(e){let t=Hr[e],n=Ay()?.prompts?.[e];if(n&&n.version===t.version&&typeof n.template=="string"){let s=new Set(t.placeholders);if(_y(n.template).every(o=>s.has(o)))return{id:e,version:n.version,source:"langfuse-bundled",template:n.template}}return{id:e,version:t.version,source:"local-fallback",template:t.template}}function $y(e,t,n){let s=new Set(Hr[e].placeholders);return t.replace(Td,(o,i)=>s.has(i)?n[i]??"":o)}function wt(e){let t=Ad(e);return{name:`${ky}${e}`,version:t.version,source:t.source}}function Ft(e,t){return $y(e,Ad(e).template,t)}var ky,Ty,Td,Is,kd,Dt=N(()=>{"use strict";y();oe();Cd();ky="vibespot-stage-",Ty="prompts.bundle.json",Td=/\{\{\s*([a-zA-Z][\w]*)\s*\}\}/g});function _d(e,t,n,s,o){let i=t.length>0?`Current template modules (in page order):
1041
+ { "host_template_types": ["PAGE"], "is_available_for_new_content": true }`}}});function mv(){if(Bu!==void 0)return Bu;if(qs!==void 0)return qs;try{let e=JSON.parse(I(Kt(pv)));qs=e&&typeof e=="object"&&e.prompts?e:null}catch{qs=null}return qs}function gv(e){let t=new Set;for(let n of e.matchAll(Ju))t.add(n[1]);return[...t]}function Hu(e){let t=Ca[e],n=mv()?.prompts?.[e];if(n&&n.version===t.version&&typeof n.template=="string"){let s=new Set(t.placeholders);if(gv(n.template).every(o=>s.has(o)))return{id:e,version:n.version,source:"langfuse-bundled",template:n.template}}return{id:e,version:t.version,source:"local-fallback",template:t.template}}function fv(e,t,n){let s=new Set(Ca[e].placeholders);return t.replace(Ju,(o,r)=>s.has(r)?n[r]??"":o)}function Bt(e){let t=Hu(e);return{name:`${uv}${e}`,version:t.version,source:t.source}}function Jt(e,t){return fv(e,Hu(e).template,t)}var uv,pv,Ju,qs,Bu,Ht=j(()=>{"use strict";y();ae();Lu();uv="vibespot-stage-",pv="prompts.bundle.json",Ju=/\{\{\s*([a-zA-Z][\w]*)\s*\}\}/g});function Uu(e,t,n,s,o){let r=t.length>0?`Current template modules (in page order):
1180
1042
  ${t.map((d,u)=>`${u+1}. ${d}`).join(`
1181
- `)}`:"No modules yet (new page).",r=n.length>0?`
1043
+ `)}`:"No modules yet (new page).",i=n.length>0?`
1182
1044
 
1183
1045
  Module library (reusable from other templates):
1184
1046
  ${n.map(d=>`- ${d.name} (used in: ${d.usedIn.join(", ")})`).join(`
@@ -1193,16 +1055,16 @@ All pages:
1193
1055
  ${o.pages.map(d=>`- ${d.label} (${d.id}, ${d.moduleCount} modules)`).join(`
1194
1056
  `)}
1195
1057
 
1196
- The user's message applies to the current page unless they reference another page by name or say "all pages" / "every page" / "the whole site".`:"",c=`${i}${r}${a}${l}`;return Ft("intent-analyzer",{themeName:e,contextData:c})}var $d,Ed=N(()=>{"use strict";y();Dt();$d={type:"object",properties:{intent:{type:"string",enum:["create","create_site","modify","add","remove","rearrange","style_change","question"]},contentType:{type:"string",enum:["page","email","blog"],description:'Content type: "page" (default), "email" for email templates, or "blog" for blog templates'},affectedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that need changes"},unchangedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that stay as-is"},newModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},position:{type:"number"}},required:["name","description","position"]},description:"New modules to create"},reuseModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},sourceTemplate:{type:"string"},position:{type:"number"}},required:["name","sourceTemplate","position"]},description:"Modules to copy from the library (immutable structure)"},guidesNeeded:{type:"array",items:{type:"string",enum:["design","content","conversion","hubspot_rules","humanify"]}},designSystemChanges:{type:"boolean",description:"True if shared CSS / design system needs regeneration"},answer:{type:"string",description:'For "question" intent only \u2014 the answer to return directly'},pages:{type:"array",items:{type:"object",properties:{id:{type:"string",description:"Kebab-case page ID (e.g. wp-home)"},label:{type:"string",description:"Human-readable page name"},pageType:{type:"string",enum:["landing_page","website_page","blog_post"]},purpose:{type:"string",description:"One-sentence page purpose"},slug:{type:"string",description:"URL path without leading /"}},required:["id","label","pageType","purpose","slug"]},description:'For "create_site" intent \u2014 list of pages to generate'},sharedModules:{type:"array",items:{type:"string"},description:'For "create_site" intent \u2014 module names shared across all pages (e.g. site-header, site-footer)'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function Md(e,t,n,s,o,i,r){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let a=t.modules.map(g=>g.moduleName),l=_d(t.themeName,a,r,t.brandAssets?.themeContext,t.sitePages?{activePageLabel:t.activePageLabel,pages:t.sitePages.map(g=>({id:g.id,label:g.label,moduleCount:g.moduleCount}))}:void 0),c=[],d=t.messages.slice(-6);for(let g of d)if(g.role==="user"||g.role==="assistant"){let h=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:h})}c.push({role:"user",content:e});let u=await te("intent-analyzer",()=>Pe(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:$d,name:"pipeline_plan"},maxTokens:2e3,prompt:wt("intent-analyzer")}));if(u.type!=="structured"){M.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:a,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:g}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],t.contentMode==="email"?m.contentType="email":m.contentType=m.contentType==="email"?"email":"page",M.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:Ey(m)}),m}function Ey(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 Id=N(()=>{"use strict";y();dt();Ed();Dt();le();Be()});function Yo(e,t){let n=[];n.push(Ft("design-system",{themeName:e})),n.push(`
1058
+ The user's message applies to the current page unless they reference another page by name or say "all pages" / "every page" / "the whole site".`:"",c=`${r}${i}${a}${l}`;return Jt("intent-analyzer",{themeName:e,contextData:c})}var Gu,Wu=j(()=>{"use strict";y();Ht();Gu={type:"object",properties:{intent:{type:"string",enum:["create","create_site","modify","add","remove","rearrange","style_change","question"]},contentType:{type:"string",enum:["page","email","blog"],description:'Content type: "page" (default), "email" for email templates, or "blog" for blog templates'},affectedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that need changes"},unchangedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that stay as-is"},newModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},position:{type:"number"}},required:["name","description","position"]},description:"New modules to create"},reuseModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},sourceTemplate:{type:"string"},position:{type:"number"}},required:["name","sourceTemplate","position"]},description:"Modules to copy from the library (immutable structure)"},guidesNeeded:{type:"array",items:{type:"string",enum:["design","content","conversion","hubspot_rules","humanify"]}},designSystemChanges:{type:"boolean",description:"True if shared CSS / design system needs regeneration"},answer:{type:"string",description:'For "question" intent only \u2014 the answer to return directly'},pages:{type:"array",items:{type:"object",properties:{id:{type:"string",description:"Kebab-case page ID (e.g. wp-home)"},label:{type:"string",description:"Human-readable page name"},pageType:{type:"string",enum:["landing_page","website_page","blog_post"]},purpose:{type:"string",description:"One-sentence page purpose"},slug:{type:"string",description:"URL path without leading /"}},required:["id","label","pageType","purpose","slug"]},description:'For "create_site" intent \u2014 list of pages to generate'},sharedModules:{type:"array",items:{type:"string"},description:'For "create_site" intent \u2014 module names shared across all pages (e.g. site-header, site-footer)'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function Ku(e,t,n,s,o,r,i,a){r({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let l=t.modules.map(f=>f.moduleName),c=Uu(t.themeName,l,i,t.brandAssets?.themeContext,t.sitePages?{activePageLabel:t.activePageLabel,pages:t.sitePages.map(f=>({id:f.id,label:f.label,moduleCount:f.moduleCount}))}:void 0),d=[],u=t.messages.slice(-6);for(let f of u)if(f.role==="user"||f.role==="assistant"){let h=f.role==="assistant"&&f.content.length>300?f.content.slice(0,300)+"...":f.content;d.push({role:f.role,content:h})}d.push({role:"user",content:e});let p=await ce("intent-analyzer",()=>Ne(n,s,o,{systemPrompt:c,messages:d,structuredOutput:{schema:Gu,name:"pipeline_plan"},maxTokens:2e3,prompt:Bt("intent-analyzer"),signal:a}));if(p.type!=="structured"){A.warn("intent-analyzer","Did not get structured output, falling back");let f=t.modules.length===0;return{intent:f?"create":"modify",affectedModules:f?[]:l,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:f}}let g=p.data;return g.affectedModules=g.affectedModules||[],g.unchangedModules=g.unchangedModules||[],g.newModules=g.newModules||[],g.newModules=g.newModules.map(f=>({...f,name:He(String(f.name??""))})).filter(f=>f.name.length>0),g.pages&&(g.pages=g.pages.map(f=>({...f,id:He(String(f.id??"")),slug:He(String(f.slug??""))})).filter(f=>f.id.length>0)),g.sharedModules&&(g.sharedModules=g.sharedModules.map(f=>He(String(f??""))).filter(f=>f.length>0)),g.guidesNeeded=g.guidesNeeded||[],t.contentMode==="email"||t.contentMode==="blog"?g.contentType=t.contentMode:g.contentType=g.contentType==="email"||g.contentType==="blog"?g.contentType:"page",A.info("intent-analyzer","Plan",{intent:g.intent,affected:g.affectedModules.length,unchanged:g.unchangedModules.length,new:g.newModules.length,reuse:g.reuseModules?.length||0,designSystem:g.designSystemChanges}),r({type:"agent_decision",step:"analyzing",decision:hv(g)}),g}function hv(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 Vu=j(()=>{"use strict";y();mt();Wu();Ht();re();Ue();wt()});function Ta(e,t){let n=[];n.push(Jt("design-system",{themeName:e})),n.push(`
1197
1059
 
1198
1060
  ## Design Guide
1199
- ${Fd()}`),t?.styleguide&&n.push(`
1061
+ ${ep()}`),t?.styleguide&&n.push(`
1200
1062
 
1201
1063
  ## Brand Style Guide
1202
1064
  ${t.styleguide}`),t?.themeContext&&n.push(`
1203
1065
 
1204
1066
  ## Product Context
1205
- ${t.themeContext}`);let s=t?.brandKit&&(t.brandKit.colors?.primary||t.brandKit.colors?.secondary||t.brandKit.colors?.accent||t.brandKit.fonts?.heading||t.brandKit.fonts?.body);if(s){let o=[],i=t.brandKit;i.colors?.primary&&o.push(`- Primary color: ${i.colors.primary}`),i.colors?.secondary&&o.push(`- Secondary color: ${i.colors.secondary}`),i.colors?.accent&&o.push(`- Accent color: ${i.colors.accent}`),i.fonts?.heading&&o.push(`- Heading font: ${i.fonts.heading}`),i.fonts?.body&&o.push(`- Body font: ${i.fonts.body}`),i.logoUrl&&o.push(`- Logo URL: ${i.logoUrl}`),o.length>0&&n.push(`
1067
+ ${t.themeContext}`);let s=t?.brandKit&&(t.brandKit.colors?.primary||t.brandKit.colors?.secondary||t.brandKit.colors?.accent||t.brandKit.fonts?.heading||t.brandKit.fonts?.body);if(s){let o=[],r=t.brandKit;r.colors?.primary&&o.push(`- Primary color: ${r.colors.primary}`),r.colors?.secondary&&o.push(`- Secondary color: ${r.colors.secondary}`),r.colors?.accent&&o.push(`- Accent color: ${r.colors.accent}`),r.fonts?.heading&&o.push(`- Heading font: ${r.fonts.heading}`),r.fonts?.body&&o.push(`- Body font: ${r.fonts.body}`),r.logoUrl&&o.push(`- Logo URL: ${r.logoUrl}`),o.length>0&&n.push(`
1206
1068
 
1207
1069
  ## Brand Kit \u2014 MANDATORY Design Constraints
1208
1070
  The following brand identity values MUST be used. Do NOT substitute or override them:
@@ -1212,11 +1074,11 @@ ${o.join(`
1212
1074
  ## No Brand Provided \u2014 Follow the Generation Recipe
1213
1075
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1214
1076
 
1215
- ${Od()}`),n.join("")}function Ur(e,t){let n=Yo(e),o=n.indexOf(`
1077
+ ${Qu()}`),n.join("")}function qu(e,t){let n=Ta(e),o=n.indexOf(`
1216
1078
 
1217
1079
  ## Design Guide
1218
- `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Design Guide
1219
- ${Fd()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1080
+ `);if(o===-1)return[{type:"text",text:n}];let r=n.slice(0,o),i=`## Design Guide
1081
+ ${ep()}`,a=[{type:"text",text:r},{type:"text",text:i,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1220
1082
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1221
1083
  ${t.themeContext}`);let c=t?.brandKit&&(t.brandKit.colors?.primary||t.brandKit.colors?.secondary||t.brandKit.colors?.accent||t.brandKit.fonts?.heading||t.brandKit.fonts?.body);if(c){let d=[],u=t.brandKit;u.colors?.primary&&d.push(`- Primary color: ${u.colors.primary}`),u.colors?.secondary&&d.push(`- Secondary color: ${u.colors.secondary}`),u.colors?.accent&&d.push(`- Accent color: ${u.colors.accent}`),u.fonts?.heading&&d.push(`- Heading font: ${u.fonts.heading}`),u.fonts?.body&&d.push(`- Body font: ${u.fonts.body}`),u.logoUrl&&d.push(`- Logo URL: ${u.logoUrl}`),d.length>0&&l.push(`## Brand Kit \u2014 MANDATORY Design Constraints
1222
1084
  The following brand identity values MUST be used. Do NOT substitute or override them:
@@ -1224,13 +1086,13 @@ ${d.join(`
1224
1086
  `)}`)}return!c&&!t?.styleguide&&l.push(`## No Brand Provided \u2014 Follow the Generation Recipe
1225
1087
  No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
1226
1088
 
1227
- ${Od()}`),l.length>0&&a.push({type:"text",text:l.join(`
1089
+ ${Qu()}`),l.length>0&&a.push({type:"text",text:l.join(`
1228
1090
 
1229
- `)}),a}function My(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(`
1230
- `)}function Nd(e,t,n,s){let o=[],i=My(t);return o.push(Ft("module-planner",{themeName:e,cssSummary:i})),(!s||s.includes("content"))&&o.push(`
1091
+ `)}),a}function yv(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(r=>`.${r[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(r=>r[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(r=>r[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(`
1092
+ `)}function Xu(e,t,n,s){let o=[],r=yv(t);return o.push(Jt("module-planner",{themeName:e,cssSummary:r})),(!s||s.includes("content"))&&o.push(`
1231
1093
 
1232
1094
  ## Content & Copywriting Guide
1233
- ${Iy()}`),n?.brandvoice&&o.push(`
1095
+ ${bv()}`),n?.brandvoice&&o.push(`
1234
1096
 
1235
1097
  ## Brand Voice
1236
1098
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1239,7 +1101,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1239
1101
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1240
1102
 
1241
1103
  ## Anti-AI Copy Rules
1242
- ${Py()}`),o.join("")}function Od(){let e=cs(),t=Pd(e,"## 4. Color System","## 5."),n=Pd(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1104
+ ${Sv()}`),o.join("")}function Qu(){let e=No(),t=zu(e,"## 4. Color System","## 5."),n=zu(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
1243
1105
  Read the user's request carefully. What industry? What audience? What mood?
1244
1106
  Map it to ONE of these aesthetic directions \u2014 then commit fully:
1245
1107
 
@@ -1295,7 +1157,7 @@ Before finalizing, ask yourself:
1295
1157
 
1296
1158
  If any answer is "no," go bolder. The user wants personality, not safety.`),s.join(`
1297
1159
 
1298
- `)}function Pd(e,t,n){let s=e.indexOf(t);if(s===-1)return"";let o=e.indexOf(n,s);return o===-1?e.slice(s):e.slice(s,o).trim()}function Fd(){return`### Design Philosophy
1160
+ `)}function zu(e,t,n){let s=e.indexOf(t);if(s===-1)return"";let o=e.indexOf(n,s);return o===-1?e.slice(s):e.slice(s,o).trim()}function ep(){return`### Design Philosophy
1299
1161
  You are a senior UI designer. Every page must look professionally designed, not like AI output.
1300
1162
  Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
1301
1163
 
@@ -1402,7 +1264,7 @@ Include these in shared CSS:
1402
1264
  | All animations same speed | Stagger with increasing delays |
1403
1265
  | Skip hover/focus states | Every interactive element needs feedback |
1404
1266
  | Use \`<br>\` tags for spacing | Use proper margin/padding |
1405
- | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function Iy(){return`### Mandatory Page Sections (generate all)
1267
+ | Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function bv(){return`### Mandatory Page Sections (generate all)
1406
1268
  1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
1407
1269
  2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
1408
1270
  3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
@@ -1490,7 +1352,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
1490
1352
  - Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
1491
1353
  - Keep paragraphs to 2-3 sentences max
1492
1354
  - Aim for 6th-grade reading level
1493
- - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function Py(){return`### Banned Punctuation
1355
+ - Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function Sv(){return`### Banned Punctuation
1494
1356
  - **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
1495
1357
  - **Semicolons**: Feel academic, not conversational. Use periods instead.
1496
1358
  - **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
@@ -1520,12 +1382,12 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
1520
1382
  - Use plain short words: use > utilize, start > commence, help > facilitate
1521
1383
  - Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
1522
1384
  - Front-load the benefit in the first 5 words
1523
- - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Gr,Rd,Dd=N(()=>{"use strict";y();Ke();Dt();Gr={type:"object",properties:{cssVariables:{type:"object",description:"CSS custom property name \u2192 value map. Every var() used in sharedCss must be defined here."},sharedCss:{type:"string",description:"Complete shared CSS file. MUST start with :root {} block defining all cssVariables, followed by reset, typography, layout, components, animations, and responsive styles."},sharedJs:{type:"string",description:"Optional shared JS for scroll animations (IntersectionObserver). Wrap in IIFE. Empty string if not needed."},aesthetic:{type:"string",description:"Brief description of the chosen aesthetic direction (e.g., 'dark luxury with warm gold accents')"}},required:["cssVariables","sharedCss","aesthetic"]};Rd={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module identifier. If this module already exists in the project, use the existing name verbatim. For new modules, use kebab-case (e.g., 'hero', 'pricing-cards')."},description:{type:"string",description:"What this module does"},contentBrief:{type:"string",description:"Specific content: headlines, body copy, stats, CTAs"},layoutNotes:{type:"string",description:"Visual layout approach referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Module names in page display order"},narrative:{type:"string",description:"Brief description of the page story/flow"}},required:["modules","moduleOrder","narrative"]}});function Wr(e){if(!e)return"";let t=[];return e.colors&&(e.colors.primary&&t.push(`- Primary color: ${e.colors.primary}`),e.colors.secondary&&t.push(`- Secondary color: ${e.colors.secondary}`),e.colors.accent&&t.push(`- Accent color: ${e.colors.accent}`)),e.fonts&&(e.fonts.heading&&t.push(`- Heading font: ${e.fonts.heading}`),e.fonts.body&&t.push(`- Body font: ${e.fonts.body}`)),e.logoUrl&&t.push(`- Logo URL: ${e.logoUrl}`),t.length===0?"":`
1385
+ - Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Yu,Zu,tp=j(()=>{"use strict";y();tt();Ht();Yu={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"]};Zu={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module identifier. If this module already exists in the project, use the existing name verbatim. For new modules, use kebab-case (e.g., 'hero', 'pricing-cards')."},description:{type:"string",description:"What this module does"},contentBrief:{type:"string",description:"Specific content: headlines, body copy, stats, CTAs"},layoutNotes:{type:"string",description:"Visual layout approach referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Module names in page display order"},narrative:{type:"string",description:"Brief description of the page story/flow"}},required:["modules","moduleOrder","narrative"]}});function Aa(e){if(!e)return"";let t=[];return e.colors&&(e.colors.primary&&t.push(`- Primary color: ${e.colors.primary}`),e.colors.secondary&&t.push(`- Secondary color: ${e.colors.secondary}`),e.colors.accent&&t.push(`- Accent color: ${e.colors.accent}`)),e.fonts&&(e.fonts.heading&&t.push(`- Heading font: ${e.fonts.heading}`),e.fonts.body&&t.push(`- Body font: ${e.fonts.body}`)),e.logoUrl&&t.push(`- Logo URL: ${e.logoUrl}`),t.length===0?"":`
1524
1386
 
1525
1387
  ## Brand Kit \u2014 MANDATORY Design Constraints
1526
1388
  The following brand identity values MUST be used. Do NOT substitute or override them:
1527
1389
  ${t.join(`
1528
- `)}`}function qo(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1390
+ `)}`}function _a(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
1529
1391
 
1530
1392
  Your job: create a complete set of inline-safe design tokens for an email template. Email clients do NOT support CSS custom properties (var()), external stylesheets, flexbox, grid, or JavaScript. All styling must be inline.
1531
1393
 
@@ -1614,25 +1476,25 @@ Do NOT use: system-ui, -apple-system, Segoe UI, Inter, or any Google Fonts.
1614
1476
  - No external font imports`),n.push(`
1615
1477
 
1616
1478
  ## Email Design Guide
1617
- ${Ld()}`),t?.styleguide&&n.push(`
1479
+ ${rp()}`),t?.styleguide&&n.push(`
1618
1480
 
1619
1481
  ## Brand Style Guide
1620
1482
  ${t.styleguide}`),t?.themeContext&&n.push(`
1621
1483
 
1622
1484
  ## Product Context
1623
- ${t.themeContext}`);let s=Wr(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
1485
+ ${t.themeContext}`);let s=Aa(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
1624
1486
 
1625
1487
  ## No Brand Provided \u2014 Be Creative
1626
- No brand colors or fonts have been set. Invent an original color palette that fits the email's topic and audience. Do NOT fall back to generic grays and blues. Choose web-safe font pairings (heading + body) that match the mood \u2014 vary between serif, sans-serif, and other stacks based on what fits.`),n.join("")}function Kr(e,t){let n=qo(e),o=n.indexOf(`
1488
+ No brand colors or fonts have been set. Invent an original color palette that fits the email's topic and audience. Do NOT fall back to generic grays and blues. Choose web-safe font pairings (heading + body) that match the mood \u2014 vary between serif, sans-serif, and other stacks based on what fits.`),n.join("")}function np(e,t){let n=_a(e),o=n.indexOf(`
1627
1489
 
1628
1490
  ## Email Design Guide
1629
- `);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Email Design Guide
1630
- ${Ld()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1491
+ `);if(o===-1)return[{type:"text",text:n}];let r=n.slice(0,o),i=`## Email Design Guide
1492
+ ${rp()}`,a=[{type:"text",text:r},{type:"text",text:i,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
1631
1493
  ${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
1632
- ${t.themeContext}`);let c=Wr(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1494
+ ${t.themeContext}`);let c=Aa(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
1633
1495
  No brand colors or fonts have been set. Invent an original color palette that fits the email's topic and audience. Do NOT fall back to generic grays and blues. Choose web-safe font pairings (heading + body) that match the mood \u2014 vary between serif, sans-serif, and other stacks based on what fits.`),l.length>0&&a.push({type:"text",text:l.join(`
1634
1496
 
1635
- `)}),a}function jd(e,t,n,s){let o=[],i=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
1497
+ `)}),a}function op(e,t,n,s){let o=[],r=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
1636
1498
  `);o.push(`You are the Email Module Planner for vibeSpot, a HubSpot email template builder.
1637
1499
 
1638
1500
  Your job: plan the modules (sections) for an email template. You define what each section contains and how it should look. You do NOT write module code \u2014 downstream Email Module Developers handle that.
@@ -1644,7 +1506,7 @@ The Design Tokens have already been created. Your module plans MUST reference th
1644
1506
  ## Design Tokens
1645
1507
  These literal values will be used in inline styles by module developers:
1646
1508
 
1647
- ${i}
1509
+ ${r}
1648
1510
 
1649
1511
  ## Email Structure Rules
1650
1512
 
@@ -1691,7 +1553,7 @@ List all module names in display order (top to bottom)
1691
1553
  One sentence describing the email's purpose and flow`),(!s||s.includes("content"))&&o.push(`
1692
1554
 
1693
1555
  ## Email Content Guide
1694
- ${Ny()}`),n?.brandvoice&&o.push(`
1556
+ ${vv()}`),n?.brandvoice&&o.push(`
1695
1557
 
1696
1558
  ## Brand Voice
1697
1559
  ${n.brandvoice}`),n?.themeContext&&o.push(`
@@ -1700,7 +1562,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
1700
1562
  ${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
1701
1563
 
1702
1564
  ## Anti-AI Copy Rules
1703
- ${Ry()}`);let r=Wr(n?.brandKit);return r&&o.push(r),o.join("")}function Ld(){return`### Email Design Philosophy
1565
+ ${xv()}`);let i=Aa(n?.brandKit);return i&&o.push(i),o.join("")}function rp(){return`### Email Design Philosophy
1704
1566
  Design for the inbox, not the browser. Email templates must look clean and professional in Gmail, Outlook, Apple Mail, and Yahoo Mail simultaneously.
1705
1567
 
1706
1568
  ### Color Strategy
@@ -1733,7 +1595,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1733
1595
  - Hero images: 600px wide, 2:1 to 3:1 aspect ratio
1734
1596
  - Always include alt text (images blocked by default in many clients)
1735
1597
  - Use display:block to prevent gaps in Outlook
1736
- - Product images: consistent sizing within a row`}function Ny(){return`### Email Types and Structure
1598
+ - Product images: consistent sizing within a row`}function vv(){return`### Email Types and Structure
1737
1599
 
1738
1600
  **Welcome / Onboarding Email**
1739
1601
  - Warm greeting with first-name personalization
@@ -1779,7 +1641,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1779
1641
  - One idea per paragraph, 2-3 sentences max
1780
1642
  - Use "you" more than "we"
1781
1643
  - Specific > vague: "saves 3 hours/week" beats "saves time"
1782
- - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function Ry(){return`### Email-Specific Anti-AI Rules
1644
+ - CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function xv(){return`### Email-Specific Anti-AI Rules
1783
1645
  - No em dashes (\u2014) in email copy. Period.
1784
1646
  - No "I hope this email finds you well"
1785
1647
  - No "In today's fast-paced world"
@@ -1788,61 +1650,49 @@ Design for the inbox, not the browser. Email templates must look clean and profe
1788
1650
  - One exclamation mark per email maximum
1789
1651
  - Avoid tricolon structures ("Fast, reliable, secure")
1790
1652
  - Write like a colleague, not a press release
1791
- - Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var Vr,Jd=N(()=>{"use strict";y();Vr={type:"object",properties:{cssVariables:{type:"object",description:"Token name \u2192 literal CSS value map. NOT CSS custom properties. These are reference values for inline styles (e.g., 'bg-color': '#f4f4f4', 'font-body': 'Arial, Helvetica, sans-serif')."},sharedCss:{type:"string",description:"MUST be empty string for email templates. Email uses inline styles only."},sharedJs:{type:"string",description:"MUST be empty string for email templates. No JavaScript in email."},aesthetic:{type:"string",description:"Brief description of the chosen email design direction."}},required:["cssVariables","sharedCss","aesthetic"]}});async function Bd(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?qo(n.themeName,n.brandAssets):Yo(n.themeName,n.brandAssets),d=l?a?Kr(n.themeName,n.brandAssets):Ur(n.themeName,n.brandAssets):void 0,u=`## User Request
1792
- ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1793
-
1794
- ## Current Shared CSS (update this)
1795
- \`\`\`css
1796
- ${n.sharedCss}
1797
- \`\`\``);let m=Un(s),g=a?Vr:Gr,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:wt("design-system")}})),f;h.type!=="structured"?(M.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,M.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1798
- ${Object.entries(S).map(([j,J])=>` ${j.startsWith("--")?j:`--${j}`}: ${J};`).join(`
1799
- `)}
1800
- }
1801
-
1802
- ${b}`));let v=Object.keys(S||{}).length,w=a?[`Email design tokens: ${f.aesthetic||"created"} | ${v} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${v} variables, ${b.length} chars CSS`];return r({type:"agent_decision",step:"designing",decision:w.join(`
1803
- `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function Hd(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?qo(n.themeName,n.brandAssets):Yo(n.themeName,n.brandAssets),d=l?a?Kr(n.themeName,n.brandAssets):Ur(n.themeName,n.brandAssets):void 0,u=`## User Request
1804
- ${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
1653
+ - Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var sp,ip=j(()=>{"use strict";y();sp={type:"object",properties:{cssVariables:{type:"object",description:"Token name \u2192 literal CSS value map. NOT CSS custom properties. These are reference values for inline styles (e.g., 'bg-color': '#f4f4f4', 'font-body': 'Arial, Helvetica, sans-serif')."},sharedCss:{type:"string",description:"MUST be empty string for email templates. Email uses inline styles only."},sharedJs:{type:"string",description:"MUST be empty string for email templates. No JavaScript in email."},aesthetic:{type:"string",description:"Brief description of the chosen email design direction."}},required:["cssVariables","sharedCss","aesthetic"]}});function wv(e,t){let n=r=>{let i=String(r??"");return t.has(i)&&ws(i)?i:He(i)},s=e.modules.map(r=>({...r,name:n(r.name)})).filter(r=>r.name.length>0),o=(e.moduleOrder||[]).map(r=>n(r)).filter(r=>r.length>0);return{...e,modules:s,moduleOrder:o}}async function ss(e,t,n,s,o,r,i,a){let l=t.contentType==="email";i({type:"agent_step",step:"designing",label:l?"Creating email design tokens...":"Creating design system..."});let c=s==="anthropic-api"||s==="claude-oauth",d=l?_a(n.themeName,n.brandAssets):Ta(n.themeName,n.brandAssets),u=c?l?np(n.themeName,n.brandAssets):qu(n.themeName,n.brandAssets):void 0,p=`## User Request
1654
+ ${e}`;n.modules.length>0&&t.designSystemChanges&&(p+=`
1805
1655
 
1806
1656
  ## Current Shared CSS (update this)
1807
1657
  \`\`\`css
1808
1658
  ${n.sharedCss}
1809
- \`\`\``);let m=Un(s),g=a?Vr:Gr,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:wt("design-system")}})),f;h.type!=="structured"?(M.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,M.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
1810
- ${Object.entries(S).map(([E,O])=>` ${E.startsWith("--")?E:`--${E}`}: ${O};`).join(`
1659
+ \`\`\``);let g=ts(s),f=l?sp:Yu,h=await ce("design-system",()=>Ne(s,o,r,{systemPrompt:d,systemBlocks:u,messages:[{role:"user",content:p}],structuredOutput:{schema:f,name:"design_system"},maxTokens:16e3,...g>0?{thinkingBudgetTokens:g}:{},...l?{}:{prompt:Bt("design-system")},signal:a})),b;h.type!=="structured"?(A.warn("page-architect","Design system: did not get structured output, using fallback"),b={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(b=h.data,A.info("page-architect","Design system created",{aesthetic:b.aesthetic,varCount:Object.keys(b.cssVariables||{}).length,cssLength:b.sharedCss?.length||0}));let S=l?"":b.sharedCss||"",v=b.cssVariables;!l&&v&&typeof v=="object"&&Object.keys(v).length>0&&(S.includes(":root")||(S=`:root {
1660
+ ${Object.entries(v).map(([V,H])=>` ${V.startsWith("--")?V:`--${V}`}: ${H};`).join(`
1811
1661
  `)}
1812
1662
  }
1813
1663
 
1814
- ${b}`));let v=[],w=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,$=[...new Set((e.match(w)||[]).map(k=>k.trim()))];if($.length>0){let k=$.filter(O=>b.toLowerCase().includes(O.toLowerCase())),E=$.filter(O=>!k.includes(O));E.length>0&&v.push(`Note: ${E.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let j=Object.keys(S||{}).length,J=a?[`Email design tokens: ${f.aesthetic||"created"} | ${j} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${j} variables, ${b.length} chars CSS`,...v];r({type:"agent_decision",step:"designing",decision:J.join(`
1815
- `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let K=a?jd(n.themeName,S||{},n.brandAssets,t.guidesNeeded):Nd(n.themeName,b,n.brandAssets,t.guidesNeeded),H=`## User Request
1816
- ${e}`;if(t.newModules.length>0&&(H+=`
1664
+ ${S}`));let k=[],_=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,M=[...new Set((e.match(_)||[]).map(O=>O.trim()))];if(M.length>0){let O=M.filter(H=>S.toLowerCase().includes(H.toLowerCase())),V=M.filter(H=>!O.includes(H));V.length>0&&k.push(`Note: ${V.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let R=Object.keys(v||{}).length,J=l?[`Email design tokens: ${b.aesthetic||"created"} | ${R} tokens`]:[`Design system: ${b.aesthetic||"created"} | ${R} variables, ${S.length} chars CSS`,...k];return i({type:"agent_decision",step:"designing",decision:J.join(`
1665
+ `)}),i({type:"design_system_ready",sharedCss:S,sharedJs:b.sharedJs||"",aesthetic:b.aesthetic||""}),{...b,sharedCss:S}}async function ap(e,t,n,s,o,r,i,a){let l=await ss(e,t,n,s,o,r,i,a);return wr(e,t,n,l,l.sharedCss,s,o,r,i,a)}async function wr(e,t,n,s,o,r,i,a,l,c){let d=t.contentType==="email",u=s.cssVariables,p=ts(r);l({type:"agent_step",step:"designing",label:"Planning modules..."});let g=d?op(n.themeName,u||{},n.brandAssets,t.guidesNeeded):Xu(n.themeName,o,n.brandAssets,t.guidesNeeded),f=`## User Request
1666
+ ${e}`;if(t.newModules.length>0&&(f+=`
1817
1667
 
1818
1668
  ## Planned Modules
1819
- ${t.newModules.map((k,E)=>`${E+1}. **${k.name}** \u2014 ${k.description}`).join(`
1820
- `)}`),n.modules.length>0){let k=new Set(t.affectedModules),E=n.modules.filter(re=>k.has(re.moduleName)),O=n.modules.filter(re=>!k.has(re.moduleName));E.length>0&&(H+=`
1669
+ ${t.newModules.map((v,k)=>`${k+1}. **${v.name}** \u2014 ${v.description}`).join(`
1670
+ `)}`),n.modules.length>0){let v=new Set(t.affectedModules),k=n.modules.filter(M=>v.has(M.moduleName)),_=n.modules.filter(M=>!v.has(M.moduleName));k.length>0&&(f+=`
1821
1671
 
1822
1672
  ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1823
1673
  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.
1824
- `+E.map(re=>`- \`${re.moduleName}\``).join(`
1825
- `)),O.length>0&&(H+=`
1674
+ `+k.map(M=>`- \`${M.moduleName}\``).join(`
1675
+ `)),_.length>0&&(f+=`
1826
1676
 
1827
1677
  ## Existing Modules to Keep (do not re-plan)
1828
1678
  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).
1829
- `+O.map(re=>`- \`${re.moduleName}\``).join(`
1830
- `))}let X=await te("module-planner",()=>Pe(s,o,i,{systemPrompt:K,messages:[{role:"user",content:H}],structuredOutput:{schema:Rd,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:wt("module-planner")}})),F,T={modules:t.newModules.map(k=>({name:k.name,description:k.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(k=>k.name),narrative:"Page generated from user request"};if(X.type!=="structured")M.warn("page-architect","Module planner: did not get structured output, using fallback"),F=T;else{let k=X.data;Array.isArray(k?.modules)&&k.modules.length>0?(F=k,F.moduleOrder=F.moduleOrder||F.modules.map(E=>E.name),F.narrative=F.narrative||"Page generated from user request"):(M.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:k?Object.keys(k):[]}),F=T),M.info("page-architect","Module plan",{moduleCount:F.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${F.narrative} | ${F.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:F.modules,moduleOrder:F.moduleOrder,narrative:F.narrative}}var Ud=N(()=>{"use strict";y();dt();Dd();Jd();Dt();le();Be()});function Oy(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(`
1831
- `)}function Gd(e,t,n,s,o){let i=Oy(s),r=t.map(d=>`- **${d.label}** (${d.pageType}, slug: "${d.slug}"): ${d.purpose}`).join(`
1679
+ `+_.map(M=>`- \`${M.moduleName}\``).join(`
1680
+ `))}let h=await ce("module-planner",()=>Ne(r,i,a,{systemPrompt:g,messages:[{role:"user",content:f}],structuredOutput:{schema:Zu,name:"module_plan"},maxTokens:8e3,...p>0?{thinkingBudgetTokens:p}:{},...d?{}:{prompt:Bt("module-planner")},signal:c})),b,S={modules:t.newModules.map(v=>({name:v.name,description:v.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(v=>v.name),narrative:"Page generated from user request"};if(h.type!=="structured")A.warn("page-architect","Module planner: did not get structured output, using fallback"),b=S;else{let v=h.data;Array.isArray(v?.modules)&&v.modules.length>0?(b=v,b.moduleOrder=b.moduleOrder||b.modules.map(k=>k.name),b.narrative=b.narrative||"Page generated from user request"):(A.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:v?Object.keys(v):[]}),b=S),A.info("page-architect","Module plan",{moduleCount:b.modules.length})}return b=wv(b,new Set(n.modules.map(v=>v.moduleName))),l({type:"agent_decision",step:"designing",decision:`Page: ${b.narrative} | ${b.modules.length} modules planned`}),{designSystem:{cssVariables:s.cssVariables||{},sharedCss:o,sharedJs:s.sharedJs},modules:b.modules,moduleOrder:b.moduleOrder,narrative:b.narrative}}var lp=j(()=>{"use strict";y();mt();tp();ip();Ht();re();Ue();wt()});function kv(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(r=>`.${r[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(r=>r[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(r=>r[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(`
1681
+ `)}function cp(e,t,n,s,o){let r=kv(s),i=t.map(d=>`- **${d.label}** (${d.pageType}, slug: "${d.slug}"): ${d.purpose}`).join(`
1832
1682
  `),a=n.map(d=>`- **${d}**`).join(`
1833
1683
  `),l=[],c=t.map(d=>` - "${d.label}" \u2192 href="/${d.slug}"`).join(`
1834
- `);return l.push(Ft("site-module-planner",{themeName:e,siteMap:r,sharedList:a,cssSummary:i,navHrefs:c,sharedModuleNamesCsv:n.join(", ")})),o?.brandvoice&&l.push(`
1684
+ `);return l.push(Jt("site-module-planner",{themeName:e,siteMap:i,sharedList:a,cssSummary:r,navHrefs:c,sharedModuleNamesCsv:n.join(", ")})),o?.brandvoice&&l.push(`
1835
1685
 
1836
1686
  ## Brand Voice
1837
1687
  ${o.brandvoice}`),o?.themeContext&&l.push(`
1838
1688
 
1839
1689
  ## Product Context
1840
- ${o.themeContext}`),l.join("")}var Wd,Kd=N(()=>{"use strict";y();Dt();Wd={type:"object",properties:{sharedModules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Shared module identifier (e.g., site-header, site-footer)"},description:{type:"string"},contentBrief:{type:"string",description:"Content for this shared module"},layoutNotes:{type:"string",description:"Layout referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]},description:"Modules shared across all pages (header, footer)"},pages:{type:"array",items:{type:"object",properties:{pageId:{type:"string",description:"Matches the page ID from the site map"},modules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},contentBrief:{type:"string"},layoutNotes:{type:"string"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Per-page module names in display order (excluding shared modules)"}},required:["pageId","modules","moduleOrder"]}},narrative:{type:"string",description:"Brief description of the overall site story and how pages connect"}},required:["sharedModules","pages","narrative"]}});async function zd(e,t,n,s,o,i,r,a){a({type:"agent_step",step:"planning_site",label:`Planning modules for ${t.pages?.length||0} pages...`});let l=t.pages||[],c=t.sharedModules||["site-header","site-footer"],d=Gd(n.themeName,l,c,s,n.brandAssets),u=`## User Request
1690
+ ${o.themeContext}`),l.join("")}var dp,up=j(()=>{"use strict";y();Ht();dp={type:"object",properties:{sharedModules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Shared module identifier (e.g., site-header, site-footer)"},description:{type:"string"},contentBrief:{type:"string",description:"Content for this shared module"},layoutNotes:{type:"string",description:"Layout referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]},description:"Modules shared across all pages (header, footer)"},pages:{type:"array",items:{type:"object",properties:{pageId:{type:"string",description:"Matches the page ID from the site map"},modules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},contentBrief:{type:"string"},layoutNotes:{type:"string"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Per-page module names in display order (excluding shared modules)"}},required:["pageId","modules","moduleOrder"]}},narrative:{type:"string",description:"Brief description of the overall site story and how pages connect"}},required:["sharedModules","pages","narrative"]}});async function mp(e,t,n,s,o,r,i,a,l){a({type:"agent_step",step:"planning_site",label:`Planning modules for ${t.pages?.length||0} pages...`});let c=t.pages||[],d=t.sharedModules||["site-header","site-footer"],u=cp(n.themeName,c,d,s,n.brandAssets),p=`## User Request
1841
1691
  ${e}
1842
1692
 
1843
1693
  ## Site Map
1844
- ${l.map(v=>`- ${v.label} (${v.slug}): ${v.purpose}`).join(`
1845
- `)}`,m=Un(o),g=await te("site-module-planner",()=>Pe(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:Wd,name:"site_module_plan"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},prompt:wt("site-module-planner")}));if(g.type!=="structured")return M.warn("site-planner","Did not get structured output, building fallback"),Vd(t,c,s);let h=g.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return M.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),Vd(t,c,s);let f=h.sharedModules.map(v=>({name:v.name,description:v.description,contentBrief:v.contentBrief,layoutNotes:v.layoutNotes})),b=h.pages.map(v=>({pageId:v.pageId,modules:(v.modules||[]).map(w=>({name:w.name,description:w.description,contentBrief:w.contentBrief,layoutNotes:w.layoutNotes})),moduleOrder:v.moduleOrder||[]})),S=f.length+b.reduce((v,w)=>v+w.modules.length,0);return M.info("site-planner","Site plan complete",{pages:b.length,sharedModules:f.length,totalModules:S}),a({type:"agent_decision",step:"planning_site",decision:`${b.length} pages planned, ${f.length} shared modules, ${S} total modules`}),a({type:"site_blueprint_ready",pages:b.map(v=>{let w=l.find($=>$.id===v.pageId);return{pageId:v.pageId,label:w?.label||v.pageId,moduleCount:v.modules.length}}),sharedModuleCount:f.length}),{designSystem:{cssVariables:{},sharedCss:s},pages:b,sharedModules:f,narrative:h.narrative||"Multi-page site generated from user request"}}function Vd(e,t,n){let s=e.pages||[];return{designSystem:{cssVariables:{},sharedCss:n},pages:s.map(o=>({pageId:o.id,modules:[{name:`${o.slug}-hero`,description:`Hero section for ${o.label}`,contentBrief:`Create a hero for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"},{name:`${o.slug}-content`,description:`Main content for ${o.label}`,contentBrief:`Create main content for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"}],moduleOrder:[`${o.slug}-hero`,`${o.slug}-content`]})),sharedModules:t.map(o=>({name:o,description:`Shared ${o} module`,contentBrief:`Generate ${o} for the site`,layoutNotes:"Use responsive layout matching the design system"})),narrative:"Multi-page site (fallback plan)"}}var Yd=N(()=>{"use strict";y();dt();Kd();Dt();le();Be()});function Xo(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 zr=N(()=>{"use strict";y()});function Ps(e,t,n,s){let o=[];return o.push(Ft("module-developer",{themeName:e})),t&&o.push(`
1694
+ ${c.map(k=>`- ${k.label} (${k.slug}): ${k.purpose}`).join(`
1695
+ `)}`,g=ts(o),f=await ce("site-module-planner",()=>Ne(o,r,i,{systemPrompt:u,messages:[{role:"user",content:p}],structuredOutput:{schema:dp,name:"site_module_plan"},maxTokens:16e3,...g>0?{thinkingBudgetTokens:g}:{},prompt:Bt("site-module-planner"),signal:l}));if(f.type!=="structured")return A.warn("site-planner","Did not get structured output, building fallback"),pp(t,d,s);let h=f.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return A.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),pp(t,d,s);let b=h.sharedModules.map(k=>({name:He(String(k.name??"")),description:k.description,contentBrief:k.contentBrief,layoutNotes:k.layoutNotes})).filter(k=>k.name.length>0),S=h.pages.map(k=>({pageId:He(String(k.pageId??"")),modules:(k.modules||[]).map(_=>({name:He(String(_.name??"")),description:_.description,contentBrief:_.contentBrief,layoutNotes:_.layoutNotes})).filter(_=>_.name.length>0),moduleOrder:(k.moduleOrder||[]).map(_=>He(String(_??""))).filter(_=>_.length>0)})),v=b.length+S.reduce((k,_)=>k+_.modules.length,0);return A.info("site-planner","Site plan complete",{pages:S.length,sharedModules:b.length,totalModules:v}),a({type:"agent_decision",step:"planning_site",decision:`${S.length} pages planned, ${b.length} shared modules, ${v} total modules`}),a({type:"site_blueprint_ready",pages:S.map(k=>{let _=c.find(M=>M.id===k.pageId);return{pageId:k.pageId,label:_?.label||k.pageId,moduleCount:k.modules.length}}),sharedModuleCount:b.length}),{designSystem:{cssVariables:{},sharedCss:s},pages:S,sharedModules:b,narrative:h.narrative||"Multi-page site generated from user request"}}function pp(e,t,n){let s=e.pages||[];return{designSystem:{cssVariables:{},sharedCss:n},pages:s.map(o=>({pageId:o.id,modules:[{name:`${o.slug}-hero`,description:`Hero section for ${o.label}`,contentBrief:`Create a hero for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"},{name:`${o.slug}-content`,description:`Main content for ${o.label}`,contentBrief:`Create main content for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"}],moduleOrder:[`${o.slug}-hero`,`${o.slug}-content`]})),sharedModules:t.map(o=>({name:o,description:`Shared ${o} module`,contentBrief:`Generate ${o} for the site`,layoutNotes:"Use responsive layout matching the design system"})),narrative:"Multi-page site (fallback plan)"}}var gp=j(()=>{"use strict";y();mt();up();Ht();re();Ue();wt()});function Ys(e,t,n,s){let o=[];return o.push(Jt("module-developer",{themeName:e})),t&&o.push(`
1846
1696
 
1847
1697
  ## Theme Shared CSS (use these custom properties)
1848
1698
  \`\`\`css
@@ -1850,29 +1700,29 @@ ${t}
1850
1700
  \`\`\``),(!n||n.includes("hubspot_rules"))&&o.push(`
1851
1701
 
1852
1702
  ## HubSpot CMS Rules
1853
- ${Je()}`),(!n||n.includes("conversion"))&&o.push(`
1703
+ ${et()}`),(!n||n.includes("conversion"))&&o.push(`
1854
1704
 
1855
1705
  ## Conversion Guide
1856
- ${ye()}`),s?.themeContext&&o.push(`
1706
+ ${Ce()}`),s?.themeContext&&o.push(`
1857
1707
 
1858
1708
  ## Product Context
1859
1709
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1860
1710
 
1861
1711
  ## Anti-AI Copy Rules
1862
- ${qd()}`),o.join("")}function Zo(e,t,n,s){let o=[],i=Ps(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
1712
+ ${fp()}`),o.join("")}function kr(e,t,n,s){let o=[],r=Ys(e,"",[],s?{...s,humanify:!1}:void 0);t&&(r+=`
1863
1713
 
1864
1714
  ## Theme Shared CSS (use these custom properties)
1865
1715
  \`\`\`css
1866
1716
  ${t}
1867
- \`\`\``),o.push({type:"text",text:i});let r=[];(!n||n.includes("hubspot_rules"))&&r.push(`## HubSpot CMS Rules
1868
- ${Je()}`),(!n||n.includes("conversion"))&&r.push(`## Conversion Guide
1869
- ${ye()}`),r.length>0&&o.push({type:"text",text:r.join(`
1717
+ \`\`\``),o.push({type:"text",text:r});let i=[];(!n||n.includes("hubspot_rules"))&&i.push(`## HubSpot CMS Rules
1718
+ ${et()}`),(!n||n.includes("conversion"))&&i.push(`## Conversion Guide
1719
+ ${Ce()}`),i.length>0&&o.push({type:"text",text:i.join(`
1870
1720
 
1871
1721
  `),cache_control:{type:"ephemeral"}});let a=[];return s?.themeContext&&a.push(`## Product Context
1872
1722
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&a.push(`## Anti-AI Copy Rules
1873
- ${qd()}`),a.length>0&&o.push({type:"text",text:a.join(`
1723
+ ${fp()}`),a.length>0&&o.push({type:"text",text:a.join(`
1874
1724
 
1875
- `)}),o}function qd(){return`### Banned Punctuation
1725
+ `)}),o}function fp(){return`### Banned Punctuation
1876
1726
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1877
1727
  - **Semicolons**: Use periods instead in marketing copy.
1878
1728
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1911,7 +1761,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1911
1761
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1912
1762
  - Full names, specific roles (not "John D., CEO")
1913
1763
  - Never start with "This product is..." \u2014 start with the person's situation
1914
- - Vary length and voice across testimonials`}function Xd(e,t,n){let s=[];return s.push(`## User Request
1764
+ - Vary length and voice across testimonials`}function hp(e,t,n){let s=[];return s.push(`## User Request
1915
1765
  ${e}`),s.push(`
1916
1766
 
1917
1767
  ## Module Specification
@@ -1938,7 +1788,7 @@ ${n.moduleCss}
1938
1788
  **module.js:**
1939
1789
  \`\`\`js
1940
1790
  ${n.moduleJs}
1941
- \`\`\``)),s.join("")}var Ns,Yr=N(()=>{"use strict";y();Ke();Dt();Ns={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});function qr(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1791
+ \`\`\``)),s.join("")}var Xs,Pa=j(()=>{"use strict";y();tt();Ht();Xs={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});function Ea(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
1942
1792
 
1943
1793
  Your job: generate ONE HubSpot CMS email module. You receive a module specification and must produce the complete module code optimized for email client rendering.
1944
1794
 
@@ -2096,17 +1946,17 @@ Modules that serve as email footers MUST include:
2096
1946
  ${t.themeContext}`),t?.humanify!==!1&&n.push(`
2097
1947
 
2098
1948
  ## Anti-AI Copy Rules
2099
- ${Qd()}`),t?.brandKit){let s=[];t.brandKit.colors&&(t.brandKit.colors.primary&&s.push(`- Primary color: ${t.brandKit.colors.primary}`),t.brandKit.colors.secondary&&s.push(`- Secondary color: ${t.brandKit.colors.secondary}`),t.brandKit.colors.accent&&s.push(`- Accent color: ${t.brandKit.colors.accent}`)),t.brandKit.fonts&&(t.brandKit.fonts.heading&&s.push(`- Heading font: ${t.brandKit.fonts.heading}`),t.brandKit.fonts.body&&s.push(`- Body font: ${t.brandKit.fonts.body}`)),t.brandKit.logoUrl&&s.push(`- Logo URL: ${t.brandKit.logoUrl}`),s.length>0&&n.push(`
1949
+ ${bp()}`),t?.brandKit){let s=[];t.brandKit.colors&&(t.brandKit.colors.primary&&s.push(`- Primary color: ${t.brandKit.colors.primary}`),t.brandKit.colors.secondary&&s.push(`- Secondary color: ${t.brandKit.colors.secondary}`),t.brandKit.colors.accent&&s.push(`- Accent color: ${t.brandKit.colors.accent}`)),t.brandKit.fonts&&(t.brandKit.fonts.heading&&s.push(`- Heading font: ${t.brandKit.fonts.heading}`),t.brandKit.fonts.body&&s.push(`- Body font: ${t.brandKit.fonts.body}`)),t.brandKit.logoUrl&&s.push(`- Logo URL: ${t.brandKit.logoUrl}`),s.length>0&&n.push(`
2100
1950
 
2101
1951
  ## Brand Kit \u2014 MANDATORY Design Constraints
2102
1952
  The following brand identity values MUST be used. Do NOT substitute or override them:
2103
1953
  ${s.join(`
2104
- `)}`)}return n.join("")}function Zd(e,t){let n=[],s=qr(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=Sl()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2105
- ${o}`,cache_control:{type:"ephemeral"}});let i=[];return t?.themeContext&&i.push(`## Product Context
2106
- ${t.themeContext}`),t?.humanify!==!1&&i.push(`## Anti-AI Copy Rules
2107
- ${Qd()}`),i.length>0&&n.push({type:"text",text:i.join(`
1954
+ `)}`)}return n.join("")}function yp(e,t){let n=[],s=Ea(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=cc()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
1955
+ ${o}`,cache_control:{type:"ephemeral"}});let r=[];return t?.themeContext&&r.push(`## Product Context
1956
+ ${t.themeContext}`),t?.humanify!==!1&&r.push(`## Anti-AI Copy Rules
1957
+ ${bp()}`),r.length>0&&n.push({type:"text",text:r.join(`
2108
1958
 
2109
- `)}),n}function Qd(){return`### Banned Punctuation
1959
+ `)}),n}function bp(){return`### Banned Punctuation
2110
1960
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2111
1961
  - **Semicolons**: Use periods instead.
2112
1962
  - **Exclamation marks**: One per email max. Zero ideal for B2B.
@@ -2125,7 +1975,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2125
1975
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2126
1976
  - Use plain words: use > utilize, start > commence, help > facilitate
2127
1977
  - Front-load the benefit in the first 5 words
2128
- - Email subject lines: specific, benefit-first, under 50 chars`}function eu(e,t,n){let s=[];return s.push(`## User Request
1978
+ - Email subject lines: specific, benefit-first, under 50 chars`}function Sp(e,t,n){let s=[];return s.push(`## User Request
2129
1979
  ${e}`),s.push(`
2130
1980
 
2131
1981
  ## Email Module Specification
@@ -2145,7 +1995,7 @@ ${n.fieldsJson}
2145
1995
  **module.html:**
2146
1996
  \`\`\`html
2147
1997
  ${n.moduleHtml}
2148
- \`\`\``),s.join("")}var tu,nu=N(()=>{"use strict";y();Ke();tu={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types: ["EMAIL"]'},moduleHtml:{type:"string",description:"Complete module.html with TABLE-BASED layout and ALL CSS inline. No <style> blocks."},moduleCss:{type:"string",description:"Must be empty string \u2014 all CSS is inline in moduleHtml for email"},moduleJs:{type:"string",description:"Must be empty string \u2014 no JavaScript in email"}},required:["moduleName","fieldsJson","metaJson","moduleHtml"]}});function Xr(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
1998
+ \`\`\``),s.join("")}var vp,xp=j(()=>{"use strict";y();tt();vp={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types: ["EMAIL"]'},moduleHtml:{type:"string",description:"Complete module.html with TABLE-BASED layout and ALL CSS inline. No <style> blocks."},moduleCss:{type:"string",description:"Must be empty string \u2014 all CSS is inline in moduleHtml for email"},moduleJs:{type:"string",description:"Must be empty string \u2014 no JavaScript in email"}},required:["moduleName","fieldsJson","metaJson","moduleHtml"]}});function Ia(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
2149
1999
 
2150
2000
  Your job: generate ONE HubSpot CMS blog module. You receive a module specification and must produce the complete module code optimized for blog templates.
2151
2001
 
@@ -2330,22 +2180,22 @@ The blog post body module wraps \`{{ content.post_body }}\` with reading-optimiz
2330
2180
  ${s.themeContext}`),s?.humanify!==!1&&o.push(`
2331
2181
 
2332
2182
  ## Anti-AI Copy Rules
2333
- ${ou()}`);let i=[];if(n?.includes("conversion"))try{let r=ye();r&&i.push(`## Conversion Guide
2334
- ${r}`)}catch{}if(n?.includes("hubspot_rules"))try{let r=Je();r&&i.push(`## HubSpot Rules
2335
- ${r}`)}catch{}return i.length>0&&o.push(`
2183
+ ${kp()}`);let r=[];if(n?.includes("conversion"))try{let i=Ce();i&&r.push(`## Conversion Guide
2184
+ ${i}`)}catch{}if(n?.includes("hubspot_rules"))try{let i=et();i&&r.push(`## HubSpot Rules
2185
+ ${i}`)}catch{}return r.length>0&&o.push(`
2336
2186
 
2337
- ${i.join(`
2187
+ ${r.join(`
2338
2188
 
2339
- `)}`),o.join("")}function su(e,t,n,s){let o=[],i=Xr(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=vl()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2340
- ${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=ye();c&&a.push(`## Conversion Guide
2341
- ${c}`)}catch{}if(n?.includes("hubspot_rules"))try{let c=Je();c&&a.push(`## HubSpot Rules
2189
+ `)}`),o.join("")}function wp(e,t,n,s){let o=[],r=Ia(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:r});let i;try{i=dc()}catch{i=""}i&&o.push({type:"text",text:`## Blog Template Rules Reference
2190
+ ${i}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=Ce();c&&a.push(`## Conversion Guide
2191
+ ${c}`)}catch{}if(n?.includes("hubspot_rules"))try{let c=et();c&&a.push(`## HubSpot Rules
2342
2192
  ${c}`)}catch{}a.length>0&&o.push({type:"text",text:a.join(`
2343
2193
 
2344
2194
  `),cache_control:{type:"ephemeral"}});let l=[];return s?.themeContext&&l.push(`## Product Context
2345
2195
  ${s.themeContext}`),s?.humanify!==!1&&l.push(`## Anti-AI Copy Rules
2346
- ${ou()}`),l.length>0&&o.push({type:"text",text:l.join(`
2196
+ ${kp()}`),l.length>0&&o.push({type:"text",text:l.join(`
2347
2197
 
2348
- `)}),o}function ou(){return`### Banned Punctuation
2198
+ `)}),o}function kp(){return`### Banned Punctuation
2349
2199
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2350
2200
  - **Semicolons**: Use periods instead.
2351
2201
  - **Exclamation marks**: Maximum one per page. Zero ideal for B2B.
@@ -2364,7 +2214,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2364
2214
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2365
2215
  - Use plain words: use > utilize, start > commence, help > facilitate
2366
2216
  - Front-load the benefit in the first 5 words
2367
- - Blog headlines: specific, benefit-first, no clickbait`}function iu(e,t,n){let s=[];return s.push(`## User Request
2217
+ - Blog headlines: specific, benefit-first, no clickbait`}function Cp(e,t,n){let s=[];return s.push(`## User Request
2368
2218
  ${e}`),s.push(`
2369
2219
 
2370
2220
  ## Blog Module Specification
@@ -2389,36 +2239,142 @@ ${n.moduleHtml}
2389
2239
  **module.css:**
2390
2240
  \`\`\`css
2391
2241
  ${n.moduleCss}
2392
- \`\`\``),s.join("")}var ru,au=N(()=>{"use strict";y();Ke();Ke();ru={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types with "BLOG_POST" and/or "BLOG_LISTING"'},moduleHtml:{type:"string",description:"Complete module.html using HubSpot blog variables where appropriate"},moduleCss:{type:"string",description:"Complete module.css with reading-optimized styles"},moduleJs:{type:"string",description:"Optional module.js (vanilla JS in IIFE) or empty string"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function Rs(e,t,n,s,o,i,r,a,l,c,d,u){let m=u==="email",g=u==="blog",h=m?"email module":g?"blog module":"module";l({type:"agent_step",step:"developing",label:`Generating ${t.length} ${h}${t.length===1?"":"s"}...`});let f=o==="anthropic-api"||o==="claude-oauth",b=m?qr(s,d):g?Xr(s,n,c,d):Ps(s,n,c,d),S=f?m?Zd(s,d):g?su(s,n,c,d):Zo(s,n,c,d):void 0,v=Xo(a),w=t.length,$=m?tu:g?ru:Ns,j=m||g?void 0:wt("module-developer"),J=t.map((H,X)=>v(async()=>{l({type:"module_progress",module:H.name,status:"generating",current:X+1,total:w});let F="";for(let T=0;T<2;T++)try{T>0&&(M.warn("module-developer",`${H.name}: retrying after failure (attempt ${T+1})`),l({type:"module_progress",module:H.name,status:"retrying",current:X+1,total:w}));let k=await lu(e,H,b,o,i,r,0,S,m,$,g,j);return l({type:"module_progress",module:H.name,status:"complete",current:X+1,total:w,moduleFiles:k}),{moduleName:H.name,module:k}}catch(k){F=k instanceof Error?k.message:typeof k=="object"&&k!==null?JSON.stringify(k):String(k),M.error("module-developer",`Failed: ${H.name} (attempt ${T+1})`,{error:F})}return l({type:"module_progress",module:H.name,status:"failed",current:X+1,total:w}),{moduleName:H.name,error:F}}));return(await Promise.allSettled(J)).map(H=>H.status==="fulfilled"?H.value:{moduleName:"unknown",error:H.reason instanceof Error?H.reason.message:String(H.reason)})}async function lu(e,t,n,s,o,i,r=0,a,l=!1,c=Ns,d=!1,u){let m=l?eu(e,t,t.existingCode):d?iu(e,t,t.existingCode):Xd(e,t,t.existingCode),g=await Pe(s,o,i,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:m}],structuredOutput:{schema:c,name:"module_output"},maxTokens:16e3,...u?{prompt:u}:{}});if(g.type!=="structured"){if(r<2)return M.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),lu(e,t,n,s,o,i,r+1,a,l,c,d,u);throw new Error(`Module "${t.name}" failed to produce structured output after ${r+1} attempts`)}let h=g.data,f=typeof h.fieldsJson=="string"?h.fieldsJson:JSON.stringify(h.fieldsJson,null,2),b=typeof h.metaJson=="string"?h.metaJson:JSON.stringify(h.metaJson,null,2);return{moduleName:t.name,fieldsJson:f,metaJson:b,moduleHtml:String(h.moduleHtml||""),moduleCss:l?"":String(h.moduleCss||""),moduleJs:l?void 0:h.moduleJs?String(h.moduleJs):void 0}}var cu=N(()=>{"use strict";y();dt();zr();Yr();nu();au();Dt();le()});function dn(e,t,n,s,o){let i=s==="email",r=s==="blog";return n({type:"agent_step",step:"quality_check",label:i?"Email quality check...":r?"Blog quality check...":"Quality check..."}),e.map(a=>{let l=[],c={...a};c.fieldsJson=du(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=du(c.metaJson,c.moduleName,"metaJson",l,i,r);let d={};c.fieldsJson=Dy(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=jy(c.moduleHtml,d),c.fieldsJson=Ly(c.fieldsJson,c.moduleName,l),i?c=qy(c,l):(c.moduleCss=Jy(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=Hy(c.moduleCss,c.moduleName,t,l),c.moduleHtml=Uy(c.moduleHtml,c.moduleName,t,l),r&&(c=Xy(c,l))),c.moduleHtml=Wy(c.moduleHtml,c.moduleName,l),i||Ky(c,l),c.metaJson=Vy(c.metaJson,c.moduleName,l,i,r),o&&Yy(c,o,l);let u=l.every(m=>m.autoFixed);return l.length>0&&M.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(m=>m.autoFixed).length,unfixed:l.filter(m=>!m.autoFixed).length}),{module:c,issues:l,valid:u}})}function du(e,t,n,s,o=!1,i=!1){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0}):e):ct(e)===null?(s.push({module:t,field:n,message:`Invalid JSON in ${n} \u2014 reset to empty`,autoFixed:!0}),n==="fieldsJson"?"[]":JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0})):e}function Dy(e,t,n,s){let o=e;for(let[i,r]of Fy)new RegExp(`"name"\\s*:\\s*"${i}"`,"g").test(o)&&(n.push({module:t,field:"fieldsJson",message:`"${i}" is a reserved field name \u2192 renamed to "${r}"`,autoFixed:!0}),o=o.replace(new RegExp(`"name"\\s*:\\s*"${i}"`,"g"),`"name": "${r}"`),s[i]=r);return o}function jy(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`module\\.${s}\\b`,"g"),`module.${o}`);return n}function Ly(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 Jy(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 mu(e){return By.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Hy(e,t,n,s){if(!e)return e;let o=n+"-",i=/\.([a-zA-Z][\w-]*)/g,r=new Set,a;for(;(a=i.exec(e))!==null;){let c=a[1];!c.startsWith(o)&&!mu(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${Gy(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==e&&s.push({module:t,field:"moduleCss",message:`${r.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function Uy(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,r=!1,a=e.replace(i,(l,c)=>{let d=/(\{%[-~]?[\s\S]*?[-~]?%\}|\{\{[\s\S]*?\}\})/g,u=c.split(d),m=!1,g=u.map((h,f)=>f%2===1?h:h.split(/(\s+)/).map(b=>/^\s*$/.test(b)?b:b&&!b.startsWith(o)&&!mu(b)&&/^[a-zA-Z][\w-]*$/.test(b)?(m=!0,o+b):b).join("")).join("");return m?(r=!0,`class="${g}"`):l});return r&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),a}function Gy(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Wy(e,t,n){if(!e)return e;let s=e,i=["if","elif","else","endif","for","endfor","set","do","block","endblock","macro","endmacro","call","endcall","filter","endfilter","raw","endraw","include","import","from","extends","print","unless","endunless","is","not","and","or","in"].join("|"),r=new RegExp(`\\b[a-zA-Z][\\w-]*-(${i})\\b(?!-)`,"g"),a=/(\{%[-~]?[\s\S]*?[-~]?%\})/g,l=!1;s=s.replace(a,h=>h.replace(r,(b,S)=>(l=!0,S))),l&&n.push({module:t,field:"moduleHtml",message:"Stripped CSS-class prefix from HubL keywords inside {% %} tags",autoFixed:!0});let c=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,d=[],u;for(;(u=c.exec(s))!==null;){let h=u[1],f=!h.startsWith("end"),b=f?h:h.replace("end","");d.push({tag:h,isOpen:f,baseTag:b,start:u.index,end:u.index+u[0].length})}let m=[],g=[];for(let h=0;h<d.length;h++)if(d[h].isOpen)m.push(h);else{let f=-1;for(let b=m.length-1;b>=0;b--)if(d[m[b]].baseTag===d[h].baseTag){f=b;break}f!==-1?m.splice(f,1):g.push(h)}if(g.length>0){for(let h=g.length-1;h>=0;h--){let f=d[g[h]];s=s.slice(0,f.start)+`<!-- removed orphan {% ${f.tag} %} -->`+s.slice(f.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${g.length} orphan closing tag${g.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(m.length>0){let h=m.map(b=>d[b].baseTag),f=h.reverse().map(b=>`{% end${b} %}`).join(`
2242
+ \`\`\``),s.join("")}var Tp,Ap=j(()=>{"use strict";y();tt();tt();Tp={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types with "BLOG_POST" and/or "BLOG_LISTING"'},moduleHtml:{type:"string",description:"Complete module.html using HubSpot blog variables where appropriate"},moduleCss:{type:"string",description:"Complete module.css with reading-optimized styles"},moduleJs:{type:"string",description:"Optional module.js (vanilla JS in IIFE) or empty string"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function Ma(e,t,n,s,o,r,i,a,l,c,d,u,p){let g=u==="email",f=u==="blog",h=g?"email module":f?"blog module":"module";l({type:"agent_step",step:"developing",label:`Generating ${t.length} ${h}${t.length===1?"":"s"}...`});let b=o==="anthropic-api"||o==="claude-oauth",S=g?Ea(s,d):f?Ia(s,n,c,d):Ys(s,n,c,d),v=b?g?yp(s,d):f?wp(s,n,c,d):kr(s,n,c,d):void 0,k=xr(a,p),_=t.length,M=g?vp:f?Tp:Xs,R=g||f?void 0:Bt("module-developer"),J=t.map((V,H)=>k(async()=>{l({type:"module_progress",module:V.name,status:"generating",current:H+1,total:_});let P="";for(let F=0;F<2;F++){if(p?.aborted)throw new Ie;try{F>0&&(A.warn("module-developer",`${V.name}: retrying after failure (attempt ${F+1})`),l({type:"module_progress",module:V.name,status:"retrying",current:H+1,total:_}));let z=await _p(e,V,S,o,r,i,0,v,g,M,f,R,p);return l({type:"module_progress",module:V.name,status:"complete",current:H+1,total:_,moduleFiles:z}),{moduleName:V.name,module:z}}catch(z){if(Ws(z))throw z instanceof Ie?z:new Ie;P=z instanceof Error?z.message:typeof z=="object"&&z!==null?JSON.stringify(z):String(z),A.error("module-developer",`Failed: ${V.name} (attempt ${F+1})`,{error:P})}}return l({type:"module_progress",module:V.name,status:"failed",current:H+1,total:_}),{moduleName:V.name,error:P}})),O=await Promise.allSettled(J);if(p?.aborted)throw new Ie;return O.map((V,H)=>V.status==="fulfilled"?V.value:{moduleName:t[H].name,error:V.reason instanceof Error?V.reason.message:String(V.reason)})}async function _p(e,t,n,s,o,r,i=0,a,l=!1,c=Xs,d=!1,u,p){let g=l?Sp(e,t,t.existingCode):d?Cp(e,t,t.existingCode):hp(e,t,t.existingCode),f=await Ne(s,o,r,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:g}],structuredOutput:{schema:c,name:"module_output"},maxTokens:16e3,...u?{prompt:u}:{},signal:p});if(f.type!=="structured"){if(i<2)return A.warn("module-developer",`${t.name}: no structured output, retry ${i+1}`),_p(e,t,n,s,o,r,i+1,a,l,c,d,u,p);throw new Error(`Module "${t.name}" failed to produce structured output after ${i+1} attempts`)}let h=f.data,b=typeof h.fieldsJson=="string"?h.fieldsJson:JSON.stringify(h.fieldsJson,null,2),S=typeof h.metaJson=="string"?h.metaJson:JSON.stringify(h.metaJson,null,2);return{moduleName:t.name,fieldsJson:b,metaJson:S,moduleHtml:String(h.moduleHtml||""),moduleCss:l?"":String(h.moduleCss||""),moduleJs:l?void 0:h.moduleJs?String(h.moduleJs):void 0}}var Pp=j(()=>{"use strict";y();mt();Qn();Pa();xp();Ap();Ht();re()});function Zs(e,t,n,s,o){let r=s==="email",i=s==="blog";return n({type:"agent_step",step:"quality_check",label:r?"Email quality check...":i?"Blog quality check...":"Quality check..."}),e.map(a=>{let l=[],c={...a};c.fieldsJson=Ep(c.fieldsJson,c.moduleName,"fieldsJson",l,r),c.metaJson=Ep(c.metaJson,c.moduleName,"metaJson",l,r,i);let d={};c.fieldsJson=Tv(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=Av(c.moduleHtml,d),c.fieldsJson=_v(c.fieldsJson,c.moduleName,l),r?c=jv(c,l):(c.moduleCss=Pv(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=Iv(c.moduleCss,c.moduleName,t,l),c.moduleHtml=Mv(c.moduleHtml,c.moduleName,t,l),i&&(c=Lv(c,l))),c.moduleHtml=Rv(c.moduleHtml,c.moduleName,l),r||Nv(c,l),c.metaJson=Ov(c.metaJson,c.moduleName,l,r,i),o&&Dv(c,o,l);let u=l.every(p=>p.autoFixed);return l.length>0&&A.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(p=>p.autoFixed).length,unfixed:l.filter(p=>!p.autoFixed).length}),{module:c,issues:l,valid:u}})}function Ep(e,t,n,s,o=!1,r=!1){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:[o?"EMAIL":r?"BLOG_POST":"PAGE"],is_available_for_new_content:!0}):e):pt(e)===null?(s.push({module:t,field:n,message:`Invalid JSON in ${n} \u2014 reset to empty`,autoFixed:!0}),n==="fieldsJson"?"[]":JSON.stringify({host_template_types:[o?"EMAIL":r?"BLOG_POST":"PAGE"],is_available_for_new_content:!0})):e}function Tv(e,t,n,s){let o=e;for(let[r,i]of Cv)new RegExp(`"name"\\s*:\\s*"${r}"`,"g").test(o)&&(n.push({module:t,field:"fieldsJson",message:`"${r}" is a reserved field name \u2192 renamed to "${i}"`,autoFixed:!0}),o=o.replace(new RegExp(`"name"\\s*:\\s*"${r}"`,"g"),`"name": "${i}"`),s[r]=i);return o}function Av(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`module\\.${s}\\b`,"g"),`module.${o}`);return n}function _v(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 Pv(e,t,n,s){if(!e)return e;let o=e,r=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return r.test(o)&&(s.push({module:t,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(r,"/* CDN import removed */")),o}function Mp(e){return Ev.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Iv(e,t,n,s){if(!e)return e;let o=n+"-",r=/\.([a-zA-Z][\w-]*)/g,i=new Set,a;for(;(a=r.exec(e))!==null;){let c=a[1];!c.startsWith(o)&&!Mp(c)&&i.add(c)}if(i.size<=3)return e;let l=e;for(let c of i){let d=new RegExp(`\\.${$v(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==e&&s.push({module:t,field:"moduleCss",message:`${i.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function Mv(e,t,n,s){if(!e)return e;let o=n+"-",r=/class="([^"]*)"/g,i=!1,a=e.replace(r,(l,c)=>{let d=/(\{%[-~]?[\s\S]*?[-~]?%\}|\{\{[\s\S]*?\}\})/g,u=c.split(d),p=!1,g=u.map((f,h)=>h%2===1?f:f.split(/(\s+)/).map(b=>/^\s*$/.test(b)?b:b&&!b.startsWith(o)&&!Mp(b)&&/^[a-zA-Z][\w-]*$/.test(b)?(p=!0,o+b):b).join("")).join("");return p?(i=!0,`class="${g}"`):l});return i&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),a}function $v(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Rv(e,t,n){if(!e)return e;let s=e,r=["if","elif","else","endif","for","endfor","set","do","block","endblock","macro","endmacro","call","endcall","filter","endfilter","raw","endraw","include","import","from","extends","print","unless","endunless","is","not","and","or","in"].join("|"),i=new RegExp(`\\b[a-zA-Z][\\w-]*-(${r})\\b(?!-)`,"g"),a=/(\{%[-~]?[\s\S]*?[-~]?%\})/g,l=!1;s=s.replace(a,f=>f.replace(i,(b,S)=>(l=!0,S))),l&&n.push({module:t,field:"moduleHtml",message:"Stripped CSS-class prefix from HubL keywords inside {% %} tags",autoFixed:!0});let c=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,d=[],u;for(;(u=c.exec(s))!==null;){let f=u[1],h=!f.startsWith("end"),b=h?f:f.replace("end","");d.push({tag:f,isOpen:h,baseTag:b,start:u.index,end:u.index+u[0].length})}let p=[],g=[];for(let f=0;f<d.length;f++)if(d[f].isOpen)p.push(f);else{let h=-1;for(let b=p.length-1;b>=0;b--)if(d[p[b]].baseTag===d[f].baseTag){h=b;break}h!==-1?p.splice(h,1):g.push(f)}if(g.length>0){for(let f=g.length-1;f>=0;f--){let h=d[g[f]];s=s.slice(0,h.start)+`<!-- removed orphan {% ${h.tag} %} -->`+s.slice(h.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${g.length} orphan closing tag${g.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(p.length>0){let f=p.map(b=>d[b].baseTag),h=f.reverse().map(b=>`{% end${b} %}`).join(`
2393
2243
  `);s=`${s}
2394
- ${f}`,n.push({module:t,field:"moduleHtml",message:`Added ${h.length} missing closing tag${h.length===1?"":"s"}: ${h.map(b=>`{% end${b} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:t,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function uu(e){if(!e)return[];let t=[],n=/\b(rgba?|hsla?)\(([^()]*)\)/gi,s;for(;(s=n.exec(e))!==null;){let o=s[2];(o.trim()===""||o.split(",").some(i=>i.trim()===""))&&t.push(s[0].trim())}return t}function Ky(e,t){let n=ct(e.fieldsJson),s=Array.isArray(n)?ln(n):{},o=e.moduleHtml||"";try{o=Ln(e.moduleHtml||"",{module:s})}catch{}let i=[...uu(o),...uu(e.moduleCss||"")];if(i.length===0)return;let r=i[0].length>60?i[0].slice(0,57)+"\u2026":i[0];t.push({module:e.moduleName,field:"moduleCss",message:`${i.length} invalid CSS color value${i.length===1?"":"s"} (e.g. \`${r}\`) \u2014 renders unstyled. A style field with no default is likely fed into rgba()/hsla().`,autoFixed:!1,code:"invalid-css"})}function Vy(e,t,n,s=!1,o=!1){let i=ct(e);if(!i||typeof i!="object")return e;let r=i,a=!1;if(r.host_template_types){if(s)r.host_template_types.includes("EMAIL")||(r.host_template_types=["EMAIL"],a=!0,n.push({module:t,field:"metaJson",message:'Fixed host_template_types to ["EMAIL"] for email module',autoFixed:!0}));else if(o){let l=r.host_template_types;l.includes("BLOG_POST")||l.includes("BLOG_LISTING")||(r.host_template_types=["BLOG_POST"],a=!0,n.push({module:t,field:"metaJson",message:"Fixed host_template_types to include blog type for blog module",autoFixed:!0}))}}else{let l=s?"EMAIL":o?"BLOG_POST":"PAGE";r.host_template_types=[l],a=!0}return r.is_available_for_new_content===void 0&&(r.is_available_for_new_content=!0,a=!0),a?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(r,null,2)):e}function pu(e,t){let n=[],s=new Set(t.map(o=>`/${o}`));for(let o of e){if(!o.moduleName.includes("header")&&!o.moduleName.includes("nav")&&!o.moduleName.includes("footer"))continue;let i=/href=["'](\/?[a-z0-9][a-z0-9-]*(?:\/[a-z0-9-]*)*)["']/gi,r,a=[];for(;(r=i.exec(o.moduleHtml))!==null;){let l=r[1];l.startsWith("/")||(l="/"+l),!(l==="/"||l.startsWith("/http")||l.startsWith("/#"))&&a.push(l)}for(let l of a)s.has(l)||n.push({module:o.moduleName,message:`Nav link "${l}" does not match any page slug (valid: ${t.map(c=>"/"+c).join(", ")})`,autoFixed:!1})}return n}function Yy(e,t,n){let s=new Set;if(t.colors?.primary&&s.add(t.colors.primary.toLowerCase()),t.colors?.secondary&&s.add(t.colors.secondary.toLowerCase()),t.colors?.accent&&s.add(t.colors.accent.toLowerCase()),s.size===0&&!t.fonts?.heading&&!t.fonts?.body)return;let o=(e.moduleHtml||"")+(e.moduleCss||"");if(s.size>0){let i=new Set;for(let a of o.matchAll(zy))i.add(a[0].toLowerCase());let r=new Set(["#ffffff","#000000","#f4f4f4","#f5f5f5","#fafafa","#eeeeee","#e0e0e0","#dddddd","#cccccc","#999999","#666666","#333333","#1a1a1a","#111111","#222222","#444444","#555555","#777777","#888888","#aaaaaa","#bbbbbb"]);for(let a of i)if(!r.has(a)&&!s.has(a)){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand color ${a} (brand colors: ${[...s].join(", ")})`,autoFixed:!1});break}}if(t.fonts?.heading||t.fonts?.body){let i=[];t.fonts.heading&&i.push(t.fonts.heading.toLowerCase()),t.fonts.body&&i.push(t.fonts.body.toLowerCase());let r=/font-family:\s*([^;}"]+)/gi;for(let a of o.matchAll(r)){let l=a[1].toLowerCase().trim();if(!i.some(c=>l.includes(c))){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand font "${a[1].trim()}" (brand fonts: ${i.join(", ")})`,autoFixed:!1});break}}}}function qy(e,t){let n={...e},s=n.moduleHtml;n.moduleCss&&n.moduleCss.trim()&&(t.push({module:e.moduleName,field:"moduleCss",message:"Cleared moduleCss \u2014 email modules must use inline styles only",autoFixed:!0}),n.moduleCss=""),n.moduleJs&&n.moduleJs.trim()&&(t.push({module:e.moduleName,field:"moduleJs",message:"Cleared moduleJs \u2014 email clients do not support JavaScript",autoFixed:!0}),n.moduleJs=void 0),/<style[\s>]/i.test(s)&&(s=s.replace(/<style[^>]*>[\s\S]*?<\/style>/gi,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed <style> blocks \u2014 email clients strip them",autoFixed:!0})),/display\s*:\s*flex/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:flex \u2014 not supported in email clients",autoFixed:!1}),/display\s*:\s*grid/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:grid \u2014 not supported in email clients",autoFixed:!1}),/var\s*\(/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains var() \u2014 CSS custom properties not supported in email",autoFixed:!1});let o=/\{[{%].*?(?:require_css|require_js|scope_css|get_asset_url)\s*\(.*?\}[}%]/g;o.test(s)&&(s=s.replace(o,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed banned HubL functions for email (require_css, require_js, scope_css, get_asset_url)",autoFixed:!0}));let i=/<link[^>]*href="https?:\/\/[^"]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^"]*"[^>]*\/?>/gi;return i.test(s)&&(s=s.replace(i,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed CDN <link> tags \u2014 external resources not supported in email",autoFixed:!0})),n.moduleHtml=s,n}function Xy(e,t){let n={...e},s=n.moduleHtml;return/\{\{[\s]*content\.body[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.body[\s]*\}\}/g,"{{ content.post_body }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.body \u2192 content.post_body (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.title[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.title[\s]*\}\}/g,"{{ content.name }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.title \u2192 content.name (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.author_name[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.author_name[\s]*\}\}/g,"{{ content.blog_post_author }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.author_name \u2192 content.blog_post_author",autoFixed:!0})),/\{\{[\s]*content\.date[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.date[\s]*\}\}/g,"{{ content.publish_date }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.date \u2192 content.publish_date",autoFixed:!0})),/\{\{[\s]*content\.image[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.image[\s]*\}\}/g,"{{ content.featured_image }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.image \u2192 content.featured_image",autoFixed:!0})),/\{%.*dnd_area.*%\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains dnd_area \u2014 blog templates typically use fixed module positions",autoFixed:!1}),/\{\{[\s]*content\.publish_date[\s]*\}\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"publish_date used without |datetimeformat filter \u2014 dates may render as raw timestamps",autoFixed:!1}),n.moduleHtml=s,n}var Fy,By,zy,Zr=N(()=>{"use strict";y();Ko();le();vr();Fy=[["name","item_name"],["label","section_label"],["body","body_text"]];By=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);zy=/#[0-9a-fA-F]{6}\b/g});import{execSync as Zy}from"child_process";async function gu(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(Gn(n)){let T={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(T)try{Zy(`command -v ${T}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${T}" to be installed and on your PATH.`)}}let d=await Md(e,t,n,s,o,r,a);if(d.intent==="question"&&d.answer){let F=Date.now()-l;return r({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}}}if(d.intent==="create_site"&&d.pages&&d.pages.length>0)return Qy(e,d,t,n,s,o,i,r,l);let u=null,m=t.sharedCss,g=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Hd(e,d,t,n,s,o,r),d.contentType!=="email"&&(m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g),r({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let f=[];if(u)for(let F of u.modules)f.push({name:F.name,description:F.description,contentBrief:F.contentBrief,layoutNotes:F.layoutNotes});else{for(let F of d.newModules)f.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 T=t.modules.find(k=>k.moduleName===F);T&&f.push({name:F,description:`Modify existing module: ${F}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:T})}}let b=[],S=[];if(f.length>0){let F=await te("module-development",()=>Rs(e,f,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:f.length}});for(let T of F)T.module?b.push(T.module):S.push(T.moduleName)}let v=null;if(b.length>0){v=dn(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit);let F=v.filter(k=>k.issues.some(E=>E.field==="fieldsJson"&&E.message.includes("reset to empty"))).map(k=>k.module.moduleName);if(F.length>0){let k=F.map(E=>f.find(O=>O.name===E)).filter(E=>E!=null);if(k.length>0){M.info("pipeline",`Retrying ${k.length} module(s) with broken fieldsJson: ${k.map(O=>O.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${k.length} module(s) with invalid fields JSON...`});let E=await te("module-development-retry",()=>Rs(e,k,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:k.length}});for(let O of E)if(O.module){let re=b.findIndex(_e=>_e.moduleName===O.moduleName);re>=0&&(b[re]=O.module)}v=dn(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit)}}b=v.map(k=>k.module);let T=v.reduce((k,E)=>k+E.issues.length,0);if(T>0){let k=v.reduce((O,re)=>O+re.issues.filter(_e=>_e.autoFixed).length,0);M.info("pipeline",`Quality check: ${T} issues, ${k} auto-fixed`);let E=v.flatMap(O=>O.issues).map(O=>`${O.autoFixed?"\u2713":"\u26A0"} ${O.module}: ${O.message}`).join(`
2395
- `);r({type:"agent_decision",step:"quality_check",decision:`${T} issues found, ${k} auto-fixed
2396
- ${E}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let w=tb(t,d,b,u,a),$=nb(t,d,u,w);if(u?.moduleOrder?.length){let F=new Set(u.moduleOrder),T=w.filter(k=>!F.has(k.moduleName)).map(k=>k.moduleName);T.length>0&&r({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${T.length} module${T.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${T.join(", ")}`})}let j=Date.now()-l,J=b.length,K=d.unchangedModules.length,H=v?v.flatMap(F=>F.issues):[],X=sb(d,J,K,S,j,u,H);return S.length>0?r({type:"pipeline_partial",succeeded:b.map(F=>F.moduleName),failed:S,durationMs:j}):r({type:"pipeline_complete",modulesGenerated:J,modulesUnchanged:K,durationMs:j,assistantMessage:X}),{modules:w,moduleOrder:$,sharedCss:m,sharedJs:g,assistantMessage:X,contentType:d.contentType,stats:{modulesGenerated:J,modulesUnchanged:K,modulesFailed:S.length,durationMs:j}}}async function Qy(e,t,n,s,o,i,r,a,l){let c=t.pages,d=t.sharedModules||["site-header","site-footer"],u=await Bd(e,t,n,s,o,i,a),m=u.sharedCss||n.sharedCss,g=u.sharedJs||n.sharedJs;a({type:"blueprint_ready",moduleOrder:d,sharedCss:m,sharedJs:g});let h=await zd(e,t,n,m,s,o,i,a);a({type:"agent_step",step:"developing",label:`Generating modules for ${c.length} pages...`});let f=[];for(let E of h.sharedModules)f.push({...E});for(let E of h.pages)for(let O of E.modules)f.push({name:O.name,description:O.description,contentBrief:O.contentBrief,layoutNotes:O.layoutNotes});let b=c.map(E=>`- "${E.label}" \u2192 /${E.slug}`).join(`
2397
- `);for(let E of f)(E.name.includes("header")||E.name.includes("nav"))&&(E.layoutNotes+=`
2244
+ ${h}`,n.push({module:t,field:"moduleHtml",message:`Added ${f.length} missing closing tag${f.length===1?"":"s"}: ${f.map(b=>`{% end${b} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:t,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function Ip(e){if(!e)return[];let t=[],n=/\b(rgba?|hsla?)\(([^()]*)\)/gi,s;for(;(s=n.exec(e))!==null;){let o=s[2];(o.trim()===""||o.split(",").some(r=>r.trim()===""))&&t.push(s[0].trim())}return t}function Nv(e,t){let n=pt(e.fieldsJson),s=Array.isArray(n)?fn(n):{},o=e.moduleHtml||"";try{o=Yn(e.moduleHtml||"",{module:s})}catch{}let r=[...Ip(o),...Ip(e.moduleCss||"")];if(r.length===0)return;let i=r[0].length>60?r[0].slice(0,57)+"\u2026":r[0];t.push({module:e.moduleName,field:"moduleCss",message:`${r.length} invalid CSS color value${r.length===1?"":"s"} (e.g. \`${i}\`) \u2014 renders unstyled. A style field with no default is likely fed into rgba()/hsla().`,autoFixed:!1,code:"invalid-css"})}function Ov(e,t,n,s=!1,o=!1){let r=pt(e);if(!r||typeof r!="object")return e;let i=r,a=!1;if(i.host_template_types){if(s)i.host_template_types.includes("EMAIL")||(i.host_template_types=["EMAIL"],a=!0,n.push({module:t,field:"metaJson",message:'Fixed host_template_types to ["EMAIL"] for email module',autoFixed:!0}));else if(o){let l=i.host_template_types;l.includes("BLOG_POST")||l.includes("BLOG_LISTING")||(i.host_template_types=["BLOG_POST"],a=!0,n.push({module:t,field:"metaJson",message:"Fixed host_template_types to include blog type for blog module",autoFixed:!0}))}}else{let l=s?"EMAIL":o?"BLOG_POST":"PAGE";i.host_template_types=[l],a=!0}return i.is_available_for_new_content===void 0&&(i.is_available_for_new_content=!0,a=!0),a?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(i,null,2)):e}function $p(e,t){let n=[],s=new Set(t.map(o=>`/${o}`));for(let o of e){if(!o.moduleName.includes("header")&&!o.moduleName.includes("nav")&&!o.moduleName.includes("footer"))continue;let r=/href=["'](\/?[a-z0-9][a-z0-9-]*(?:\/[a-z0-9-]*)*)["']/gi,i,a=[];for(;(i=r.exec(o.moduleHtml))!==null;){let l=i[1];l.startsWith("/")||(l="/"+l),!(l==="/"||l.startsWith("/http")||l.startsWith("/#"))&&a.push(l)}for(let l of a)s.has(l)||n.push({module:o.moduleName,message:`Nav link "${l}" does not match any page slug (valid: ${t.map(c=>"/"+c).join(", ")})`,autoFixed:!1})}return n}function Dv(e,t,n){let s=new Set;if(t.colors?.primary&&s.add(t.colors.primary.toLowerCase()),t.colors?.secondary&&s.add(t.colors.secondary.toLowerCase()),t.colors?.accent&&s.add(t.colors.accent.toLowerCase()),s.size===0&&!t.fonts?.heading&&!t.fonts?.body)return;let o=(e.moduleHtml||"")+(e.moduleCss||"");if(s.size>0){let r=new Set;for(let a of o.matchAll(Fv))r.add(a[0].toLowerCase());let i=new Set(["#ffffff","#000000","#f4f4f4","#f5f5f5","#fafafa","#eeeeee","#e0e0e0","#dddddd","#cccccc","#999999","#666666","#333333","#1a1a1a","#111111","#222222","#444444","#555555","#777777","#888888","#aaaaaa","#bbbbbb"]);for(let a of r)if(!i.has(a)&&!s.has(a)){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand color ${a} (brand colors: ${[...s].join(", ")})`,autoFixed:!1});break}}if(t.fonts?.heading||t.fonts?.body){let r=[];t.fonts.heading&&r.push(t.fonts.heading.toLowerCase()),t.fonts.body&&r.push(t.fonts.body.toLowerCase());let i=/font-family:\s*([^;}"]+)/gi;for(let a of o.matchAll(i)){let l=a[1].toLowerCase().trim();if(!r.some(c=>l.includes(c))){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand font "${a[1].trim()}" (brand fonts: ${r.join(", ")})`,autoFixed:!1});break}}}}function jv(e,t){let n={...e},s=n.moduleHtml;n.moduleCss&&n.moduleCss.trim()&&(t.push({module:e.moduleName,field:"moduleCss",message:"Cleared moduleCss \u2014 email modules must use inline styles only",autoFixed:!0}),n.moduleCss=""),n.moduleJs&&n.moduleJs.trim()&&(t.push({module:e.moduleName,field:"moduleJs",message:"Cleared moduleJs \u2014 email clients do not support JavaScript",autoFixed:!0}),n.moduleJs=void 0),/<style[\s>]/i.test(s)&&(s=s.replace(/<style[^>]*>[\s\S]*?<\/style>/gi,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed <style> blocks \u2014 email clients strip them",autoFixed:!0})),/display\s*:\s*flex/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:flex \u2014 not supported in email clients",autoFixed:!1}),/display\s*:\s*grid/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:grid \u2014 not supported in email clients",autoFixed:!1}),/var\s*\(/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains var() \u2014 CSS custom properties not supported in email",autoFixed:!1});let o=/\{[{%].*?(?:require_css|require_js|scope_css|get_asset_url)\s*\(.*?\}[}%]/g;o.test(s)&&(s=s.replace(o,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed banned HubL functions for email (require_css, require_js, scope_css, get_asset_url)",autoFixed:!0}));let r=/<link[^>]*href="https?:\/\/[^"]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^"]*"[^>]*\/?>/gi;return r.test(s)&&(s=s.replace(r,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed CDN <link> tags \u2014 external resources not supported in email",autoFixed:!0})),n.moduleHtml=s,n}function Lv(e,t){let n={...e},s=n.moduleHtml;return/\{\{[\s]*content\.body[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.body[\s]*\}\}/g,"{{ content.post_body }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.body \u2192 content.post_body (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.title[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.title[\s]*\}\}/g,"{{ content.name }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.title \u2192 content.name (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.author_name[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.author_name[\s]*\}\}/g,"{{ content.blog_post_author }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.author_name \u2192 content.blog_post_author",autoFixed:!0})),/\{\{[\s]*content\.date[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.date[\s]*\}\}/g,"{{ content.publish_date }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.date \u2192 content.publish_date",autoFixed:!0})),/\{\{[\s]*content\.image[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.image[\s]*\}\}/g,"{{ content.featured_image }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.image \u2192 content.featured_image",autoFixed:!0})),/\{%.*dnd_area.*%\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains dnd_area \u2014 blog templates typically use fixed module positions",autoFixed:!1}),/\{\{[\s]*content\.publish_date[\s]*\}\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"publish_date used without |datetimeformat filter \u2014 dates may render as raw timestamps",autoFixed:!1}),n.moduleHtml=s,n}var Cv,Ev,Fv,$a=j(()=>{"use strict";y();Sr();re();ca();Cv=[["name","item_name"],["label","section_label"],["body","body_text"]];Ev=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);Fv=/#[0-9a-fA-F]{6}\b/g});function Bv(e){return e.replace(/^--/,"").replace(/[-_]/g," ").replace(/\b\w/g,t=>t.toUpperCase()).trim()}function Cr(e,t,n){for(let s of t)for(let[o,r]of Object.entries(e))if(o.toLowerCase().includes(s)&&Np.test(String(r).trim()))return String(r).trim();return n}function Rp(e,t,n){for(let s of t)for(let[o,r]of Object.entries(e)){let i=o.toLowerCase();if(i.includes("font")&&i.includes(s)&&String(r).trim())return String(r).trim()}for(let[s,o]of Object.entries(e))if(s.toLowerCase().includes("font")&&String(o).trim())return String(o).trim();return n}function Jv(e){let t=[],n=new Set;for(let[s,o]of Object.entries(e)){let r=String(o).trim();if(!(!Np.test(r)||r.startsWith("var("))&&!n.has(r.toLowerCase())&&(n.add(r.toLowerCase()),t.push({label:Bv(s),value:r}),t.length>=6))break}return t}function bn(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Hv(e,t,n){let s=Cr(e,["background","bg","surface","dark"],"#0f1115"),o=Cr(e,["text","foreground","fg","ink","light"],"#f5f5f7"),r=Cr(e,["primary","brand","accent","cta"],"#e8613a"),i=Cr(e,["on-primary","button-text","light","background"],"#ffffff");return`<!doctype html><html><head><meta charset="utf-8"><style>
2245
+ *{margin:0;box-sizing:border-box}
2246
+ body{font-family:${bn(n)};background:${bn(s)};color:${bn(o)}}
2247
+ .hero{padding:48px 40px;display:flex;flex-direction:column;gap:18px;align-items:flex-start}
2248
+ .eyebrow{font-size:12px;letter-spacing:.12em;text-transform:uppercase;opacity:.7}
2249
+ h1{font-family:${bn(t)};font-size:38px;line-height:1.08;font-weight:700;max-width:14ch}
2250
+ p{font-size:16px;line-height:1.55;opacity:.85;max-width:46ch}
2251
+ .btn{margin-top:6px;display:inline-block;padding:13px 26px;border-radius:8px;
2252
+ background:${bn(r)};color:${bn(i)};font-family:${bn(t)};
2253
+ font-weight:600;font-size:15px;text-decoration:none}
2254
+ </style></head><body>
2255
+ <section class="hero">
2256
+ <span class="eyebrow">Preview</span>
2257
+ <h1>Build pages that feel like your brand.</h1>
2258
+ <p>This is a sample hero rendered from the design system above \u2014 same palette, type, and button style your real modules will use.</p>
2259
+ <a class="btn" href="#">Get started</a>
2260
+ </section>
2261
+ </body></html>`}function Op(e){let t=e.cssVariables||{},n=Jv(t),s=Rp(t,["head","display","title","serif"],"Space Grotesk, system-ui, sans-serif"),o=Rp(t,["body","text","base","sans"],"DM Sans, system-ui, sans-serif"),r=Hv(t,s,o);return{kind:"design",headline:"Here's the look \u2014 approve before I build the page",data:{aesthetic:e.aesthetic||"custom",palette:n,typography:{heading:s,body:o},heroHtml:r}}}function Fp(){return{kind:"brand_intake",headline:"Want me to match your brand, or should I surprise you?",data:{surpriseLabel:"Surprise me",surpriseHint:"I'll invent a design system that fits your request.",bringLabel:"Bring your brand",bringHint:"Paste colors, code, a tone of voice, or point me at a site/theme.",channels:[{key:"colors",label:"Brand colors",placeholder:`Primary #e8613a
2262
+ Ink #0f1115
2263
+ Surface #ffffff`,multiline:!0},{key:"code",label:"Paste CSS or HTML",placeholder:":root { --brand: #e8613a } \u2026",multiline:!0},{key:"voice",label:"Tone of voice",placeholder:"Direct, specific, no buzzword soup",multiline:!0},{key:"siteUrl",label:"Site URL",placeholder:"https://yourbrand.com",multiline:!1},{key:"themePath",label:"HubSpot theme path",placeholder:"/path/to/theme",multiline:!1}]}}}var Np,Dp=j(()=>{"use strict";y();Np=/^(#|rgb|hsl|var\()/i});function Ra(e){return[...new Set(e.map(t=>t.trim()).filter(Boolean))]}function Na(){return{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]}}function jp(e){let t=Na(),n,s=new RegExp(Uv.source,"g");for(;(n=s.exec(e))!==null;){let d=new RegExp(Gv.source,"g"),u;for(;(u=d.exec(n[1]))!==null;){let p=u[1].trim(),g=u[2].trim();p&&g&&!t.cssVariables[p]&&(t.cssVariables[p]=g)}}let o=new Map,r,i=new RegExp(Bp.source,"g");for(;(r=i.exec(e))!==null;){let d=r[0].trim().toLowerCase();["#fff","#ffffff","#000","#000000"].includes(d)||o.set(d,(o.get(d)??0)+1)}t.palette=[...o.entries()].sort((d,u)=>u[1]-d[1]).slice(0,12).map(([d,u])=>({value:d,count:u}));let a=[],l,c=new RegExp(Wv.source,"gi");for(;(l=c.exec(e))!==null;){let d=l[1].split(",")[0].trim().replace(/^["']|["']$/g,"");d&&!d.startsWith("var(")&&a.push(d)}return t.fontFamilies=Ra(a).slice(0,8),t}function Kv(e){let t=Na(),n=e.split(/[\n,]/).map(o=>o.trim()).filter(Boolean),s=0;for(let o of n){let i=new RegExp(Bp.source,"g").exec(o);if(!i)continue;let a=i[0].trim(),l=o.slice(0,i.index).replace(/[:\-–—]+\s*$/,"").trim(),c=l?l.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,""):"",d=c?`--color-${c}`:s===0?"--color-primary":s===1?"--color-secondary":`--color-accent-${s-1}`;t.cssVariables[d]||(t.cssVariables[d]=a,t.palette.push({value:a.toLowerCase(),count:1}),s++)}return t}async function Vv(e){let t=/^https?:\/\//i.test(e)?e:`https://${e}`,n=new AbortController,s=setTimeout(()=>n.abort(),1e4);try{let o=await fetch(t,{signal:n.signal,redirect:"follow",headers:Lp});if(!o.ok)return A.warn("brand-intake",`site fetch ${t} \u2192 HTTP ${o.status}`),"";let r=await o.text(),i="";for(let l of r.matchAll(/<style[^>]*>([\s\S]*?)<\/style>/gi))i+=`
2264
+ ${l[1]}`;for(let l of r.matchAll(/<meta[^>]+name=["']theme-color["'][^>]*>/gi)){let c=/content=["']([^"']+)["']/i.exec(l[0])?.[1];c&&(i+=`
2265
+ --theme-color: ${c};`)}for(let l of r.matchAll(/style=["']([^"']+)["']/gi))i+=`
2266
+ .inline{${l[1]}}`;let a=[];for(let l of r.matchAll(/<link\b[^>]*>/gi)){let c=l[0];if(!/rel=["'][^"']*stylesheet[^"']*["']/i.test(c))continue;let d=/href=["']([^"']+)["']/i.exec(c)?.[1];d&&a.push(d)}for(let l of a.slice(0,6))try{let c=new URL(l.startsWith("//")?`https:${l}`:l,t).toString(),d=await fetch(c,{signal:n.signal,redirect:"follow",headers:Lp});d.ok&&(i+=`
2267
+ ${await d.text()}`)}catch{}return i.trim()||(i=r),i}catch(o){return A.warn("brand-intake",`site fetch failed for ${t}: ${o instanceof Error?o.message:String(o)}`),""}finally{clearTimeout(s)}}function Tr(e,t,n,s){for(let[o,r]of Object.entries(s.cssVariables))e[o]||(e[o]=r);t.push(...s.palette.map(o=>o.value)),n.push(...s.fontFamilies)}async function Jp(e){let t={},n=[],s=[],o=[],r=[];if(e.colors?.trim()){let d=Kv(e.colors);Object.keys(d.cssVariables).length>0&&(Tr(t,n,s,d),o.push("colors"),r.push(`### Brand colors (provided)
2268
+ ${Object.entries(d.cssVariables).map(([u,p])=>`- ${u}: ${p}`).join(`
2269
+ `)}`))}if(e.code?.trim()){let d=jp(e.code);(Object.keys(d.cssVariables).length>0||d.palette.length>0||d.fontFamilies.length>0)&&(Tr(t,n,s,d),o.push("code"),r.push(`### From pasted code
2270
+ - Variables: ${Object.keys(d.cssVariables).length}
2271
+ - Colors: ${d.palette.slice(0,6).map(u=>u.value).join(", ")||"none"}
2272
+ - Fonts: ${d.fontFamilies.join(", ")||"none"}`))}if(e.themePath?.trim())try{let d=Qt(e.themePath.trim());(Object.keys(d.cssVariables).length>0||d.palette.length>0||d.fontFamilies.length>0)&&(Tr(t,n,s,d),o.push("theme"),r.push(`### From imported theme
2273
+ - Variables: ${Object.keys(d.cssVariables).length}
2274
+ - Colors: ${d.palette.slice(0,6).map(u=>u.value).join(", ")||"none"}
2275
+ - Fonts: ${d.fontFamilies.join(", ")||"none"}`))}catch(d){A.warn("brand-intake",`theme token extraction failed: ${d instanceof Error?d.message:String(d)}`)}if(e.siteUrl?.trim()){let d=await Vv(e.siteUrl.trim());if(d){let u=jp(d);(Object.keys(u.cssVariables).length>0||u.palette.length>0||u.fontFamilies.length>0)&&(Tr(t,n,s,u),o.push("site"),r.push(`### From site (${e.siteUrl.trim()})
2276
+ - Colors: ${u.palette.slice(0,6).map(p=>p.value).join(", ")||"none"}
2277
+ - Fonts: ${u.fontFamilies.join(", ")||"none"}`))}}Object.keys(t).length===0&&Ra(n).slice(0,6).forEach((d,u)=>{let p=u===0?"primary":u===1?"secondary":`accent-${u-1}`;t[`--color-${p}`]=d});let i=Ra(s);i[0]&&!Object.keys(t).some(d=>d.includes("font")&&d.includes("head"))&&(t["--font-heading"]=i[0]),i[1]&&!Object.keys(t).some(d=>d.includes("font")&&d.includes("body"))&&(t["--font-body"]=i[1]||i[0]);let a=Object.keys(t).length?gn({...Na(),cssVariables:t}):"",l=e.voice?.trim()||void 0;l&&o.push("voice");let c;if(r.length>0||l){let d=["# Brand intake (user-provided)","Use these EXACT brand tokens as the foundation of the design system. Map the colors and fonts into `:root` variables and build every component style around them \u2014 do not invent a different palette."];r.length&&d.push(r.join(`
2278
+
2279
+ `)),l&&d.push(`### Tone of voice
2280
+ ${l}`),c=d.join(`
2281
+
2282
+ `)}return{cssVariables:t,rootCss:a,styleguide:c,brandvoice:l,channels:o}}var Bp,Uv,Gv,Wv,Lp,Hp=j(()=>{"use strict";y();Os();re();Bp=/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/g,Uv=/:root\s*\{([^}]*)\}/g,Gv=/(--[A-Za-z0-9-_]+)\s*:\s*([^;]+?)\s*(?:;|$)/g,Wv=/font-family\s*:\s*([^;}]+)[;}]/gi;Lp={"User-Agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0 Safari/537.36",Accept:"text/html,application/xhtml+xml,text/css,*/*;q=0.8","Accept-Language":"en-US,en;q=0.9"}});function Up(e){let t=new Map;e.modules.forEach((r,i)=>{t.has(r.name)||t.set(r.name,i)});let n=[],s=new Set;for(let r of e.moduleOrder||[]){let i=t.get(r);if(i==null||s.has(i))continue;s.add(i);let a=e.modules[i];n.push({name:a.name,description:a.description||"",sourceIndex:i})}return e.modules.forEach((r,i)=>{s.has(i)||n.push({name:r.name,description:r.description||"",sourceIndex:i})}),{kind:"structure",headline:"Here's the structure \u2014 reorder, cut, or add sections before I build",data:{narrative:e.narrative||"",modules:n}}}function Gp(e,t){if(!t||t.length===0)return e;let n=[],s=new Set;for(let o of t){let r=o.sourceIndex!=null?e.modules[o.sourceIndex]:void 0,i=He(o.name)||r?.name;i&&(s.has(i)||(s.add(i),r?n.push({name:i,description:o.description??r.description,contentBrief:r.contentBrief,layoutNotes:r.layoutNotes}):n.push({name:i,description:o.description||`User-added section: ${i}`,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use a responsive layout matching the existing design system"})))}return n.length===0?e:{...e,modules:n,moduleOrder:n.map(o=>o.name)}}var Wp=j(()=>{"use strict";y();wt()});import{execSync as zv}from"child_process";function Vp(){return`cp_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function Sn(e){Qs.delete(e)}function zp(){let e=xc();if(!(!e||e.costUsd<=0))return Math.round(e.costUsd*qv*100)/100}async function qp(e,t,n,s,o,r,i,a,l=!1,c){let d=Date.now(),u=r;if(ns(n)){let v={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(v)try{zv(`command -v ${v}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${v}" to be installed and on your PATH.`)}}let p=await Ku(e,t,n,s,o,i,a,c);if(c?.aborted)throw new Ie;if(p.intent==="question"&&p.answer){let S=Date.now()-d;return i({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:S,answer:p.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:p.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:S}}}if(p.intent==="create_site"&&p.pages&&p.pages.length>0)return Qv(e,p,t,n,s,o,r,i,d,c);let g=null,f=t.sharedCss,h=t.sharedJs;if(p.intent==="create"||p.designSystemChanges){if(l&&p.contentType!=="email"){if(p.intent==="create"&&!Yv(t))return Xv({kind:"brand_intake",userMessage:e,plan:p,sharedCss:f,sharedJs:h,startTime:d,libraryModules:a},t,i);let S=await ss(e,p,t,n,s,o,i,c);return Fa({kind:"design",userMessage:e,plan:p,designSystem:S,sharedCss:S.sharedCss,sharedJs:S.sharedJs||h,startTime:d,libraryModules:a},t,i)}g=await ap(e,p,t,n,s,o,i,c),p.contentType!=="email"&&(f=g.designSystem.sharedCss||f,h=g.designSystem.sharedJs||h),i({type:"blueprint_ready",moduleOrder:g.moduleOrder,sharedCss:f,sharedJs:h})}if(c?.aborted)throw new Ie;return Oa(e,p,t,g,f,h,n,s,o,u,i,a,d,c)}function Yp(e,t,n,s,o){let r=Vp();Qs.set(r,t);let i=zp();return o({type:"checkpoint_requested",kind:e,preview:n,...i!=null?{estCostNext:i}:{}}),{modules:[...s.modules],moduleOrder:s.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:"",contentType:t.plan.contentType,stats:{modulesGenerated:0,modulesUnchanged:s.modules.length,modulesFailed:0,durationMs:Date.now()-t.startTime},pendingCheckpoint:{kind:e,resumeToken:r,preview:n,createdAt:new Date().toISOString(),resumeState:t}}}function Fa(e,t,n){if(!e.designSystem)throw new Error("Cannot park at the design checkpoint without a design system.");return Yp("design",e,Op(e.designSystem),t,n)}function Kp(e,t,n){return Yp("structure",e,Up(e.blueprint),t,n)}function Yv(e){return!!(e.brandAssets?.styleguide&&e.brandAssets.styleguide.trim()||e.sharedCss&&e.sharedCss.includes(":root"))}function Xv(e,t,n){let s=Vp();Qs.set(s,e);let o=Fp(),r=zp();return n({type:"checkpoint_requested",kind:"brand_intake",preview:o,...r!=null?{estCostNext:r}:{}}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,assistantMessage:"",contentType:e.plan.contentType,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:Date.now()-e.startTime},pendingCheckpoint:{kind:"brand_intake",resumeToken:s,preview:o,createdAt:new Date().toISOString(),resumeState:e}}}async function Zv(e,t,n,s,o,r,i,a,l){Sn(e);let c=n.action==="approve"?n.brandIntake:void 0,d=s,u,p=null;if(c)if(p=await Jp(c),p.channels.length>0){let h=[s.brandAssets?.styleguide,p.styleguide].filter(b=>b&&b.trim()).join(`
2283
+
2284
+ `);u={...h?{styleguide:h}:{},...p.brandvoice?{brandvoice:p.brandvoice}:{}},d={...s,brandAssets:{...s.brandAssets,...h?{styleguide:h}:{},...p.brandvoice?{brandvoice:p.brandvoice}:{}},sharedCss:p.rootCss||s.sharedCss},a({type:"agent_decision",step:"designing",decision:`Brand intake: using ${p.channels.join(", ")} \u2192 ${Object.keys(p.cssVariables).length} brand token(s)`})}else a({type:"agent_decision",step:"designing",decision:"Brand intake: couldn't extract usable design tokens from what you provided \u2014 generating a design system instead. Try pasting your brand colors or CSS directly."});let g=await ss(t.userMessage,t.plan,d,o,r,i,a,l);p&&Object.keys(p.cssVariables).length>0&&(g.cssVariables={...g.cssVariables||{},...p.cssVariables},p.rootCss&&!g.sharedCss.includes(p.rootCss.trim())&&(g.sharedCss=`${g.sharedCss}
2285
+
2286
+ /* Brand intake overrides (VIB-1878) */
2287
+ ${p.rootCss}`));let f=Fa({kind:"design",userMessage:t.userMessage,plan:t.plan,designSystem:g,sharedCss:g.sharedCss,sharedJs:g.sharedJs||t.sharedJs,startTime:t.startTime,libraryModules:t.libraryModules},s,a);return u&&(f.brandAssetsUpdate=u),f}async function Xp(e,t,n,s,o,r,i,a,l,c){let d=Qs.get(e);if(!d&&c&&(d=c,Qs.set(e,d)),!d)throw new Error("This checkpoint has expired (the server may have restarted). Send your request again to start over.");if(t.action==="cancel")return Sn(e),{modules:[...n.modules],moduleOrder:n.moduleOrder,sharedCss:n.sharedCss,sharedJs:n.sharedJs,assistantMessage:"Cancelled \u2014 nothing was built.",canceled:!0,stats:{modulesGenerated:0,modulesUnchanged:n.modules.length,modulesFailed:0,durationMs:0}};if(d.kind==="brand_intake")return Zv(e,d,t,n,s,o,r,a,l);if(d.kind==="structure"){if(Sn(e),t.action==="steer"){let h=(t.note||"").trim(),b=h?`${d.userMessage}
2288
+
2289
+ ## Structure steer (revise the module plan to honor this)
2290
+ ${h}`:d.userMessage,S=await wr(b,d.plan,n,d.designSystem,d.sharedCss,s,o,r,a,l);return Kp({...d,userMessage:b,blueprint:S},n,a)}let f=Gp(d.blueprint,t.outline);return a({type:"blueprint_ready",moduleOrder:f.moduleOrder,sharedCss:d.sharedCss,sharedJs:d.sharedJs}),Oa(d.userMessage,d.plan,n,f,d.sharedCss,d.sharedJs??"",s,o,r,i,a,d.libraryModules,d.startTime,l)}if(t.action==="steer"){Sn(e);let f=(t.note||"").trim(),h=f?`${d.userMessage}
2291
+
2292
+ ## Design steer (revise the design system to honor this)
2293
+ ${f}`:d.userMessage,b=await ss(h,d.plan,n,s,o,r,a,l);return Fa({...d,userMessage:h,designSystem:b,sharedCss:b.sharedCss,sharedJs:b.sharedJs||d.sharedJs},n,a)}if(Sn(e),!d.designSystem)throw new Error("Checkpoint resume state is missing its design system. Send your request again to start over.");let u=await wr(d.userMessage,d.plan,n,d.designSystem,d.sharedCss,s,o,r,a,l),p=d.plan.contentType!=="email"&&u.designSystem.sharedCss||d.sharedCss,g=d.plan.contentType!=="email"&&u.designSystem.sharedJs||d.sharedJs;return t.action!=="skip"?Kp({kind:"structure",userMessage:d.userMessage,plan:d.plan,designSystem:d.designSystem,blueprint:u,sharedCss:p,sharedJs:g??"",startTime:d.startTime,libraryModules:d.libraryModules},n,a):(a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:p,sharedJs:g}),Oa(d.userMessage,d.plan,n,u,p,g??"",s,o,r,i,a,d.libraryModules,d.startTime,l))}async function Zp(e,t,n,s,o,r,i,a,l,c,d){let u=[],p=[];if(t.length>0){let f=await ce("module-development",()=>Ma(e,t,n,o.themeName,r,i,a,l,c,s.guidesNeeded,o.brandAssets,s.contentType,d),{metadata:{moduleCount:t.length}});for(let h of f)h.module?u.push(h.module):p.push(h.moduleName)}let g=null;if(u.length>0){g=Zs(u,o.themeName,c,s.contentType,o.brandAssets?.brandKit);let f=g.filter(h=>h.issues.some(b=>b.field==="fieldsJson"&&b.message.includes("reset to empty"))).map(h=>h.module.moduleName);if(f.length>0){let h=f.map(b=>t.find(S=>S.name===b)).filter(b=>b!=null);if(h.length>0){A.info("pipeline",`Retrying ${h.length} module(s) with broken fieldsJson: ${h.map(S=>S.name).join(", ")}`),c({type:"agent_decision",step:"quality_check",decision:`Regenerating ${h.length} module(s) with invalid fields JSON...`});let b=await ce("module-development-retry",()=>Ma(e,h,n,o.themeName,r,i,a,l,c,s.guidesNeeded,o.brandAssets,s.contentType,d),{metadata:{moduleCount:h.length}});for(let S of b)if(S.module){let v=u.findIndex(k=>k.moduleName===S.moduleName);v>=0&&(u[v]=S.module)}g=Zs(u,o.themeName,c,s.contentType,o.brandAssets?.brandKit)}}}return{generatedModules:u,failedModules:p,validationResults:g}}async function Oa(e,t,n,s,o,r,i,a,l,c,d,u,p,g){let f=[];if(s)for(let H of s.modules)f.push({name:H.name,description:H.description,contentBrief:H.contentBrief,layoutNotes:H.layoutNotes});else{for(let H of t.newModules)f.push({name:H.name,description:H.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let H of t.affectedModules){let P=n.modules.find(F=>F.moduleName===H);P&&f.push({name:H,description:`Modify existing module: ${H}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:P})}}let h=await Zp(e,f,o,t,n,i,a,l,c,d,g),b=h.generatedModules,S=h.failedModules,v=h.validationResults;if(v){b=v.map(P=>P.module);let H=v.reduce((P,F)=>P+F.issues.length,0);if(H>0){let P=v.reduce((z,L)=>z+L.issues.filter(W=>W.autoFixed).length,0);A.info("pipeline",`Quality check: ${H} issues, ${P} auto-fixed`);let F=v.flatMap(z=>z.issues).map(z=>`${z.autoFixed?"\u2713":"\u26A0"} ${z.module}: ${z.message}`).join(`
2294
+ `);d({type:"agent_decision",step:"quality_check",decision:`${H} issues found, ${P} auto-fixed
2295
+ ${F}`})}else d({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let k=tx(n,t,b,s,u),_=nx(n,t,s,k);if(s?.moduleOrder?.length){let H=new Set(s.moduleOrder),P=k.filter(F=>!H.has(F.moduleName)).map(F=>F.moduleName);P.length>0&&d({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${P.length} module${P.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${P.join(", ")}`})}let M=Date.now()-p,R=b.length,J=t.unchangedModules.length,O=v?v.flatMap(H=>H.issues):[],V=sx(t,R,J,S,M,s,O);return S.length>0?d({type:"pipeline_partial",succeeded:b.map(H=>H.moduleName),failed:S,durationMs:M}):d({type:"pipeline_complete",modulesGenerated:R,modulesUnchanged:J,durationMs:M,assistantMessage:V}),{modules:k,moduleOrder:_,sharedCss:o,sharedJs:r,assistantMessage:V,contentType:t.contentType,stats:{modulesGenerated:R,modulesUnchanged:J,modulesFailed:S.length,durationMs:M}}}async function Qv(e,t,n,s,o,r,i,a,l,c){let d=t.pages,u=t.sharedModules||["site-header","site-footer"],p=await ss(e,t,n,s,o,r,a,c),g=p.sharedCss||n.sharedCss,f=p.sharedJs||n.sharedJs;a({type:"blueprint_ready",moduleOrder:u,sharedCss:g,sharedJs:f});let h=await mp(e,t,n,g,s,o,r,a,c);a({type:"agent_step",step:"developing",label:`Generating modules for ${d.length} pages...`});let b=[];for(let L of h.sharedModules)b.push({...L});for(let L of h.pages)for(let W of L.modules)b.push({name:W.name,description:W.description,contentBrief:W.contentBrief,layoutNotes:W.layoutNotes});let S=d.map(L=>`- "${L.label}" \u2192 /${L.slug}`).join(`
2296
+ `);for(let L of b)(L.name.includes("header")||L.name.includes("nav"))&&(L.layoutNotes+=`
2398
2297
 
2399
2298
  ## Site Navigation
2400
2299
  This is a multi-page site. Include navigation links to all pages:
2401
- ${b}
2402
- Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await te("module-development",()=>Rs(e,f,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:f.length}}),v=[],w=[];for(let E of S)E.module?v.push(E.module):w.push(E.moduleName);let $=v,j=[];if(v.length>0){let E=dn(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit),O=E.filter(z=>z.issues.some(ue=>ue.field==="fieldsJson"&&ue.message.includes("reset to empty"))).map(z=>z.module.moduleName);if(O.length>0){let z=O.map(ue=>f.find(ne=>ne.name===ue)).filter(ue=>ue!=null);if(z.length>0){M.info("pipeline",`Retrying ${z.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${z.length} module(s) with invalid fields JSON...`});let ue=await te("module-development-retry",()=>Rs(e,z,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:z.length}});for(let ne of ue)if(ne.module){let $e=v.findIndex(Ws=>Ws.moduleName===ne.moduleName);$e>=0&&(v[$e]=ne.module)}E=dn(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}$=E.map(z=>z.module),j=E.flatMap(z=>z.issues);let re=pu($,c.map(z=>z.slug));j.push(...re);let _e=j.length;if(_e>0){let z=j.filter(ue=>ue.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${_e} issues found, ${z} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let J=new Map($.map(E=>[E.moduleName,E])),K=h.sharedModules.map(E=>J.get(E.name)).filter(E=>!!E),H=new Map(c.map(E=>[E.id,E])),X=h.pages.map(E=>{let O=E.modules.map(ne=>J.get(ne.name)).filter(ne=>!!ne),re=d.filter(ne=>ne.includes("header")||ne.includes("nav")),_e=d.filter(ne=>ne.includes("footer")),z=[...re,...E.moduleOrder,..._e],ue=H.get(E.pageId);return{pageId:E.pageId,templateId:E.pageId,label:ue?.label||E.pageId,pageType:ue?.pageType||"website_page",modules:[...K,...O],moduleOrder:z}}),F=Date.now()-l,T=eb(c,v.length,w,F,h.narrative,j);return w.length>0?a({type:"pipeline_partial",succeeded:v.map(E=>E.moduleName),failed:w,durationMs:F}):a({type:"pipeline_complete",modulesGenerated:v.length,modulesUnchanged:0,durationMs:F,assistantMessage:T}),{modules:$,moduleOrder:$.map(E=>E.moduleName),sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{modulesGenerated:v.length,modulesUnchanged:0,modulesFailed:w.length,durationMs:F},multiPage:{pages:X,sharedModules:K,sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{pagesGenerated:c.length,modulesGenerated:v.length,modulesFailed:w.length,durationMs:F}}}}function eb(e,t,n,s,o,i){let r=Math.round(s/1e3),a=[];a.push(`Created ${e.length}-page site with ${t} modules in ${r}s.`),a.push(`
2300
+ ${S}
2301
+ Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let v=await Zp(e,b,g,t,n,s,o,r,i,a,c),k=v.generatedModules,_=v.failedModules,M=k,R=[];if(v.validationResults){M=v.validationResults.map(_e=>_e.module),R=v.validationResults.flatMap(_e=>_e.issues);let L=$p(M,d.map(_e=>_e.slug));R.push(...L);let W=R.length;if(W>0){let _e=R.filter(Be=>Be.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${W} issues found, ${_e} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let J=new Map(M.map(L=>[L.moduleName,L])),O=h.sharedModules.map(L=>J.get(L.name)).filter(L=>!!L),V=new Map(d.map(L=>[L.id,L])),H=h.pages.map(L=>{let W=L.modules.map(ie=>J.get(ie.name)).filter(ie=>!!ie),_e=u.filter(ie=>ie.includes("header")||ie.includes("nav")),Be=u.filter(ie=>ie.includes("footer")),yt=[..._e,...L.moduleOrder,...Be],ot=V.get(L.pageId);return{pageId:L.pageId,templateId:L.pageId,label:ot?.label||L.pageId,pageType:ot?.pageType||"website_page",modules:[...O,...W],moduleOrder:yt}}),P=Date.now()-l,F=ex(d,k.length,_,P,h.narrative,R);return _.length>0?a({type:"pipeline_partial",succeeded:k.map(L=>L.moduleName),failed:_,durationMs:P}):a({type:"pipeline_complete",modulesGenerated:k.length,modulesUnchanged:0,durationMs:P,assistantMessage:F}),{modules:M,moduleOrder:M.map(L=>L.moduleName),sharedCss:g,sharedJs:f||"",assistantMessage:F,stats:{modulesGenerated:k.length,modulesUnchanged:0,modulesFailed:_.length,durationMs:P},multiPage:{pages:H,sharedModules:O,sharedCss:g,sharedJs:f||"",assistantMessage:F,stats:{pagesGenerated:d.length,modulesGenerated:k.length,modulesFailed:_.length,durationMs:P}}}}function ex(e,t,n,s,o,r){let i=Math.round(s/1e3),a=[];a.push(`Created ${e.length}-page site with ${t} modules in ${i}s.`),a.push(`
2403
2302
 
2404
2303
  **Pages:** ${e.map(d=>d.label).join(", ")}`),o&&a.push(`
2405
2304
 
2406
2305
  ${o}`),n.length>0&&a.push(`
2407
2306
 
2408
- **Failed:** ${n.join(", ")}. You can retry these individually.`);let l=i.filter(d=>!d.autoFixed),c=i.filter(d=>d.autoFixed);if(c.length>0||l.length>0){let d=[];c.length>0&&d.push(`**Auto-fixed:** ${c.map(u=>`${u.module}: ${u.message}`).join(", ")}`),l.length>0&&d.push(`**Warnings:** ${l.map(u=>`${u.module}: ${u.message}`).join(", ")}`),a.push(`
2307
+ **Failed:** ${n.join(", ")}. You can retry these individually.`);let l=r.filter(d=>!d.autoFixed),c=r.filter(d=>d.autoFixed);if(c.length>0||l.length>0){let d=[];c.length>0&&d.push(`**Auto-fixed:** ${c.map(u=>`${u.module}: ${u.message}`).join(", ")}`),l.length>0&&d.push(`**Warnings:** ${l.map(u=>`${u.module}: ${u.message}`).join(", ")}`),a.push(`
2409
2308
 
2410
2309
  ${d.join(`
2411
- `)}`)}return a.join("")}function tb(e,t,n,s,o){let i=[],r=new Set;for(let a of n)i.push(a),r.add(a.moduleName);for(let a of t.unchangedModules){if(r.has(a))continue;let l=e.modules.find(c=>c.moduleName===a);l&&(i.push(l),r.add(a))}if(t.reuseModules)for(let a of t.reuseModules){if(r.has(a.name))continue;let l=o.find(c=>c.name===a.name&&c.module);l&&l.module&&(i.push(l.module),r.add(a.name))}return i}function nb(e,t,n,s){if(n?.moduleOrder?.length){let a=[...n.moduleOrder],l=new Set(a);for(let c of s)if(!l.has(c.moduleName)){let d=a.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?a.splice(d,0,c.moduleName):a.push(c.moduleName),l.add(c.moduleName),M.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return a}if(t.intent==="create")return s.map(a=>a.moduleName);let o=[...e.moduleOrder],i=[...t.newModules.map(a=>({name:a.name,position:a.position})),...(t.reuseModules||[]).map(a=>({name:a.name,position:a.position}))].sort((a,l)=>a.position-l.position);for(let a of i){let l=Math.min(a.position,o.length);o.splice(l,0,a.name)}let r=new Set(s.map(a=>a.moduleName));return o.filter(a=>r.has(a))}function sb(e,t,n,s,o,i,r){let a=Math.round(o/1e3),l=[];if(e.intent==="create")l.push(`Created ${t} module${t===1?"":"s"} in ${a}s.`);else if(e.intent==="modify"||e.intent==="style_change")l.push(`Updated ${t} module${t===1?"":"s"} in ${a}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(e.intent==="add"){let u=e.newModules.map(m=>m.name).join(", ");l.push(`Added ${u} in ${a}s.`)}else e.intent==="remove"?l.push(`Removed modules in ${a}s.`):e.intent==="rearrange"&&l.push(`Rearranged modules in ${a}s.`);i?.narrative&&l.push(`
2310
+ `)}`)}return a.join("")}function tx(e,t,n,s,o){let r=[],i=new Set;for(let a of n)r.push(a),i.add(a.moduleName);for(let a of t.unchangedModules){if(i.has(a))continue;let l=e.modules.find(c=>c.moduleName===a);l&&(r.push(l),i.add(a))}if(t.reuseModules)for(let a of t.reuseModules){if(i.has(a.name))continue;let l=o.find(c=>c.name===a.name&&c.module);l?.module?(r.push(l.module),i.add(a.name)):A.warn("pipeline",`Reuse of "${a.name}" requested but no library payload found \u2014 skipping`)}return r}function nx(e,t,n,s){if(n?.moduleOrder?.length){let a=[...n.moduleOrder],l=new Set(a);for(let c of s)if(!l.has(c.moduleName)){let d=a.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?a.splice(d,0,c.moduleName):a.push(c.moduleName),l.add(c.moduleName),A.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return a}if(t.intent==="create")return s.map(a=>a.moduleName);let o=[...e.moduleOrder],r=[...t.newModules.map(a=>({name:a.name,position:a.position})),...(t.reuseModules||[]).map(a=>({name:a.name,position:a.position}))].sort((a,l)=>a.position-l.position);for(let a of r){let l=Math.min(a.position,o.length);o.splice(l,0,a.name)}let i=new Set(s.map(a=>a.moduleName));return o.filter(a=>i.has(a))}function sx(e,t,n,s,o,r,i){let a=Math.round(o/1e3),l=[];if(e.intent==="create")l.push(`Created ${t} module${t===1?"":"s"} in ${a}s.`);else if(e.intent==="modify"||e.intent==="style_change")l.push(`Updated ${t} module${t===1?"":"s"} in ${a}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(e.intent==="add"){let u=e.newModules.map(p=>p.name).join(", ");l.push(`Added ${u} in ${a}s.`)}else e.intent==="remove"?l.push(`Removed modules in ${a}s.`):e.intent==="rearrange"&&l.push(`Rearranged modules in ${a}s.`);r?.narrative&&l.push(`
2412
2311
 
2413
- ${i.narrative}`),s.length>0&&l.push(`
2312
+ ${r.narrative}`),s.length>0&&l.push(`
2414
2313
 
2415
- **Failed:** ${s.join(", ")}. You can retry these individually.`);let c=r.filter(u=>!u.autoFixed),d=r.filter(u=>u.autoFixed);if(d.length>0||c.length>0){let u=[];d.length>0&&u.push(`**Auto-fixed:** ${d.map(m=>`${m.module}: ${m.message}`).join(", ")}`),c.length>0&&u.push(`**Warnings:** ${c.map(m=>`${m.module}: ${m.message}`).join(", ")}`),l.push(`
2314
+ **Failed:** ${s.join(", ")}. You can retry these individually.`);let c=i.filter(u=>!u.autoFixed),d=i.filter(u=>u.autoFixed);if(d.length>0||c.length>0){let u=[];d.length>0&&u.push(`**Auto-fixed:** ${d.map(p=>`${p.module}: ${p.message}`).join(", ")}`),c.length>0&&u.push(`**Warnings:** ${c.map(p=>`${p.module}: ${p.message}`).join(", ")}`),l.push(`
2416
2315
 
2417
2316
  ${u.join(`
2418
- `)}`)}return l.join("")}var fu=N(()=>{"use strict";y();dt();Id();Ud();Yd();cu();Zr();le();Be();dt()});var vu={};Ge(vu,{runFigmaConversion:()=>ob});import{basename as bu}from"path";async function ob(e,t,n,s,o,i,r,a,l){let c=Date.now();r({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=ib(e.designTokens,t);r({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),r({type:"agent_decision",step:"designing",decision:`Generated CSS variables and utility classes from ${e.designTokens.colors.length} colors, ${e.designTokens.typography.length} typography styles`});let{specs:m,moduleOrder:g}=ab(e.sections,e.assets,t);r({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),r({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${g.join(", ")}`}),r({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let h=n==="anthropic-api"||n==="claude-oauth",f=Ps(t,d,["hubspot_rules","conversion"],a),b=h?Zo(t,d,["hubspot_rules","conversion"],a):void 0,S=Xo(i),v=m.length,$=(await te("module-development",()=>{let k=m.map((E,O)=>{let re=e.sections[O];return S(async()=>{r({type:"module_progress",module:E.name,status:"generating",current:O+1,total:v});let _e=db(re,E,e.assets,t,l!==!1),z="";for(let ue=0;ue<2;ue++)try{ue>0&&(M.warn("figma-pipeline",`${E.name}: retrying (attempt ${ue+1})`),r({type:"module_progress",module:E.name,status:"retrying",current:O+1,total:v}));let ne=await Pe(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:_e}],structuredOutput:{schema:Ns,name:"module_output"},maxTokens:16e3});if(ne.type!=="structured")throw new Error("No structured output returned");let $e=ne.data,Ws={moduleName:E.name,fieldsJson:typeof $e.fieldsJson=="string"?$e.fieldsJson:JSON.stringify($e.fieldsJson,null,2),metaJson:typeof $e.metaJson=="string"?$e.metaJson:JSON.stringify($e.metaJson,null,2),moduleHtml:String($e.moduleHtml||""),moduleCss:String($e.moduleCss||""),moduleJs:$e.moduleJs?String($e.moduleJs):void 0};return r({type:"module_progress",module:E.name,status:"complete",current:O+1,total:v,moduleFiles:Ws}),{moduleName:E.name,module:Ws}}catch(ne){z=ne instanceof Error?ne.message:String(ne),M.error("figma-pipeline",`Failed: ${E.name} (attempt ${ue+1}): ${z}`)}return r({type:"module_progress",module:E.name,status:"failed",current:O+1,total:v}),{moduleName:E.name,error:z}})});return Promise.allSettled(k)},{metadata:{moduleCount:v}})).map(k=>k.status==="fulfilled"?k.value:{moduleName:"unknown",error:String(k.reason)}),j=$.filter(k=>k.module).map(k=>k.module),J=$.filter(k=>k.error).map(k=>k.moduleName),H=dn(j,t,r).map(k=>k.module),X=Date.now()-c,F=Math.round(X/1e3),T=`Imported ${H.length} modules from Figma design "${e.fileName}" in ${F}s.`;return J.length>0?r({type:"pipeline_partial",succeeded:H.map(k=>k.moduleName),failed:J,durationMs:X}):r({type:"pipeline_complete",modulesGenerated:H.length,modulesUnchanged:0,durationMs:X,assistantMessage:T}),{modules:H,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:T,stats:{modulesGenerated:H.length,modulesUnchanged:0,modulesFailed:J.length,durationMs:X}}}function Qo(e){let t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,s=parseInt(e.slice(5,7),16)/255,o=Math.max(t,n,s),i=Math.min(t,n,s),r=(o+i)/2;if(o===i)return{h:0,s:0,l:r};let a=o-i,l=r>.5?a/(2-o-i):a/(o+i),c=0;return o===t?c=((n-s)/a+(n<s?6:0))/6:o===n?c=((s-t)/a+2)/6:c=((t-n)/a+4)/6,{h:c*360,s:l,l:r}}function ib(e,t){let n=[],s=t,o=[...e.colors].sort((T,k)=>k.occurrences-T.occurrences),i=o.filter(T=>T.usage==="background"||T.usage==="fill"),r=o.filter(T=>T.usage==="text"),a=i[0]||o[0],l=a?Qo(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(T=>Qo(T.hex).l>.7):o.find(T=>Qo(T.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(T=>!d.has(T.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(T=>!d.has(T.hex)).slice(0,6).forEach((T,k)=>n.push(` --${s}-color-${k+1}: ${T.hex}`)),a){let T=Qo(a.hex).l;n.push(` --${s}-color-surface: ${l?hu(a.hex,.05):yu(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?hu(a.hex,.15):yu(a.hex,.12)}`)}let g=e.typography.filter(T=>T.role==="heading"||T.role==="subheading"),h=e.typography.filter(T=>T.role==="body"||T.role==="label"||T.role==="caption"),f=g[0]?.fontFamily||h[0]?.fontFamily||"system-ui",b=h[0]?.fontFamily||f;n.push(` --${s}-font-display: "${f}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let S=g.sort((T,k)=>k.fontSize-T.fontSize);S[0]&&n.push(` --${s}-size-h1: ${S[0].fontSize}px`),S[1]&&n.push(` --${s}-size-h2: ${S[1].fontSize}px`),S[2]&&n.push(` --${s}-size-h3: ${S[2].fontSize}px`);let v=h.sort((T,k)=>k.occurrences-T.occurrences)[0];v&&n.push(` --${s}-size-body: ${v.fontSize}px`);let w=[...new Set(e.spacing.map(T=>T.value))].sort((T,k)=>T-k),$=["xs","sm","md","lg","xl","2xl","section"];w.slice(0,$.length).forEach((T,k)=>{n.push(` --${s}-space-${$[k]}: ${T}px`)});let j=e.effects.filter(T=>T.type==="shadow"),J=e.effects.filter(T=>T.type==="radius");j[0]&&n.push(` --${s}-shadow: ${j[0].cssValue}`),J.sort((T,k)=>parseFloat(T.cssValue)-parseFloat(k.cssValue)),J[0]&&n.push(` --${s}-radius: ${J[0].cssValue}`),J[1]&&n.push(` --${s}-radius-lg: ${J[1].cssValue}`);let K=`:root {
2317
+ `)}`)}return l.join("")}var qv,Qs,Da=j(()=>{"use strict";y();mt();Qn();Vu();lp();gp();Pp();$a();Dp();Hp();Wp();jo();re();Ue();mt();qv=6,Qs=new Map});var to={};Ve(to,{collectThemeFiles:()=>em,extractDesignContext:()=>lx});import{existsSync as Ar,readdirSync as _r,readFileSync as ox}from"fs";import{join as _t}from"path";import{spawn as rx}from"child_process";async function Qp(){return ja||(ja=(await import("@anthropic-ai/sdk")).default),ja}function eo(e){try{return ox(e,"utf-8")}catch{return""}}function em(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2318
+ ### ${a}
2319
+ \`\`\`
2320
+ ${l}
2321
+ \`\`\`
2322
+ `;return n+c.length>ix?!1:(t.push(c),n+=c.length,!0)}let o=eo(_t(e,"theme.json"));o&&s("theme.json",o);let r=_t(e,"css");if(Ar(r)){for(let a of _r(r).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,eo(_t(r,a))))break}let i=_t(e,"modules");if(Ar(i))for(let a of _r(i).filter(l=>l.endsWith(".module"))){let l=_t(i,a),c=eo(_t(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(Ar(i))for(let a of _r(i).filter(l=>l.endsWith(".module"))){let l=_t(i,a),c=eo(_t(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(Ar(i))for(let a of _r(i).filter(l=>l.endsWith(".module"))){let l=_t(i,a),c=eo(_t(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function ax(){if(!Pr)try{Pr=I(Kt("extraction-prompt.md"))}catch{Pr=""}return Pr}function La(e,t,n){return new Promise((s,o)=>{let r={...process.env};delete r.CLAUDECODE;let i=rx(e,t,{stdio:["pipe","pipe","pipe"],env:r,shell:process.platform==="win32"}),a="",l="";i.stdout.on("data",c=>{a+=c.toString()}),i.stderr.on("data",c=>{l+=c.toString()}),i.on("error",c=>o(new Error(`${e} failed to start: ${c.message}`))),i.on("close",c=>{c===0||a.trim()?s(a.trim()):o(new Error(`${e} exited with code ${c}: ${l.trim()}`))}),i.stdin.write(n),i.stdin.end()})}async function lx(e,t){t?.({status:"Collecting theme files..."});let n=em(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=ax();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:
2323
+ ${n}`;t?.({status:"Analyzing design patterns..."});let r=$(),i=r.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(i){case"anthropic-api":case"api":{let u=De("anthropic-api");if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");let p=await Qp(),g=new p({apiKey:u});d=r.anthropicApiModel||"claude-sonnet-4-6";let f=await g.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=f.content.map(h=>h.type==="text"?h.text:"").join(""),c=nt(f.usage);break}case"claude-oauth":{let{getValidAccessToken:u,OAUTH_EXTRA_HEADERS:p,OAUTH_SYSTEM_PREFIX:g}=await Promise.resolve().then(()=>($t(),Ci)),f=await u();if(!f)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let h=await Qp(),b=new h({authToken:f,defaultHeaders:p});d=r.anthropicApiModel||"claude-sonnet-4-6";let S=await b.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:g},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=S.content.map(v=>v.type==="text"?v.text:"").join(""),c=nt(S.usage);break}case"openai-api":{let u=De("openai-api");if(!u)throw new Error("OpenAI API key not configured. Open Settings to add one.");d=r.openaiApiModel||"gpt-4o";let p=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`},body:JSON.stringify({model:d,max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!p.ok)throw new Error(`OpenAI API error: ${p.status} ${await p.text()}`);let g=await p.json();a=g.choices?.[0]?.message?.content||"",c=Bn(g.usage);break}case"gemini-api":{let u=De("gemini-api");if(!u)throw new Error("Gemini API key not configured. Open Settings to add one.");d=r.geminiApiModel||"gemini-2.5-flash";let p=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${d}:generateContent?key=${u}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!p.ok)throw new Error(`Gemini API error: ${p.status} ${await p.text()}`);let g=await p.json();a=g.candidates?.[0]?.content?.parts?.map(f=>f.text).join("")||"",c=Jn(g.usageMetadata);break}case"claude-code":{let u=`${s}
2324
+
2325
+ ## User Request
2326
+ ${o}`,p=["--print"];r.claudeCodeModel&&p.push("--model",r.claudeCodeModel),a=await La("claude",p,u);break}case"gemini-cli":{let u=`${s}
2327
+
2328
+ ## User Request
2329
+ ${o}`;a=await La("gemini",[],u);break}case"codex-cli":{let u=`${s}
2330
+
2331
+ ## User Request
2332
+ ${o}`;a=await La("codex",[],u);break}default:throw new Error(`Unknown AI engine: ${i}. Open Settings to configure one.`)}if(!a.trim())throw new Error("AI returned empty response.");return d&&Ct({engine:i,model:d,name:"styleguide-extraction",input:{system:s,messages:[{role:"user",content:o}]},output:a,usage:c,startTime:l,endTime:new Date}),t?.({status:"Design extraction complete."}),a}var ja,ix,Pr,no=j(()=>{"use strict";y();ae();te();Ue();un();ja=null;ix=8e4;Pr=""});var Ba={};Ve(Ba,{extractBrandvoice:()=>cx});async function cx(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.
2333
+
2334
+ Return a markdown document with these sections (skip any section where the content provides no signal):
2335
+
2336
+ ## Tone
2337
+ Overall communication style (e.g., confident but approachable, technical but clear, playful, authoritative).
2338
+
2339
+ ## Voice Characteristics
2340
+ 3-5 bullet points describing how this brand "sounds" (e.g., "Uses short, punchy sentences", "Addresses reader directly with 'you'").
2341
+
2342
+ ## Vocabulary
2343
+ - **Preferred words**: Terms used repeatedly or intentionally
2344
+ - **Avoided patterns**: Any notable absences or anti-patterns
2345
+
2346
+ ## Sentence Style
2347
+ Typical sentence length, structure, use of questions, imperatives, etc.
2348
+
2349
+ ## Dos and Don'ts
2350
+ 3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
2351
+
2352
+ Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let r=await Ne(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),i=r.type==="text"?r.text:JSON.stringify(r.data);return!i||i.trim().length<20?null:(A.info("brandvoice-extractor",`Extracted brand voice (${i.length} chars)`),i.trim())}catch(r){let i=r instanceof Error?r.message:String(r);return A.warn("brandvoice-extractor",`Brand voice extraction failed: ${i}`),null}}var Ja=j(()=>{"use strict";y();mt();re()});var Er={};Ve(Er,{extractThemeContext:()=>dx});async function dx(e,t,n,s,o){if(!e||e.length<50)return null;let i=`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.
2353
+
2354
+ Return a markdown document with these sections (skip any section where the content provides no information):
2355
+
2356
+ ## Product / Company
2357
+ Name, one-line description, and what it does.
2358
+
2359
+ ## Value Propositions
2360
+ Key benefits or features (bulleted list).
2361
+
2362
+ ## Target Audience
2363
+ Who this product/service is for.
2364
+
2365
+ ## Tone & Voice
2366
+ Communication style (e.g., professional, casual, technical, friendly).
2367
+
2368
+ ## Key Terminology
2369
+ Specific terms, product names, or branded language used consistently.
2370
+
2371
+ Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
2372
+
2373
+ Existing product context (update if the new content adds info, keep what's still accurate):
2374
+ ${t}`:""}`;try{let a=await Ne(n,s,o,{systemPrompt:i,messages:[{role:"user",content:e}],maxTokens:1e3}),l=a.type==="text"?a.text:JSON.stringify(a.data);return!l||l.trim().length<20?null:(A.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return A.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var Ir=j(()=>{"use strict";y();mt();re()});import{join as tm}from"path";function ux(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function Mr(e,t,n){e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=tm(e.themePath,".vibespot");$e(o),U(tm(o,s),n)}async function nm(e,t){let n=ux(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:qe({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>px(e,t,n,s))}async function px(e,t,n,s){let o=mx(t)?t:{...await gx(e),...t??{}};n.includes("styleguide")&&await Ha(e,"styleguide",s,()=>ce("extract-styleguide",()=>o.extractStyleguide(e)));let r=n.filter(a=>a==="brandvoice"||a==="themeContext");if(r.length===0)return s;let i="";try{i=o.buildPreviewHtml()}catch(a){let l=a instanceof Error?a.message:String(a);for(let c of r)s.skipped.push(c),s.errors.push({asset:c,message:`Could not render preview HTML: ${l}`});return s}if(!i||i.length<50){for(let a of r)s.skipped.push(a);return s}return n.includes("brandvoice")&&await Ha(e,"brandvoice",s,()=>ce("extract-brandvoice",()=>o.extractBrandvoice(e,i))),n.includes("themeContext")&&await Ha(e,"themeContext",s,()=>ce("extract-theme-context",()=>o.extractThemeContext(e,i))),s}async function Ha(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}Mr(e,t,o),n.extracted.push(t)}catch(o){let r=o instanceof Error?o.message:String(o);n.skipped.push(t),n.errors.push({asset:t,message:r}),A.warn("brand-enrichment",`${t} enrichment skipped: ${r}`)}}function mx(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function gx(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(no(),to)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(Xn(),yr)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(os(),Ga)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(Ja(),Ba)),{extractThemeContext:r}=await Promise.resolve().then(()=>(Ir(),Er)),i=$();return{extractStyleguide:()=>t(e.themePath),buildPreviewHtml:n,extractBrandvoice:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(i);return o(l,c,d,u)},extractThemeContext:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(i);return r(l,a.brandAssets?.themeContext,c,d,u)}}}var Ua=j(()=>{"use strict";y();ae();te();re();Ue()});var am={};Ve(am,{runFigmaConversion:()=>fx});import{basename as rm}from"path";async function fx(e,t,n,s,o,r,i,a,l){let c=Date.now();i({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=hx(e.designTokens,t);i({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),i({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:p,moduleOrder:g}=bx(e.sections,e.assets,t);i({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),i({type:"agent_decision",step:"designing",decision:`Mapped ${p.length} Figma sections to modules: ${g.join(", ")}`}),i({type:"agent_step",step:"developing",label:`Converting ${p.length} modules...`});let f=n==="anthropic-api"||n==="claude-oauth",h=Ys(t,d,["hubspot_rules","conversion"],a),b=f?kr(t,d,["hubspot_rules","conversion"],a):void 0,S=xr(r),v=p.length,_=(await ce("module-development",()=>{let F=p.map((z,L)=>{let W=e.sections[L];return S(async()=>{i({type:"module_progress",module:z.name,status:"generating",current:L+1,total:v});let _e=xx(W,z,e.assets,t,l!==!1),Be="";for(let yt=0;yt<2;yt++)try{yt>0&&(A.warn("figma-pipeline",`${z.name}: retrying (attempt ${yt+1})`),i({type:"module_progress",module:z.name,status:"retrying",current:L+1,total:v}));let ot=await Ne(n,s,o,{systemPrompt:h,systemBlocks:b,messages:[{role:"user",content:_e}],structuredOutput:{schema:Xs,name:"module_output"},maxTokens:16e3});if(ot.type!=="structured")throw new Error("No structured output returned");let ie=ot.data,Tn={moduleName:z.name,fieldsJson:typeof ie.fieldsJson=="string"?ie.fieldsJson:JSON.stringify(ie.fieldsJson,null,2),metaJson:typeof ie.metaJson=="string"?ie.metaJson:JSON.stringify(ie.metaJson,null,2),moduleHtml:String(ie.moduleHtml||""),moduleCss:String(ie.moduleCss||""),moduleJs:ie.moduleJs?String(ie.moduleJs):void 0};return i({type:"module_progress",module:z.name,status:"complete",current:L+1,total:v,moduleFiles:Tn}),{moduleName:z.name,module:Tn}}catch(ot){Be=ot instanceof Error?ot.message:String(ot),A.error("figma-pipeline",`Failed: ${z.name} (attempt ${yt+1}): ${Be}`)}return i({type:"module_progress",module:z.name,status:"failed",current:L+1,total:v}),{moduleName:z.name,error:Be}})});return Promise.allSettled(F)},{metadata:{moduleCount:v}})).map(F=>F.status==="fulfilled"?F.value:{moduleName:"unknown",error:String(F.reason)}),M=_.filter(F=>F.module).map(F=>F.module),R=_.filter(F=>F.error).map(F=>F.moduleName),O=Zs(M,t,i).map(F=>F.module),V=Date.now()-c,H=Math.round(V/1e3),P=`Imported ${O.length} modules from Figma design "${e.fileName}" in ${H}s.`;return R.length>0?i({type:"pipeline_partial",succeeded:O.map(F=>F.moduleName),failed:R,durationMs:V}):i({type:"pipeline_complete",modulesGenerated:O.length,modulesUnchanged:0,durationMs:V,assistantMessage:P}),{modules:O,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:P,stats:{modulesGenerated:O.length,modulesUnchanged:0,modulesFailed:R.length,durationMs:V}}}function $r(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),r=Math.min(t,n,s),i=(o+r)/2;if(o===r)return{h:0,s:0,l:i};let a=o-r,l=i>.5?a/(2-o-r):a/(o+r),c=0;return o===t?c=((n-s)/a+(n<s?6:0))/6:o===n?c=((s-t)/a+2)/6:c=((t-n)/a+4)/6,{h:c*360,s:l,l:i}}function hx(e,t){let n=[],s=t,o=[...e.colors].sort((P,F)=>F.occurrences-P.occurrences),r=o.filter(P=>P.usage==="background"||P.usage==="fill"),i=o.filter(P=>P.usage==="text"),a=r[0]||o[0],l=a?$r(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=i[0]||(l?o.find(P=>$r(P.hex).l>.7):o.find(P=>$r(P.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(P=>!d.has(P.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(P=>!d.has(P.hex)).slice(0,6).forEach((P,F)=>n.push(` --${s}-color-${F+1}: ${P.hex}`)),a){let P=$r(a.hex).l;n.push(` --${s}-color-surface: ${l?sm(a.hex,.05):om(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?sm(a.hex,.15):om(a.hex,.12)}`)}let g=e.typography.filter(P=>P.role==="heading"||P.role==="subheading"),f=e.typography.filter(P=>P.role==="body"||P.role==="label"||P.role==="caption"),h=g[0]?.fontFamily||f[0]?.fontFamily||"system-ui",b=f[0]?.fontFamily||h;n.push(` --${s}-font-display: "${h}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let S=g.sort((P,F)=>F.fontSize-P.fontSize);S[0]&&n.push(` --${s}-size-h1: ${S[0].fontSize}px`),S[1]&&n.push(` --${s}-size-h2: ${S[1].fontSize}px`),S[2]&&n.push(` --${s}-size-h3: ${S[2].fontSize}px`);let v=f.sort((P,F)=>F.occurrences-P.occurrences)[0];v&&n.push(` --${s}-size-body: ${v.fontSize}px`);let k=[...new Set(e.spacing.map(P=>P.value))].sort((P,F)=>P-F),_=["xs","sm","md","lg","xl","2xl","section"];k.slice(0,_.length).forEach((P,F)=>{n.push(` --${s}-space-${_[F]}: ${P}px`)});let M=e.effects.filter(P=>P.type==="shadow"),R=e.effects.filter(P=>P.type==="radius");M[0]&&n.push(` --${s}-shadow: ${M[0].cssValue}`),R.sort((P,F)=>parseFloat(P.cssValue)-parseFloat(F.cssValue)),R[0]&&n.push(` --${s}-radius: ${R[0].cssValue}`),R[1]&&n.push(` --${s}-radius-lg: ${R[1].cssValue}`);let J=`:root {
2419
2375
  ${n.join(`;
2420
2376
  `)};
2421
- }`,H=`
2377
+ }`,O=`
2422
2378
  /* Reset */
2423
2379
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
2424
2380
 
@@ -2502,8 +2458,8 @@ body {
2502
2458
  h1 { font-size: 2rem; }
2503
2459
  h2 { font-size: 1.5rem; }
2504
2460
  h3 { font-size: 1.25rem; }
2505
- }`;return{sharedCss:K+`
2506
- `+H,sharedJs:`(function() {
2461
+ }`;return{sharedCss:J+`
2462
+ `+O,sharedJs:`(function() {
2507
2463
  var observer = new IntersectionObserver(function(entries) {
2508
2464
  entries.forEach(function(entry) {
2509
2465
  if (entry.isIntersecting) {
@@ -2513,11 +2469,11 @@ body {
2513
2469
  });
2514
2470
  }, { threshold: 0.1 });
2515
2471
  document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
2516
- })();`}}function hu(e,t){return Su(e,t)}function yu(e,t){return Su(e,-t)}function Su(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 rb(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function ab(e,t,n){let s=new Set,o=[];for(let i of e){let r=rb(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=lb(i.textContent),l=cb(i,t,n),c=`Figma section "${i.name}" \u2014 ${i.width}x${i.height}px, ${i.textContent.length} text elements, ${i.children.length} children`;o.push({name:r,description:c,contentBrief:a,layoutNotes:l})}return{specs:o,moduleOrder:o.map(i=>i.name)}}function lb(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(`
2517
- `)}function cb(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(`
2518
- 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(`
2519
- Available image assets:`);for(let o of t){let i=bu(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2520
- `)}function db(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
2472
+ })();`}}function sm(e,t){return im(e,t)}function om(e,t){return im(e,-t)}function im(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 yx(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function bx(e,t,n){let s=new Set,o=[];for(let r of e){let i=yx(r.name);if(s.has(i)){let d=2;for(;s.has(`${i}-${d}`);)d++;i=`${i}-${d}`}s.add(i);let a=Sx(r.textContent),l=vx(r,t,n),c=`Figma section "${r.name}" \u2014 ${r.width}x${r.height}px, ${r.textContent.length} text elements, ${r.children.length} children`;o.push({name:i,description:c,contentBrief:a,layoutNotes:l})}return{specs:o,moduleOrder:o.map(r=>r.name)}}function Sx(e){let t={};for(let o of e){let r=o.role;t[r]||(t[r]=[]),t[r].push(o.text)}let n=[],s=["headline","subheadline","body","cta","label","caption"];for(let o of s)if(t[o])for(let r of t[o])n.push(`**${o}** (use as field default): "${r}"`);return n.join(`
2473
+ `)}function vx(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(`
2474
+ Children (${e.children.length}):`);for(let o of e.children){let r=` - ${o.type} "${o.name}" (${o.width}x${o.height})`;o.layoutMode&&(r+=` [${o.layoutMode}]`),o.childCount>0&&(r+=` [${o.childCount} children]`),o.characters&&(r+=` text: "${o.characters.slice(0,60)}"`),s.push(r)}}if(t.length>0){s.push(`
2475
+ Available image assets:`);for(let o of t){let r=rm(o.localPath);s.push(` - get_asset_url("${n}/assets/${r}") \u2014 ${o.name}`)}}return s.join(`
2476
+ `)}function xx(e,t,n,s,o){let r=[];if(r.push(`## Figma Design Translation
2521
2477
 
2522
2478
  TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
2523
2479
  - Use the EXACT text content from the design as field default values
@@ -2537,17 +2493,17 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
2537
2493
  - Hide purely decorative elements if they break mobile layout
2538
2494
  - Add a \`@media (max-width: 1023px)\` block for tablet if the layout has 3+ columns
2539
2495
 
2540
- ## Section: "${e.name}" (${e.width}x${e.height}px)`),e.backgroundColor&&i.push(`Background: ${e.backgroundColor}`),(e.layoutMode||e.itemSpacing||e.paddingTop)&&(i.push(`
2541
- ### Layout`),e.layoutMode&&i.push(`Direction: ${e.layoutMode}`),e.itemSpacing&&i.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&i.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`)),e.textContent.length>0){i.push(`
2542
- ### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let r of e.textContent)i.push(`- **${r.role}** (${r.fontSize}px, weight ${r.fontWeight}): "${r.text}"`)}if(e.children.length>0){i.push(`
2543
- ### Structure (${e.children.length} children)`);for(let r of e.children){let a=`- ${r.type} "${r.name}" (${r.width}x${r.height})`;r.layoutMode&&(a+=` layout: ${r.layoutMode}`),r.childCount>0&&(a+=`, ${r.childCount} children`),r.characters&&(a+=`
2544
- text: "${r.characters.slice(0,100)}"`),i.push(a)}}if(n.length>0)if(o){i.push(`
2545
- ### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let r of n){let a=bu(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2546
- ### Images \u2014 USE IMAGE FIELDS WITH PLACEHOLDERS`),i.push('Do NOT use get_asset_url(). Instead, create "image" type fields in fields.json for each image.'),i.push('Set a descriptive default.src (e.g. "https://placehold.co/600x400?text=Hero+Image") and default.alt text.'),i.push("In the module HTML, use: {{ module.field_name.src }} and {{ module.field_name.alt }}"),i.push("This gives content editors full control to replace images in HubSpot.");for(let r of n)i.push(`- "${r.name}" \u2014 create an image field for this`)}return i.push(`
2496
+ ## Section: "${e.name}" (${e.width}x${e.height}px)`),e.backgroundColor&&r.push(`Background: ${e.backgroundColor}`),(e.layoutMode||e.itemSpacing||e.paddingTop)&&(r.push(`
2497
+ ### Layout`),e.layoutMode&&r.push(`Direction: ${e.layoutMode}`),e.itemSpacing&&r.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&r.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`)),e.textContent.length>0){r.push(`
2498
+ ### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let i of e.textContent)r.push(`- **${i.role}** (${i.fontSize}px, weight ${i.fontWeight}): "${i.text}"`)}if(e.children.length>0){r.push(`
2499
+ ### Structure (${e.children.length} children)`);for(let i of e.children){let a=`- ${i.type} "${i.name}" (${i.width}x${i.height})`;i.layoutMode&&(a+=` layout: ${i.layoutMode}`),i.childCount>0&&(a+=`, ${i.childCount} children`),i.characters&&(a+=`
2500
+ text: "${i.characters.slice(0,100)}"`),r.push(a)}}if(n.length>0)if(o){r.push(`
2501
+ ### Available Image Assets \u2014 USE get_asset_url()`),r.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let i of n){let a=rm(i.localPath);r.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${i.name}`)}}else{r.push(`
2502
+ ### Images \u2014 USE IMAGE FIELDS WITH PLACEHOLDERS`),r.push('Do NOT use get_asset_url(). Instead, create "image" type fields in fields.json for each image.'),r.push('Set a descriptive default.src (e.g. "https://placehold.co/600x400?text=Hero+Image") and default.alt text.'),r.push("In the module HTML, use: {{ module.field_name.src }} and {{ module.field_name.alt }}"),r.push("This gives content editors full control to replace images in HubSpot.");for(let i of n)r.push(`- "${i.name}" \u2014 create an image field for this`)}return r.push(`
2547
2503
  ## Module Specification
2548
2504
  - **Name**: ${t.name}
2549
- - **Description**: ${t.description}`),i.join(`
2550
- `)}var xu=N(()=>{"use strict";y();dt();zr();Yr();Zr();le();Be()});var wu={};Ge(wu,{buildPlanModePrompt:()=>ub});function ub(e,t,n,s,o){let i=mb(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
2505
+ - **Description**: ${t.description}`),r.join(`
2506
+ `)}var lm=j(()=>{"use strict";y();mt();Qn();Pa();$a();re();Ue()});var cm={};Ve(cm,{buildPlanModePrompt:()=>wx});function wx(e,t,n,s,o){let r=kx(o,!!t?.plan),i=[];return i.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
2551
2507
 
2552
2508
  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.
2553
2509
 
@@ -2611,208 +2567,117 @@ Drive toward filling these gaps in priority order:
2611
2567
  4. **Sections / modules** \u2014 high-level page structure (hero, features, testimonials, pricing, FAQ, footer, etc.)
2612
2568
  5. **Content** \u2014 actual copy, value props, social proof, key messages
2613
2569
  6. **Brand voice and visual style** \u2014 formal/casual, palette preferences, reference sites
2614
- 7. **Constraints** \u2014 must-haves, must-avoids, integrations needed`),t?.styleguide&&r.push(`## Available styleguide
2570
+ 7. **Constraints** \u2014 must-haves, must-avoids, integrations needed`),t?.styleguide&&i.push(`## Available styleguide
2615
2571
 
2616
2572
  The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
2617
2573
 
2618
2574
  \`\`\`
2619
- ${Qr(t.styleguide,1500)}
2620
- \`\`\``),t?.brandvoice&&r.push(`## Available brand voice
2575
+ ${Wa(t.styleguide,1500)}
2576
+ \`\`\``),t?.brandvoice&&i.push(`## Available brand voice
2621
2577
 
2622
2578
  \`\`\`
2623
- ${Qr(t.brandvoice,1e3)}
2624
- \`\`\``),t?.themeContext&&r.push(`## Theme context
2579
+ ${Wa(t.brandvoice,1e3)}
2580
+ \`\`\``),t?.themeContext&&i.push(`## Theme context
2625
2581
 
2626
2582
  \`\`\`
2627
- ${Qr(t.themeContext,1e3)}
2628
- \`\`\``),n.length>0&&r.push(`## Existing modules in this theme
2583
+ ${Wa(t.themeContext,1e3)}
2584
+ \`\`\``),n.length>0&&i.push(`## Existing modules in this theme
2629
2585
 
2630
2586
  These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
2631
2587
 
2632
2588
  ${n.map(a=>`- ${a}`).join(`
2633
- `)}`),s.length>0&&r.push(`## Module library (reusable across templates)
2589
+ `)}`),s.length>0&&i.push(`## Module library (reusable across templates)
2634
2590
 
2635
2591
  These modules exist in other templates and could be reused here. Reference them by name in the plan if appropriate.
2636
2592
 
2637
2593
  ${s.map(a=>`- **${a.name}** (used in: ${a.usedIn.join(", ")})`).join(`
2638
- `)}`),t?.plan&&r.push(`## Current plan (continue refining)
2594
+ `)}`),t?.plan&&i.push(`## Current plan (continue refining)
2639
2595
 
2640
2596
  The plan in progress so far. Build on it \u2014 preserve what's there, only update sections that are changing based on the user's latest message.
2641
2597
 
2642
2598
  \`\`\`markdown
2643
2599
  ${t.plan}
2644
- \`\`\``),r.push(`## Phase guidance for this turn
2600
+ \`\`\``),i.push(`## Phase guidance for this turn
2645
2601
 
2646
- ${i}`),r.join(`
2602
+ ${r}`),i.join(`
2647
2603
 
2648
- `)}function mb(e,t){return e===0&&!t?"**Phase 1: UNDERSTAND.** This is the user's first message in plan mode. Acknowledge what they said, then ask 2\u20133 high-leverage questions to surface gaps. The plan block should be a skeleton with TBDs and an **Open questions** section. Do NOT propose specific sections or content yet \u2014 you don't know enough.":e===0&&t?`**Phase 1-T: TEMPLATED START.** The user picked a plan-mode template, so a structured plan already exists. Your job on this turn is to:
2604
+ `)}function kx(e,t){return e===0&&!t?"**Phase 1: UNDERSTAND.** This is the user's first message in plan mode. Acknowledge what they said, then ask 2\u20133 high-leverage questions to surface gaps. The plan block should be a skeleton with TBDs and an **Open questions** section. Do NOT propose specific sections or content yet \u2014 you don't know enough.":e===0&&t?`**Phase 1-T: TEMPLATED START.** The user picked a plan-mode template, so a structured plan already exists. Your job on this turn is to:
2649
2605
  - Briefly acknowledge the template and that you'll work from this structure (1\u20132 sentences in chat).
2650
2606
  - Pick 2\u20133 of the highest-leverage items from the plan's **Open questions** section and ask the user about them. Prefer questions about: product/page name + one-line pitch, primary CTA, and target audience. Save tone/visual questions for later turns.
2651
2607
  - Do NOT propose new sections or rewrite the existing structure on this turn \u2014 the user explicitly chose this scaffold. Keep the plan block VERBATIM (same headings, same sections, same open-questions list) and only re-emit it.
2652
2608
  - If the user's first message already supplies content (e.g. "It's for Acme, a fintech startup, primary CTA is book a demo"), thread that into the plan's TBDs and check those items off the **Open questions** list before asking your follow-ups.
2653
- - Use \`vibespot-choices\` chips when one of your questions is multiple-choice (e.g. "Primary CTA?", "Cuisine?").`:e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function Qr(e,t){return e.length<=t?e:e.slice(0,t)+`
2654
- ... [truncated]`}var Cu=N(()=>{"use strict";y()});var aa={};Ge(aa,{applyPipelineResult:()=>un,handleAgenticGenerate:()=>ei,handleFigmaImport:()=>Fs,handleGenerate:()=>pb,handleGenerateStream:()=>Os,handlePlanModeStream:()=>oa,isGenerating:()=>Yt,isPlanModeActive:()=>ia,resolveAgenticEngine:()=>Wn,setParseWarningCallback:()=>na,shouldUseAgenticMode:()=>ra});import{execSync as ea}from"child_process";function na(e){ta=e}function Yt(){return jt!==null}function Ct(e){if(jt){let t=C();if(!t||t.id!==jt){M.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}lt("assistant",e),ed(e,ta||void 0),L()}async function Os(e,t,n,s){let o=C();if(!o)throw new Error("No active session");jt=o.id;let r=s?.length?Vo(s):void 0;try{let a=R(),l=a.aiEngine||sa();switch(l){case"anthropic-api":case"api":{let c=Fe("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await $r(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,Ct,r);break}case"claude-oauth":{await dd(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,Ct,r);break}case"openai-api":{let c=Fe("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await Er(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,Ct,r);break}case"gemini-api":{let c=Fe("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await Mr(e,c,o.themeName,t,n,Ct,r);break}case"claude-code":await ud(e,o.themeName,t,n,Ct,r);break;case"gemini-cli":await Rr("gemini",e,o.themeName,t,n,Ct,r);break;case"codex-cli":await Rr("codex",e,o.themeName,t,n,Ct,r);break;case"langdock-api":{let c=Fe("langdock-api",a);if(!c)throw new Error("Langdock API key not configured. Open Settings to add one.");let d=a.langdockProvider||"anthropic",u={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},m=a.langdockBaseUrl||u[d],g=a.langdockApiModel;switch(d){case"openai":case"mistral":await Er(e,c,o.themeName,g||"gpt-4.1",t,n,Ct,r,`${m}/v1/chat/completions`);break;case"google":await Mr(e,c,o.themeName,t,n,Ct,r,`${m}/v1beta/models/${g||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,g);break;default:await $r(e,c,o.themeName,g||"claude-sonnet-4-6",t,n,Ct,r,m);break}break}default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{jt=null,ta=null}}function sa(){let e=R();if(Ze())return"claude-oauth";if(e.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(e.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(e.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return ea("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return ea("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return ea("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function pb(e){let t="";return await Os(e,n=>{t+=n}),t}function ku(){let e=C(),t=ke(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder],o={modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,contentMode:t?.contentMode,brandAssets:e.brandAssets?{...e.brandAssets}:void 0};return e.templates.length>1&&(o.activePageLabel=t?.label,o.sitePages=e.templates.map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))),o}function Wn(e){let t=e.aiEngine||sa();if(!Ms(t))throw new Error("Agentic pipeline is not available for this engine.");if(Gn(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Ze())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=Fe(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=e.geminiApiModel||"gemini-2.5-pro";break;case"langdock-api":{let o={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-flash",mistral:"mistral-large-latest"};s=e.langdockApiModel||o[e.langdockProvider||"anthropic"];break}case"claude-code":s=e.claudeCodeModel||"";break;case"codex-cli":s=e.codexCliModel||"";break;case"gemini-cli":s=e.geminiCliModel||"";break;default:s=""}return{engine:t,apiKey:n,model:s}}function Tu(e){let t=e.multiPage;return{modules:e.modules.map(n=>n.moduleName),moduleCount:e.modules.length,moduleOrder:e.moduleOrder,stats:e.stats,...t?{pages:t.pages.map(n=>n.pageId)}:{},assistantMessage:e.assistantMessage}}async function ei(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=s.id;jt=o;try{let i=R(),{engine:r,apiKey:a,model:l}=Wn(i),c=i.agenticConcurrency||20,d=ku(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
2609
+ - Use \`vibespot-choices\` chips when one of your questions is multiple-choice (e.g. "Primary CTA?", "Cuisine?").`:e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function Wa(e,t){return e.length<=t?e:e.slice(0,t)+`
2610
+ ... [truncated]`}var dm=j(()=>{"use strict";y()});var Ga={};Ve(Ga,{applyPipelineResult:()=>xn,cancelActiveGeneration:()=>Ya,handleAgenticGenerate:()=>Fr,handleAgenticResume:()=>Qa,handleFigmaImport:()=>ro,handleGenerate:()=>Tx,handleGenerateStream:()=>oo,handlePlanModeStream:()=>el,isGenerating:()=>Gt,isPlanModeActive:()=>tl,resolveAgenticEngine:()=>vn,setParseWarningCallback:()=>za,shouldUseAgenticMode:()=>nl});import{execSync as Ka}from"child_process";function za(e){Va=e}function Gt(){return Ut.size>0}async function Or(e){let t=Rr.get(e)||Promise.resolve(),n,s=new Promise(r=>{n=r}),o=t.then(()=>s);return Rr.set(e,o),await t,()=>{n(),Rr.get(e)===o&&Rr.delete(e)}}function um(){let e={abort:new AbortController};return qa.add(e),{run:e,signal:e.abort.signal}}function pm(e){qa.delete(e)}function Ya(){let e=!1;for(let t of qa)t.abort.abort(),e=!0;return e}function Cx(e,t){let n=x();if(!n||n.id!==e){A.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}ct("assistant",t),_u(t,Va||void 0),D()}async function oo(e,t,n,s){let o=x();if(!o)throw new Error("No active session");let r=o.id,i=await Or(r);Ut.add(r);let a=c=>Cx(r,c),l=s?.length?vr(s):void 0;try{let c=$(),d=c.aiEngine||Xa();switch(d){case"anthropic-api":case"api":{let u=De("anthropic-api",c);if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");await Qi(e,u,o.themeName,c.anthropicApiModel||"claude-sonnet-4-6",t,n,a,l);break}case"claude-oauth":{await Cd(e,o.themeName,c.anthropicApiModel||"claude-sonnet-4-6",t,n,a,l);break}case"openai-api":{let u=De("openai-api",c);if(!u)throw new Error("OpenAI API key not configured. Open Settings to add one.");await ea(e,u,o.themeName,c.openaiApiModel||"gpt-4o",t,n,a,l);break}case"gemini-api":{let u=De("gemini-api",c);if(!u)throw new Error("Gemini API key not configured. Open Settings to add one.");await ta(e,u,o.themeName,t,n,a,l);break}case"claude-code":await Td(e,o.themeName,t,n,a,l);break;case"gemini-cli":await oa("gemini",e,o.themeName,t,n,a,l);break;case"codex-cli":await oa("codex",e,o.themeName,t,n,a,l);break;case"langdock-api":{let u=De("langdock-api",c);if(!u)throw new Error("Langdock API key not configured. Open Settings to add one.");let p=c.langdockProvider||"anthropic",g={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},f=c.langdockBaseUrl||g[p],h=c.langdockApiModel;switch(p){case"openai":case"mistral":await ea(e,u,o.themeName,h||"gpt-4.1",t,n,a,l,`${f}/v1/chat/completions`);break;case"google":await ta(e,u,o.themeName,t,n,a,l,`${f}/v1beta/models/${h||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,h);break;default:await Qi(e,u,o.themeName,h||"claude-sonnet-4-6",t,n,a,l,f);break}break}default:throw new Error(`Unknown AI engine: ${d}. Open Settings to configure one.`)}}finally{Ut.delete(r),Va=null,i()}}function Xa(){let e=$();if(Qe())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 Ka("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return Ka("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return Ka("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Tx(e){let t="";return await oo(e,n=>{t+=n}),t}function so(){let e=x(),t=xe(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder],o={modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,contentMode:t?.contentMode,brandAssets:e.brandAssets?{...e.brandAssets}:void 0};return e.templates.length>1&&(o.activePageLabel=t?.label,o.sitePages=e.templates.map(r=>({id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length}))),o}function vn(e){let t=e.aiEngine||Xa();if(!zs(t))throw new Error("Agentic pipeline is not available for this engine.");if(ns(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Qe())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=De(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=e.geminiApiModel||"gemini-2.5-pro";break;case"langdock-api":{let o={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-flash",mistral:"mistral-large-latest"};s=e.langdockApiModel||o[e.langdockProvider||"anthropic"];break}case"claude-code":s=e.claudeCodeModel||"";break;case"codex-cli":s=e.codexCliModel||"";break;case"gemini-cli":s=e.geminiCliModel||"";break;default:s=""}return{engine:t,apiKey:n,model:s}}function Za(e){let t=e.multiPage;return{modules:e.modules.map(n=>n.moduleName),moduleCount:e.modules.length,moduleOrder:e.moduleOrder,stats:e.stats,...t?{pages:t.pages.map(n=>n.pageId)}:{},assistantMessage:e.assistantMessage}}async function Fr(e,t,n,s=!1){let o=x();if(!o)throw new Error("No active session");let r=o.id,{run:i,signal:a}=um(),l=await Or(r);try{if(a.aborted)return A.info("ai-handler","Agentic run cancelled before start (barge-in)"),Nr(so());Ut.add(r);let c=$(),{engine:d,apiKey:u,model:p}=vn(c),g=c.agenticConcurrency||20,f=so(),h=f.brandAssets?.plan,b=e;h&&h.trim()&&(b=`## Approved plan
2655
2611
 
2656
2612
  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.
2657
2613
 
2658
- ${u}
2614
+ ${h}
2659
2615
 
2660
2616
  ---
2661
2617
 
2662
2618
  ## User message
2663
2619
 
2664
- ${e}`);let g=n?.length?Vo(n):void 0;if(g?.length)for(let $ of g)$.type==="document"&&$.extractedText&&(m+=`
2620
+ ${e}`);let S=n?.length?vr(n):void 0;if(S?.length)for(let O of S)O.type==="document"&&O.extractedText&&(b+=`
2665
2621
 
2666
2622
  ---
2667
- [Attached document: ${$.originalName}]
2668
- ${$.extractedText}`),$.type==="image"&&$.usage==="asset"&&$.assetPath&&(m+=`
2623
+ [Attached document: ${O.originalName}]
2624
+ ${O.extractedText}`),O.type==="image"&&O.usage==="asset"&&O.assetPath&&(b+=`
2669
2625
 
2670
- [Uploaded image: ${$.originalName} \u2192 available as get_asset_url("${$.assetPath}")]`);let h=Ot(),f=new Set(d.modules.map($=>$.moduleName)),b=h.filter($=>!f.has($.module.moduleName)).map($=>({name:$.module.moduleName,usedIn:$.usedIn})),{result:S,cost:v}=await er(()=>tt({name:"agent_pipeline",sessionId:d.themeName,input:e,metadata:{engine:r,model:l,concurrency:c},tags:["vibespot","agentic-pipeline"]},async()=>{let $=await gu(m,d,r,a,l,c,t,b);return nr(Tu($)),$}));S.cost=v;let w=C();if(!w||w.id!==o)throw M.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return S}finally{jt=null}}async function Fs(e,t,n,s){let o=C();if(!o)throw new Error("No active session");let i=o.id;jt=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(xu(),vu)),a=R(),{engine:l,apiKey:c,model:d}=Wn(a),u=a.agenticConcurrency||20,m=ku(),{result:g,cost:h}=await er(()=>tt({name:"figma_import",sessionId:t,input:{fileName:e.fileName,sections:e.sections.length},metadata:{engine:l,model:d,concurrency:u},tags:["vibespot","figma-import"]},async()=>{let b=await r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets);return nr(Tu(b)),b}));g.cost=h;let f=C();if(!f||f.id!==i)throw M.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{jt=null}}function un(e,t){let n=e.multiPage;if(n&&n.pages.length>0){let s=new Map;for(let o of n.pages)s.set(o.pageId,{label:o.label||o.pageId,pageType:o.pageType||"website_page"});xc({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(He({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Wt(e.moduleOrder),e.contentType==="email"){let o=ke();o&&!o.contentMode&&(o.contentMode="email")}t?.cost&&hc(t.cost),lt("assistant",e.assistantMessage,t),L()}async function oa(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=R(),{engine:i,apiKey:r,model:a}=Wn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(Cu(),wu)),Promise.resolve().then(()=>(dt(),wd))]),d=s.messages.filter(w=>w.role==="assistant").length,u=s.modules.map(w=>w.moduleName),m=Ot(),g=new Set(u),h=m.filter(w=>!g.has(w.module.moduleName)).map(w=>({name:w.module.moduleName,usedIn:w.usedIn})),f=l(s.themeName,s.brandAssets,u,h,d),b=n?.length?Vo(n):void 0,S=e;if(b?.length)for(let w of b)w.type==="document"&&w.extractedText&&(S+=`
2626
+ [Uploaded image: ${O.originalName} \u2192 available as get_asset_url("${O.assetPath}")]`);let v=Lt(),k=new Set(f.modules.map(O=>O.moduleName)),_=v.filter(O=>!k.has(O.module.moduleName)).map(O=>({name:O.module.moduleName,usedIn:O.usedIn,module:O.module})),{result:M,cost:R}=await Do(()=>qe({name:"agent_pipeline",sessionId:f.themeName,input:e,metadata:{engine:d,model:p,concurrency:g},tags:["vibespot","agentic-pipeline"]},async()=>{let O=await qp(b,f,d,u,p,g,t,_,s,a);return Bo(Za(O)),O})).catch(O=>{if(Ws(O))return A.info("ai-handler","Agentic run cancelled (barge-in)"),{result:Nr(f),cost:void 0};throw O});if(M.cost=R,M.canceled)return M;let J=x();if(!J||J.id!==r)throw A.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return M}finally{Ut.delete(r),pm(i),l()}}function Nr(e){return{modules:[...e.modules],moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,assistantMessage:"",canceled:!0,stats:{modulesGenerated:0,modulesUnchanged:e.modules.length,modulesFailed:0,durationMs:0}}}async function Qa(e,t,n,s){let o=x();if(!o)throw new Error("No active session");let r=o.id,{run:i,signal:a}=um(),l=await Or(r);try{if(a.aborted)return A.info("ai-handler","Checkpoint resume cancelled before start (barge-in)"),Nr(so());Ut.add(r);let c=$(),{engine:d,apiKey:u,model:p}=vn(c),g=c.agenticConcurrency||20,f=so(),{result:h,cost:b}=await Do(()=>qe({name:"agent_pipeline_resume",sessionId:f.themeName,input:{action:t.action,kind:t.kind},metadata:{engine:d,model:p,concurrency:g},tags:["vibespot","agentic-pipeline","checkpoint-resume"]},async()=>{let v=await Xp(e,t,f,d,u,p,g,n,a,s);return Bo(Za(v)),v})).catch(v=>{if(Ws(v))return A.info("ai-handler","Checkpoint resume cancelled (barge-in)"),{result:Nr(f),cost:void 0};throw v});if(h.cost=b,h.canceled)return h;let S=x();if(!S||S.id!==r)throw A.warn("ai-handler","Session changed during checkpoint resume \u2014 discarding output"),new Error("Session changed during generation");return h.brandAssetsUpdate&&(h.brandAssetsUpdate.styleguide&&Mr(S,"styleguide",h.brandAssetsUpdate.styleguide),h.brandAssetsUpdate.brandvoice&&Mr(S,"brandvoice",h.brandAssetsUpdate.brandvoice),D()),h}finally{Ut.delete(r),pm(i),l()}}async function ro(e,t,n,s){let o=x();if(!o)throw new Error("No active session");let r=o.id,i=await Or(r);Ut.add(r);try{let{runFigmaConversion:a}=await Promise.resolve().then(()=>(lm(),am)),l=$(),{engine:c,apiKey:d,model:u}=vn(l),p=l.agenticConcurrency||20,g=so(),{result:f,cost:h}=await Do(()=>qe({name:"figma_import",sessionId:t,input:{fileName:e.fileName,sections:e.sections.length},metadata:{engine:c,model:u,concurrency:p},tags:["vibespot","figma-import"]},async()=>{let S=await a(e,t,c,d,u,p,n,g.brandAssets,s?.useAssets);return Bo(Za(S)),S}));f.cost=h;let b=x();if(!b||b.id!==r)throw A.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return f}finally{Ut.delete(r),i()}}function xn(e,t){let n=e.multiPage;if(n&&n.pages.length>0){let s=new Map;for(let o of n.pages)s.set(o.pageId,{label:o.label||o.pageId,pageType:o.pageType||"website_page"});Gc({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else{Ge({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Yt(e.moduleOrder);let s=e.contentType;if(s==="email"){let o=xe();o&&!o.contentMode&&(o.contentMode="email")}else if(s==="blog"){let o=xe();o&&(o.contentMode||(o.contentMode="blog"),o.pageType!=="blog_post"&&(o.pageType="blog_post"))}}t?.cost&&Lc(t.cost),ct("assistant",e.assistantMessage,t),D()}async function el(e,t,n){let s=x();if(!s)throw new Error("No active session");let o=$(),{engine:r,apiKey:i,model:a}=vn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(dm(),cm)),Promise.resolve().then(()=>(mt(),ju))]),d=s.messages.filter(k=>k.role==="assistant").length,u=s.modules.map(k=>k.moduleName),p=Lt(),g=new Set(u),f=p.filter(k=>!g.has(k.module.moduleName)).map(k=>({name:k.module.moduleName,usedIn:k.usedIn})),h=l(s.themeName,s.brandAssets,u,f,d),b=n?.length?vr(n):void 0,S=e;if(b?.length)for(let k of b)k.type==="document"&&k.extractedText&&(S+=`
2671
2627
 
2672
2628
  ---
2673
- [Attached document: ${w.originalName}]
2674
- ${w.extractedText}`);let v=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return v.type==="text"?v.text:JSON.stringify(v.data)}function ia(){return!!R().planMode}function ra(){let e=R(),t=e.aiEngine||sa();return Ms(t)?e.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:e.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var ta,jt,Kn=N(()=>{"use strict";y();ee();Ce();Ko();le();tr();Or();$t();jr();fu();Be();ta=null;jt=null});import{readFileSync as gb,readdirSync as fb,existsSync as hb}from"fs";import{dirname as yb,join as ti}from"path";import{fileURLToPath as bb}from"url";function vb(e){let t=e.match(Sb);if(!t)return null;let[,n,s]=t,o={};for(let i of n.split(/\r?\n/)){let r=i.indexOf(":");if(r===-1)continue;let a=i.slice(0,r).trim(),l=i.slice(r+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),a&&(o[a]=l)}return{fields:o,body:s.trimStart()}}function xb(e){let t=vb(e);if(!t)return null;let{fields:n,body:s}=t,o=n.id,i=n.label,r=n.description??"";if(!o||!i)return null;let a=n.order?Number(n.order):NaN,l=n.contentType==="email"?"email":void 0;return{id:o,label:i,description:r,icon:n.icon||void 0,order:Number.isFinite(a)?a:9999,contentType:l,body:s.trimEnd()+`
2675
- `}}function wb(){let e=[ti(Au,"../../assets/plan-templates"),ti(Au,"../assets/plan-templates"),ti(process.cwd(),"assets/plan-templates")];for(let t of e)if(hb(t))return t;return null}function _u(){if(qt)return qt;let e=wb();if(!e)return qt=[],qt;let t=[],n=[];try{n=fb(e)}catch{return qt=[],qt}for(let s of n)if(s.endsWith(".md"))try{let o=gb(ti(e,s),"utf-8"),i=xb(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),qt=t,qt}function $u(e){return _u().find(t=>t.id===e)??null}function Eu(){return _u().map(({id:e,label:t,description:n,icon:s,order:o,contentType:i})=>({id:e,label:t,description:n,icon:s,order:o,contentType:i}))}var Au,Sb,qt,Mu=N(()=>{"use strict";y();Au=yb(bb(import.meta.url)),Sb=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;qt=null});import{existsSync as Iu,mkdirSync as Cb,writeFileSync as kb,rmSync as Tb}from"fs";import{join as Pu}from"path";function Nu(e){return Pu(e,".vibespot",Ab)}function ni(e){let t=C();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=ke();n&&(n.plan=e);try{let s=Pu(t.themePath,".vibespot");Iu(s)||Cb(s,{recursive:!0}),kb(Nu(t.themePath),e,"utf-8")}catch(s){M.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return L(),e}function la(){let e=C();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=ke();t&&delete t.plan;try{let n=Nu(e.themePath);Iu(n)&&Tb(n)}catch(n){M.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}L()}function Ru(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(t,400,{error:"Plan content cannot be empty"});return}ni(o),p(t,200,{ok:!0,plan:o})})}function Ou(e,t){qe(e,t,()=>{la(),Y({planMode:!1}),p(t,200,{ok:!0})})}function Fu(e,t){p(t,200,{templates:Eu()})}function Du(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.templateId=="string"?n.templateId.trim():"";if(!o){p(t,400,{error:"templateId is required"});return}let i=$u(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}ni(i.body),Y({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var Ab,ju=N(()=>{"use strict";y();Xe();Ce();Kt();ee();le();Mu();Ab="plan.md"});function Lu(e){let t,n,s;for(ca.lastIndex=0;(s=ca.exec(e))!==null;)t=s[1].trim();let o;for(da.lastIndex=0;(o=da.exec(e))!==null;)try{let r=JSON.parse(o[1].trim());r&&typeof r.question=="string"&&Array.isArray(r.options)&&r.options.every(a=>typeof a=="string")&&r.options.length>0&&(n={question:r.question,options:r.options})}catch{}return{cleanedContent:e.replace(ca,"").replace(da,"").replace(/\n{3,}/g,`
2676
-
2677
- `).trim(),plan:t,choices:n}}var ca,da,Ju=N(()=>{"use strict";y();ca=/```vibespot-plan\s*\n([\s\S]*?)```/g,da=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as ua}from"child_process";function Bu(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+=`
2678
- Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
2679
- Process timed out`,t.completedAt=Date.now())},n||3e5)}function Ds(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};Xt.set(o,i);let r=ua(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&r.stdin&&(r.stdin.write(s.stdin),r.stdin.end()),Bu(r,i,s?.timeout),o}function mn(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};Xt.set(s,o);let i=e.split(" "),r=ua(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Bu(r,o,n?.timeout),s}function si(e){return Xt.get(e)}function _b(){let e=Date.now()-18e5;for(let[t,n]of Xt)n.completedAt&&n.completedAt<e&&Xt.delete(t)}function oi(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};Xt.set(s,o);let i=e.split(" "),r=ua(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),a=c=>{for(let d of o.listeners)try{d(c)}catch{}};r.stdout?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.stderr?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),r.on("error",c=>{o.status="failed",o.output+=`
2680
- Process error: ${c.message}`,o.completedAt=Date.now(),o.listeners.clear()});let l=n?.timeout||3e5;return setTimeout(()=>{o.status==="running"&&(r.kill(),o.status="failed",o.output+=`
2681
- Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Hu(e,t){let n=Xt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Uu(e,t){let n=Xt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var Xt,ii=N(()=>{"use strict";y();Xt=new Map;setInterval(_b,600*1e3)});import{readFileSync as $b,readdirSync as Eb,existsSync as Mb}from"fs";import{dirname as Ib,join as ri}from"path";import{fileURLToPath as Pb}from"url";function Nb(){let e=[ri(Gu,"../../starters"),ri(Gu,"../starters"),ri(process.cwd(),"starters")];for(let t of e)if(Mb(t))return t;return null}function Wu(){if(Vn!==null)return Vn;let e=Nb();if(!e)return Vn=[],Vn;let t=[];for(let n of Eb(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse($b(ri(e,n),"utf-8"));t.push({id:s.id,name:s.name,description:s.description,category:s.category||"General",contentType:s.contentType==="email"?"email":void 0,modules:s.modules||[],moduleOrder:s.moduleOrder||[],sharedCss:s.sharedCss||"",sharedJs:s.sharedJs||""})}catch{}return Vn=t,Vn}function Ku(){return Wu().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function ma(e){return Wu().find(t=>t.id===e)||null}var Gu,Vn,Vu=N(()=>{"use strict";y();Gu=Ib(Pb(import.meta.url)),Vn=null});var Ls={};Ge(Ls,{collectThemeFiles:()=>Yu,extractDesignContext:()=>jb});import{existsSync as ai,readdirSync as li,readFileSync as Rb}from"fs";import{join as kt}from"path";import{spawn as Ob}from"child_process";async function zu(){return pa||(pa=(await import("@anthropic-ai/sdk")).default),pa}function js(e){try{return Rb(e,"utf-8")}catch{return""}}function Yu(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
2682
- ### ${a}
2683
- \`\`\`
2684
- ${l}
2685
- \`\`\`
2686
- `;return n+c.length>Fb?!1:(t.push(c),n+=c.length,!0)}let o=js(kt(e,"theme.json"));o&&s("theme.json",o);let i=kt(e,"css");if(ai(i)){for(let a of li(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,js(kt(i,a))))break}let r=kt(e,"modules");if(ai(r))for(let a of li(r).filter(l=>l.endsWith(".module"))){let l=kt(r,a),c=js(kt(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(ai(r))for(let a of li(r).filter(l=>l.endsWith(".module"))){let l=kt(r,a),c=js(kt(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(ai(r))for(let a of li(r).filter(l=>l.endsWith(".module"))){let l=kt(r,a),c=js(kt(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function Db(){if(!ci)try{ci=P(bn("extraction-prompt.md"))}catch{ci=""}return ci}function ga(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=Ob(e,t,{stdio:["pipe","pipe","pipe"],env:i,shell:!0}),a="",l="";r.stdout.on("data",c=>{a+=c.toString()}),r.stderr.on("data",c=>{l+=c.toString()}),r.on("error",c=>o(new Error(`${e} failed to start: ${c.message}`))),r.on("close",c=>{c===0||a.trim()?s(a.trim()):o(new Error(`${e} exited with code ${c}: ${l.trim()}`))}),r.stdin.write(n),r.stdin.end()})}async function jb(e,t){t?.({status:"Collecting theme files..."});let n=Yu(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=Db();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:
2687
- ${n}`;t?.({status:"Analyzing design patterns..."});let i=R(),r=i.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(r){case"anthropic-api":case"api":{let u=Fe("anthropic-api");if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");let m=await zu(),g=new m({apiKey:u});d=i.anthropicApiModel||"claude-sonnet-4-6";let h=await g.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=h.content.map(f=>f.type==="text"?f.text:"").join(""),c=et(h.usage);break}case"claude-oauth":{let{getValidAccessToken:u,OAUTH_EXTRA_HEADERS:m,OAUTH_SYSTEM_PREFIX:g}=await Promise.resolve().then(()=>($t(),ji)),h=await u();if(!h)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let f=await zu(),b=new f({authToken:h,defaultHeaders:m});d=i.anthropicApiModel||"claude-sonnet-4-6";let S=await b.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:g},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=S.content.map(v=>v.type==="text"?v.text:"").join(""),c=et(S.usage);break}case"openai-api":{let u=Fe("openai-api");if(!u)throw new Error("OpenAI API key not configured. Open Settings to add one.");d=i.openaiApiModel||"gpt-4o";let m=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`},body:JSON.stringify({model:d,max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!m.ok)throw new Error(`OpenAI API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.choices?.[0]?.message?.content||"",c=En(g.usage);break}case"gemini-api":{let u=Fe("gemini-api");if(!u)throw new Error("Gemini API key not configured. Open Settings to add one.");d=i.geminiApiModel||"gemini-2.5-flash";let m=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${d}:generateContent?key=${u}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!m.ok)throw new Error(`Gemini API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.candidates?.[0]?.content?.parts?.map(h=>h.text).join("")||"",c=Mn(g.usageMetadata);break}case"claude-code":{let u=`${s}
2688
-
2689
- ## User Request
2690
- ${o}`,m=["--print"];i.claudeCodeModel&&m.push("--model",i.claudeCodeModel),a=await ga("claude",m,u);break}case"gemini-cli":{let u=`${s}
2691
-
2692
- ## User Request
2693
- ${o}`;a=await ga("gemini",[],u);break}case"codex-cli":{let u=`${s}
2694
-
2695
- ## User Request
2696
- ${o}`;a=await ga("codex",[],u);break}default:throw new Error(`Unknown AI engine: ${r}. Open Settings to configure one.`)}if(!a.trim())throw new Error("AI returned empty response.");return d&&St({engine:r,model:d,name:"styleguide-extraction",input:{system:s,messages:[{role:"user",content:o}]},output:a,usage:c,startTime:l,endTime:new Date}),t?.({status:"Design extraction complete."}),a}var pa,Fb,ci,Js=N(()=>{"use strict";y();oe();ee();Be();on();pa=null;Fb=8e4;ci=""});var fa={};Ge(fa,{extractBrandvoice:()=>Lb});async function Lb(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.
2697
-
2698
- Return a markdown document with these sections (skip any section where the content provides no signal):
2699
-
2700
- ## Tone
2701
- Overall communication style (e.g., confident but approachable, technical but clear, playful, authoritative).
2702
-
2703
- ## Voice Characteristics
2704
- 3-5 bullet points describing how this brand "sounds" (e.g., "Uses short, punchy sentences", "Addresses reader directly with 'you'").
2705
-
2706
- ## Vocabulary
2707
- - **Preferred words**: Terms used repeatedly or intentionally
2708
- - **Avoided patterns**: Any notable absences or anti-patterns
2709
-
2710
- ## Sentence Style
2711
- Typical sentence length, structure, use of questions, imperatives, etc.
2712
-
2713
- ## Dos and Don'ts
2714
- 3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
2715
-
2716
- Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Pe(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),r=i.type==="text"?i.text:JSON.stringify(i.data);return!r||r.trim().length<20?null:(M.info("brandvoice-extractor",`Extracted brand voice (${r.length} chars)`),r.trim())}catch(i){let r=i instanceof Error?i.message:String(i);return M.warn("brandvoice-extractor",`Brand voice extraction failed: ${r}`),null}}var ha=N(()=>{"use strict";y();dt();le()});var di={};Ge(di,{extractThemeContext:()=>Jb});async function Jb(e,t,n,s,o){if(!e||e.length<50)return null;let r=`You are a content analyst. Extract a concise product/company brief from the rendered landing page HTML below. The HTML contains the actual text content (headings, paragraphs, button labels, image alt text, etc.) with all template variables resolved to their default values.
2717
-
2718
- Return a markdown document with these sections (skip any section where the content provides no information):
2719
-
2720
- ## Product / Company
2721
- Name, one-line description, and what it does.
2722
-
2723
- ## Value Propositions
2724
- Key benefits or features (bulleted list).
2725
-
2726
- ## Target Audience
2727
- Who this product/service is for.
2728
-
2729
- ## Tone & Voice
2730
- Communication style (e.g., professional, casual, technical, friendly).
2731
-
2732
- ## Key Terminology
2733
- Specific terms, product names, or branded language used consistently.
2734
-
2735
- Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
2736
-
2737
- Existing product context (update if the new content adds info, keep what's still accurate):
2738
- ${t}`:""}`;try{let a=await Pe(n,s,o,{systemPrompt:r,messages:[{role:"user",content:e}],maxTokens:1e3}),l=a.type==="text"?a.text:JSON.stringify(a.data);return!l||l.trim().length<20?null:(M.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return M.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var ui=N(()=>{"use strict";y();dt();le()});import{join as qu}from"path";function Bb(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function Hb(e,t,n){e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=qu(e.themePath,".vibespot");Re(o),B(qu(o,s),n)}async function Xu(e,t){let n=Bb(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:tt({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>Ub(e,t,n,s))}async function Ub(e,t,n,s){let o=Gb(t)?t:{...await Wb(e),...t??{}};n.includes("styleguide")&&await ya(e,"styleguide",s,()=>te("extract-styleguide",()=>o.extractStyleguide(e)));let i=n.filter(a=>a==="brandvoice"||a==="themeContext");if(i.length===0)return s;let r="";try{r=o.buildPreviewHtml()}catch(a){let l=a instanceof Error?a.message:String(a);for(let c of i)s.skipped.push(c),s.errors.push({asset:c,message:`Could not render preview HTML: ${l}`});return s}if(!r||r.length<50){for(let a of i)s.skipped.push(a);return s}return n.includes("brandvoice")&&await ya(e,"brandvoice",s,()=>te("extract-brandvoice",()=>o.extractBrandvoice(e,r))),n.includes("themeContext")&&await ya(e,"themeContext",s,()=>te("extract-theme-context",()=>o.extractThemeContext(e,r))),s}async function ya(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}Hb(e,t,o),n.extracted.push(t)}catch(o){let i=o instanceof Error?o.message:String(o);n.skipped.push(t),n.errors.push({asset:t,message:i}),M.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function Gb(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function Wb(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(Js(),Ls)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(ws(),Wo)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Kn(),aa)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(ha(),fa)),{extractThemeContext:i}=await Promise.resolve().then(()=>(ui(),di)),r=R();return{extractStyleguide:()=>t(e.themePath),buildPreviewHtml:n,extractBrandvoice:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return o(l,c,d,u)},extractThemeContext:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return i(l,a.brandAssets?.themeContext,c,d,u)}}}var Zu=N(()=>{"use strict";y();oe();ee();le();Be()});import{existsSync as zn,readdirSync as Qu,rmSync as Kb,writeFileSync as pn,mkdirSync as mi}from"fs";import{join as Ne,basename as Vb}from"path";import{homedir as zb}from"os";import{execFileSync as tm}from"child_process";function gi(){if(pi&&Date.now()-pi.ts<Yb)return pi.data;let e=[];if(zn(ut))try{for(let t of Qu(ut,{withFileTypes:!0}))if(t.isDirectory()){let n=Ne(ut,t.name,"theme.json");if(zn(n)){let s=0,o=Ne(ut,t.name,"modules");if(zn(o))try{s=Qu(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return pi={data:e,ts:Date.now()},e}function sm(e){let t=C(),n=io(),s=!1;try{tm("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...nm}),s=!0}catch{}let o=Fn().sort((r,a)=>a.updatedAt-r.updatedAt),i=gi();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length,isImported:!!t.isImported}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i,contentMode:Jn()})}function om(e,t){W(e,n=>{try{if(Yt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s,starterId:o,assetType:i}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let r=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!r){p(t,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Ne(ut,r);if(Re(ut),zn(a)&&Kb(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!ma(o)){p(t,400,{error:`Starter template "${o}" not found`});return}is(a,r),On(a,r),o&&typeof o=="string"?(qb(a,r,o),Te()):i==="email"&&(Rt("module_only","Email","email"),$n(a,r)),L(),p(t,200,{ok:!0,themeName:r,themePath:a,starterId:o||void 0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function qb(e,t,n){let s=ma(n);if(!s)return;let o=C();if(!o)return;let i=s.contentType==="email",r=s.modules.map(u=>({...u})),a=[...s.moduleOrder],l=i?`email-${t}`:`lp-${t}`,c={id:l,label:`${s.name}`,pageType:i?"module_only":"landing_page",contentMode:i?"email":void 0,templateFile:i?"templates/email.html":`templates/${l}.html`,modules:r,moduleOrder:a,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};i&&$n(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Ne(e,"modules");mi(d,{recursive:!0});for(let u of s.modules){let m=Ne(d,`${u.moduleName}.module`);mi(m,{recursive:!0}),pn(Ne(m,"fields.json"),u.fieldsJson,"utf-8"),pn(Ne(m,"meta.json"),u.metaJson,"utf-8"),pn(Ne(m,"module.html"),u.moduleHtml,"utf-8"),pn(Ne(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&pn(Ne(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Ne(e,"css");mi(u,{recursive:!0}),pn(Ne(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Ne(e,"js");mi(u,{recursive:!0}),pn(Ne(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function im(e){p(e,200,{starters:Ku()})}function rm(e,t){W(e,n=>{try{if(Yt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Le(),r=R(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Ne(ut,a);Re(ut),r.hubspotUploadMode==="cli"||!i?(async()=>{tm("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...nm});let c=await em(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})})().catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})}):as(i,o,l).then(async()=>{let c=await em(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})}).catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}async function em(e,t){On(e,t,{isImported:!0}),Go(e),L();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await Xu(n),L()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function am(e,t){W(e,n=>{try{if(Yt()){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(zn(o)||(o=Ne(ut,s)),!zn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Vb(o);On(o,i),Go(o),L(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:C()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function lm(e,t){W(e,n=>{try{if(Yt()){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=jo(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 cm(e,t){W(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}Y({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function dm(e){let t=Le();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await cl(t);if(n.length===0){p(e,200,{themes:[]});return}let s=[],o=n.map(async a=>{let l=a.path||a.name;try{let c=await lo(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:a.name,path:l})}catch{}});await Promise.all(o),s.sort((a,l)=>a.name.localeCompare(l.name));let i=gi(),r=new Set(i.map(a=>a.name));p(e,200,{themes:s.map(a=>({...a,existsLocally:r.has(a.name)}))})})().catch(n=>{p(e,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}var nm,ut,pi,Yb,fi=N(()=>{"use strict";y();Xe();ee();rs();po();sn();Ce();Kt();Kn();nn();ee();oe();Vu();Cs();Zu();nm=process.platform==="win32"?{shell:!0}:{},ut=Ne(zb(),"vibespot-themes"),pi=null,Yb=5e3});import{existsSync as Xb,readFileSync as Zb,appendFileSync as Qb}from"fs";import{join as um}from"path";import{homedir as mm}from"os";function nS(e){let t=e.match(/^gpt-(\d+(?:\.\d+)?)(?:-(.+))?$/);if(t){let n=t[1],s=t[2];if(!s)return`GPT-${n}`;let o=s.replace(/-/g," ").replace(/\b\w/g,i=>i.toUpperCase());return`GPT-${n} ${o}`}return e.startsWith("codex-")?`Codex ${e.slice(6).replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}`:/^o\d/.test(e)?e.replace(/-/g," "):e}async function Sa(e,t={},n=ym){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function sS(e){let t=await Sa("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 oS(e){let t=await Sa("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function gm(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:nS(n)}))}async function iS(e){let t=await Sa(`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 rS(e=!1){if(!e&&Date.now()-Yn.ts<eS&&Object.keys(Yn.data).length>0)return Yn.data;let t=R(),n={...ba},s=[],o=Fe("anthropic-api",t);o&&s.push(sS(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c,n["claude-code"]=c)}).catch(()=>{}));let i=Fe("openai-api",t);i&&s.push(oS(i).then(c=>{if(!c.length)return;let d=gm(c,hm);d.length&&(n["openai-api"]=d);let u=gm(c,tS);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let r=Fe("gemini-api",t);r&&s.push(iS(r).then(c=>{c.length&&(n["gemini-api"]=c,n["gemini-cli"]=c)}).catch(()=>{}));let a=!1;await Promise.race([Promise.all(s).then(()=>{a=!0}),new Promise(c=>setTimeout(c,ym+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=pm[l]||pm.anthropic,a&&(Yn.data=n,Yn.ts=Date.now()),n}function bm(e){let t=nl(),n=R(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,codexCliModel:n.codexCliModel||null,geminiCliModel:n.geminiCliModel||null,geminiApiModel:n.geminiApiModel||null,langdockApiModel:n.langdockApiModel||null,langdockBaseUrl:n.langdockBaseUrl||null,langdockProvider:n.langdockProvider||"anthropic",hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(o=>({portalId:o.portalId,portalName:o.portalName,dataCenter:o.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null,langfuseEnabled:n.langfuseEnabled,langfuseBaseUrl:n.langfuseBaseUrl||null};p(e,200,{version:Sn(),environment:t,config:s,models:ba,sessionCount:Fn().length,localThemeCount:gi().length})}function Sm(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");rS(n).then(s=>p(t,200,{models:s})).catch(()=>p(t,200,{models:ba}))}function vm(e,t){let n=new URL(e.url||"/","http://localhost"),s=n.searchParams.get("group")||"all",o=s==="ai"||s==="platform"?s:"all",i=n.searchParams.get("refresh")==="1",r=fm[o];if(!i&&Date.now()-r.ts<aS&&Object.keys(r.data).length>0){p(t,200,{...r.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=sl();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:ol()};else{let l=io();a={tools:l.tools,availableEngines:l.availableEngines}}fm[o]={data:a,ts:Date.now()},p(t,200,{...a,group:o,cached:!1})}function xm(e,t){W(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli","langdock-api"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let r={aiEngine:s};if(o)switch(s){case"claude-code":r.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":r.anthropicApiModel=o;break;case"openai-api":r.openaiApiModel=o;break;case"codex-cli":r.codexCliModel=o;break;case"gemini-cli":r.geminiCliModel=o;break;case"gemini-api":r.geminiApiModel=o;break;case"langdock-api":r.langdockApiModel=o;break}Y(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function wm(e,t){W(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"langdock":l.langdockApiKey="";break;case"figma":l.figmaToken="";break;case"langfuse-public":l.langfusePublicKey="";break;case"langfuse-secret":l.langfuseSecretKey="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"langdock":i.langdockApiKey=o;break;case"figma":i.figmaToken=o;break;case"langfuse-public":i.langfusePublicKey=o;break;case"langfuse-secret":i.langfuseSecretKey=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(i);let r=null;if(!R().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(Y({aiEngine:c}),r=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Cm(e,t){W(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let r=mn(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function km(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}"),o=R(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){ao(s.personalAccessKey).then(r=>{Xn(s.personalAccessKey,r.portalId,r.portalName,r.dataCenter),p(t,200,{ok:!0,portalName:r.portalName,portalId:r.portalId,dataCenter:r.dataCenter})}).catch(r=>{p(t,400,{error:r instanceof Error?r.message:String(r)})});return}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=Ds("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:a});return}if(i==="api"){let r=o.hubspotAccounts||[];if(r.length>0&&!s.force){let a=r.find(l=>l.portalId===o.activeHubSpotAccount)||r[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ht();if(a.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Tm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}");if(!no().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=so();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=Ds("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=mn("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:r,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Am(e,t){W(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((R().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Ni(s),p(t,200,{ok:!0});return}if(s){Ri(s),p(t,200,{ok:!0});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=Ds("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=Ds("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 _m(e){let t=mn("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function $m(e,t){W(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=mn("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=mn("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,Y({openaiApiKey:i}),process.platform!=="win32"){let r=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(r){let a=`export OPENAI_API_KEY="${r}"`,l=process.env.SHELL?.includes("zsh")?um(mm(),".zshrc"):um(mm(),".bashrc");try{(Xb(l)?Zb(l,"utf-8"):"").includes("OPENAI_API_KEY")||Qb(l,`
2739
- # Added by vibeSpot
2740
- ${a}
2741
- `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=mn("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 Em(e,t){W(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}Y({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Mm(e,t){W(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(t,400,{error:"toolId (string) and enabled (boolean) required"});return}Oi(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 Im(e,t){W(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider","langfuseEnabled","langfuseBaseUrl"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langfuseEnabled!==void 0&&typeof s.langfuseEnabled!="boolean"){p(t,400,{error:"langfuseEnabled must be a boolean"});return}if(s.langfuseBaseUrl!==void 0&&typeof s.langfuseBaseUrl!="string"){p(t,400,{error:"langfuseBaseUrl must be a string"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){p(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(i.langdockProvider){let r={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};i.langdockApiModel=r[i.langdockProvider]||"",Yn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}Y(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Pm(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=si(n);if(!s){p(t,404,{error:"Job not found"});return}p(t,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}var Yn,eS,ba,pm,hm,tS,ym,aS,fm,Nm=N(()=>{"use strict";y();Xe();ee();Ce();fi();nn();sn();oe();ii();Yn={data:{},ts:0},eS=600*1e3,ba={"claude-code":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}],"codex-cli":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"},{id:"gpt-5.2-codex",label:"GPT-5.2 Codex"},{id:"gpt-5.1-codex-max",label:"GPT-5.1 Codex Max"},{id:"gpt-5.1-codex-mini",label:"GPT-5.1 Codex Mini"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"codex-mini-latest",label:"Codex Mini (latest)"}],"anthropic-api":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"claude-oauth":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"openai-api":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"}],"gemini-api":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],"gemini-cli":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}]},pm={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],openai:[{id:"gpt-4.1",label:"GPT-4.1 (default)"},{id:"gpt-4.1-mini",label:"GPT-4.1 Mini"},{id:"gpt-4.1-nano",label:"GPT-4.1 Nano"},{id:"gpt-4o",label:"GPT-4o"},{id:"o3-mini",label:"o3 Mini"}],google:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],mistral:[{id:"mistral-large-latest",label:"Mistral Large (default)"},{id:"mistral-medium-latest",label:"Mistral Medium"},{id:"mistral-small-latest",label:"Mistral Small"},{id:"codestral-latest",label:"Codestral"},{id:"pixtral-large-latest",label:"Pixtral Large"}]},hm=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,tS=hm;ym=2500;aS=60*1e3,fm={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}}});function Rm(e,t){W(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"access_token is required"});return}Fi(s.trim(),(o||"").trim());let i=R();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&Y({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Om(e,t){let n=Ze(),s=en();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Fm(e,t){try{Zs(),R().aiEngine==="claude-oauth"&&Y({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var Dm=N(()=>{"use strict";y();Xe();ee();$t()});import{existsSync as lS,rmSync as cS}from"fs";import{join as dS}from"path";function jm(e,t,n){if(e==="GET"){let s=C(),o=Fn().sort((i,r)=>r.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName,isImported:!!s.isImported}:null,sessions:o});return}if(e==="DELETE"){W(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Mc(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 Lm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=jo(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 Jm(e,t){W(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}if(/[\/\\]|\.\./.test(s)||s==="."||!s.replace(/[^a-z0-9]/gi,"")){p(t,400,{error:"Invalid theme name"});return}let o=dS(ut,s);if(!lS(o)){p(t,404,{error:"Theme not found on disk"});return}cS(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Bm(e,t){W(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){p(t,400,{error:"Invalid name"});return}let r=Ic(s,i);r.ok?p(t,200,{ok:!0,newName:i}):p(t,400,{error:r.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Hm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=Pc(s);o.ok?p(t,200,{ok:!0,newName:o.newName,newSessionId:o.newSessionId}):p(t,400,{error:o.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var Um=N(()=>{"use strict";y();Xe();Ce();fi()});import{existsSync as hi,readFileSync as uS,readdirSync as mS,rmSync as zm}from"fs";import{join as Oe,basename as pS,relative as gS,sep as fS}from"path";import hS from"jszip";function Ym(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=Ot();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.contentMode==="email"?"email":s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1,hasBrandKit:!!t.brandAssets?.brandKit&&Object.keys(t.brandAssets.brandKit).length>0,brandKit:t.brandAssets?.brandKit||null}})}function qm(e,t=[]){for(let n of mS(e,{withFileTypes:!0}))if(n.isDirectory()){if(yS.has(n.name))continue;qm(Oe(e,n.name),t)}else n.isFile()&&t.push(Oe(e,n.name));return t}async function Xm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!hi(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=pS(n);try{let i=new hS;for(let a of qm(n)){let l=Oe(o,gS(n,a)).split(fS).join("/");i.file(l,uS(a))}let r=await i.generateAsync({type:"nodebuffer",compression:"DEFLATE",compressionOptions:{level:6}});e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${s}.zip"`,"Content-Length":r.length}),e.end(r)}catch(i){M.error("download-zip","Failed to create zip archive",i),p(e,500,{error:"Failed to create zip archive"})}}function Zm(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.contentMode==="email"?"email":o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){W(t,o=>{try{let{pageType:i,label:r}=JSON.parse(o);if(!i||!r){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only","email"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=i==="email",d=Rt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&$n(s.themePath,s.themeName),L(),p(n,200,{ok:!0,template:{id:d.id,label:d.label,pageType:d.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Ac(i,!!r)){p(n,404,{error:"Template not found"});return}L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function Qm(e,t){W(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!fs(s)){p(t,404,{error:"Template not found"});return}L();let i=C();p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function ep(e,t){W(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"templateId and newLabel are required"});return}if(!Tc(s,o.trim())){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function tp(e,t){W(e,n=>{try{let{templateIds:s}=JSON.parse(n);if(!Array.isArray(s)||s.some(i=>typeof i!="string")){p(t,400,{error:"templateIds must be an array of strings"});return}if(!kc(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}L(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function np(e,t){W(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=Cc(s,o);if(!i){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function sp(e){let t=Ot();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function op(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}W(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=Ot().find(d=>d.module.moduleName===i);if(!a){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...a.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function ip(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){W(t,o=>{try{let{type:i,content:r}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=r==="on",s.updatedAt=Date.now(),L(),p(n,200,{ok:!0});return}if(!r){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let a=i,l=a==="themeContext"?"theme-context.md":`${a}.md`;s.brandAssets[a]=r,s.updatedAt=Date.now();let c=Oe(s.themePath,".vibespot");Re(c),B(Oe(c,l),r);let d=null;a==="styleguide"&&(d=va(s,r)),L(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let r=i;s.brandAssets&&delete s.brandAssets[r],s.updatedAt=Date.now();let a=r==="themeContext"?"theme-context.md":`${r}.md`,l=Oe(s.themePath,".vibespot",a);hi(l)&&zm(l),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function ap(e,t){p(t,200,rp)}function SS(e){let t=[],n=[],s=e.split(`
2742
- `),o=!1,i=!1;for(let r of s){let a=r.trim();if(/^##\s+color/i.test(a)){o=!0,i=!1;continue}if(/^##\s+typography/i.test(a)){i=!0,o=!1;continue}if(/^##\s+/.test(a)&&!(/color/i.test(a)||/typography/i.test(a))){o=!1,i=!1;continue}if(o){let l=a.match(bS);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Gm.exec(a);if(Gm.lastIndex=0,l){let c=l[1].trim().replace(/['"`]/g,"").split(",")[0].trim();c&&!n.includes(c)&&n.push(c)}if(/\bheading|body|display|monospace\b/i.test(a)&&!l){let c=a.split(":").slice(1).join(":").trim();if(c){let d=c.replace(/['"`*]/g,"").split(",")[0].trim().split("(")[0].trim();d&&d.length<60&&!/^\d/.test(d)&&!n.includes(d)&&n.push(d)}}}}return{colors:t.slice(0,6),fonts:n.slice(0,4)}}function va(e,t){let{colors:n,fonts:s}=SS(t);if(n.length===0&&s.length===0)return null;e.brandAssets||(e.brandAssets={});let o=e.brandAssets.brandKit||{};if(n.length>0&&(o.colors||(o.colors={}),n[0]&&(o.colors.primary=n[0]),n[1]&&(o.colors.secondary=n[1]),n[2]&&(o.colors.accent=n[2])),s.length>0){o.fonts||(o.fonts={});let r=a=>{let l=a.toLowerCase(),c=rp.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=r(s[0])),s[1]?o.fonts.body=r(s[1]):s[0]&&(o.fonts.body=r(s[0]))}e.brandAssets.brandKit=o;let i=Oe(e.themePath,".vibespot");return Re(i),B(Oe(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function lp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){W(t,o=>{try{let i=JSON.parse(o);s.brandAssets||(s.brandAssets={});let r={};if(i.colors&&typeof i.colors=="object"){let l={};for(let c of["primary","secondary","accent"])typeof i.colors[c]=="string"&&vS.test(i.colors[c])&&(l[c]=i.colors[c]);Object.keys(l).length>0&&(r.colors=l)}if(i.fonts&&typeof i.fonts=="object"){let l={};for(let c of["heading","body"])typeof i.fonts[c]=="string"&&i.fonts[c].trim()&&(l[c]=i.fonts[c].trim());Object.keys(l).length>0&&(r.fonts=l)}typeof i.logoUrl=="string"&&i.logoUrl.trim()&&(r.logoUrl=i.logoUrl.trim()),s.brandAssets.brandKit=r,s.updatedAt=Date.now();let a=Oe(s.themePath,".vibespot");Re(a),B(Oe(a,"brand-kit.json"),JSON.stringify(r,null,2)),L(),p(n,200,{ok:!0,brandKit:r})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Oe(s.themePath,".vibespot","brand-kit.json");hi(o)&&zm(o),L(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Wm(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Oe(e.themePath,".vibespot");Re(o),B(Oe(o,s),n)}function Km(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function Vm(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Js(),Ls));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Kn(),aa)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),qa)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ws(),Wo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(ha(),fa));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(ui(),di));return u(d,e.brandAssets?.themeContext,r,a,l)}function cp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",r=o.sourcePath;if(i==="all"){let c=["styleguide","brandvoice","themeContext"],d=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>te(Km(g),()=>Vm(n,g,r))))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Wm(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=va(n,u.styleguide)),L(),p(t,200,{ok:!0,type:"all",extracted:u,brandKit:m});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let a=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:i},tags:["vibespot","brand-extract"]},()=>te(Km(i),()=>Vm(n,i,r)));if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Wm(n,i,a);let l=null;i==="styleguide"&&(l=va(n,a)),L(),p(t,200,{ok:!0,type:i,content:a,brandKit:l})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function dp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:r}=JSON.parse(s),a;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Le();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),f=Oe(h(),"vibespot-themes",".references",g);Re(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(po(),yl));await b(u,m,f),a=f}else if(o==="local"){if(!r){p(t,400,{error:"localPath is required for local import"});return}if(!hi(r)){p(t,400,{error:`Path not found: ${r}`});return}a=r}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(Js(),Ls)),c=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Oe(n.themePath,".vibespot");Re(d),B(Oe(d,"styleguide.md"),c),L(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var yS,rp,bS,Gm,vS,up=N(()=>{"use strict";y();Xe();le();Be();ee();rs();Ce();oe();yS=new Set([".git",".vibespot","node_modules"]);rp=[{name:"System Default",stack:"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",category:"system"},{name:"Inter",stack:"Inter, system-ui, sans-serif",category:"sans-serif"},{name:"DM Sans",stack:"'DM Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Open Sans",stack:"'Open Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Roboto",stack:"Roboto, system-ui, sans-serif",category:"sans-serif"},{name:"Lato",stack:"Lato, system-ui, sans-serif",category:"sans-serif"},{name:"Montserrat",stack:"Montserrat, system-ui, sans-serif",category:"sans-serif"},{name:"Poppins",stack:"Poppins, system-ui, sans-serif",category:"sans-serif"},{name:"Nunito",stack:"Nunito, system-ui, sans-serif",category:"sans-serif"},{name:"Raleway",stack:"Raleway, system-ui, sans-serif",category:"sans-serif"},{name:"Work Sans",stack:"'Work Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Source Sans 3",stack:"'Source Sans 3', system-ui, sans-serif",category:"sans-serif"},{name:"Manrope",stack:"Manrope, system-ui, sans-serif",category:"sans-serif"},{name:"Plus Jakarta Sans",stack:"'Plus Jakarta Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Outfit",stack:"Outfit, system-ui, sans-serif",category:"sans-serif"},{name:"Space Grotesk",stack:"'Space Grotesk', system-ui, sans-serif",category:"sans-serif"},{name:"Albert Sans",stack:"'Albert Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Figtree",stack:"Figtree, system-ui, sans-serif",category:"sans-serif"},{name:"Helvetica",stack:"Helvetica, Arial, sans-serif",category:"sans-serif"},{name:"Arial",stack:"Arial, Helvetica, sans-serif",category:"sans-serif"},{name:"Verdana",stack:"Verdana, Geneva, sans-serif",category:"sans-serif"},{name:"Georgia",stack:"Georgia, 'Times New Roman', serif",category:"serif"},{name:"Playfair Display",stack:"'Playfair Display', Georgia, serif",category:"serif"},{name:"Merriweather",stack:"Merriweather, Georgia, serif",category:"serif"},{name:"Lora",stack:"Lora, Georgia, serif",category:"serif"},{name:"PT Serif",stack:"'PT Serif', Georgia, serif",category:"serif"},{name:"Libre Baskerville",stack:"'Libre Baskerville', Georgia, serif",category:"serif"},{name:"Source Serif 4",stack:"'Source Serif 4', Georgia, serif",category:"serif"},{name:"Cormorant Garamond",stack:"'Cormorant Garamond', Garamond, serif",category:"serif"},{name:"Times New Roman",stack:"'Times New Roman', Times, serif",category:"serif"},{name:"Sora",stack:"Sora, system-ui, sans-serif",category:"display"},{name:"Clash Display",stack:"'Clash Display', system-ui, sans-serif",category:"display"},{name:"Cabinet Grotesk",stack:"'Cabinet Grotesk', system-ui, sans-serif",category:"display"},{name:"Satoshi",stack:"Satoshi, system-ui, sans-serif",category:"display"},{name:"General Sans",stack:"'General Sans', system-ui, sans-serif",category:"display"},{name:"JetBrains Mono",stack:"'JetBrains Mono', 'Fira Code', monospace",category:"monospace"},{name:"Fira Code",stack:"'Fira Code', 'Courier New', monospace",category:"monospace"},{name:"Source Code Pro",stack:"'Source Code Pro', monospace",category:"monospace"},{name:"Courier New",stack:"'Courier New', Courier, monospace",category:"monospace"}];bS=/#[0-9a-fA-F]{6}\b/g,Gm=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;vS=/^#[0-9a-fA-F]{6}$/});import{join as xS}from"path";function mp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function pp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=ve();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){qe(t,n,o=>{o.deleteEntirely?yc(o.moduleName):bc(o.moduleName),L(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function gp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=ke();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:r,content:a}=o;if(!i||!r){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(r){case"html":l.moduleHtml=a;break;case"css":l.moduleCss=a;break;case"js":l.moduleJs=a||void 0;break;case"fields":try{JSON.parse(a)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:p(t,400,{error:`Invalid fileType: ${r}`});return}n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function fp(e,t){qe(e,t,n=>{Array.isArray(n.order)?(Wt(n.order),L(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function hp(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}try{Te();let n=Ao(t.themePath),s=oi(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:xS(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function yp(e,t){W(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Sc(s,o,i),L(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function bp(e,t){W(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=gl(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2743
- `),r={sourceDir:o.sourceDir,componentCount:o.components.length,components:o.components.map(a=>({name:a.name,description:a.description})),hasTailwind:o.hasTailwind,cssVarCount:o.cssVarCount,fonts:o.fonts,interactions:o.interactions,conversionPrompt:`Import and convert the React landing page from ${s} to native HubSpot modules.
2744
-
2745
- Source analysis found ${o.components.length} components:
2746
- ${i}
2747
-
2748
- Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CSS variables
2749
- Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
2750
- Interactions: ${o.interactions.join(", ")}
2751
-
2752
- Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};p(t,200,r)}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Sp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}if(!rt()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?dc(n.themePath,o,50):cc(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function vp(e,t){W(e,n=>{try{let s=C();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(lt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let r=s.templates.find(c=>c.id===i);if(!r){p(t,404,{error:"Template not found"});return}let a=r.moduleOrder.map(c=>`modules/${c}.module`);r.templateFile&&a.push(r.templateFile);let l=mc(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}Uc()}else{let r=uc(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}Hc()}L(),p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var xp=N(()=>{"use strict";y();Xe();Ce();_o();ii();mo();Pn()});import{writeFileSync as wS,mkdirSync as Cp}from"fs";import{join as yi}from"path";import{randomUUID as CS}from"crypto";function kp(e){let t=e.match(kS);if(!t)return null;let n=t[1],s=t[2]?decodeURIComponent(t[2].replace(/-/g," ")):void 0,o;try{let r=new URL(e).searchParams.get("node-id");r&&(o=r.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function Si(e,t){let n=await fetch(`${TS}${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 wa(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=wp.length)throw s;let r=wp[n];M.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${r}s`),t&&t(`Figma rate limited \u2014 retrying in ${r}s...`),await new Promise(a=>setTimeout(a,r*1e3))}}function gn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)gn(s,t,n+1)}function Tp(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=Tp(n,t);if(s)return s}return null}function AS(e,t){if(t){let s=Tp(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>xa.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>xa.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>xa.has(s.type)):[]}function bi(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 _S(e){let t=new Map;for(let n of e)gn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=bi(o.color),r=t.get(i),a=s.type==="TEXT",l=a?"text":"fill";r?(r.occurrences++,a&&r.usage!=="text"&&(r.usage="text")):t.set(i,{hex:i,opacity:o.opacity??o.color.a,occurrences:1,usage:l})}}if(s.strokes){for(let o of s.strokes)if(o.type==="SOLID"&&o.color){let i=bi(o.color),r=t.get(i);r?r.occurrences++:t.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function $S(e){let t=new Map;for(let n of e)gn(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,r=o.fontWeight||400,a=o.lineHeightPx?Math.round(o.lineHeightPx/i*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";i>=32?d="heading":i>=20?d="subheading":i<=12?d="caption":r>=600&&i<=14&&(d="label");let u=`${c}-${i}-${r}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:r,lineHeight:a,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function ES(e){let t=[],n=new Set;for(let s of e)gn(s,o=>{if(!o.layoutMode||o.layoutMode==="NONE")return;if(o.itemSpacing&&o.itemSpacing>0){let c=`gap-${o.itemSpacing}-${o.name}`;n.has(c)||(n.add(c),t.push({context:`${o.name} gap`,value:o.itemSpacing,type:"gap"}))}let i=o.paddingTop||0,r=o.paddingRight||0,a=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||r>0||a>0||l>0){let c=`pad-${i}-${r}-${a}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===a&&l===r&&i===l?i:Math.max(i,r,a,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function MS(e){let t=[],n=new Set;for(let s of e)gn(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r,g:a,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(r*255)},${Math.round(a*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let i=`${o.cornerRadius}px`;n.has(`radius-${i}`)||(n.add(`radius-${i}`),t.push({type:"radius",cssValue:i,context:o.name}))}});return t}function IS(e,t){let n=[];return gn(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,r="body";o>=32?r="headline":o>=20?r="subheadline":o<=12?r="caption":i>=600&&o<=16&&(r="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(r="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:r,sectionName:t})}),n}function PS(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 NS(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return bi(t.color)}if(e.backgroundColor)return bi(e.backgroundColor)}function RS(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:IS(t,t.name),children:(t.children||[]).slice(0,20).map(PS),backgroundColor:NS(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 OS(e){let t=[];for(let n of e)gn(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 Ap(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());wS(t,s)}async function FS(e,t,n,s,o){if(t.length===0)return new Map;Cp(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await wa(()=>Si(`/v1/images/${e}?ids=${r}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(a.images)){if(!d)continue;let u=c.replace(/:/g,"-"),m=yi(s,`frame-${u}.png`);try{await Ap(d,m),l.set(c,m),M.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){M.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function DS(e,t,n,s,o){if(t.length===0)return[];Cp(s,{recursive:!0});let i=50,r=[];for(let a=0;a<t.length;a+=i){let l=t.slice(a,a+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${a+1}-${Math.min(a+i,t.length)} of ${t.length})...`);let d=await wa(()=>Si(`/v1/images/${e}?ids=${c}&format=png&scale=2`,n),o);for(let u of l){let m=d.images[u.nodeId];if(!m)continue;let h=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${CS().slice(0,6)}.png`,f=yi(s,h);try{await Ap(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),M.info("figma",`Downloaded asset: ${h}`)}catch(b){M.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function _p(e,t,n,s,o){o&&o("Fetching Figma file...");let i=t?`/v1/files/${e}?ids=${t}&geometry=paths`:`/v1/files/${e}?geometry=paths`,r=await wa(()=>Si(i,n),o);M.info("figma",`Fetched file: ${r.name}`);let a=AS(r.document,t);if(a.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");M.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:_S(a),typography:$S(a),spacing:ES(a),effects:MS(a)};M.info("figma","Design tokens extracted",{colors:l.colors.length,typography:l.typography.length,spacing:l.spacing.length,effects:l.effects.length}),o&&o("Mapping page structure...");let c=RS(a),d=yi(s,".vibespot","figma-frames"),u=await FS(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=OS(a),h=yi(s,"assets"),f=await DS(e,g,n,h,o);return M.info("figma",`Extraction complete: ${m.length} sections, ${f.length} assets`),{fileName:r.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:f}}function $p(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 Ep(e){return await Si("/v1/me",e)}var kS,TS,wp,xa,Mp=N(()=>{"use strict";y();le();kS=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;TS="https://api.figma.com",wp=[10,20,40,60,120];xa=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var Fp={};Ge(Fp,{getCachedExtraction:()=>Op,handleFigmaExtractRoute:()=>ka,handleFigmaGenerateRoute:()=>Ta,handleFigmaTestTokenRoute:()=>Ca});import{randomUUID as Ip}from"crypto";import{existsSync as Pp,mkdirSync as Np,writeFileSync as jS,copyFileSync as LS}from"fs";import{join as vi,basename as JS}from"path";function Rp(){let e=Date.now();for(let[t,n]of Bs)n.expires<e&&Bs.delete(t)}function Op(e){Rp();let t=Bs.get(e);return t?(Bs.delete(e),t.extraction):null}function Ca(e,t){qe(e,t,async n=>{let s=n.token||R().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Ep(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);M.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function ka(e,t){qe(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||R().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=kp(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=C()?.themePath||`/tmp/vibespot-figma-${Ip().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)}
2753
-
2754
- `)};try{let c=await _p(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=Ip();Rp(),Bs.set(d,{extraction:c,expires:Date.now()+BS});let u=$p(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);M.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function HS(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((a,l)=>l.occurrences-a.occurrences),i=o[0],r=o[1];i&&s.push(`- **Primary:** \`${i.hex}\` (${i.variableName||"dominant color"})`),r&&s.push(`- **Secondary:** \`${r.hex}\` (${r.variableName||"accent color"})`),s.push(""),s.push("### Full palette","");for(let a of o.slice(0,15)){let l=a.variableName?`${a.variableName}`:`${a.occurrences}\xD7 used`;s.push(`- \`${a.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(r=>r.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let i=new Set;for(let r of t.typography){let a=`${r.role}-${r.fontSize}-${r.fontWeight}`;i.has(a)||(i.add(a),s.push(`| ${r.role} | ${r.fontFamily} | ${r.fontSize}px | ${r.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(i=>i.value))].sort((i,r)=>i-r);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let i of t.spacing)s.push(`- **${i.type}** (${i.context}): ${i.value}px`);s.push("")}if(t.effects.length>0){s.push("## Effects","");for(let o of t.effects)o.type==="shadow"?s.push(`- **Box shadow** (${o.context}): \`${o.cssValue}\``):o.type==="radius"?s.push(`- **Border radius** (${o.context}): ${o.cssValue}`):o.type==="blur"&&s.push(`- **Blur** (${o.context}): ${o.cssValue}`);s.push("")}return s.join(`
2755
- `)}function Ta(e,t){qe(e,t,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(t,400,{error:"Missing extractionId or themeName"});return}let r=Op(s);if(!r){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=C();if(!a){p(t,400,{error:"No active session. Create a theme first."});return}t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
2756
-
2757
- `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=HS(r),d=vi(a.themePath,".vibespot");if(Pp(d)||Np(d,{recursive:!0}),jS(vi(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,L(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)Rt("landing_page","Landing Page");else{a.modules=[],a.moduleOrder=[],a.sharedCss="",a.sharedJs="";let f=a.templates.find(b=>b.id===a.activeTemplateId);f&&(f.modules=[],f.moduleOrder=[],f.sharedCss="",f.sharedJs="")}if(L(),i&&r.assets.length>0){let f=vi(a.themePath,"assets");Np(f,{recursive:!0});let b=0;for(let S of r.assets)if(Pp(S.localPath)){let v=vi(f,JS(S.localPath));try{LS(S.localPath,v),S.localPath=v,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],g=await Fs(r,o,f=>{if(f.type==="agent_step")u.push({step:f.step,label:f.label}),l({type:"progress",message:`${f.label}...`});else if(f.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(f.decision)),l({type:"progress",message:` ${f.decision}`})}else f.type==="design_system_ready"?He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Wt(f.moduleOrder),l({type:"progress",message:`Planned ${f.moduleOrder.length} modules`})):f.type==="module_progress"&&(f.status==="generating"?l({type:"progress",message:`Generating module: ${f.module}`}):f.status==="complete"&&f.moduleFiles?(He({modules:[{moduleName:f.module,fieldsJson:f.moduleFiles.fieldsJson,metaJson:f.moduleFiles.metaJson,moduleHtml:f.moduleFiles.moduleHtml,moduleCss:f.moduleFiles.moduleCss,moduleJs:f.moduleFiles.moduleJs}]}),m.push({name:f.module,status:"complete"}),l({type:"progress",message:`Module complete: ${f.module}`})):f.status==="failed"&&(m.push({name:f.module,status:"failed"}),l({type:"progress",message:`Module failed: ${f.module}`})))},{useAssets:i});un(g,{steps:u,modules:m,stats:g.stats}),Te(),rn(a.themePath,`Figma import: ${r.fileName}`);let h=ve().map(f=>f.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${h.length} modules generated`}),l({type:"complete",ok:!0,modules:h})}catch(c){let d=c instanceof Error?c.message:String(c);M.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Bs,BS,Aa=N(()=>{"use strict";y();Xe();ee();le();Mp();Ce();gs();hr();Pn();Kn();Kt();Bs=new Map,BS=1800*1e3});import{readdirSync as Ea,statSync as US}from"fs";import{join as q,relative as GS}from"path";function qn(e){let t=q(e,Lt);if(!x(t))return null;try{return JSON.parse(P(t))}catch{return null}}function wi(e,t){let n=q(e,Lt);B(n,JSON.stringify(t,null,2)+`
2758
- `)}function Hs(e){let t=[];if(!x(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),_a(e,t,null);let n=$a(q(e,"theme.json"));if(!n)return t.push({severity:"error",rule:"theme.json.missing",file:"theme.json",message:"theme.json is missing or invalid JSON",fix:"Recreate the theme so theme.json is generated, or restore it from version control."}),_a(e,t,qn(e));VS(e,n,t),zS(e,n,t),YS(e,t),XS(e,t),ZS(e,t),QS(e,t);let s=qn(e);return ev(s,t),_a(e,t,s)}function _a(e,t,n){let s=t.filter(r=>r.severity==="error").length,o=t.filter(r=>r.severity==="warning").length,i=t.filter(r=>r.severity==="info").length;return{themePath:e,passed:s===0,errorCount:s,warningCount:o,infoCount:i,findings:t,metadata:n}}function VS(e,t,n){let s={documentation_url:'Add a "documentation_url" entry pointing to public docs for the theme.',license:'Add a "license" entry \u2014 an SPDX identifier or URL (e.g. "MIT").',example_url:'Add an "example_url" entry pointing to a public live preview of the theme.'};for(let r of WS)Tt(t,r)||n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json is missing required field "${r}"`,fix:s[r]??`Add a "${r}" entry to theme.json.`});for(let r of KS)(!(r in t)||typeof t[r]!="boolean")&&n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json must declare boolean "${r}"`,fix:`Add "${r}": true (or false) to theme.json.`});let o=t.author;!o||typeof o!="object"?n.push({severity:"error",rule:"theme.json.author.missing",file:"theme.json",message:'theme.json is missing required "author" block',fix:'Add { "author": { "name": "...", "email": "...", "url": "..." } } to theme.json.'}):(Tt(o,"name")||n.push({severity:"error",rule:"theme.json.author.name.missing",file:"theme.json",message:"theme.json author.name is missing",fix:"Provide a publisher name in theme.json author.name."}),Tt(o,"email")||n.push({severity:"error",rule:"theme.json.author.email.missing",file:"theme.json",message:"theme.json author.email is missing",fix:"Provide a contact email in theme.json author.email."}),Tt(o,"url")||n.push({severity:"error",rule:"theme.json.author.url.missing",file:"theme.json",message:"theme.json author.url is missing",fix:"Add a public URL for the publisher (homepage or support page)."}));let i=t.preview_path;if(typeof i=="string"&&i.length>0){let r=Jp(e,i);x(r)||n.push({severity:"error",rule:"theme.json.preview_path.invalid",file:"theme.json",message:`preview_path "${i}" does not point to an existing file`,fix:"Update preview_path to a real template, e.g. ./templates/home.html."})}}function zS(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Jp(e,s);if(!x(o)){n.push({severity:"error",rule:"theme.json.screenshot.missing",file:"theme.json",message:`Screenshot not found at ${s}`,fix:"Place a 1500\xD71000 PNG at the screenshot_path declared in theme.json."});return}/\.(png|jpg|jpeg)$/i.test(s)||n.push({severity:"warning",rule:"theme.json.screenshot.format",file:s,message:"Screenshot should be a PNG or JPG",fix:"Re-export the screenshot as PNG (1500\xD71000) or JPG."})}function YS(e,t){let n=q(e,"modules");if(!x(n)){t.push({severity:"warning",rule:"modules.empty",message:"Theme has no modules/ directory",fix:"Generate at least one module before submitting to Marketplace."});return}let s=0,o=[];try{o=Ea(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=q(n,i);qS(e,r,i,t)}s===0&&t.push({severity:"warning",rule:"modules.empty",message:"Theme has no .module directories",fix:"Generate at least one module before submitting to Marketplace."})}function qS(e,t,n,s){let o=$a(q(t,"meta.json")),i=mt(e,q(t,"meta.json"));o?(Tt(o,"label")||s.push({severity:"error",rule:"module.meta.label.missing",file:i,message:`${n}: meta.json is missing "label"`,fix:`Add a "label" entry to the module's meta.json.`,autoFixable:!0}),o.is_available_for_new_content===!1&&s.push({severity:"info",rule:"module.meta.unavailable",file:i,message:`${n}: is_available_for_new_content=false (won\u2019t be selectable in HubSpot UI)`})):s.push({severity:"error",rule:"module.meta.missing",file:i,message:`${n}: meta.json is missing or invalid`,fix:"Recreate the module so meta.json is generated."});let r=q(t,"fields.json"),a=mt(e,r);if(!x(r))s.push({severity:"warning",rule:"module.fields.missing",file:a,message:`${n}: fields.json is missing`,fix:"Add a fields.json (an empty array [] is acceptable for static modules)."});else{let c=$a(r);Array.isArray(c)?jp(c,n,a,s):s.push({severity:"warning",rule:"module.fields.invalid",file:a,message:`${n}: fields.json is not a JSON array`})}let l=q(t,"module.html");x(l)||s.push({severity:"error",rule:"module.html.missing",file:mt(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function jp(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)";Tt(i,"label")||s.push({severity:"error",rule:"module.field.label.missing",file:n,message:`${t}.${r}: field is missing "label"`,fix:`Add a human-readable "label" to the "${r}" field in fields.json.`,autoFixable:!0}),!Tt(i,"help_text")&&i.type!=="group"&&s.push({severity:"info",rule:"module.field.help_text.missing",file:n,message:`${t}.${r}: consider adding "help_text"`,fix:`Add a short "help_text" describing what "${r}" controls.`}),Array.isArray(i.children)&&jp(i.children,t,n,s)}}function XS(e,t){let n=[],s=q(e,"css");xi(s,".css").forEach(i=>{Dp(i,n,e)});let o=q(e,"modules");if(x(o))for(let i of Us(o)){if(!i.endsWith(".module"))continue;let r=q(o,i);["module.css","module.html"].forEach(a=>{let l=q(r,a);x(l)&&Dp(l,n,e)})}for(let i of n)t.push({severity:"error",rule:"asset.cdn-import",file:i.file,message:`External CDN reference found: ${i.match}`,fix:"Remove external @import / <link> URLs and bundle the asset locally.",autoFixable:!0})}function Dp(e,t,n){let s;try{s=P(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:mt(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:mt(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:mt(n,e),match:r[0]})}function ZS(e,t){let n=[{rule:"asset.hardcoded.hubfs",re:/https?:\/\/[\w.-]*hubfs[\w.-]*\/(\d+)\//i,message:"Hardcoded portal-specific HubFS URL detected"},{rule:"asset.hardcoded.usercontent",re:/hubspotusercontent[-\w]*\.net\/(\w+\/)?(\d+)\//i,message:"Hardcoded portal-specific HubSpot user-content URL detected"},{rule:"asset.hardcoded.preview",re:/\d+\.hs-sites\.com|hubspotpagebuilder\.com\/\d+/i,message:"Hardcoded portal preview URL detected"}],s=[],o=q(e,"css");xi(o,".css").forEach(a=>s.push(a));let i=q(e,"js");xi(i,".js").forEach(a=>s.push(a));let r=q(e,"modules");if(x(r))for(let a of Us(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=q(r,a,l);x(c)&&s.push(c)});for(let a of s){let l;try{l=P(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:mt(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function QS(e,t){let n=q(e,"modules");if(x(n))for(let s of Us(n)){if(!s.endsWith(".module"))continue;let o=q(n,s,"module.html");if(!x(o))continue;let i;try{i=P(o)}catch{continue}let r=/<img\b([^>]*)>/gi,a;for(;a=r.exec(i);){let c=a[1];/\balt\s*=/.test(c)||t.push({severity:"warning",rule:"a11y.img.alt-missing",file:mt(e,o),message:`${s}: <img> without alt attribute`,fix:'Add an alt attribute (alt="" is fine for purely decorative images).'})}/<(section|article|header|footer|main|nav|aside|h[1-6])\b/i.test(i)||t.push({severity:"info",rule:"a11y.semantics.missing",file:mt(e,o),message:`${s}: module.html has no semantic landmarks (section/article/header/etc.)`,fix:"Wrap the module's main content in a <section> with a heading."})}}function ev(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Lt,message:"marketplace.json sidecar not found",fix:"Run `vibespot marketplace edit` (CLI) or open the Marketplace panel in the editor to fill in listing details."});return}e.category?Zt.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Lt,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${Zt.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Lt,message:"marketplace.json has no category",fix:`Pick one of: ${Zt.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Lt,message:"marketplace.json description is missing or short (<40 chars)",fix:"Provide a 1\u20132 sentence description of the theme for the Marketplace listing."}),e.supportUrl||t.push({severity:"warning",rule:"marketplace.json.supportUrl.missing",file:Lt,message:"marketplace.json has no supportUrl",fix:"Add a public support URL where buyers can reach the publisher."});let n=e.features?.length??0;n<2?t.push({severity:"warning",rule:"marketplace.json.features.too_few",file:Lt,message:`marketplace.json needs at least 2 features (has ${n})`,fix:"Add 2\u20135 short bullet points highlighting what the theme does well."}):n>5&&t.push({severity:"warning",rule:"marketplace.json.features.too_many",file:Lt,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function Ci(e){let t=[],n=[],s=q(e,"modules");if(x(s))for(let i of Us(s)){if(!i.endsWith(".module"))continue;let r=q(s,i),a=i.replace(/\.module$/,""),l=q(r,"meta.json");if(x(l))try{let d=JSON.parse(P(l));Tt(d,"label")||(d.label=Bp(a),B(l,JSON.stringify(d,null,2)+`
2759
- `),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=q(r,"fields.json");if(x(c))try{let d=JSON.parse(P(c));if(Array.isArray(d)){let u=Lp(d);u>0&&(B(c,JSON.stringify(d,null,2)+`
2760
- `),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=tv(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function tv(e){let t=[],n=/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,s=/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,o=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*><\/script>/gi,i=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*\/>/gi;function r(c){let d;try{d=P(c)}catch{return}let u=d.replace(n,"");u!==d&&(B(c,u),t.push(mt(e,c)))}function a(c){let d;try{d=P(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(B(c,u),t.push(mt(e,c)))}xi(q(e,"css"),".css").forEach(r);let l=q(e,"modules");if(x(l))for(let c of Us(l)){if(!c.endsWith(".module"))continue;let d=q(l,c),u=q(d,"module.css"),m=q(d,"module.html");x(u)&&r(u),x(m)&&a(m)}return t}function Lp(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!Tt(s,"label")&&Tt(s,"name")&&(s.label=Bp(String(s.name)),t++),Array.isArray(s.children)&&(t+=Lp(s.children))}return t}function $a(e){if(!x(e))return null;try{let t=JSON.parse(P(e));return t&&typeof t=="object"?t:null}catch{return null}}function Tt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Jp(e,t){let n=t.replace(/^\.?\//,"");return q(e,n)}function mt(e,t){return GS(e,t).split("\\").join("/")}function Us(e){try{return Ea(e)}catch{return[]}}function xi(e,t){if(!x(e))return[];try{let n=[];for(let s of Ea(e)){let o=q(e,s);US(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Bp(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var Zt,WS,KS,Lt,Ma=N(()=>{"use strict";y();oe();Zt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],WS=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],KS=["enable_domain_stylesheets","is_available_for_new_content"],Lt="marketplace.json"});function Ia(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Te()}catch{}return t.themePath}function Hp(e,t){let n=Ia(t);if(!n)return;let s=Hs(n);p(t,200,{report:s,categories:Zt})}function Up(e,t){let n=Ia(t);if(!n)return;let s=Ci(n),o=Hs(n);p(t,200,{fix:s,report:o})}function Gp(e,t,n){let s=Ia(n);if(s){if(e==="GET"){p(n,200,{metadata:qn(s),categories:Zt});return}if(e==="POST"){qe(t,n,o=>{let i={category:typeof o.category=="string"?o.category:void 0,description:typeof o.description=="string"?o.description:void 0,features:Array.isArray(o.features)?o.features.filter(r=>typeof r=="string"&&r.trim().length>0):void 0,supportUrl:typeof o.supportUrl=="string"?o.supportUrl:void 0,documentationUrl:typeof o.documentationUrl=="string"?o.documentationUrl:void 0,pricingTier:o.pricingTier==="free"||o.pricingTier==="paid"?o.pricingTier:void 0,tags:Array.isArray(o.tags)?o.tags.filter(r=>typeof r=="string"):void 0};wi(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Wp=N(()=>{"use strict";y();Xe();Ce();Ma()});function nv(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Te()}catch{}return t.themePath}function Kp(e,t){let n=nv(t);if(!n)return;let s=Bo(n);p(t,200,{report:s})}function Vp(e,t){let n=C();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=Dn(n.themePath),o=bs(s);if(!o){p(t,200,{applied:!1,reason:"No tokens to apply."});return}if(!n.sharedCss||n.sharedCss.trim().length===0){n.sharedCss=o,n.updatedAt=Date.now(),L(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=Ho(n.themePath,n.themeName);i?p(t,200,{applied:!0,written:i,rootBlock:o}):p(t,200,{applied:!1,reason:"Theme already has shared CSS."})}var zp=N(()=>{"use strict";y();Xe();Ce();Uo()});import{createServer as sv}from"http";import{readFileSync as Ra,existsSync as Gs}from"fs";import{join as Bt,extname as qp}from"path";import{WebSocketServer as ov,WebSocket as iv}from"ws";function Ae(e){Ti&&Ti.readyState===iv.OPEN&&Ti.send(JSON.stringify(e))}function ki(e){Ai.push(e),Ae(e)}function Jt(){Ai=[]}function Pa(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;ki(o)}else ki(n);if(n.type==="agent_step")e.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=e[e.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Wt(n.moduleOrder),ki({type:"modules_updated",modules:ve().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(He({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),ki({type:"modules_updated",modules:ve().map(s=>s.moduleName)}),t.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&t.push({name:n.module,status:"failed"})}}function Na(e){let t=e.cost;if(!t||t.calls===0)return;let n=C();Ae({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}function Jn(){return Zp}function _i(e){let{port:t,uiDir:n}=e;Zp=e.contentMode||"page";let s=sv((i,r)=>rv(i,r,n)),o=new ov({server:s});return o.on("connection",i=>lv(i)),new Promise((i,r)=>{s.on("error",a=>{a.code==="EADDRINUSE"?s.listen(t+1,"0.0.0.0",()=>{i({port:t+1,close:()=>{s.close(),o.close()}})}):r(a)}),s.listen(t,"0.0.0.0",()=>{i({port:t,close:()=>{s.close(),o.close()}})})})}function rv(e,t,n){let s=new URL(e.url||"/",`http://${e.headers.host}`),o=e.method||"GET";if(t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("X-XSS-Protection","1; mode=block"),t.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname==="/healthz"){t.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify({status:"ok"}));return}if(s.pathname.startsWith("/api/")){av(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=wr();t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",r=Cr(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){cv(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";Yp(i,Bt(n,"docs"),e,t);return}Yp(s.pathname,n,e,t)}function av(e,t,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1|100\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|10\.\d+\.\d+\.\d+)(:\d+)?$/.test(o)&&s.setHeader("Access-Control-Allow-Origin",o),s.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type"),e==="OPTIONS"){s.writeHead(204),s.end();return}switch(t){case"/api/session":mp(e,s);break;case"/api/modules":pp(e,n,s);break;case"/api/modules/reorder":fp(n,s);break;case"/api/modules/code":gp(n,s);break;case"/api/upload":hp(s);break;case"/api/upload-files":e==="POST"?fd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":yp(n,s);break;case"/api/import":bp(n,s);break;case"/api/setup":sm(s);break;case"/api/setup/create":om(n,s);break;case"/api/setup/fetch":rm(n,s);break;case"/api/setup/open":am(n,s);break;case"/api/setup/resume":lm(n,s);break;case"/api/setup/apikey":cm(n,s);break;case"/api/setup/remote-themes":e==="GET"?dm(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?im(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?bm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/models":e==="GET"?Sm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/tools":e==="GET"?vm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?xm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?wm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Cm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?km(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?Tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?Am(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?_m(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?$m(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Em(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Mm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Rm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Om(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Im(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Wa()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":jm(e,n,s);break;case"/api/themes/switch":e==="POST"?Lm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Jm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Bm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?Hm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?Sp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?vp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Ym(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Zm(e,n,s);break;case"/api/templates/activate":e==="POST"?Qm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?ep(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?np(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?tp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?sp(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":ip(e,n,s);break;case"/api/brand-kit":lp(e,n,s);break;case"/api/fonts":e==="GET"?ap(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?cp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?dp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Xm(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?Ca(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?ka(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?Ta(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Ru(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Ou(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Fu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?Du(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?Hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?Up(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Gp(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Kp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Vp(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?Pm(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?op(t,n,s):p(s,404,{error:"Not found"})}}function lv(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(ia()){lt("user",o),L();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await oa(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=Lu(l||a);c.plan&&(ni(c.plan),e.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&e.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),lt("assistant",c.cleanedContent),L(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(a){e.send(JSON.stringify({type:"error",message:a instanceof Error?a.message:String(a)}))}break}lt("user",o),L();let r=ra();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Jt();let l=[],c=[],d=await ei(o,Pa(l,c),i);un(d,{steps:l,modules:c,stats:d.stats,cost:d.cost}),Na(d)}else na(l=>{Ae({type:"parse_warning",message:l})}),await Os(o,l=>{Ae({type:"stream",content:l})},l=>{Ae({type:"stream_status",content:l})},i);let a=C();if(a){Te();let l=ke(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${a.themeName}-theme.css`),l.sharedJs&&d.push(`js/${a.themeName}-animations.js`),c=ir(a.themePath,l.id,o,d)}else c=rn(a.themePath,o);c&&Ae({type:"version_created",hash:c})}Ae({type:"generation_complete"});{let l=C();Ae({type:"modules_updated",modules:ve().map(c=>c.moduleName),templateId:l?.activeTemplateId||null,templates:(l?.templates||[]).map(c=>({id:c.id,label:c.label,pageType:c.pageType,moduleCount:c.modules.length}))})}Jt();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Ae({type:"suggest_brand_extraction"})}}catch(a){Jt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:r}=await Promise.resolve().then(()=>(Aa(),Fp)),a=r(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=C();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:h}=await import("fs"),{createThemeScaffold:f}=await Promise.resolve().then(()=>(rs(),fl)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!h(b)){let{mkdirSync:v}=await import("fs");v(b,{recursive:!0})}h(S)||f(S,i),On(S,i),L()}Ae({type:"figma_import_started",fileName:a.fileName}),Jt();let c=[],d=[],u=await Fs(a,i,Pa(c,d));un(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),Na(u),Te(),rn(C().themePath,`Figma import: ${a.fileName}`),Ae({type:"generation_complete"});{let m=C();Ae({type:"modules_updated",modules:ve().map(g=>g.moduleName),templateId:m?.activeTemplateId||null,templates:(m?.templates||[]).map(g=>({id:g.id,label:g.label,pageType:g.pageType,moduleCount:g.modules.length}))})}Jt()}catch(l){Jt(),Ae({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=R(),{engine:r,apiKey:a,model:l}=Wn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ws(),Wo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(ui(),di)),m=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>te("extract-theme-context",()=>u(d,o.brandAssets?.themeContext,r,a,l))),{mkdirSync:g,writeFileSync:h}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let f=Bt(o.themePath,".vibespot");Gs(f)||g(f,{recursive:!0}),h(Bt(f,"theme-context.md"),m),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(Js(),Ls)),b=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>f(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=Bt(o.themePath,".vibespot");Gs(S)||g(S,{recursive:!0}),h(Bt(S,"styleguide.md"),b),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Te();let i=Ao(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(R().hubspotUploadMode||"api")==="api"){let l=Le();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await $o(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2761
- `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
2762
- `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
2763
- `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Ht();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:Jn()}))}else{let d=ko(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2764
- `),errors:d}))}}else{let l=oi(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:Bt(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}))};Hu(l,c);let d=setInterval(()=>{let u=si(l);if(!(!u||u.status==="running"))if(clearInterval(d),Uu(l,c),u.status==="completed"){let m=ht(),g=m.portalId?ts(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:Jn()}))}else{let m=To(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.
2765
-
2766
- IMPORTANT: Be verbose in your response. For each error:
2767
- 1. State exactly which file has the problem and what the error is
2768
- 2. Explain WHY this error occurs (e.g. "HubSpot doesn't support textarea field type" or "field name 'name' is reserved in HubSpot modules")
2769
- 3. Describe the specific fix you're applying (e.g. "Changing field type from textarea to text" or "Renaming field from 'name' to 'item_name'")
2770
- 4. Apply the fix to the module files
2771
-
2772
- CRITICAL: After fixing the reported errors, scan ALL other module files in the theme for the same issues. For example, if you fix "name" \u2192 "item_name" in one module, check every other module's fields.json for the same problem. Fix all occurrences, not just the ones in the error log.
2629
+ [Attached document: ${k.originalName}]
2630
+ ${k.extractedText}`);let v=await c(r,i,a,{systemPrompt:h,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return v.type==="text"?v.text:JSON.stringify(v.data)}function tl(){return!!$().planMode}function nl(){let e=$(),t=e.aiEngine||Xa();return zs(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 Va,Ut,Rr,qa,os=j(()=>{"use strict";y();te();me();Sr();re();jo();rr();$t();va();Da();Ua();Qn();Ue();Va=null;Ut=new Set;Rr=new Map;qa=new Set});import{writeFileSync as fw,mkdirSync as Gg}from"fs";import{join as Wr}from"path";import{randomUUID as hw}from"crypto";function Wg(e){let t;try{t=new URL(e)}catch{return null}if(t.protocol!=="https:"||!bw.has(t.hostname.toLowerCase()))return null;let n=t.pathname.match(yw);if(!n)return null;let s=n[1],o=n[2]?decodeURIComponent(n[2].replace(/-/g," ")):void 0,r,i=t.searchParams.get("node-id");return i&&(r=i.replace(/-/g,":"),!/^[a-zA-Z0-9:]+$/.test(r))?null:{fileKey:s,nodeId:r,fileName:o}}function Kg(e){return e.map(t=>encodeURIComponent(t)).join(",")}async function Vr(e,t){let n=await fetch(`${vw}${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 ll(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=Ug.length)throw s;let i=Ug[n];A.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${i}s`),t&&t(`Figma rate limited \u2014 retrying in ${i}s...`),await new Promise(a=>setTimeout(a,i*1e3))}}function Cn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)Cn(s,t,n+1)}function Vg(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=Vg(n,t);if(s)return s}return null}function xw(e,t){if(t){let s=Vg(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(r=>al.has(r.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>al.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>al.has(s.type)):[]}function Kr(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 ww(e){let t=new Map;for(let n of e)Cn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let r=Kr(o.color),i=t.get(r),a=s.type==="TEXT",l=a?"text":"fill";i?(i.occurrences++,a&&i.usage!=="text"&&(i.usage="text")):t.set(r,{hex:r,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 r=Kr(o.color),i=t.get(r);i?i.occurrences++:t.set(r,{hex:r,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function kw(e){let t=new Map;for(let n of e)Cn(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,r=o.fontSize||16,i=o.fontWeight||400,a=o.lineHeightPx?Math.round(o.lineHeightPx/r*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";r>=32?d="heading":r>=20?d="subheading":r<=12?d="caption":i>=600&&r<=14&&(d="label");let u=`${c}-${r}-${i}`,p=t.get(u);p?p.occurrences++:t.set(u,{fontFamily:c,fontSize:r,fontWeight:i,lineHeight:a,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function Cw(e){let t=[],n=new Set;for(let s of e)Cn(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 r=o.paddingTop||0,i=o.paddingRight||0,a=o.paddingBottom||0,l=o.paddingLeft||0;if(r>0||i>0||a>0||l>0){let c=`pad-${r}-${i}-${a}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=r===a&&l===i&&r===l?r:Math.max(r,i,a,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function Tw(e){let t=[],n=new Set;for(let s of e)Cn(s,o=>{if(o.effects){for(let r of o.effects)if(r.type==="DROP_SHADOW"&&r.color&&r.offset){let{r:i,g:a,b:l,a:c}=r.color,d=`${r.offset.x}px ${r.offset.y}px ${r.radius||0}px rgba(${Math.round(i*255)},${Math.round(a*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let r=`${o.cornerRadius}px`;n.has(`radius-${r}`)||(n.add(`radius-${r}`),t.push({type:"radius",cssValue:r,context:o.name}))}});return t}function Aw(e,t){let n=[];return Cn(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,r=s.style?.fontWeight||400,i="body";o>=32?i="headline":o>=20?i="subheadline":o<=12?i="caption":r>=600&&o<=16&&(i="label"),r>=600&&s.characters.length<40&&o>=14&&o<32&&(i="cta"),n.push({text:s.characters,fontSize:o,fontWeight:r,role:i,sectionName:t})}),n}function _w(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 Pw(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Kr(t.color)}if(e.backgroundColor)return Kr(e.backgroundColor)}function Ew(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:Aw(t,t.name),children:(t.children||[]).slice(0,20).map(_w),backgroundColor:Pw(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 Iw(e){let t=[];for(let n of e)Cn(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}function Mw(e){let t;try{t=new URL(e)}catch{return!1}return t.protocol==="https:"&&Sw.has(t.hostname.toLowerCase())}async function zg(e,t){if(!Mw(e))throw new Error("Figma image download URL is not on the allowed Figma CDN host list");let n=await fetch(e,{redirect:"manual"});if(!n.ok)throw new Error(`Failed to download image: ${n.status}`);let s=Number(n.headers.get("content-length")||"0");if(Number.isFinite(s)&&s>Gr)throw new Error(`Figma image download exceeds ${Gr} bytes`);let o=n.headers.get("content-type")||"";if(!o.toLowerCase().startsWith("image/"))throw new Error(`Figma image download returned non-image content: ${o||"unknown"}`);let r=Buffer.from(await n.arrayBuffer());if(r.byteLength>Gr)throw new Error(`Figma image download exceeds ${Gr} bytes`);fw(t,r)}async function $w(e,t,n,s,o){if(t.length===0)return new Map;Gg(s,{recursive:!0});let r=t.map(c=>c.id),i=Kg(r);o&&o("Exporting frame screenshots...");let a=await ll(()=>Vr(`/v1/images/${e}?ids=${i}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(a.images)){if(!d)continue;let u=c.replace(/:/g,"-"),p=Wr(s,`frame-${u}.png`);try{await zg(d,p),l.set(c,p),A.info("figma",`Downloaded frame screenshot: ${p}`)}catch(g){A.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function Rw(e,t,n,s,o){if(t.length===0)return[];Gg(s,{recursive:!0});let r=50,i=[];for(let a=0;a<t.length;a+=r){let l=t.slice(a,a+r),c=Kg(l.map(u=>u.nodeId));o&&o(`Exporting images (${a+1}-${Math.min(a+r,t.length)} of ${t.length})...`);let d=await ll(()=>Vr(`/v1/images/${e}?ids=${c}&format=png&scale=2`,n),o);for(let u of l){let p=d.images[u.nodeId];if(!p)continue;let f=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${hw().slice(0,6)}.png`,h=Wr(s,f);try{await zg(p,h),i.push({name:u.name,localPath:h,nodeId:u.nodeId,format:"png"}),A.info("figma",`Downloaded asset: ${f}`)}catch(b){A.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return i}async function qg(e,t,n,s,o){o&&o("Fetching Figma file...");let r=t?`/v1/files/${e}?ids=${encodeURIComponent(t)}&geometry=paths`:`/v1/files/${e}?geometry=paths`,i=await ll(()=>Vr(r,n),o);A.info("figma",`Fetched file: ${i.name}`);let a=xw(i.document,t);if(a.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");A.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:ww(a),typography:kw(a),spacing:Cw(a),effects:Tw(a)};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=Ew(a),d=Wr(s,".vibespot","figma-frames"),u=await $w(e,a,n,d,o),p=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=Iw(a),f=Wr(s,"assets"),h=await Rw(e,g,n,f,o);return A.info("figma",`Extraction complete: ${p.length} sections, ${h.length} assets`),{fileName:i.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:p,assets:h}}function Yg(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 Xg(e){return await Vr("/v1/me",e)}var yw,bw,Sw,Gr,vw,Ug,al,Zg=j(()=>{"use strict";y();re();yw=/^\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/,bw=new Set(["figma.com","www.figma.com"]),Sw=new Set(["s3-alpha.figma.com","s3-alpha-sig.figma.com","figma-alpha-api.s3.amazonaws.com","figma-alpha-api.s3.us-west-2.amazonaws.com"]),Gr=25*1024*1024;vw="https://api.figma.com",Ug=[10,20,40,60,120];al=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var of={};Ve(of,{getCachedExtraction:()=>sf,handleFigmaExtractRoute:()=>dl,handleFigmaGenerateRoute:()=>ul,handleFigmaTestTokenRoute:()=>cl});import{randomUUID as Qg}from"crypto";import{existsSync as ef,mkdirSync as tf,writeFileSync as Nw,copyFileSync as Ow}from"fs";import{join as zr,basename as Fw}from"path";function nf(){let e=Date.now();for(let[t,n]of io)n.expires<e&&io.delete(t)}function sf(e){nf();let t=io.get(e);return t?(io.delete(e),t.extraction):null}function cl(e,t){Ze(e,t,async n=>{let s=n.token||$().figmaToken;if(!s){m(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Xg(s);m(t,200,{ok:!0,user:o})}catch(o){let r=N(o);A.warn("figma",`Token test failed: ${r}`),m(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function dl(e,t){Ze(e,t,async n=>{let s=n.url;if(!s){m(t,400,{error:"Missing 'url' field"});return}let o=n.token||$().figmaToken;if(!o){m(t,400,{error:"No Figma token configured. Add one in Settings."});return}let r=Wg(s);if(!r){m(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=x()?.themePath||`/tmp/vibespot-figma-${Qg().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)}
2773
2631
 
2774
- After fixing all errors, summarize the changes you made.
2632
+ `)};try{let c=await qg(r.fileKey,r.nodeId,o,a,p=>l({type:"progress",message:p})),d=Qg();nf(),io.set(d,{extraction:c,expires:Date.now()+Dw});let u=Yg(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=N(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 jw(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((a,l)=>l.occurrences-a.occurrences),r=o[0],i=o[1];r&&s.push(`- **Primary:** \`${r.hex}\` (${r.variableName||"dominant color"})`),i&&s.push(`- **Secondary:** \`${i.hex}\` (${i.variableName||"accent color"})`),s.push(""),s.push("### Full palette","");for(let a of o.slice(0,15)){let l=a.variableName?`${a.variableName}`:`${a.occurrences}\xD7 used`;s.push(`- \`${a.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(i=>i.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let r=new Set;for(let i of t.typography){let a=`${i.role}-${i.fontSize}-${i.fontWeight}`;r.has(a)||(r.add(a),s.push(`| ${i.role} | ${i.fontFamily} | ${i.fontSize}px | ${i.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(r=>r.value))].sort((r,i)=>r-i);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let r of t.spacing)s.push(`- **${r.type}** (${r.context}): ${r.value}px`);s.push("")}if(t.effects.length>0){s.push("## Effects","");for(let o of t.effects)o.type==="shadow"?s.push(`- **Box shadow** (${o.context}): \`${o.cssValue}\``):o.type==="radius"?s.push(`- **Border radius** (${o.context}): ${o.cssValue}`):o.type==="blur"&&s.push(`- **Blur** (${o.context}): ${o.cssValue}`);s.push("")}return s.join(`
2633
+ `)}function ul(e,t){Ze(e,t,async n=>{let s=n.extractionId,o=n.themeName,r=n.useAssets!==!1;if(!s||!o){m(t,400,{error:"Missing extractionId or themeName"});return}let i=sf(s);if(!i){m(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=x();if(!a){m(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)}
2775
2634
 
2776
- Upload log:
2777
- ${o}`;lt("user",i),L(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await Os(i,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=C();if(r){Te();let a=rn(r.themePath,"AI fix: upload errors");a&&e.send(JSON.stringify({type:"version_created",hash:a}))}e.send(JSON.stringify({type:"upload_fix_complete"}));{let a=C();e.send(JSON.stringify({type:"modules_updated",modules:ve().map(l=>l.moduleName),templateId:a?.activeTemplateId||null,templates:(a?.templates||[]).map(l=>({id:l.id,label:l.label,pageType:l.pageType,moduleCount:l.modules.length}))}))}}catch(r){e.send(JSON.stringify({type:"upload_failed",output:r instanceof Error?r.message:String(r),errors:[{file:"AI fix",message:r instanceof Error?r.message:String(r),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.brandAssets?.plan;if(!i||!i.trim()){e.send(JSON.stringify({type:"error",message:"No plan to approve. Send a chat message first."}));break}Y({planMode:!1});let r="Implement the approved plan.";lt("user",r),L();try{Jt();let a=[],l=[],c=await ei(r,Pa(a,l));un(c,{steps:a,modules:l,stats:c.stats,cost:c.cost}),Na(c);let d=C();if(d){Te();let u=ke(),m=null;if(u){let g=u.moduleOrder.map(h=>`modules/${h}.module`);u.templateFile&&g.push(u.templateFile),u.sharedCss&&g.push(`css/${d.themeName}-theme.css`),u.sharedJs&&g.push(`js/${d.themeName}-animations.js`),m=ir(d.themePath,u.id,"Approved plan: implementation",g)}else m=rn(d.themePath,"Approved plan: implementation");m&&Ae({type:"version_created",hash:m})}Ae({type:"generation_complete"});{let u=C();Ae({type:"modules_updated",modules:ve().map(m=>m.moduleName),templateId:u?.activeTemplateId||null,templates:(u?.templates||[]).map(m=>({id:m.id,label:m.label,pageType:m.pageType,moduleCount:m.modules.length}))})}Jt()}catch(a){Jt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{la(),Y({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),Ti=e;let t=C();if(t){let n=R(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Yt(),i=ke();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:ve().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:rt(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",updatedAt:t.updatedAt,templateId:i?.id||null,pageType:i?.pageType||null,templates:(t.templates||[]).map(r=>({id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||"",isGenerating:o,costTotal:t.costTotal||null})),o&&Ai.length>0)for(let r of Ai)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function cv(e,t){let n=C();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=Bt(n.themePath,"assets",e);if(!Gs(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=qp(s),i=Xp[o]||"application/octet-stream",r=Ra(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Yp(e,t,n,s){let i=Bt(t,e==="/"?"/index.html":e);if(!Gs(i)){let c=Bt(t,"index.html");if(Gs(c)){let d=Ra(c);s.writeHead(200,{"Content-Type":"text/html","Cache-Control":"no-cache"}),s.end(d)}else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not found");return}let r=qp(i),a=Xp[r]||"application/octet-stream",l=r===".html";try{let c=Ra(i);s.writeHead(200,{"Content-Type":a,"Cache-Control":"no-store"}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}var Xp,Ti,Ai,Zp,Cs=N(()=>{"use strict";y();Ce();Pn();ws();Kn();ju();Ju();ee();nn();_o();ii();sr();Xe();oe();Be();fi();Nm();Dm();Um();up();xp();jr();Aa();Wp();zp();Xp={".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"},Ti=null,Ai=[];Zp="page"});y();y();import{Command as wv}from"commander";y();y();gt();oe();function Ee(){let e=I.vibes,t=I.accent,n=I.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${I.dim(`v${Sn()}`)}`),console.log()}y();nn();$t();Qt();ee();sn();Qe();gt();async function co(){await ge("Checking your environment");let e=Qn();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),oo(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),G(`Node.js v${e.version}`);let t=es();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),G(`Git ${t.version}`);let n=R(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Le(),S=Ht();if(b)o=S?.portalId||"",i=S?.portalName||"",G(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{se("No HubSpot account connected"),await yt(`You need a Personal Access Key to deploy themes.
2635
+ `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=jw(i),d=zr(a.themePath,".vibespot");if(ef(d)||tf(d,{recursive:!0}),Nw(zr(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,D(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)jt("landing_page","Landing Page");else{a.modules=[],a.moduleOrder=[],a.sharedCss="",a.sharedJs="";let h=a.templates.find(b=>b.id===a.activeTemplateId);h&&(h.modules=[],h.moduleOrder=[],h.sharedCss="",h.sharedJs="")}if(D(),r&&i.assets.length>0){let h=zr(a.themePath,"assets");tf(h,{recursive:!0});let b=0;for(let S of i.assets)if(ef(S.localPath)){let v=zr(h,Fw(S.localPath));try{Ow(S.localPath,v),S.localPath=v,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],p=[],g=await ro(i,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"?Ge({sharedCss:h.sharedCss,sharedJs:h.sharedJs}):h.type==="blueprint_ready"?(Ge({sharedCss:h.sharedCss,sharedJs:h.sharedJs}),Yt(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?(Ge({modules:[{moduleName:h.module,fieldsJson:h.moduleFiles.fieldsJson,metaJson:h.moduleFiles.metaJson,moduleHtml:h.moduleFiles.moduleHtml,moduleCss:h.moduleFiles.moduleCss,moduleJs:h.moduleFiles.moduleJs}]}),p.push({name:h.module,status:"complete"}),l({type:"progress",message:`Module complete: ${h.module}`})):h.status==="failed"&&(p.push({name:h.module,status:"failed"}),l({type:"progress",message:`Module failed: ${h.module}`})))},{useAssets:r});xn(g,{steps:u,modules:p,stats:g.stats}),Ae(),pn(a.themePath,`Figma import: ${i.fileName}`);let f=pe().map(h=>h.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${f.length} modules generated`}),l({type:"complete",ok:!0,modules:f})}catch(c){let d=N(c);A.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var io,Dw,pl=j(()=>{"use strict";y();At();Re();te();re();Zg();me();Ps();zi();Hn();os();Xt();io=new Map,Dw=1800*1e3});y();y();import{Command as Mk}from"commander";y();y();y();import An from"chalk";var bt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},El=!!process.env.NO_COLOR;function Et(e){return El?An:An.hex(e)}var E={accent:Et(bt.accent),accentBright:Et(bt.accentBright),success:Et(bt.success),info:Et(bt.info),warn:Et(bt.warn),error:Et(bt.error),muted:Et(bt.muted),vibes:Et(bt.vibes),heading:El?An.bold:An.bold.hex(bt.accent),command:Et(bt.accentBright),dim:An.dim,bold:An.bold};ae();function Pe(){let e=E.vibes,t=E.accent,n=E.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")} ${E.dim(`v${Mt()}`)}`),console.log()}y();y();on();te();$t();import{join as So}from"path";import{homedir as vo}from"os";import{readFileSync as Bl,existsSync as xo,readdirSync as gh}from"fs";var an=process.platform==="win32"?"where":"which",Jl=4e3;function gs(){let e=Se("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:Se(`${an} node`).stdout}}function fs(){let e=Se("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:Se(`${an} git`).stdout}}function St(){let e=Se("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:Se(`${an} hs`).stdout}}function Rn(){let e=Se("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=So(vo(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(xo(t)){let o=gh(t);(o.some(i=>i.includes("credentials")||i.includes("auth")||i.includes("token")||i===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:Se(`${an} claude`).stdout,authenticated:n,authDetail:s}}function hs(e){try{let t=So(vo(),".hscli","config.yml");if(!xo(t))return"na1";let n=Bl(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 i=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!i)return"na1";if(i[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function vt(){let e=Se("hs accounts list",{timeout:Jl});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 r=e.stdout.split(`
2636
+ `);for(let i of r){let a=i.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(a&&!/Account ID/i.test(i)&&!/^-+$/.test(i.trim())&&!/^Name\s/i.test(i.trim())){let l=a[1].trim(),c=a[2].trim(),d=a[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Nn(){let e=Se("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=So(vo(),".config","gcloud","application_default_credentials.json"),n=xo(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:Se(`${an} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function On(){let e=Se("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 r=So(vo(),".codex","auth.json");xo(r)&&(n=Bl(r,"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:Se(`${an} codex`).stdout,authenticated:s,authDetail:o}}function wo(){let e=Se("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
2637
+ `)[0]?.replace("gh version ","").split(" ")[0]||"",path:Se(`${an} gh`).stdout}}function ko(){let e=Se("gh auth status 2>&1",{timeout:Jl});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 Hl(){return!!process.env.ANTHROPIC_API_KEY}function Co(e){return parseInt(e.split(".")[0],10)>=18}function Ul(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function fh(){let e=$(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(r=>({name:r.portalName,portalId:r.portalId,authType:"personalaccesskey",isDefault:r.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Vt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}var $n={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function Mn(e,...t){if(e)return{configured:!0,masked:fo(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:fo(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function Ti(e){return{anthropic:Mn(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:Mn(e.openaiApiKey,"OPENAI_API_KEY"),gemini:Mn(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:Mn(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:Mn(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:Mn(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function Ai(e){let t=[];return e.claudeCode&&t.push("claude-code"),e.claudeOAuth&&t.push("claude-oauth"),e.apiKeys.anthropic.configured&&t.push("anthropic-api"),e.apiKeys.openai.configured&&t.push("openai-api"),e.geminiCli&&t.push("gemini-cli"),e.apiKeys.gemini.configured&&t.push("gemini-api"),e.codexCli&&t.push("codex-cli"),e.apiKeys.langdock.configured&&t.push("langdock-api"),t}function _i(e,t){if(e==="cli"){if(!t)return{name:"HubSpot CLI",found:!1,version:"",path:"",authenticated:!1,portalName:"",portalId:"",dataCenter:"na1",accounts:[],uploadMode:"cli"};let n=St(),s=n.found?vt():{authenticated:!1,portalName:"",portalId:"",accounts:[]},o=s.portalId?hs(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...fh()}}function Gl(){let e=$(),t=e.hubspotUploadMode||"api",n=Ti(e),s={authenticated:Qe(),expiresAt:rn()?.expiresAt},o=i=>({name:i,found:!1,version:"",path:"",authenticated:!1,authDetail:"Not scanned"}),r=i=>({name:i,found:!1,version:"",path:""});return{tools:{node:r("Node.js"),git:r("Git"),hubspot:_i(t,!1),github:{...r("GitHub CLI"),authenticated:!1,username:""},claudeCode:o("Claude Code"),claudeOAuth:s,geminiCli:o("Gemini CLI"),codexCli:o("OpenAI Codex CLI")},apiKeys:n,activeEngine:e.aiEngine||null,availableEngines:Ai({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:rt("claude-code"),geminiCli:rt("gemini-cli"),codexCli:rt("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function Wl(){let e=$(),t=Ti(e),n={authenticated:Qe(),expiresAt:rn()?.expiresAt},s=rt("claude-code")?Rn():{...$n,name:"Claude Code"},o=rt("gemini-cli")?Nn():{...$n,name:"Gemini CLI"},r=rt("codex-cli")?On():{...$n,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:r,claudeOAuth:n,availableEngines:Ai({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:r.found&&r.authenticated})}}function Kl(){let t=$().hubspotUploadMode||"api",n=wo(),s=n.found?ko():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:_i(t,!0)}}function To(){let e=$(),t=e.hubspotUploadMode||"api",n=gs(),s=fs(),o=_i(t,!0),r=wo(),i=r.found?ko():{authenticated:!1,username:""},a={authenticated:Qe(),expiresAt:rn()?.expiresAt},l=rt("claude-code")?Rn():{...$n,name:"Claude Code"},c=rt("gemini-cli")?Nn():{...$n,name:"Gemini CLI"},d=rt("codex-cli")?On():{...$n,name:"OpenAI Codex CLI"},u=Ti(e);return{tools:{node:n,git:s,hubspot:o,github:{...r,...i},claudeCode:l,claudeOAuth:a,geminiCli:c,codexCli:d},apiKeys:u,activeEngine:e.aiEngine||null,availableEngines:Ai({apiKeys:u,claudeOAuth:a.authenticated,claudeCode:l.found&&l.authenticated,geminiCli:c.found&&c.authenticated,codexCli:d.found&&d.authenticated}),enabledCLITools:e.enabledCLITools||[],scanned:!0}}$t();on();te();cn();y();import*as le from"@clack/prompts";function Ei(e){le.isCancel(e)&&(le.cancel(E.muted("Operation cancelled.")),process.exit(0))}async function fe(e){le.intro(E.heading(e))}async function he(e){le.outro(E.success(e))}async function xt(e,t){le.note(e,t?E.heading(t):void 0)}async function ve(e){let t=e.validate,n=await le.text({message:E.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:t?s=>t(s??""):void 0});return Ei(n),n}async function Ee(e){let t=await le.confirm({message:E.accent(e.message),initialValue:e.initialValue??!0});return Ei(t),t}async function Nt(e){let t=await le.select({message:E.accent(e.message),options:e.options});return Ei(t),t}async function je(){let e=le.spinner();return{start:t=>e.start(E.muted(t)),stop:t=>e.stop(E.success(t)),message:t=>e.message(E.muted(t))}}function B(e){le.log.info(e)}function K(e){le.log.success(E.success(e))}function se(e){le.log.warn(E.warn(e))}function Z(e){le.log.error(E.error(e))}async function Eo(){await fe("Checking your environment");let e=gs();e.found||(Z("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Co(e.version)||(Z(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),K(`Node.js v${e.version}`);let t=fs();t.found||(Z("Git not found. Install it from https://git-scm.com"),process.exit(1)),K(`Git ${t.version}`);let n=$(),s=n.hubspotUploadMode!=="cli",o="",r="";if(s){let b=Je(),S=Vt();if(b)o=S?.portalId||"",r=S?.portalName||"",K(`HubSpot${r?`: ${r}`:""}${o?` (${o})`:""} \u2014 API mode`);else{se("No HubSpot account connected"),await xt(`You need a Personal Access Key to deploy themes.
2778
2638
  Create one at: https://app.hubspot.com/l/personal-access-key
2779
- Make sure the Content scope is enabled.`,"HubSpot connection required");let v=await Se({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:$=>$.trim()?void 0:"Key is required"}),w=await De();w.start("Validating key...");try{let $=await ao(v);Xn(v,$.portalId,$.portalName,$.dataCenter),b=v,o=$.portalId,i=$.portalName,w.stop(`Connected to ${$.portalName} (${$.portalId})`)}catch($){w.stop("Validation failed"),V(`Invalid key: ${$ instanceof Error?$.message:String($)}`),process.exit(1)}}}else{let b=ft();if(b.found)G(`HubSpot CLI v${b.version}`);else{se("HubSpot CLI not found"),await Me({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let w=await De();w.start("Installing HubSpot CLI..."),ie("npm install -g @hubspot/cli").success||(w.stop("Failed"),V("Try: npm install -g @hubspot/cli"),process.exit(1)),b=ft(),w.stop(`HubSpot CLI v${b.version} installed`)}let S=ht();if(S.authenticated)G(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{se("HubSpot not authenticated"),await Me({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let w=await De();w.start("Waiting for HubSpot authentication..."),Va("hs init")||(w.stop("Authentication failed"),process.exit(1)),S=ht(),w.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,i=S.portalName}let r=kn(),a=Tn(),l=An(),c=el(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex","langdock-api":"Langdock (EU)"},u=Ze(),m,g=n.aiEngine,h=[];if(r.found&&h.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&h.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&h.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&h.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&h.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&h.sort((b,S)=>b.value===g?-1:S.value===g?1:0),h.length===1)m=h[0].value,G(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await Mt({message:"Choose your AI engine:",options:h});else if(await yt(`You need an AI coding assistant to power the conversion.
2639
+ Make sure the Content scope is enabled.`,"HubSpot connection required");let v=await ve({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:_=>_.trim()?void 0:"Key is required"}),k=await je();k.start("Validating key...");try{let _=await _o(v);us(v,_.portalId,_.portalName,_.dataCenter),b=v,o=_.portalId,r=_.portalName,k.stop(`Connected to ${_.portalName} (${_.portalId})`)}catch(_){k.stop("Validation failed"),Z(`Invalid key: ${_ instanceof Error?_.message:String(_)}`),process.exit(1)}}}else{let b=St();if(b.found)K(`HubSpot CLI v${b.version}`);else{se("HubSpot CLI not found"),await Ee({message:"Install HubSpot CLI globally?"})||(Z("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let k=await je();k.start("Installing HubSpot CLI..."),Se("npm install -g @hubspot/cli").success||(k.stop("Failed"),Z("Try: npm install -g @hubspot/cli"),process.exit(1)),b=St(),k.stop(`HubSpot CLI v${b.version} installed`)}let S=vt();if(S.authenticated)K(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{se("HubSpot not authenticated"),await Ee({message:"Run `hs init` now?"})||(Z("Run `hs init` manually."),process.exit(1));let k=await je();k.start("Waiting for HubSpot authentication..."),Ol("hs init")||(k.stop("Authentication failed"),process.exit(1)),S=vt(),k.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,r=S.portalName}let i=Rn(),a=Nn(),l=On(),c=Hl(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex","langdock-api":"Langdock (EU)"},u=Qe(),p,g=n.aiEngine,f=[];if(i.found&&f.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&f.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&f.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&f.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&f.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&f.sort((b,S)=>b.value===g?-1:S.value===g?1:0),f.length===1)p=f[0].value,K(`AI engine: ${d[p]} (auto-detected)`);else if(f.length>1)p=await Nt({message:"Choose your AI engine:",options:f});else if(await xt(`You need an AI coding assistant to power the conversion.
2780
2640
 
2781
- ${I.bold("Option 1:")} Install Claude Code ${I.muted("(recommended)")}
2641
+ ${E.bold("Option 1:")} Install Claude Code ${E.muted("(recommended)")}
2782
2642
  https://claude.ai/code
2783
2643
 
2784
- ${I.bold("Option 2:")} Install Gemini CLI
2644
+ ${E.bold("Option 2:")} Install Gemini CLI
2785
2645
  https://github.com/google-gemini/gemini-cli
2786
2646
 
2787
- ${I.bold("Option 3:")} Install OpenAI Codex
2647
+ ${E.bold("Option 3:")} Install OpenAI Codex
2788
2648
  https://github.com/openai/codex
2789
2649
 
2790
- ${I.bold("Option 4:")} Set an Anthropic API key
2650
+ ${E.bold("Option 4:")} Set an Anthropic API key
2791
2651
  export ANTHROPIC_API_KEY=sk-ant-...
2792
- (get one at https://console.anthropic.com)`,"AI engine required"),m=await Mt({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),m==="api"){let b=await Se({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:S=>S.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,Y({anthropicApiKey:b})}let f;return m==="claude-code"&&(f=await Mt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),Y({aiEngine:m}),await fe("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}mo();y();Qt();oe();Qe();gt();ee();rs();po();import{join as ls}from"path";async function go(){await ge("HubSpot Theme Setup");let e=await Mt({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=ls(process.cwd(),"workspace");if(Re(s),e==="fetch"){t=await Se({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=ls(s,t);let l=await De();l.start("Fetching theme from HubSpot...");let c=R(),d=Le();if(c.hubspotUploadMode==="cli"||!d)ie(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),V(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await as(d,t,n)}catch(u){l.stop("Fetch failed"),V(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${I.dim(n)}`)}else{t=await Se({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=ls(s,t);let l=await De();l.start("Creating theme...");try{is(n,t)}catch(c){l.stop("Creation failed"),V(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${I.dim(n)}`)}await ge("Checking theme compatibility");let o=ls(n,"templates/layouts/base.html");x(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),G("base.html found");let i=P(o),r=!1;if(i.includes("template_css"))G("template_css support");else{se("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2793
- `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
2794
- `,l);i=i.slice(0,c)+`
2652
+ (get one at https://console.anthropic.com)`,"AI engine required"),p=await Nt({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"}]}),p==="api"){let b=await ve({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:S=>S.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,Y({anthropicApiKey:b})}let h;return p==="claude-code"&&(h=await Nt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),Y({aiEngine:p}),await he("Environment ready!"),{aiEngine:p,model:h,portalId:o,portalName:r}}y();on();ae();import{readdirSync as Ii,statSync as _h}from"fs";import{join as ye,basename as Mi,extname as Ph}from"path";function Zl(e){return typeof e!="string"||e.length===0||e.length>2048||/[\s;&|`$()<>\\]/.test(e)?!1:!!(/^https?:\/\/[^\s]+$/.test(e)||/^git@[\w.-]+:[\w./~+-]+$/.test(e))}function Ql(e){let t=[],n=[ye(e,"src/components/landing"),ye(e,"src/components/sections"),ye(e,"src/components"),ye(e,"src/pages"),ye(e,"app/components"),ye(e,"components")];for(let s of n)if(w(s))try{let o=Ii(s);for(let r of o){let i=ye(s,r);if(!_h(i).isFile())continue;let l=Ph(r);if(![".tsx",".jsx"].includes(l))continue;let c=Mi(r,l);if(c.startsWith("ui")||c==="index")continue;let d=I(i),u=Eh(c,d);t.push({name:c,path:i,description:u})}}catch{}return t}function Eh(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 ec(e){let t=[ye(e,"src/index.css"),ye(e,"src/globals.css"),ye(e,"src/app/globals.css"),ye(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!w(o))continue;let r=I(o),i=r.match(/--[\w-]+:/g);i&&(n+=i.length);let a=r.match(/font-family:\s*['"]([^'"]+)['"]/g);if(a)for(let c of a){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=r.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 tc(e){let t=[],n=ye(e,"src/hooks");if(w(n))try{let o=Ii(n);for(let r of o)/scroll/i.test(r)&&t.push("Scroll animations"),/intersection/i.test(r)&&t.push("Scroll animations")}catch{}let s=ye(e,"src/components/landing");if(w(s))try{let o=Ii(s);for(let r of o){if(!r.endsWith(".tsx")&&!r.endsWith(".jsx"))continue;let i=I(ye(s,r));/carousel|embla|swiper/i.test(i)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(i)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(i)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(i)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function nc(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!Zl(e))throw new Error(`Refusing to clone unsafe source URL: ${e}. Only http(s):// and git@host:path URLs without shell metacharacters are allowed.`);n=!0;let l=Mi(e.replace(/\.git$/,""))||"react-source";if(t=ye(process.cwd(),"workspace",l),!w(t)){let c=ee(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!w(t))throw new Error(`Directory not found: ${t}`);let s=Ql(t),o=w(ye(t,"tailwind.config.ts"))||w(ye(t,"tailwind.config.js")),{varCount:r,fonts:i}=ec(t),a=tc(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:r,fonts:i,interactions:a}}async function Io(){await fe("Source Project");let e=await ve({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:f=>{if(!f.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){Zl(e)||(Z("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let f=Mi(e.replace(/\.git$/,""))||"react-source";if(t=ye(process.cwd(),"workspace",f),w(t))K(`Using existing clone: ${E.dim(t)}`);else{let h=await je();h.start("Cloning repository..."),ee(["clone","--depth","1","--",e,t]).success||(h.stop("Clone failed"),Z(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),h.stop(`Cloned to ${E.dim(t)}`)}}else t=e,w(t)||(Z(`Directory not found: ${t}`),process.exit(1)),K(`Using local source: ${E.dim(t)}`);let s=await je();s.start("Analyzing project structure...");let o=Ql(t),r=w(ye(t,"tailwind.config.ts"))||w(ye(t,"tailwind.config.js")),{varCount:i,fonts:a}=ec(t),l=tc(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(se("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((f,h)=>` ${E.dim(`${h+1}.`)} ${E.bold(f.name)} ${E.muted(`\u2014 ${f.description}`)}`).join(`
2653
+ `),d=r?`Tailwind + custom CSS (${i} variables)`:`Custom CSS (${i} variables)`,u=a.length>0?a.join(", "):"System fonts",p=l.join(", ");return await xt(`${c}
2654
+
2655
+ CSS: ${d}
2656
+ JS: ${p}
2657
+ Font: ${u}`,`${o.length} components detected`),await Ee({message:"Does this look right?"})||(Z("Please adjust your source directory and try again."),process.exit(0)),await he("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:r,cssVarCount:i,fonts:a,interactions:l}}y();on();import{join as Cs}from"path";y();function Dn(e){return typeof e=="string"&&e.length>0&&e.length<=200&&/^[A-Za-z0-9][A-Za-z0-9 ._-]*$/.test(e)&&!e.includes("..")}ae();te();xs();$o();async function Ro(){await fe("HubSpot Theme Setup");let e=await Nt({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=Cs(process.cwd(),"workspace");if($e(s),e==="fetch"){t=await ve({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>{if(!u.trim())return"Theme name is required";if(!Dn(u.trim()))return"Use only letters, numbers, spaces, dots, underscores, and hyphens"}}),t=t.trim(),n=Cs(s,t);let l=await je();l.start("Fetching theme from HubSpot...");let c=$(),d=Je();if(c.hubspotUploadMode==="cli"||!d)cs("hs",["cms","fetch",t,n]).success||(l.stop("Fetch failed"),Z(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await ks(d,t,n)}catch(u){l.stop("Fetch failed"),Z(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${E.dim(n)}`)}else{t=await ve({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=Cs(s,t);let l=await je();l.start("Creating theme...");try{vs(n,t)}catch(c){l.stop("Creation failed"),Z(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${E.dim(n)}`)}await fe("Checking theme compatibility");let o=Cs(n,"templates/layouts/base.html");w(o)||(Z(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),K("base.html found");let r=I(o),i=!1;if(r.includes("template_css"))K("template_css support");else{se("Missing template_css support in base.html");let l=r.indexOf("theme-overrides.css")!==-1?r.indexOf("{{",r.lastIndexOf(`
2658
+ `,r.indexOf("theme-overrides.css"))):r.lastIndexOf("require_css");if(l>0){let c=r.lastIndexOf(`
2659
+ `,l);r=r.slice(0,c)+`
2795
2660
  {% if template_css %}
2796
2661
  {{ require_css(get_asset_url(template_css)) }}
2797
- {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))G("template_js support");else{se("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2798
- `,l),d=i.indexOf(`
2662
+ {% endif %}`+r.slice(c),i=!0}}if(r.includes("template_js"))K("template_js support");else{se("Missing template_js support in base.html");let l=r.indexOf("require_js");if(l>0){let c=r.indexOf(`
2663
+ `,l),d=r.indexOf(`
2799
2664
  `,c+1),u=`
2800
2665
  {% if template_js %}
2801
2666
  {{ require_js(get_asset_url(template_js)) }}
2802
- {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
2803
- `)+1;i=i.slice(0,i.indexOf(`
2804
- `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
2805
- `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await De();l.start("Patching base.html..."),B(o,i),l.stop("base.html patched with template_css/template_js support")}let a=ls(n,".hsignore");if(x(a)){let l=P(a);l.includes("docs/")||(B(a,l+`
2667
+ {% endif %}`,p=r.indexOf("}}",l)+2+r.slice(r.indexOf("}}",l)+2).indexOf(`
2668
+ `)+1;r=r.slice(0,r.indexOf(`
2669
+ `,r.indexOf("}}",l)+2))+u+r.slice(r.indexOf(`
2670
+ `,r.indexOf("}}",l)+2)),i=!0}}if(i){let l=await je();l.start("Patching base.html..."),U(o,r),l.stop("base.html patched with template_css/template_js support")}let a=Cs(n,".hsignore");if(w(a)){let l=I(a);l.includes("docs/")||(U(a,l+`
2806
2671
  docs/
2807
- `),G("Added docs/ to .hsignore"))}else B(a,`docs/
2672
+ `),K("Added docs/ to .hsignore"))}else U(a,`docs/
2808
2673
  *.md
2809
2674
  node_modules/
2810
2675
  .git
2811
- `),G("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}y();import{join as nt}from"path";import{readdirSync as ps,rmSync as Ol}from"fs";y();Ke();oe();import{spawn as Bg}from"child_process";import{join as Q,basename as Hg}from"path";import{readdirSync as bt,statSync as Al,writeFileSync as Ug}from"fs";var Gg=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"]),fo=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(t){this.model=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(Q(s,"css")),c=this.listDir(Q(s,"js")),d=this.listDir(Q(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${r} source components found)...`);let m="",g="",h=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((v,w)=>{let $={...process.env};delete $.CLAUDECODE;let j=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&j.push("--model",this.model);let J=Bg("claude",j,{cwd:s,stdio:["pipe","pipe","pipe"],env:$,shell:!0});J.stdout.on("data",K=>{m+=K.toString()}),J.stderr.on("data",K=>{g+=K.toString()}),J.on("error",K=>w(new Error(`Claude Code failed to start: ${K.message}`))),J.on("close",K=>{K!==0?w(new Error(`Claude Code exited with code ${K}.
2676
+ `),K("Created .hsignore");return await he("Theme ready!"),{themePath:n,themeName:t}}y();import{join as st}from"path";import{readdirSync as Hs,rmSync as Ad}from"fs";y();tt();ae();import{spawn as Fh}from"child_process";import{join as ne,basename as Dh}from"path";import{readdirSync as kt,statSync as yc,writeFileSync as jh}from"fs";var Lh=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"]),Oo=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,r=t.conversionGuide||Ce();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let i=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(ne(s,"css")),c=this.listDir(ne(s,"js")),d=this.listDir(ne(s,"templates")),u=this.buildFullPrompt(n,s,r);o("convert",`Starting Claude Code (${i} source components found)...`);let p="",g="",f=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((v,k)=>{let _={...process.env};delete _.CLAUDECODE;let M=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&M.push("--model",this.model);let R=Fh("claude",M,{cwd:s,stdio:["pipe","pipe","pipe"],env:_,shell:process.platform==="win32"});R.stdout.on("data",J=>{p+=J.toString()}),R.stderr.on("data",J=>{g+=J.toString()}),R.on("error",J=>k(new Error(`Claude Code failed to start: ${J.message}`))),R.on("close",J=>{J!==0?k(new Error(`Claude Code exited with code ${J}.
2812
2677
  `+(g?`Stderr: ${g.slice(0,500)}
2813
- `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):v()}),J.stdin.on("error",()=>{}),J.stdin.write(u),J.stdin.end(),setTimeout(()=>{J.kill(),w(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let f=Q(s,"..","vibespot-conversion.log");try{let w=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
2814
- ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
2815
- `);Ug(f,w,"utf-8"),o("status",`Log written to ${Hg(f)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(v=>!a.has(v.moduleName+".module")).length===0){let v=m.slice(0,1500)||"(no output)",w=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
2678
+ `:"")+(p?`Output: ${p.slice(0,500)}`:"No output"))):v()}),R.stdin.on("error",()=>{}),R.stdin.write(u),R.stdin.end(),setTimeout(()=>{R.kill(),k(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(f)}let h=ne(s,"..","vibespot-conversion.log");try{let k=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
2679
+ ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",p||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
2680
+ `);jh(h,k,"utf-8"),o("status",`Log written to ${Dh(h)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(v=>!a.has(v.moduleName+".module")).length===0){let v=p.slice(0,1500)||"(no output)",k=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
2816
2681
 
2817
2682
  This usually means the model described the conversion instead of using Write tool to create files.
2818
2683
 
@@ -2823,12 +2688,12 @@ Possible causes:
2823
2688
 
2824
2689
  Source: ${t.sourceDir}
2825
2690
  Theme: ${s}
2826
- `+(w?`
2691
+ `+(k?`
2827
2692
  Stderr:
2828
- ${w}
2693
+ ${k}
2829
2694
  `:"")+`
2830
2695
  Claude output:
2831
- ${v}`)}return b}reportProgress(t,n,s,o,i,r){let a=0,l=this.listDir(Q(t,"css"));for(let m of l){if(s.has(m)||!m.endsWith(".css"))continue;let g=`css:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared CSS (${m})`),a++)}let c=this.listDir(Q(t,"js"));for(let m of c){if(o.has(m)||!m.endsWith(".js"))continue;let g=`js:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Shared JS (${m})`),a++)}this.expectedModules===0&&(this.expectedModules=this.detectExpectedModules(t,i));let d=this.listModules(t);for(let m of d){if(n.has(m))continue;let g=`module:${m}`;if(!this.reported.has(g)){this.reported.add(g),this.moduleCount++;let h=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;r("created",`Module ${h}: ${m.replace(".module","")}`),a++}}let u=this.listDir(Q(t,"templates"));for(let m of u){if(i.has(m)||!m.endsWith(".html"))continue;let g=`template:${m}`;this.reported.has(g)||(this.reported.add(g),r("created",`Page template (${m})`),a++)}if(a===0)if(this.moduleCount>0){let m=this.expectedModules>0?`/${this.expectedModules}`:"";r("status",`${this.moduleCount}${m} modules created, conversion continuing...`)}else this.reported.size>0?r("status","Shared assets created, building modules..."):r("status","Claude Code is analyzing source files...")}buildFullPrompt(t,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
2696
+ ${v}`)}return b}reportProgress(t,n,s,o,r,i){let a=0,l=this.listDir(ne(t,"css"));for(let p of l){if(s.has(p)||!p.endsWith(".css"))continue;let g=`css:${p}`;this.reported.has(g)||(this.reported.add(g),i("created",`Shared CSS (${p})`),a++)}let c=this.listDir(ne(t,"js"));for(let p of c){if(o.has(p)||!p.endsWith(".js"))continue;let g=`js:${p}`;this.reported.has(g)||(this.reported.add(g),i("created",`Shared JS (${p})`),a++)}this.expectedModules===0&&(this.expectedModules=this.detectExpectedModules(t,r));let d=this.listModules(t);for(let p of d){if(n.has(p))continue;let g=`module:${p}`;if(!this.reported.has(g)){this.reported.add(g),this.moduleCount++;let f=this.expectedModules>0?`[${this.moduleCount}/${this.expectedModules}]`:`[${this.moduleCount}]`;i("created",`Module ${f}: ${p.replace(".module","")}`),a++}}let u=this.listDir(ne(t,"templates"));for(let p of u){if(r.has(p)||!p.endsWith(".html"))continue;let g=`template:${p}`;this.reported.has(g)||(this.reported.add(g),i("created",`Page template (${p})`),a++)}if(a===0)if(this.moduleCount>0){let p=this.expectedModules>0?`/${this.expectedModules}`:"";i("status",`${this.moduleCount}${p} modules created, conversion continuing...`)}else this.reported.size>0?i("status","Shared assets created, building modules..."):i("status","Claude Code is analyzing source files...")}buildFullPrompt(t,n,s){return`You are converting a React landing page to native HubSpot CMS modules.
2832
2697
 
2833
2698
  SOURCE DIRECTORY: ${t}
2834
2699
  THEME DIRECTORY: ${n}
@@ -2871,31 +2736,16 @@ CSS QUALITY: The converted page must visually match the original React page. Eve
2871
2736
  Do NOT run hs upload \u2014 I will handle that separately.
2872
2737
 
2873
2738
  HUBSPOT CMS RULES:
2874
- ${Je()}
2739
+ ${et()}
2875
2740
 
2876
2741
  CONVERSION GUIDE:
2877
- ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Q(t,"css");if(x(s)){for(let a of bt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Q(s,a));break}}let o=Q(t,"js");if(x(o)){for(let a of bt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Q(o,a));break}}let i=Q(t,"templates");if(x(i)){for(let a of bt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=P(Q(i,a));break}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!Gg.has(a)&&!a.startsWith("system")){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=Q(t,"modules");if(x(r))for(let a of bt(r)){if(!a.endsWith(".module"))continue;let l=Q(r,a);if(!Al(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Q(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Q(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Q(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Q(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Q(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=Q(t,"modules");return x(n)?new Set(bt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return x(t)?new Set(bt(t)):new Set}detectExpectedModules(t,n){let s=Q(t,"templates");if(!x(s))return 0;for(let o of bt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=P(Q(s,o));if(i.includes("dnd_area")){let r=i.match(/dnd_module/g);return r?r.length:0}}catch{}return 0}countSourceComponents(t){let n=Q(t,"src");return x(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of bt(t)){let o=Q(t,s);try{Al(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};y();Ke();oe();Be();on();import uf from"@anthropic-ai/sdk";import{join as ce,basename as mf}from"path";import{readdirSync as Rl}from"fs";var bo=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new uf({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=xl(o),a=mf(n)||"page",l=a.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);i("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(r,Cl(c,d,l)),m=ce(s,"css",`${l}-theme.css`);B(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),h=this.findInteractiveComponents(n),f=await this.complete(r,kl(g,h,l)),b=ce(s,"js",`${l}-animations.js`);B(b,f),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let S=this.findComponents(n),v=[];for(let J=0;J<S.length;J++){let K=S[J],H=K.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${H}.module (${J+1}/${S.length})...`);let X=P(K.path),F=await this.complete(r,wl(X,H,`See css/${l}-theme.css`));try{let T=JSON.parse(F),k={moduleName:H,fieldsJson:typeof T.fieldsJson=="string"?T.fieldsJson:JSON.stringify(T.fieldsJson,null,2),metaJson:typeof T.metaJson=="string"?T.metaJson:JSON.stringify(T.metaJson,null,2),moduleHtml:T.moduleHtml||"",moduleCss:T.moduleCss||"",moduleJs:T.moduleJs||void 0},E=ce(s,"modules",`${H}.module`);Re(E),B(ce(E,"fields.json"),k.fieldsJson),B(ce(E,"meta.json"),k.metaJson),B(ce(E,"module.html"),k.moduleHtml),B(ce(E,"module.css"),k.moduleCss),k.moduleJs&&B(ce(E,"module.js"),k.moduleJs),v.push(k),i("module-done",`${H}.module (${this.countFiles(k)} files)`)}catch{i("module-error",`Failed to parse ${H} \u2014 skipping`)}}i("template","Creating page template...");let w=v.map(J=>J.moduleName),$=await this.complete(r,Tl(w,a,l)),j=ce(s,"templates",`lp-${l}.html`);return B(j,$),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:$,modules:v}}async complete(t,n){let s=new Date,o=await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]}),r=o.content.find(a=>a.type==="text")?.text||"";return St({engine:"anthropic-api",model:this.model,name:"react-conversion",input:{system:t,messages:[{role:"user",content:n}]},output:r,usage:et(o.usage),startTime:s,endTime:new Date}),r}findAndReadCSS(t){let n=[ce(t,"src/index.css"),ce(t,"src/globals.css"),ce(t,"src/app/globals.css"),ce(t,"app/globals.css")];for(let s of n)if(x(s))return P(s);return""}findAndReadTailwind(t){let n=[ce(t,"tailwind.config.ts"),ce(t,"tailwind.config.js"),ce(t,"tailwind.config.mjs")];for(let s of n)if(x(s))return P(s);return""}findAndReadHooks(t){let n=ce(t,"src/hooks");if(!x(n))return"";try{return Rl(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2878
- ${P(ce(n,s))}`).join(`
2879
-
2880
- `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=P(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
2881
- ${i}`)}return s.join(`
2882
-
2883
- `)}findComponents(t){let n=[ce(t,"src/components/landing"),ce(t,"src/components/sections"),ce(t,"src/components")];for(let s of n)if(x(s))try{return Rl(s).filter(o=>(o.endsWith(".tsx")||o.endsWith(".jsx"))&&!o.startsWith("ui")&&o!=="index.tsx"&&o!=="index.jsx").map(o=>({name:o.replace(/\.(tsx|jsx)$/,""),path:ce(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();Ke();oe();import{spawn as pf}from"child_process";import{join as Ve}from"path";import{readdirSync as So,statSync as gf}from"fs";var vo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((a,l)=>{let c=pf("gemini",["-p",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Gemini CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Gemini CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Gemini CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
2884
-
2885
- INSTRUCTIONS:
2886
- 1. Analyze all .tsx/.jsx components in the React source
2887
- 2. Create a shared CSS file in css/ with design system variables, utilities, and theme-override countermeasures
2888
- 3. Create a shared JS file in js/ for scroll animations and interactive features
2889
- 4. For each visual section, create a HubSpot module in modules/ with fields.json, meta.json, module.html, module.css
2890
- 5. Add a styles group with "tab": "STYLE" and color pickers to each module
2891
- 6. Create a page template in templates/ that assembles all modules
2892
- 7. Make sure base.html supports template_css and template_js variables
2742
+ ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ne(t,"css");if(w(s)){for(let a of kt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=I(ne(s,a));break}}let o=ne(t,"js");if(w(o)){for(let a of kt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=I(ne(o,a));break}}let r=ne(t,"templates");if(w(r)){for(let a of kt(r))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=I(ne(r,a));break}if(!n.template){for(let a of kt(r))if(a.endsWith(".html")&&!Lh.has(a)&&!a.startsWith("system")){let l=I(ne(r,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of kt(r))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=I(ne(r,a));if(l.includes("dnd_area")){n.template=l;break}}}}let i=ne(t,"modules");if(w(i))for(let a of kt(i)){if(!a.endsWith(".module"))continue;let l=ne(i,a);if(!yc(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=ne(l,"fields.json");w(d)&&(c.fieldsJson=I(d));let u=ne(l,"meta.json");w(u)&&(c.metaJson=I(u));let p=ne(l,"module.html");w(p)&&(c.moduleHtml=I(p));let g=ne(l,"module.css");w(g)&&(c.moduleCss=I(g));let f=ne(l,"module.js");w(f)&&(c.moduleJs=I(f)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=ne(t,"modules");return w(n)?new Set(kt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return w(t)?new Set(kt(t)):new Set}detectExpectedModules(t,n){let s=ne(t,"templates");if(!w(s))return 0;for(let o of kt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let r=I(ne(s,o));if(r.includes("dnd_area")){let i=r.match(/dnd_module/g);return i?i.length:0}}catch{}return 0}countSourceComponents(t){let n=ne(t,"src");return w(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of kt(t)){let o=ne(t,s);try{yc(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};y();tt();ae();Ue();un();import ry from"@anthropic-ai/sdk";import{join as de,basename as iy}from"path";import{readdirSync as Ac}from"fs";var Jo=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new ry({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:r}=t,i=pc(o),a=iy(n)||"page",l=a.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);r("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(i,gc(c,d,l)),p=de(s,"css",`${l}-theme.css`);U(p,u),r("css-done",`Created css/${l}-theme.css`),r("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),f=this.findInteractiveComponents(n),h=await this.complete(i,fc(g,f,l)),b=de(s,"js",`${l}-animations.js`);U(b,h),r("js-done",`Created js/${l}-animations.js`),r("modules","Building modules...");let S=this.findComponents(n),v=[];for(let R=0;R<S.length;R++){let J=S[R],O=J.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();r("module",`Building ${O}.module (${R+1}/${S.length})...`);let V=I(J.path),H=await this.complete(i,mc(V,O,`See css/${l}-theme.css`));try{let P=JSON.parse(H),F=typeof P.fieldsJson=="string"?P.fieldsJson:P.fieldsJson!=null?JSON.stringify(P.fieldsJson,null,2):null,z=typeof P.metaJson=="string"?P.metaJson:P.metaJson!=null?JSON.stringify(P.metaJson,null,2):null;if(!F||!z)throw new Error("Response is missing fieldsJson or metaJson");let L={moduleName:O,fieldsJson:F,metaJson:z,moduleHtml:P.moduleHtml||"",moduleCss:P.moduleCss||"",moduleJs:P.moduleJs||void 0},W=de(s,"modules",`${O}.module`);$e(W),U(de(W,"fields.json"),L.fieldsJson),U(de(W,"meta.json"),L.metaJson),U(de(W,"module.html"),L.moduleHtml),U(de(W,"module.css"),L.moduleCss),L.moduleJs&&U(de(W,"module.js"),L.moduleJs),v.push(L),r("module-done",`${O}.module (${this.countFiles(L)} files)`)}catch{r("module-error",`Failed to parse ${O} \u2014 skipping`)}}r("template","Creating page template...");let k=v.map(R=>R.moduleName),_=await this.complete(i,hc(k,a,l)),M=de(s,"templates",`lp-${l}.html`);return U(M,_),r("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:h,template:_,modules:v}}async complete(t,n){let s=new Date,o=await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]}),i=o.content.find(a=>a.type==="text")?.text||"";return Ct({engine:"anthropic-api",model:this.model,name:"react-conversion",input:{system:t,messages:[{role:"user",content:n}]},output:i,usage:nt(o.usage),startTime:s,endTime:new Date}),i}findAndReadCSS(t){let n=[de(t,"src/index.css"),de(t,"src/globals.css"),de(t,"src/app/globals.css"),de(t,"app/globals.css")];for(let s of n)if(w(s))return I(s);return""}findAndReadTailwind(t){let n=[de(t,"tailwind.config.ts"),de(t,"tailwind.config.js"),de(t,"tailwind.config.mjs")];for(let s of n)if(w(s))return I(s);return""}findAndReadHooks(t){let n=de(t,"src/hooks");if(!w(n))return"";try{return Ac(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2743
+ ${I(de(n,s))}`).join(`
2893
2744
 
2894
- CONVERSION GUIDE:
2895
- ${s}
2745
+ `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let r=I(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(r)&&s.push(`// ${o.name}
2746
+ ${r}`)}return s.join(`
2896
2747
 
2897
- Do NOT run hs upload \u2014 I will handle that separately.
2898
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ve(t,"css");if(x(s)){for(let a of So(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Ve(s,a));break}}let o=Ve(t,"js");if(x(o)){for(let a of So(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Ve(o,a));break}}let i=Ve(t,"templates");if(x(i)){for(let a of So(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Ve(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ve(t,"modules");if(x(r))for(let a of So(r)){if(!a.endsWith(".module"))continue;let l=Ve(r,a);if(!gf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ve(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Ve(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Ve(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Ve(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Ve(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ke();oe();import{spawn as ff}from"child_process";import{join as ze}from"path";import{readdirSync as xo,statSync as hf}from"fs";var wo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((a,l)=>{let c=ff("codex",["exec","--full-auto",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Codex CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Codex CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Codex CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
2748
+ `)}findComponents(t){let n=[de(t,"src/components/landing"),de(t,"src/components/sections"),de(t,"src/components")];for(let s of n)if(w(s))try{return Ac(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:de(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();y();tt();ae();rr();import{join as Xe}from"path";import{readdirSync as ir,statSync as hb}from"fs";var zn=class{constructor(t){this.config=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,r=t.conversionGuide||Ce(),i=this.buildFullPrompt(n,s,r);return o("convert",this.config.progressMessage),await Js(this.config.binary,this.config.args,i,void 0,this.config.timeoutMs,void 0,{cwd:s,shell:process.platform==="win32"}),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}.
2899
2749
 
2900
2750
  INSTRUCTIONS:
2901
2751
  1. Analyze all .tsx/.jsx components in the React source
@@ -2910,47 +2760,95 @@ CONVERSION GUIDE:
2910
2760
  ${s}
2911
2761
 
2912
2762
  Do NOT run hs upload \u2014 I will handle that separately.
2913
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ze(t,"css");if(x(s)){for(let a of xo(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(ze(s,a));break}}let o=ze(t,"js");if(x(o)){for(let a of xo(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(ze(o,a));break}}let i=ze(t,"templates");if(x(i)){for(let a of xo(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(ze(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=ze(t,"modules");if(x(r))for(let a of xo(r)){if(!a.endsWith(".module"))continue;let l=ze(r,a);if(!hf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=ze(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=ze(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=ze(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=ze(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=ze(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ke();oe();Qe();function yf(e,t){switch(e){case"claude-code":return new fo(t);case"gemini-cli":return new vo;case"codex-cli":return new wo;case"api":case"anthropic-api":case"claude-oauth":return new bo;default:throw new Error(`The wizard does not support the "${e}" engine. Use claude-code, gemini-cli, codex-cli, or the Anthropic API.`)}}async function Co(e){await ge("Converting React to HubSpot Modules"),await yt(`AI will now analyze your React code and create
2914
- HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=yf(e.aiEngine,e.model),n=ye(),s=await De();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(h,f)=>{h==="created"?G(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=bf(e.themePath);for(let h of a)G(`Auto-fixed: ${h}`);let l=Sf(e.themePath,i),c=[];for(let h of l){let f=h.passed?"\u2705":"\u274C",b=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${f} ${h.label}${b}`)}let d=l.filter(h=>h.passed).length;c.push(`
2915
- ${d}/${l.length} checks passed`),await yt(c.join(`
2916
- `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(V(`${u.length} critical issue(s) \u2014 upload will likely fail:
2917
- `+u.map(f=>` - ${f.label}`).join(`
2918
- `)),!await Me({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&se(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2919
- `+m.map(h=>` - ${h.label}`).join(`
2920
- `));let g=nt(e.themePath,"..","vibespot-conversion.log");return x(g)&&(await Me({message:"Keep conversion log file for debugging?",initialValue:!1})?G(`Log saved: ${g}`):Ol(g)),await fe("Files ready for upload!"),i}function bf(e){let t=[];vf(e),xf(e);let n=nt(e,"modules");if(x(n))for(let o of ps(n)){if(!o.endsWith(".module"))continue;let i=nt(n,o,"fields.json");if(!x(i))continue;let r=o.replace(".module",""),a=P(i),l=!1;a.includes('"textarea"')&&(a=a.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${r}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(a)&&(a=a.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${r}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(a),u=!1;Fl(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),Dl(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2921
- `,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&B(i,a);let c=nt(n,o,"module.html");if(x(c)){let d=P(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),B(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=nt(e,"templates");if(x(s))for(let o of ps(s)){if(!o.endsWith(".html"))continue;let i=nt(s,o),r=P(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(Ol(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Fl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let r=i.charAt(0).toUpperCase()+i.slice(1);return[i,r]}return i}),t=!0),Array.isArray(s.children)&&Fl(s.children)&&(t=!0)}return t}function Dl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&Dl(s.children)&&(t=!0)}return t}function Sf(e,t){let n=[],s=t.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of t.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let r=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),a=r.length===0;n.push({label:a?"module.css created for each module":`module.css missing for: ${r.join(", ")}`,passed:s>0&&a,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=nt(e,"templates"),d=!1;if(x(c))for(let u of ps(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=P(nt(c,u));if(m.includes("dnd_area")&&/templateType\s*:\s*page/i.test(m)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function vf(e){let t=nt(e,"templates");if(x(t))for(let n of ps(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=nt(t,n),o=P(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),r=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&r)continue;let a=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);i||(c+=`
2922
- templateType: page`),r||(c+=`
2763
+ Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Xe(t,"css");if(w(s)){for(let a of ir(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=I(Xe(s,a));break}}let o=Xe(t,"js");if(w(o)){for(let a of ir(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=I(Xe(o,a));break}}let r=Xe(t,"templates");if(w(r)){for(let a of ir(r))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=I(Xe(r,a));if(l.includes("dnd_area")){n.template=l;break}}}let i=Xe(t,"modules");if(w(i))for(let a of ir(i)){if(!a.endsWith(".module"))continue;let l=Xe(i,a);if(!hb(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Xe(l,"fields.json");w(d)&&(c.fieldsJson=I(d));let u=Xe(l,"meta.json");w(u)&&(c.metaJson=I(u));let p=Xe(l,"module.html");w(p)&&(c.moduleHtml=I(p));let g=Xe(l,"module.css");w(g)&&(c.moduleCss=I(g));let f=Xe(l,"module.js");w(f)&&(c.moduleJs=I(f)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};var ar=class extends zn{constructor(){super({binary:"gemini",args:[],progressMessage:"Running Gemini CLI (this may take a few minutes)...",timeoutMs:6e5})}};y();var lr=class extends zn{constructor(){super({binary:"codex",args:["exec","--full-auto"],progressMessage:"Running OpenAI Codex (this may take a few minutes)...",timeoutMs:6e5})}};tt();ae();function yb(e,t){switch(e){case"claude-code":return new Oo(t);case"gemini-cli":return new ar;case"codex-cli":return new lr;case"api":case"anthropic-api":case"claude-oauth":return new Jo;default:throw new Error(`The wizard does not support the "${e}" engine. Use claude-code, gemini-cli, codex-cli, or the Anthropic API.`)}}async function cr(e){await fe("Converting React to HubSpot Modules"),await xt(`AI will now analyze your React code and create
2764
+ HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=yb(e.aiEngine,e.model),n=Ce(),s=await je();s.start("Starting AI conversion...");let o=Date.now(),r=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(f,h)=>{f==="created"?K(h):s.message(h)}}),i=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${i}s)`);let a=bb(e.themePath);for(let f of a)K(`Auto-fixed: ${f}`);let l=Sb(e.themePath,r),c=[];for(let f of l){let h=f.passed?"\u2705":"\u274C",b=f.passed?"":f.critical?" (CRITICAL)":" (cosmetic)";c.push(`${h} ${f.label}${b}`)}let d=l.filter(f=>f.passed).length;c.push(`
2765
+ ${d}/${l.length} checks passed`),await xt(c.join(`
2766
+ `),"Conversion Checklist");let u=l.filter(f=>!f.passed&&f.critical),p=l.filter(f=>!f.passed&&!f.critical);if(u.length>0){if(Z(`${u.length} critical issue(s) \u2014 upload will likely fail:
2767
+ `+u.map(h=>` - ${h.label}`).join(`
2768
+ `)),!await Ee({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else p.length>0&&se(`${p.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2769
+ `+p.map(f=>` - ${f.label}`).join(`
2770
+ `));let g=st(e.themePath,"..","vibespot-conversion.log");return w(g)&&(await Ee({message:"Keep conversion log file for debugging?",initialValue:!1})?K(`Log saved: ${g}`):Ad(g)),await he("Files ready for upload!"),r}function bb(e){let t=[];vb(e),xb(e);let n=st(e,"modules");if(w(n))for(let o of Hs(n)){if(!o.endsWith(".module"))continue;let r=st(n,o,"fields.json");if(!w(r))continue;let i=o.replace(".module",""),a=I(r),l=!1;a.includes('"textarea"')&&(a=a.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${i}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(a)&&(a=a.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${i}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(a),u=!1;_d(d)&&(u=!0,t.push(`${i}: fixed choice field format`)),Pd(d)&&(u=!0,t.push(`${i}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2771
+ `,l=!0)}catch{t.push(`${i}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&U(r,a);let c=st(n,o,"module.html");if(w(c)){let d=I(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),U(c,d),t.push(`${i}: now() \u2192 local_dt`))}}let s=st(e,"templates");if(w(s))for(let o of Hs(s)){if(!o.endsWith(".html"))continue;let r=st(s,o),i=I(r);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Ad(r),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function _d(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(r=>typeof r=="string")&&(s.choices=s.choices.map(r=>{if(typeof r=="string"){let i=r.charAt(0).toUpperCase()+r.slice(1);return[r,i]}return r}),t=!0),Array.isArray(s.children)&&_d(s.children)&&(t=!0)}return t}function Pd(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 i=typeof o=="string"?o:"";s.default={url:{href:i,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&Pd(s.children)&&(t=!0)}return t}function Sb(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 r=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&r,critical:!0});let i=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),a=i.length===0;n.push({label:a?"module.css created for each module":`module.css missing for: ${i.join(", ")}`,passed:s>0&&a,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=st(e,"templates"),d=!1;if(w(c))for(let u of Hs(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let p=I(st(c,u));if(p.includes("dnd_area")&&/templateType\s*:\s*page/i.test(p)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function vb(e){let t=st(e,"templates");if(w(t))for(let n of Hs(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=st(t,n),o=I(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let r=/templateType\s*:\s*page/i.test(o),i=/isAvailableForNewContent\s*:\s*true/i.test(o);if(r&&i)continue;let a=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);r||(c+=`
2772
+ templateType: page`),i||(c+=`
2923
2773
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
2924
2774
  label: ${a}`),o=c+o.slice(l)}else o=`<!--
2925
2775
  templateType: page
2926
2776
  isAvailableForNewContent: true
2927
2777
  label: ${a}
2928
2778
  -->
2929
- `+o;B(s,o),G(`Template "${n}" \u2014 annotations verified`)}}function xf(e){let t=nt(e,"modules");if(x(t))for(let n of ps(t)){if(!n.endsWith(".module"))continue;let s=nt(t,n,"meta.json");if(x(s))try{let o=JSON.parse(P(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&B(s,JSON.stringify(o,null,2)+`
2930
- `)}catch{}}}y();Qt();Qe();_o();ee();sr();import{join as ql,basename as If}from"path";function Pf(e){return(e.match(/^Uploaded file /gm)||[]).length}async function In(e){await ge("Uploading to HubSpot");let t=If(e)||e,n=R(),s=Le(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await De(),r=3;for(let a=1;a<=r;a++){i.start(a===1?"Uploading theme...":`Retrying upload (attempt ${a}/${r})...`);let l=[],c=0,d=!1;if(o){let m=await $o(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=ko(m.errors)}else{let m=ie(`hs cms upload "${e}" "${t}"`,{cwd:ql(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2931
- `);c=Pf(g),d=m.success,d||(l=To(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await fe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(V("Upload failed with unknown error."),c>0&&(se(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2932
- You can check your HubSpot Design Manager to verify.`),await Me({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Me({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?jl(e,m)?(G(`Auto-fixed: ${m.message}`),u=!0):se(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&a<r)){if(c>0&&(se(`${c} files uploaded successfully despite errors.
2933
- The theme may work \u2014 check HubSpot Design Manager.`),await Me({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await Hi(s,`${t}/modules`)}catch{}else ie(`hs cms delete "${t}/modules"`,{cwd:ql(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}y();Qe();gt();nn();oe();import{execFileSync as or}from"child_process";import{rmSync as Nf}from"fs";import{basename as Xl}from"path";async function Zl(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ge("You're all set!");let r=ts(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await yt(`Your React page has been converted and uploaded to HubSpot.
2779
+ `+o;U(s,o),K(`Template "${n}" \u2014 annotations verified`)}}function xb(e){let t=st(e,"modules");if(w(t))for(let n of Hs(t)){if(!n.endsWith(".module"))continue;let s=st(t,n,"meta.json");if(w(s))try{let o=JSON.parse(I(s)),r=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],r=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,r=!0),r&&U(s,JSON.stringify(o,null,2)+`
2780
+ `)}catch{}}}y();on();import{join as Jd,basename as Mb}from"path";y();ae();import{join as ge}from"path";import{readdirSync as ut,rmSync as wb}from"fs";function dr(e){let t=[];for(let n of e){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),/dnd.area.*only.*have.*name.*main/i.test(s)&&(o=!0),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function ur(e){let t=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(e)&&t.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(e)&&t.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(e)){let n=e.match(/field.*?(\w+)\s+has an invalid/i);t.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(e)){let n=e.match(/file '([^']+)'/i);t.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(e)&&t.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),/dnd.area.*only.*have.*name.*main/i.test(e)&&t.push({file:"templates/email.html",message:'Dnd area can only have name "main"',fixable:!0}),t}function pr(e){let t=[];return Id(e)&&t.push("textarea \u2192 text"),Md(e)&&t.push("name \u2192 item_name"),$d(e)&&t.push("now() \u2192 local_dt"),Rd(e)&&t.push("Removed HubDB templates"),Nd(e)&&t.push("Fixed link field defaults"),Od(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),kb(e)&&t.push("Stripped CDN @import statements"),Dd(e)&&t.push('dnd_area \u2192 "main" in email templates'),jd(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function Ed(e,t){let n=t.message.toLowerCase();return n.includes("textarea")?Id(e):n.includes("reserved field name")?Md(e):n.includes("now()")?$d(e):n.includes("hubdb")?Rd(e):n.includes("invalid default value")||n.includes("deserialization")?Nd(e):n.includes("color")&&n.includes("invalid")?Od(e):n.includes("dnd_area_stylesheet")?jd(e):n.includes("dnd")?Dd(e):!1}function Id(e){let t=!1,n=ge(e,"modules");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".module"))continue;let o=ge(n,s,"fields.json");if(!w(o))continue;let r=I(o);r.includes('"textarea"')&&(r=r.replace(/"textarea"/g,'"text"'),U(o,r),t=!0)}return t}function Md(e){let t=!1,n=ge(e,"modules");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".module"))continue;let o=ge(n,s,"fields.json");if(!w(o))continue;let r=I(o);/"name":\s*"name"/g.test(r)&&(r=r.replace(/"name":\s*"name"/g,'"name": "item_name"'),U(o,r),t=!0)}return t}function $d(e){let t=!1,n=ge(e,"modules");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".module"))continue;let o=ge(n,s,"module.html");if(!w(o))continue;let r=I(o);r.includes("now()")&&(r=r.replace(/now\(\)/g,"local_dt"),U(o,r),t=!0)}return t}function Rd(e){let t=!1,n=ge(e,"templates");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".html"))continue;let o=ge(n,s),r=I(o);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(wb(o),t=!0)}return t}function Nd(e){let t=!1,n=ge(e,"modules");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".module"))continue;let o=ge(n,s,"fields.json");if(w(o))try{let r=JSON.parse(I(o));Ld(r)&&(U(o,JSON.stringify(r,null,2)+`
2781
+ `),t=!0)}catch{}}return t}function kb(e){let t=!1,n=ge(e,"css");if(w(n))for(let o of ut(n)){if(!o.endsWith(".css"))continue;let r=ge(n,o),i=I(r),a=i.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==i&&(U(r,a),t=!0)}let s=ge(e,"modules");if(w(s))for(let o of ut(s)){if(!o.endsWith(".module"))continue;let r=ge(s,o,"module.css");if(!w(r))continue;let i=I(r),a=i.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==i&&(U(r,a),t=!0)}if(w(s))for(let o of ut(s)){if(!o.endsWith(".module"))continue;let r=ge(s,o,"module.html");if(!w(r))continue;let i=I(r),a=i.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==i&&(U(r,a),t=!0)}return t}function Od(e){let t=!1,n=ge(e,"modules");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".module"))continue;let o=ge(n,s,"fields.json");if(w(o))try{let r=JSON.parse(I(o));Fd(r)&&(U(o,JSON.stringify(r,null,2)+`
2782
+ `),t=!0)}catch{}}return t}function Fd(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,r=o.color;if(typeof r=="string"&&!Cb(r)){let i=Tb(r);i&&(o.color=i.hex,i.opacity!==void 0&&(o.opacity=i.opacity),t=!0)}}Array.isArray(s.children)&&Fd(s.children)&&(t=!0)}return t}function Cb(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function Tb(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 r=Math.min(255,parseInt(n[1])),i=Math.min(255,parseInt(n[2])),a=Math.min(255,parseInt(n[3])),l=`#${r.toString(16).padStart(2,"0")}${i.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=e.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function Dd(e){let t=!1,n=ge(e,"templates");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".html"))continue;let o=ge(n,s),r=I(o);if(!/templateType:\s*email/i.test(r))continue;let i=r.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');i!==r&&(U(o,i),t=!0)}return t}function jd(e){let t=!1,n=ge(e,"templates");if(!w(n))return!1;for(let s of ut(n)){if(!s.endsWith(".html"))continue;let o=ge(n,s),r=I(o);if(!/templateType:\s*email/i.test(r)||r.includes("dnd_area_stylesheet"))continue;let i=r.replace(/(\{\{\s*standard_header_includes\s*\}\})/,`$1
2783
+ {{ dnd_area_stylesheet }}`);i!==r&&(U(o,i),t=!0)}return t}function Ld(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 i=typeof o=="string"?o:"";s.default={url:{href:i,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&Ld(s.children)&&(t=!0)}return t}te();y();cn();cn();import{readdirSync as Ab}from"fs";import{join as _b,relative as Pb}from"path";var Eb=new Set([".git","node_modules",".vibespot",".DS_Store"]);function Bd(e){let t=[];for(let n of Ab(e,{withFileTypes:!0})){if(Eb.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=_b(e,n.name);n.isDirectory()?t.push(...Bd(s)):n.isFile()&&t.push(s)}return t}async function Ib(e,t,n){let s=0;async function o(){for(;s<e.length;){let i=s++;await n(e[i])}}let r=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(r)}async function mr(e,t,n,s={}){let o=s.concurrency??5,r=Bd(t),i=r.length,a=0,l=0,c=[];return await Ib(r,o,async d=>{let u=Pb(t,d).replace(/\\/g,"/"),p=`${n}/${u}`;s.onFileStart?.(u);let g=await ql(e,p,d);if(g.success)a++,s.onFileComplete?.(u);else{l++;let f={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(f),s.onFileError?.(u,f)}s.onProgress?.(a+l,i)}),{success:l===0,uploaded:a,failed:l,total:i,errors:c}}function $b(e){return(e.match(/^Uploaded file /gm)||[]).length}async function qn(e){await fe("Uploading to HubSpot");let t=Mb(e)||e,n=$(),s=Je(),o=n.hubspotUploadMode!=="cli"&&!!s,r=await je(),i=3;for(let a=1;a<=i;a++){r.start(a===1?"Uploading theme...":`Retrying upload (attempt ${a}/${i})...`);let l=[],c=0,d=!1;if(o){let p=await mr(s,e,t,{onFileComplete:()=>{c++}});d=p.success,d?c=p.uploaded:l=dr(p.errors)}else{let p=cs("hs",["cms","upload",e,t],{cwd:Jd(e,"..")}),g=[p.stdout,p.stderr].filter(Boolean).join(`
2784
+ `);c=$b(g),d=p.success,d||(l=ur(g))}if(d)return r.stop(`All files uploaded! (${c} files)`),await he("Upload complete!"),!0;if(c>0?r.stop(`${c} files uploaded, but some errors occurred`):r.stop("Upload failed"),l.length===0){if(Z("Upload failed with unknown error."),c>0&&(se(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2785
+ You can check your HubSpot Design Manager to verify.`),await Ee({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<i){if(!await Ee({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let p of l)p.fixable?Ed(e,p)?(K(`Auto-fixed: ${p.message}`),u=!0):se(`Could not auto-fix: ${p.message}`):Z(p.message);if(!(u&&a<i)){if(c>0&&(se(`${c} files uploaded successfully despite errors.
2786
+ The theme may work \u2014 check HubSpot Design Manager.`),await Ee({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(r.start("Cleaning up stuck modules..."),o)try{await Pi(s,`${t}/modules`)}catch{}else cs("hs",["cms","delete",`${t}/modules`],{cwd:Jd(e,"..")});r.stop("Cleaned up modules, retrying...")}}}return Z("Upload failed after multiple attempts."),!1}y();import{execFileSync as ra}from"child_process";import{rmSync as Rb}from"fs";import{basename as Hd}from"path";ae();async function Ud(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await fe("You're all set!");let i=hs(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await xt(`Your React page has been converted and uploaded to HubSpot.
2934
2787
  The theme and modules are now in your account, but you still
2935
- need to ${I.bold("create a new landing page")} that uses them.
2788
+ need to ${E.bold("create a new landing page")} that uses them.
2936
2789
 
2937
2790
  Next steps:
2938
2791
 
2939
- ${I.bold("1.")} Go to HubSpot ${I.muted("\u2192")} Content ${I.muted("\u2192")} Landing Pages ${I.muted("\u2192")} Create
2940
- ${I.bold("2.")} Choose your uploaded theme from the theme picker
2941
- ${I.bold("3.")} Select the landing page template that was just created
2942
- ${I.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
2943
- ${I.bold("5.")} Click each section to edit text, images, and colors
2944
- ${I.bold("6.")} Upload images via File Manager ${I.muted("(Settings \u2192 Files)")}
2945
- ${I.bold("7.")} Preview and publish!`,"What's next"),await Me({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${r}/page-ui/${t}/management/pages/landing`:`https://${r}`;try{let d=process.platform;d==="darwin"?or("open",[c],{stdio:"ignore"}):d==="win32"?or("cmd",["/c","start","",c],{stdio:"ignore"}):or("xdg-open",[c],{stdio:"ignore"}),G("Opening HubSpot Landing Pages...")}catch{D(`Open this URL in your browser: ${I.info(c)}`)}}let l=[];if(o&&x(n)&&l.push({path:n,label:`Cloned source (${Xl(n)})`}),x(s)&&l.push({path:s,label:`Theme directory (${Xl(s)})`}),l.length>0&&await Me({message:"Clean up local working directories?"}))for(let d of l)try{Nf(d.path,{recursive:!0,force:!0}),G(`Removed ${d.label}`)}catch{se(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await fe(`Thanks for using hub${I.vibes("Vibes")}! ${I.vibes("~")}`)}ee();async function Ql(){Ee();let e=await co(),t=await uo();Y({lastSourcePath:t.sourceDir});let n=await go();Y({lastThemePath:n.themePath}),await Co({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await In(n.themePath),await Zl({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function ec(){Ee(),await co()}y();mo();ee();Qe();async function tc(){Ee();let e=R();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await uo(),n=await go();await Co({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();ee();Qe();async function nc(){Ee();let e=R();if(e.lastThemePath)if(await Me({message:`Upload from ${e.lastThemePath}?`}))await In(e.lastThemePath);else{let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await In(n)}else{let t=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await In(t)}}y();nn();ee();Qe();gt();async function sc(){Ee(),await ge("Environment Diagnostics");let e=0,t=Qn();t.found?oo(t.version)?G(`Node.js v${t.version}`):(se(`Node.js v${t.version} \u2014 too old (need 18+)`),D(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),D(" Install from https://nodejs.org"),e++);let n=es();n.found?G(`Git ${n.version}`):(V("Git \u2014 not installed"),D(" Install from https://git-scm.com"),e++);let s=ft();if(!s.found)se("HubSpot CLI \u2014 not installed (only needed for deployment)"),D(" Install: npm install -g @hubspot/cli");else if(!tl(s.version))se(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),D(" Update: npm install -g @hubspot/cli@latest"),e++;else{G(`HubSpot CLI v${s.version}`);let m=ht();m.authenticated?G(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(se("HubSpot \u2014 not authenticated"),D(" Run: hs init"))}let o=kn();o.found?G(`Claude Code ${o.version} at ${o.path}`):D(I.muted("Claude Code \u2014 not installed"));let i=Tn();i.found?G(`Gemini CLI ${i.version} at ${i.path}`):D(I.muted("Gemini CLI \u2014 not installed"));let r=An();r.found?G(`OpenAI Codex ${r.version} at ${r.path}`):D(I.muted("OpenAI Codex \u2014 not installed"));let a=R(),l=!!(a.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(a.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(a.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?G("Anthropic API key configured"):D(I.muted("Anthropic API key \u2014 not set")),c?G("OpenAI API key configured"):D(I.muted("OpenAI API key \u2014 not set")),d?G("Google AI API key configured"):D(I.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};a.aiEngine&&G(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&D(I.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(se("No AI engine available"),D(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),D(" Or install: Claude Code \u2014 https://claude.ai/code"),D(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),D(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await fe("Everything looks good!"):await fe(I.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}y();Cs();Ce();import{dirname as dv,join as $i}from"path";import{existsSync as uv}from"fs";import{fileURLToPath as mv}from"url";import{execFileSync as Oa}from"child_process";import Ei from"chalk";var Qp=dv(mv(import.meta.url)),pv=4200;async function eg(){let e=Ei.hex("#e8613a"),t=Ei.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
2946
- `));let n=gv();n||(console.error(Ei.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||pv;try{let{port:o,close:i}=await _i({port:s,uiDir:n}),r=`http://localhost:${o}`;if(console.log(e(` v ${r}`)),console.log(t(` Press Ctrl+C to stop
2947
- `)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?Oa("open",[r],{stdio:"ignore"}):process.platform==="win32"?Oa("cmd",["/c","start","",r],{stdio:"ignore"}):Oa("xdg-open",[r],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
2948
- Saving session...`)),L(),i(),console.log(t(` Goodbye!
2949
- `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(Ei.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function gv(){let e=[$i(Qp,"../../ui"),$i(Qp,"../ui"),$i(process.cwd(),"ui")];for(let t of e)if(uv($i(t,"index.html")))return t;return null}y();import{resolve as tg}from"path";import{existsSync as Fa}from"fs";gt();Qe();ee();Ma();async function ng(e={}){let t=await og(e.path);if(e.fix){let o=Ci(t);if(o.applied.length>0){G(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)D(` ${i}`)}else D(I.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)se(i)}let n=Hs(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
2950
- `),n.passed||process.exit(1);return}Ee(),await ge("Marketplace check");let s=`${n.errorCount} error${ja(n.errorCount)}, ${n.warningCount} warning${ja(n.warningCount)}, ${n.infoCount} note${ja(n.infoCount)}`;n.passed?G(`Theme passes Marketplace checks (${s}).`):V(`Theme is not yet ready: ${s}.`),Da("Errors",n.findings.filter(o=>o.severity==="error")),Da("Warnings",n.findings.filter(o=>o.severity==="warning")),Da("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(D(""),D(`Tip: run ${I.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await fe("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function sg(e={}){let t=await og(e.path);Ee(),await ge("Marketplace listing details");let n=qn(t)??{},s=await Mt({message:"Category",options:Zt.map(u=>({value:u,label:u}))}),o=await Se({message:"Description (1\u20132 sentences shown on the listing)",placeholder:"A clean, fast SaaS landing page theme...",defaultValue:n.description??"",validate:u=>u.trim().length<40?"Aim for at least 40 characters.":void 0}),r=(await Se({message:"Key features (comma-separated, 2\u20135 items)",placeholder:"Hero, Pricing, Testimonials, Footer",defaultValue:(n.features??[]).join(", "),validate:u=>{let m=u.split(",").map(g=>g.trim()).filter(Boolean).length;if(m<2)return"Provide at least 2 features.";if(m>5)return"Provide at most 5 features."}})).split(",").map(u=>u.trim()).filter(Boolean),a=await Se({message:"Public support URL",placeholder:"https://example.com/support",defaultValue:n.supportUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),l=await Se({message:"Documentation URL (optional)",placeholder:"https://example.com/docs",defaultValue:n.documentationUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),c=await Mt({message:"Pricing tier",options:[{value:"free",label:"Free"},{value:"paid",label:"Paid"}]}),d={category:s,description:o.trim(),features:r,supportUrl:a.trim()||void 0,documentationUrl:l.trim()||void 0,pricingTier:c,tags:n.tags};wi(t,d),G("Saved marketplace.json"),await fe(`Run ${I.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function og(e){if(e){let o=tg(e);if(!Fa(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&Fa(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=tg(n);if(!Fa(s))throw new Error(`Theme not found: ${s}`);return s}function Da(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}function ja(e){return e===1?"":"s"}y();import{resolve as ig}from"path";import{existsSync as La}from"fs";import{basename as fv}from"path";gt();Qe();ee();Uo();async function rg(e={}){let t=await hv(e.path),n=fv(t);if(e.applyTokens){let i=Ho(t,n);i?G(`Wrote design tokens to ${i}`):D(I.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=mr(t);e.json||G(`Wrote imported theme snapshot to ${i}`)}let s=Bo(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
2951
- `),process.exit(0)),Ee(),await ge("Inverse pipeline analyzer");let o=s.summary;if(D(`${I.heading("Summary")} ${o.moduleCount} module(s), ${o.templateCount} template(s), ${o.orphanCount} orphan, ${o.paletteSize} colour(s), ${o.cssVarCount} CSS var(s), ${o.customMacroCount} macro(s)`),s.designTokens.palette.length>0){D(""),D(I.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?I.muted(` (${i.varName})`):"";D(` ${i.value} ${I.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){D(""),D(I.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))D(` ${i}`)}if(s.graph.templates.length>0){D(""),D(I.heading("Template \u2192 modules"));for(let i of s.graph.templates)D(` ${i.id}: ${i.modules.length===0?I.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){D(""),D(I.heading("Orphan modules"));for(let i of s.graph.orphanModules)D(` ${i}`)}if(s.roundTripDiff.hasSnapshot){D(""),D(I.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)D(` ${I.muted("No changes from imported snapshot.")}`);else{D(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))D(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&D(` ${I.muted(`...and ${i.files.length-12} more`)}`)}}Ja("Errors",s.findings.filter(i=>i.severity==="error")),Ja("Warnings",s.findings.filter(i=>i.severity==="warning")),Ja("Notes",s.findings.filter(i=>i.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(D(""),D(`Tip: run ${I.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await fe("Analysis complete."),process.exit(0)}async function hv(e){if(e){let o=ig(e);if(!La(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&La(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=ig(n);if(!La(s))throw new Error(`Theme not found: ${s}`);return s}function Ja(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}y();Cs();Ce();import{dirname as yv,join as Mi}from"path";import{existsSync as bv}from"fs";import{fileURLToPath as Sv}from"url";import{execFileSync as Ba}from"child_process";import Ii from"chalk";var ag=yv(Sv(import.meta.url)),vv=4200;async function lg(){let e=Ii.hex("#e8613a"),t=Ii.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
2952
- `));let n=xv();n||(console.error(Ii.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await _i({port:vv,uiDir:n,contentMode:"email"}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Email template mode \u2014 Press Ctrl+C to stop
2953
- `));try{process.platform==="darwin"?Ba("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ba("cmd",["/c","start","",i],{stdio:"ignore"}):Ba("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
2954
- Saving session...`)),L(),o(),console.log(t(` Goodbye!
2955
- `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Ii.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function xv(){let e=[Mi(ag,"../../ui"),Mi(ag,"../ui"),Mi(process.cwd(),"ui")];for(let t of e)if(bv(Mi(t,"index.html")))return t;return null}oe();function cg(){let e=new wv;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Sn()).action(eg),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Ql),e.command("init").description("Check and install required tools").action(ec),e.command("convert").description("Convert a React project to HubSpot modules").action(tc),e.command("upload").description("Upload theme to HubSpot").action(nc),e.command("doctor").description("Diagnose environment issues").action(sc);let t=e.command("marketplace").description("Prepare a theme for HubSpot Marketplace submission");return t.command("check").description("Audit the theme against Marketplace requirements").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--fix","Apply auto-fixable findings before checking").action(n=>ng(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>sg(n)),e.command("email").description("Launch email template generation mode").action(lg),e.command("inverse").description("Analyze an imported HubSpot theme: design tokens, module graph, field flags, round-trip risks").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--apply-tokens","Seed css/<theme>-theme.css with the inferred :root block when missing").option("--snapshot","Capture the current theme as the imported round-trip baseline before analysis").action(n=>rg(n)),e}var Cv=cg();Cv.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
2792
+ ${E.bold("1.")} Go to HubSpot ${E.muted("\u2192")} Content ${E.muted("\u2192")} Landing Pages ${E.muted("\u2192")} Create
2793
+ ${E.bold("2.")} Choose your uploaded theme from the theme picker
2794
+ ${E.bold("3.")} Select the landing page template that was just created
2795
+ ${E.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
2796
+ ${E.bold("5.")} Click each section to edit text, images, and colors
2797
+ ${E.bold("6.")} Upload images via File Manager ${E.muted("(Settings \u2192 Files)")}
2798
+ ${E.bold("7.")} Preview and publish!`,"What's next"),await Ee({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${i}/page-ui/${t}/management/pages/landing`:`https://${i}`;try{let d=process.platform;d==="darwin"?ra("open",[c],{stdio:"ignore"}):d==="win32"?ra("cmd",["/c","start","",c],{stdio:"ignore"}):ra("xdg-open",[c],{stdio:"ignore"}),K("Opening HubSpot Landing Pages...")}catch{B(`Open this URL in your browser: ${E.info(c)}`)}}let l=[];if(o&&w(n)&&l.push({path:n,label:`Cloned source (${Hd(n)})`}),w(s)&&l.push({path:s,label:`Theme directory (${Hd(s)})`}),l.length>0&&await Ee({message:"Clean up local working directories?"}))for(let d of l)try{Rb(d.path,{recursive:!0,force:!0}),K(`Removed ${d.label}`)}catch{se(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await he(`Thanks for using hub${E.vibes("Vibes")}! ${E.vibes("~")}`)}te();async function Gd(){Pe();let e=await Eo(),t=await Io();Y({lastSourcePath:t.sourceDir});let n=await Ro();Y({lastThemePath:n.themePath}),await cr({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await qn(n.themePath),await Ud({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function Wd(){Pe(),await Eo()}y();te();async function Kd(){Pe();let e=$();e.aiEngine||(Z("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await Io(),n=await Ro();await cr({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();te();async function Vd(){Pe();let e=$();if(e.lastThemePath)if(await Ee({message:`Upload from ${e.lastThemePath}?`}))await qn(e.lastThemePath);else{let n=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await qn(n)}else{let t=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await qn(t)}}y();te();async function zd(){Pe(),await fe("Environment Diagnostics");let e=0,t=gs();t.found?Co(t.version)?K(`Node.js v${t.version}`):(se(`Node.js v${t.version} \u2014 too old (need 18+)`),B(" Update at https://nodejs.org"),e++):(Z("Node.js \u2014 not installed"),B(" Install from https://nodejs.org"),e++);let n=fs();n.found?K(`Git ${n.version}`):(Z("Git \u2014 not installed"),B(" Install from https://git-scm.com"),e++);let s=St();if(!s.found)se("HubSpot CLI \u2014 not installed (only needed for deployment)"),B(" Install: npm install -g @hubspot/cli");else if(!Ul(s.version))se(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),B(" Update: npm install -g @hubspot/cli@latest"),e++;else{K(`HubSpot CLI v${s.version}`);let p=vt();p.authenticated?K(`HubSpot portal${p.portalName?`: ${p.portalName}`:""} (ID: ${p.portalId})`):(se("HubSpot \u2014 not authenticated"),B(" Run: hs init"))}let o=Rn();o.found?K(`Claude Code ${o.version} at ${o.path}`):B(E.muted("Claude Code \u2014 not installed"));let r=Nn();r.found?K(`Gemini CLI ${r.version} at ${r.path}`):B(E.muted("Gemini CLI \u2014 not installed"));let i=On();i.found?K(`OpenAI Codex ${i.version} at ${i.path}`):B(E.muted("OpenAI Codex \u2014 not installed"));let a=$(),l=!!(a.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(a.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(a.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?K("Anthropic API key configured"):B(E.muted("Anthropic API key \u2014 not set")),c?K("OpenAI API key configured"):B(E.muted("OpenAI API key \u2014 not set")),d?K("Google AI API key configured"):B(E.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};a.aiEngine&&K(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&B(E.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!r.found&&!i.found&&!l&&!c&&!d&&(se("No AI engine available"),B(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),B(" Or install: Claude Code \u2014 https://claude.ai/code"),B(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),B(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await he("Everything looks good!"):await he(E.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}y();import{dirname as Sk,join as ii}from"path";import{existsSync as vk}from"fs";import{fileURLToPath as xk}from"url";import{execFileSync as wl}from"child_process";import ai from"chalk";y();me();Xn();Re();import{createServer as fk}from"http";import{readFileSync as vl,existsSync as xl}from"fs";import{join as oi,extname as Df}from"path";import{WebSocketServer as hk}from"ws";y();import{randomBytes as wS,timingSafeEqual as kS}from"crypto";var pa="vibespot_token";function hu(e){let t=(process.env[e]||"").toLowerCase();return t==="1"||t==="true"||t==="yes"}function yu(e){return e==="127.0.0.1"||e==="localhost"||e==="::1"||e==="[::1]"}function CS(e){return e?e==="127.0.0.1"||e==="::1"||e==="::ffff:127.0.0.1"||e.startsWith("127."):!1}function ma(e){let t=e||process.env.VIBESPOT_HOST||"127.0.0.1",n=hu("VIBESPOT_DISABLE_AUTH"),s=process.env.VIBESPOT_AUTH_TOKEN||null,o=!1;return n?{host:t,authToken:null,generatedToken:!1,authDisabled:n}:(!s&&!yu(t)&&(s=wS(24).toString("hex"),o=!0),{host:t,authToken:s,generatedToken:o,authDisabled:n})}function bu(e){return!e.authDisabled||yu(e.host)?{severity:"none",message:null}:hu("VIBESPOT_TRUST_PROXY")?{severity:"warn",message:` ! AUTH IS DISABLED on a non-loopback bind (VIBESPOT_DISABLE_AUTH=1 + VIBESPOT_TRUST_PROXY=1).
2799
+ ! An authenticating proxy MUST be the only way to reach this server.
2800
+ ! Never publish the app port directly (keep it expose-only, e.g. behind
2801
+ ! the docker-compose.auth.yml Entra gate) \u2014 anyone who reaches it can
2802
+ ! use your AI keys and HubSpot account.`}:{severity:"refuse",message:`VIBESPOT_DISABLE_AUTH=1 with a non-loopback bind (${e.host}) would serve a fully unauthenticated server \u2014 anyone who can reach the port could use your AI keys and HubSpot account. Refusing to start. If an authenticating proxy (e.g. the docker-compose.auth.yml Entra/oauth2-proxy gate) is the ONLY ingress to this port, set VIBESPOT_TRUST_PROXY=1 to acknowledge that and continue.`}}var Su=/^(localhost|127(?:\.\d+){3}|\[::1\]|::1|100\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|10\.\d+\.\d+\.\d+|172\.(?:1[6-9]|2\d|3[01])\.\d+\.\d+)$/;function TS(e){if(!e)return null;try{return new URL(`http://${e}`).hostname}catch{return null}}function AS(e,t){let n=TS(e);return n?Su.test(n)?!0:n===t.host:!1}function br(e,t){if(!e)return!0;let n;try{n=new URL(e)}catch{return!1}return n.protocol!=="http:"&&n.protocol!=="https:"?!1:t&&n.host===t?!0:Su.test(n.hostname)}function Zn(e,t){let n=Buffer.from(e),s=Buffer.from(t);return n.length===s.length&&kS(n,s)}function _S(e,t){let n=e.headers.cookie;if(!n)return null;for(let s of n.split(";")){let o=s.indexOf("=");if(o!==-1&&s.slice(0,o).trim()===t)return s.slice(o+1).trim()}return null}function ga(e,t){if(t.authDisabled)return{ok:!0,viaQueryToken:!1};if(t.authToken){let n=e.headers.authorization;if(n?.startsWith("Bearer ")&&Zn(n.slice(7).trim(),t.authToken))return{ok:!0,viaQueryToken:!1};let s=e.headers["x-vibespot-token"];if(typeof s=="string"&&Zn(s,t.authToken))return{ok:!0,viaQueryToken:!1};let o=_S(e,pa);if(o&&Zn(o,t.authToken))return{ok:!0,viaQueryToken:!1};try{let i=new URL(e.url||"/","http://localhost").searchParams.get("token");if(i&&Zn(i,t.authToken))return{ok:!0,viaQueryToken:!0}}catch{}}return CS(e.socket.remoteAddress)&&AS(e.headers.host,t)?{ok:!0,viaQueryToken:!1}:{ok:!1,viaQueryToken:!1}}y();import{createServer as PS}from"http";import{randomBytes as ES}from"crypto";import{existsSync as wu,readFileSync as ku}from"fs";import{extname as IS,join as Cu}from"path";Xn();me();wt();var fa="preview-agent.js",MS=10;function ha(e,t){let n=(e||"").trim();if(!n)return null;let s=r=>(console.warn(`Ignoring ${t||"public origin"} (${r}): ${n}`),null),o;try{o=new URL(n)}catch{return s("not an absolute URL")}return o.protocol!=="http:"&&o.protocol!=="https:"?s("must be http or https"):o.pathname!=="/"||o.search||o.hash?s("must not have a path, query, or fragment"):o.username||o.password?s("must not carry credentials"):o.origin}var $S={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".gif":"image/gif",".svg":"image/svg+xml",".webp":"image/webp",".avif":"image/avif",".ico":"image/x-icon",".css":"text/css; charset=utf-8",".js":"text/javascript; charset=utf-8",".woff":"font/woff",".woff2":"font/woff2",".ttf":"font/ttf",".otf":"font/otf",".mp4":"video/mp4",".webm":"video/webm"};function RS(){let e={};if(!x())return e;for(let n of pe())try{let s=JSON.parse(n.fieldsJson);Array.isArray(s)&&(e[n.moduleName]=s)}catch{}return e}function vu(e){return JSON.stringify(e).replace(/</g,"\\u003c")}function NS(e,t,n={}){let s=`<script id="vs-preview-config" type="application/json">${vu({v:1,token:t})}</script><script id="vs-preview-fields" type="application/json">${vu(n)}</script><script src="/${fa}"></script>`;return e.includes("<head>")?e.replace("<head>",`<head>${s}`):s+e}function OS(e,t){return e.replace(/(["'(])\/theme-assets\/([^"')?\s]+)/g,(n,s,o)=>`${s}/theme-assets/${o}?t=${t}`)}function xu(e,t,n){let s=e.searchParams.get("t");return s&&Zn(s,t)?!0:(n.writeHead(401,{"Content-Type":"text/plain; charset=utf-8"}),n.end("Preview access token required"),!1)}function FS(e,t){let n=Cu(e,fa);if(!wu(n)){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("preview-agent.js not found");return}t.writeHead(200,{"Content-Type":"text/javascript; charset=utf-8","Cache-Control":"no-cache"}),t.end(ku(n))}function DS(e,t){let n=x();if(!n){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("No session");return}let s;try{s=Ln(Cu(n.themePath,"assets"),decodeURIComponent(e))}catch{t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("Asset not found");return}if(!wu(s)){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("Asset not found");return}t.writeHead(200,{"Content-Type":$S[IS(s).toLowerCase()]||"application/octet-stream","Cache-Control":"no-cache"}),t.end(ku(s))}function jS(e){return["default-src 'none'","script-src 'self' 'unsafe-inline'","style-src 'unsafe-inline'","img-src * data: blob:","font-src * data:","media-src * data: blob:","connect-src 'none'","base-uri 'none'","form-action 'none'",`frame-ancestors ${e.length?e.join(" "):"'none'"}`].join("; ")}function LS(e,t,n){let s=new URL(e.url||"/",`http://${e.headers.host||"localhost"}`),o=e.method||"GET";if(t.setHeader("X-Content-Type-Options","nosniff"),o!=="GET"&&o!=="HEAD"){t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("Not found");return}if(s.pathname===`/${fa}`){FS(n.uiDir,t);return}if(s.pathname==="/"){if(!xu(s,n.token,t))return;let r=OS(NS(Us(),n.token,RS()),n.token);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8","Content-Security-Policy":n.csp,"Cache-Control":"no-store"}),t.end(r);return}if(s.pathname.startsWith("/theme-assets/")){if(!xu(s,n.token,t))return;DS(s.pathname.slice(14),t);return}t.writeHead(404,{"Content-Type":"text/plain; charset=utf-8"}),t.end("Not found")}function Tu(e){let t=e.token||ES(24).toString("hex"),n=jS(e.frameAncestors),s=PS((o,r)=>LS(o,r,{token:t,uiDir:e.uiDir,csp:n}));return new Promise((o,r)=>{let i=0,a=l=>{s.once("error",c=>{c.code==="EADDRINUSE"&&i<MS?(i+=1,a(l+1)):r(c)}),s.listen(l,e.host,()=>{s.removeAllListeners("error"),o({port:l,host:e.host,token:t,publicOrigin:e.publicOrigin||null,close:()=>s.close()})})};a(e.port)})}hn();y();Re();y();At();Re();te();xs();$o();cn();me();Xt();os();import{existsSync as is,readdirSync as hm,rmSync as $x,writeFileSync as wn,mkdirSync as jr}from"fs";import{join as Me,basename as Rx,resolve as ym}from"path";import{homedir as Nx}from"os";import{execFileSync as Sm}from"child_process";te();ae();y();import{readFileSync as Ax,readdirSync as _x,existsSync as Px}from"fs";import{dirname as Ex,join as Dr}from"path";import{fileURLToPath as Ix}from"url";var mm=Ex(Ix(import.meta.url)),rs=null;function Mx(){let e=[Dr(mm,"../../starters"),Dr(mm,"../starters"),Dr(process.cwd(),"starters")];for(let t of e)if(Px(t))return t;return null}function gm(){if(rs!==null)return rs;let e=Mx();if(!e)return rs=[],rs;let t=[];for(let n of _x(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(Ax(Dr(e,n),"utf-8"));t.push({id:s.id,name:s.name,description:s.description,category:s.category||"General",contentType:s.contentType==="email"?"email":void 0,modules:s.modules||[],moduleOrder:s.moduleOrder||[],sharedCss:s.sharedCss||"",sharedJs:s.sharedJs||""})}catch{}return rs=t,rs}function fm(){return gm().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function sl(e){return gm().find(t=>t.id===e)||null}hn();Ua();var vm=process.platform==="win32"?{shell:!0}:{},gt=Me(Nx(),"vibespot-themes"),Lr=null,Ox=5e3;function Br(){if(Lr&&Date.now()-Lr.ts<Ox)return Lr.data;let e=[];if(is(gt))try{for(let t of hm(gt,{withFileTypes:!0}))if(t.isDirectory()){let n=Me(gt,t.name,"theme.json");if(is(n)){let s=0,o=Me(gt,t.name,"modules");if(is(o))try{s=hm(o,{withFileTypes:!0}).filter(r=>r.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return Lr={data:e,ts:Date.now()},e}function xm(e){let t=x(),n=To(),s=!1;try{Sm("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...vm}),s=!0}catch{}let o=Wn().sort((i,a)=>a.updatedAt-i.updatedAt),r=Br();m(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length,isImported:!!t.isImported}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:r,contentMode:tn()})}function wm(e,t){G(e,n=>{try{if(Gt()){m(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s,starterId:o,assetType:r}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"Theme name is required"});return}let i=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!i){m(t,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Me(gt,i);if($e(gt),is(a)&&$x(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!sl(o)){m(t,400,{error:`Starter template "${o}" not found`});return}vs(a,i),Gn(a,i),o&&typeof o=="string"?(Fx(a,i,o),Ae()):r==="email"&&(jt("module_only","Email","email"),jn(a,i)),D(),m(t,200,{ok:!0,themeName:i,themePath:a,starterId:o||void 0})}catch(s){m(t,500,{error:N(s)})}})}function Fx(e,t,n){let s=sl(n);if(!s)return;let o=x();if(!o)return;let r=s.contentType==="email",i=s.modules.map(u=>({...u})),a=[...s.moduleOrder],l=r?`email-${t}`:`lp-${t}`,c={id:l,label:`${s.name}`,pageType:r?"module_only":"landing_page",contentMode:r?"email":void 0,templateFile:r?"templates/email.html":`templates/${l}.html`,modules:i,moduleOrder:a,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};r&&jn(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=i,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Me(e,"modules");jr(d,{recursive:!0});for(let u of s.modules){let p=Me(d,`${u.moduleName}.module`);jr(p,{recursive:!0}),wn(Me(p,"fields.json"),u.fieldsJson,"utf-8"),wn(Me(p,"meta.json"),u.metaJson,"utf-8"),wn(Me(p,"module.html"),u.moduleHtml,"utf-8"),wn(Me(p,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&wn(Me(p,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Me(e,"css");jr(u,{recursive:!0}),wn(Me(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Me(e,"js");jr(u,{recursive:!0}),wn(Me(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function km(e){m(e,200,{starters:fm()})}function Cm(e,t){G(e,n=>{try{if(Gt()){m(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){m(t,400,{error:"Theme name is required"});return}let r=Je(),i=$(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Me(gt,a);$e(gt),i.hubspotUploadMode==="cli"||!r?(async()=>{Sm("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...vm});let c=await bm(l,a);m(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})})().catch(c=>{m(t,500,{error:N(c)})}):ks(r,o,l).then(async()=>{let c=await bm(l,a);m(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})}).catch(c=>{m(t,500,{error:N(c)})})}catch(s){m(t,500,{error:N(s)})}})}async function bm(e,t){Gn(e,t,{isImported:!0}),sr(e),D();let n=x(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await nm(n),D()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function Tm(e,t){G(e,n=>{try{if(Gt()){m(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"Theme path is required"});return}let o=s;if(is(o)||(o=Me(gt,s)),!is(o)){m(t,400,{error:`Theme folder not found: ${s}`});return}let r=Rx(o),i=x();if(i&&ym(i.themePath)===ym(o)){m(t,200,{ok:!0,themeName:i.themeName,themePath:i.themePath,moduleCount:i.modules.length,resumed:!0});return}let a=ed(o),l=a?Rs(a):null;if(l){m(t,200,{ok:!0,themeName:l.themeName,themePath:l.themePath,moduleCount:l.modules.length,resumed:!0});return}Gn(o,r),sr(o),D(),m(t,200,{ok:!0,themeName:r,themePath:o,moduleCount:x()?.modules.length||0,resumed:!1})}catch(s){m(t,500,{error:N(s)})}})}function Am(e,t){G(e,n=>{try{if(Gt()){m(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"Session ID is required"});return}let o=Rs(s);if(!o){m(t,404,{error:"Session not found"});return}m(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){m(t,500,{error:N(s)})}})}function _m(e,t){G(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"API key is required"});return}Y({anthropicApiKey:s}),m(t,200,{ok:!0})}catch(s){m(t,400,{error:N(s)})}})}function Pm(e){let t=Je();if(!t){m(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Xl(t);if(n.length===0){m(e,200,{themes:[]});return}let s=[],o=n.map(async a=>{let l=a.path||a.name;try{let c=await Po(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:a.name,path:l})}catch{}});await Promise.all(o),s.sort((a,l)=>a.name.localeCompare(l.name));let r=Br(),i=new Set(r.map(a=>a.name));m(e,200,{themes:s.map(a=>({...a,existsLocally:i.has(a.name)}))})})().catch(n=>{m(e,200,{themes:[],error:N(n)})})}y();At();Re();te();me();import{existsSync as Lx,readFileSync as Bx,appendFileSync as Jx}from"fs";import{join as $m}from"path";import{homedir as Rm}from"os";cn();ae();y();import{spawn as Em}from"child_process";var kn=new Map;function Dx(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+=`
2803
+ Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
2804
+ Process timed out`,t.completedAt=Date.now())},n||3e5).unref()}function ft(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,r={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};kn.set(o,r);let i=Em(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&i.stdin&&(i.stdin.write(s.stdin),i.stdin.end()),Dx(i,r,s?.timeout),o}function Jr(e){return kn.get(e)}function jx(){let e=Date.now()-18e5;for(let[t,n]of kn)n.completedAt&&n.completedAt<e&&kn.delete(t)}setInterval(jx,600*1e3).unref();function Hr(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,r={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};kn.set(o,r);let i=Em(e,t,{cwd:s?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"}),a=c=>{for(let d of r.listeners)try{d(c)}catch{}};i.stdout?.on("data",c=>{let d=c.toString();r.output+=d,a(d)}),i.stderr?.on("data",c=>{let d=c.toString();r.output+=d,a(d)}),i.on("close",c=>{r.status=c===0?"completed":"failed",r.exitCode=c,r.completedAt=Date.now(),r.listeners.clear()}),i.on("error",c=>{r.status="failed",r.output+=`
2805
+ Process error: ${c.message}`,r.completedAt=Date.now(),r.listeners.clear()});let l=s?.timeout||3e5;return setTimeout(()=>{r.status==="running"&&(i.kill(),r.status="failed",r.output+=`
2806
+ Process timed out`,r.completedAt=Date.now(),r.listeners.clear())},l).unref(),o}function Im(e,t){let n=kn.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Mm(e,t){let n=kn.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var as={data:{},ts:0},Hx=600*1e3,ol={"claude-code":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}],"codex-cli":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"},{id:"gpt-5.2-codex",label:"GPT-5.2 Codex"},{id:"gpt-5.1-codex-max",label:"GPT-5.1 Codex Max"},{id:"gpt-5.1-codex-mini",label:"GPT-5.1 Codex Mini"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"codex-mini-latest",label:"Codex Mini (latest)"}],"anthropic-api":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"claude-oauth":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"openai-api":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"}],"gemini-api":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],"gemini-cli":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}]},Nm={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],openai:[{id:"gpt-4.1",label:"GPT-4.1 (default)"},{id:"gpt-4.1-mini",label:"GPT-4.1 Mini"},{id:"gpt-4.1-nano",label:"GPT-4.1 Nano"},{id:"gpt-4o",label:"GPT-4o"},{id:"o3-mini",label:"o3 Mini"}],google:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],mistral:[{id:"mistral-large-latest",label:"Mistral Large (default)"},{id:"mistral-medium-latest",label:"Mistral Medium"},{id:"mistral-small-latest",label:"Mistral Small"},{id:"codestral-latest",label:"Codestral"},{id:"pixtral-large-latest",label:"Pixtral Large"}]},Dm=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,Ux=Dm;function Gx(e){let t=e.match(/^gpt-(\d+(?:\.\d+)?)(?:-(.+))?$/);if(t){let n=t[1],s=t[2];if(!s)return`GPT-${n}`;let o=s.replace(/-/g," ").replace(/\b\w/g,r=>r.toUpperCase());return`GPT-${n} ${o}`}return e.startsWith("codex-")?`Codex ${e.slice(6).replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}`:/^o\d/.test(e)?e.replace(/-/g," "):e}var jm=2500;async function rl(e,t={},n=jm){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function Wx(e){let t=await rl("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 Kx(e){let t=await rl("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function Om(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:Gx(n)}))}async function Vx(e){let t=await rl(`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 zx(e=!1){if(!e&&Date.now()-as.ts<Hx&&Object.keys(as.data).length>0)return as.data;let t=$(),n={...ol},s=[],o=De("anthropic-api",t);o&&s.push(Wx(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c,n["claude-code"]=c)}).catch(()=>{}));let r=De("openai-api",t);r&&s.push(Kx(r).then(c=>{if(!c.length)return;let d=Om(c,Dm);d.length&&(n["openai-api"]=d);let u=Om(c,Ux);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let i=De("gemini-api",t);i&&s.push(Vx(i).then(c=>{c.length&&(n["gemini-api"]=c,n["gemini-cli"]=c)}).catch(()=>{}));let a=!1;await Promise.race([Promise.all(s).then(()=>{a=!0}),new Promise(c=>setTimeout(c,jm+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=Nm[l]||Nm.anthropic,a&&(as.data=n,as.ts=Date.now()),n}function Lm(e){let t=Gl(),n=$(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,codexCliModel:n.codexCliModel||null,geminiCliModel:n.geminiCliModel||null,geminiApiModel:n.geminiApiModel||null,langdockApiModel:n.langdockApiModel||null,langdockBaseUrl:n.langdockBaseUrl||null,langdockProvider:n.langdockProvider||"anthropic",hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(o=>({portalId:o.portalId,portalName:o.portalName,dataCenter:o.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null,langfuseEnabled:n.langfuseEnabled,langfuseBaseUrl:n.langfuseBaseUrl||null};m(e,200,{version:Mt(),environment:t,config:s,models:ol,sessionCount:Wn().length,localThemeCount:Br().length})}function Bm(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");zx(n).then(s=>m(t,200,{models:s})).catch(()=>m(t,200,{models:ol}))}var qx=60*1e3,Fm={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}};function Jm(e,t){let n=new URL(e.url||"/","http://localhost"),s=n.searchParams.get("group")||"all",o=s==="ai"||s==="platform"?s:"all",r=n.searchParams.get("refresh")==="1",i=Fm[o];if(!r&&Date.now()-i.ts<qx&&Object.keys(i.data).length>0){m(t,200,{...i.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=Wl();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:Kl()};else{let l=To();a={tools:l.tools,availableEngines:l.availableEngines}}Fm[o]={data:a,ts:Date.now()},m(t,200,{...a,group:o,cached:!1})}function Hm(e,t){G(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli","langdock-api"].includes(s)){m(t,400,{error:`Invalid engine: ${s}`});return}let i={aiEngine:s};if(o)switch(s){case"claude-code":i.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":i.anthropicApiModel=o;break;case"openai-api":i.openaiApiModel=o;break;case"codex-cli":i.codexCliModel=o;break;case"gemini-cli":i.geminiCliModel=o;break;case"gemini-api":i.geminiApiModel=o;break;case"langdock-api":i.langdockApiModel=o;break}Y(i),m(t,200,{ok:!0,engine:s})}catch(s){m(t,400,{error:N(s)})}})}function Um(e,t){G(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"langdock":l.langdockApiKey="";break;case"figma":l.figmaToken="";break;case"langfuse-public":l.langfusePublicKey="";break;case"langfuse-secret":l.langfuseSecretKey="";break;default:m(t,400,{error:`Unknown provider: ${s}`});return}Y(l),m(t,200,{ok:!0,provider:s,deleted:!0});return}let r={};switch(s){case"anthropic":r.anthropicApiKey=o;break;case"openai":r.openaiApiKey=o;break;case"gemini":r.geminiApiKey=o;break;case"langdock":r.langdockApiKey=o;break;case"figma":r.figmaToken=o;break;case"langfuse-public":r.langfusePublicKey=o;break;case"langfuse-secret":r.langfuseSecretKey=o;break;default:m(t,400,{error:`Unknown provider: ${s}`});return}Y(r);let i=null;if(!$().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(Y({aiEngine:c}),i=c)}m(t,200,{ok:!0,provider:s,autoSelectedEngine:i})}catch(s){m(t,400,{error:N(s)})}})}function Gm(e,t){G(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm",args:["install","-g","@hubspot/cli"],desc:"Installing HubSpot CLI"},claude:{cmd:"npm",args:["install","-g","@anthropic-ai/claude-code"],desc:"Installing Claude Code"},gemini:{cmd:"npm",args:["install","-g","@google/gemini-cli"],desc:"Installing Gemini CLI"},codex:process.platform==="darwin"?{cmd:"brew",args:["install","--cask","codex"],desc:"Installing OpenAI Codex"}:{cmd:"npm",args:["install","-g","@openai/codex"],desc:"Installing OpenAI Codex"},gh:process.platform==="darwin"?{cmd:"brew",args:["install","gh"],desc:"Installing GitHub CLI"}:{cmd:"npm",args:["install","-g","@cli/gh"],desc:"Installing GitHub CLI"}},r=o[s];if(!r){m(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let i=ft(r.cmd,r.args,r.desc,{timeout:12e4});m(t,200,{ok:!0,jobId:i})}catch(s){m(t,400,{error:N(s)})}})}function Wm(e,t){G(e,n=>{try{let s=JSON.parse(n||"{}"),o=$(),r=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(r==="api"){_o(s.personalAccessKey).then(i=>{us(s.personalAccessKey,i.portalId,i.portalName,i.dataCenter),m(t,200,{ok:!0,portalName:i.portalName,portalId:i.portalId,dataCenter:i.dataCenter})}).catch(i=>{m(t,400,{error:N(i)})});return}else{if(!St().found){m(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ft("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});m(t,200,{ok:!0,jobId:a});return}if(r==="api"){let i=o.hubspotAccounts||[];if(i.length>0&&!s.force){let a=i.find(l=>l.portalId===o.activeHubSpotAccount)||i[0];m(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!St().found){m(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=vt();if(a.authenticated&&!s.force){m(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}m(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){m(t,500,{error:N(s)})}})}function Km(e,t){G(e,n=>{try{let s=JSON.parse(n||"{}");if(!wo().found){m(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let r=ko();if(r.authenticated&&!s.force){m(t,200,{ok:!0,alreadyAuthenticated:!0,username:r.username});return}if(s.token){let a=ft("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});m(t,200,{ok:!0,jobId:a});return}let i=ft("gh",["auth","login","--web","--git-protocol","https"],"GitHub authentication (check your browser)",{timeout:3e5});m(t,200,{ok:!0,jobId:i,browserAuthRequired:!0})}catch(s){m(t,500,{error:N(s)})}})}function Vm(e,t){G(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if(($().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){fi(s),m(t,200,{ok:!0});return}if(s){hi(s),m(t,200,{ok:!0});return}}else{if(!St().found){m(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){m(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=ft("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});m(t,200,{ok:!0,jobId:c});return}if(l){let c=ft("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});m(t,200,{ok:!0,jobId:c});return}}m(t,400,{error:"portalId required"})}catch(s){m(t,500,{error:N(s)})}})}function zm(e){let t=ft("gh",["auth","logout","--hostname","github.com","-y"],"Logging out of GitHub",{timeout:15e3});m(e,200,{ok:!0,jobId:t})}function qm(e,t){G(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let r=ft("claude",["--print","-p","reply OK"],"Authenticating Claude Code (check your browser if prompted)",{timeout:12e4,env:{CLAUDECODE:""}});m(t,200,{ok:!0,jobId:r,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let r=ft("gemini",["-p","reply OK"],"Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});m(t,200,{ok:!0,jobId:r,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let r=o.trim();if(process.env.OPENAI_API_KEY=r,Y({openaiApiKey:r}),process.platform!=="win32"){let i=/^[A-Za-z0-9_\-.:]+$/.test(r)?r:"";if(i){let a=`export OPENAI_API_KEY="${i}"`,l=process.env.SHELL?.includes("zsh")?$m(Rm(),".zshrc"):$m(Rm(),".bashrc");try{(Lx(l)?Bx(l,"utf-8"):"").includes("OPENAI_API_KEY")||Jx(l,`
2807
+ # Added by vibeSpot
2808
+ ${a}
2809
+ `)}catch{}}}m(t,200,{ok:!0,message:"API key saved"})}else{let r=ft("codex",["login"],"Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});m(t,200,{ok:!0,jobId:r,hint:"Complete the sign-in in your browser."})}break}default:m(t,400,{error:`Unknown CLI: ${s}`})}}catch(s){m(t,400,{error:N(s)})}})}function Ym(e,t){G(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){m(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}Y({hubspotUploadMode:s}),m(t,200,{ok:!0,mode:s})}catch(s){m(t,400,{error:N(s)})}})}function Xm(e,t){G(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){m(t,400,{error:"toolId (string) and enabled (boolean) required"});return}yi(s,o),m(t,200,{ok:!0,toolId:s,enabled:o})}catch(s){m(t,400,{error:N(s)})}})}function Zm(e,t){G(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider","langfuseEnabled","langfuseBaseUrl"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){m(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langfuseEnabled!==void 0&&typeof s.langfuseEnabled!="boolean"){m(t,400,{error:"langfuseEnabled must be a boolean"});return}if(s.langfuseBaseUrl!==void 0&&typeof s.langfuseBaseUrl!="string"){m(t,400,{error:"langfuseBaseUrl must be a string"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){m(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let r={};for(let i of o)i in s&&(r[i]=s[i]);if(r.langdockProvider){let i={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};r.langdockApiModel=i[r.langdockProvider]||"",as.ts=0}if(Object.keys(r).length===0){m(t,400,{error:"No valid settings fields provided"});return}Y(r),m(t,200,{ok:!0,updated:Object.keys(r)})}catch(s){m(t,400,{error:N(s)})}})}function Qm(e,t){let n=e.replace("/api/settings/job/","");if(!n){m(t,400,{error:"Job ID required"});return}let s=Jr(n);if(!s){m(t,404,{error:"Job not found"});return}m(t,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}y();ae();te();Re();import{readFileSync as Yx}from"fs";function Xx(){try{let e=Yx(Kt("whats-new.json"),"utf8"),t=JSON.parse(e);return!t||typeof t.version!="string"||!Array.isArray(t.highlights)?null:t}catch{return null}}function eg(e){let t=Xx(),n=Mt(),s=$().lastSeenVersion,o=!!t&&t.highlights.length>0&&t.version===n&&t.version!==s;m(e,200,{show:o,content:t||null,currentVersion:n})}function tg(e,t){G(e,n=>{let s=Mt();try{if(n){let o=JSON.parse(n);o&&typeof o.version=="string"&&o.version&&(s=o.version)}}catch{}Y({lastSeenVersion:s}),m(t,200,{ok:!0,lastSeenVersion:s})})}function ng(e){m(e,200,{changelog:$l()})}y();At();Re();te();$t();function sg(e,t){G(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"access_token is required"});return}wi(s.trim(),(o||"").trim());let r=$();(!r.aiEngine||r.aiEngine!=="claude-oauth")&&Y({aiEngine:"claude-oauth"}),m(t,200,{ok:!0})}catch(s){m(t,400,{error:N(s)})}})}function og(e,t){let n=Qe(),s=rn();m(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function rg(e,t){try{ps(),$().aiEngine==="claude-oauth"&&Y({aiEngine:void 0}),m(t,200,{ok:!0})}catch(n){m(t,500,{error:N(n)})}}y();At();Re();me();import{existsSync as Zx,rmSync as Qx}from"fs";import{join as ew}from"path";function ig(e,t,n){if(e==="GET"){let s=x(),o=Wn().sort((r,i)=>i.updatedAt-r.updatedAt);m(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName,isImported:!!s.isImported}:null,sessions:o});return}if(e==="DELETE"){G(t,s=>{try{let{sessionId:o,deleteFiles:r}=JSON.parse(s);td(o,r),m(n,200,{ok:!0})}catch(o){m(n,500,{error:N(o)})}});return}m(n,405,{error:"Method not allowed"})}function ag(e,t){G(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=Rs(s);if(!o){m(t,404,{error:"Session not found"});return}m(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){m(t,500,{error:N(s)})}})}function lg(e,t){G(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"Theme name is required"});return}if(/[\/\\]|\.\./.test(s)||s==="."||!s.replace(/[^a-z0-9]/gi,"")){m(t,400,{error:"Invalid theme name"});return}let o=ew(gt,s);if(!Zx(o)){m(t,404,{error:"Theme not found on disk"});return}Qx(o,{recursive:!0,force:!0}),m(t,200,{ok:!0})}catch(s){m(t,500,{error:N(s)})}})}function cg(e,t){G(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(t,400,{error:"sessionId and newName are required"});return}let r=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!r){m(t,400,{error:"Invalid name"});return}let i=nd(s,r);i.ok?m(t,200,{ok:!0,newName:r}):m(t,400,{error:i.error})}catch(s){m(t,500,{error:N(s)})}})}function dg(e,t){G(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){m(t,400,{error:"sessionId is required"});return}let o=sd(s);o.ok?m(t,200,{ok:!0,newName:o.newName,newSessionId:o.newSessionId}):m(t,400,{error:o.error})}catch(s){m(t,500,{error:N(s)})}})}y();At();Re();re();Ue();te();xs();me();ae();import{existsSync as Ur,readFileSync as tw,readdirSync as nw,rmSync as fg}from"fs";import{join as Oe,basename as sw,relative as ow,sep as rw}from"path";import iw from"jszip";import aw from"busboy";function hg(e){let t=x();if(!t){m(e,404,{error:"No active session"});return}let n=Lt();m(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.contentMode==="email"?"email":s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1,hasBrandKit:!!t.brandAssets?.brandKit&&Object.keys(t.brandAssets.brandKit).length>0,brandKit:t.brandAssets?.brandKit||null}})}var lw=new Set([".git",".vibespot","node_modules"]);function yg(e,t=[]){for(let n of nw(e,{withFileTypes:!0}))if(n.isDirectory()){if(lw.has(n.name))continue;yg(Oe(e,n.name),t)}else n.isFile()&&t.push(Oe(e,n.name));return t}async function bg(e){let t=x();if(!t){m(e,404,{error:"No active session"});return}let n=t.themePath;if(!Ur(n)){m(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=sw(n);try{let r=new iw;for(let a of yg(n)){let l=Oe(o,ow(n,a)).split(rw).join("/");r.file(l,tw(a))}let i=await r.generateAsync({type:"nodebuffer",compression:"DEFLATE",compressionOptions:{level:6}});e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${s}.zip"`,"Content-Length":i.length}),e.end(i)}catch(r){A.error("download-zip","Failed to create zip archive",r),m(e,500,{error:"Failed to create zip archive"})}}function Sg(e,t,n){let s=x();if(!s){m(n,404,{error:"No active session"});return}if(e==="GET"){m(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.contentMode==="email"?"email":o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){G(t,o=>{try{let{pageType:r,label:i}=JSON.parse(o);if(!r||!i){m(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only","email"].includes(r)){m(n,400,{error:`Invalid pageType: ${r}`});return}let l=r==="email",d=jt(l?"module_only":r,i,l?"email":void 0);l&&s.themePath&&jn(s.themePath,s.themeName),D(),m(n,200,{ok:!0,template:{id:d.id,label:d.label,pageType:d.pageType}})}catch(r){m(n,500,{error:N(r)})}});return}if(e==="DELETE"){G(t,o=>{try{let{templateId:r,deleteModules:i}=JSON.parse(o);if(!r){m(n,400,{error:"templateId is required"});return}if(!qc(r,!!i)){m(n,404,{error:"Template not found"});return}D(),m(n,200,{ok:!0})}catch(r){m(n,500,{error:N(r)})}});return}m(n,405,{error:"Method not allowed"})}function vg(e,t){G(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){m(t,400,{error:"templateId is required"});return}if(!Es(s)){m(t,404,{error:"Template not found"});return}D();let r=x();m(t,200,{ok:!0,modules:pe().map(i=>i.moduleName),messageCount:r?.messages.length||0})}catch(s){m(t,500,{error:N(s)})}})}function xg(e,t){G(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(t,400,{error:"templateId and newLabel are required"});return}if(!zc(s,o.trim())){m(t,404,{error:"Template not found"});return}D(),m(t,200,{ok:!0,newLabel:o.trim()})}catch(s){m(t,500,{error:N(s)})}})}function wg(e,t){G(e,n=>{try{let{templateIds:s}=JSON.parse(n);if(!Array.isArray(s)||s.some(r=>typeof r!="string")){m(t,400,{error:"templateIds must be an array of strings"});return}if(!Vc(s)){m(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}D(),m(t,200,{ok:!0})}catch(s){m(t,500,{error:N(s)})}})}function kg(e,t){G(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){m(t,400,{error:"templateId is required"});return}let r=Kc(s,o);if(!r){m(t,404,{error:"Template not found"});return}D(),m(t,200,{ok:!0,template:{id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length}})}catch(s){m(t,500,{error:N(s)})}})}function Cg(e){let t=Lt();m(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Tg(e,t,n){let s=x();if(!s){m(n,404,{error:"No active session"});return}G(t,o=>{try{let{moduleName:r}=JSON.parse(o);if(!r){m(n,400,{error:"moduleName is required"});return}let a=Lt().find(d=>d.module.moduleName===r);if(!a){m(n,404,{error:`Module "${r}" not found in library`});return}let l={...a.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),D(),m(n,200,{ok:!0})}catch(r){m(n,500,{error:N(r)})}})}function Ag(e,t,n){let s=x();if(!s){m(n,404,{error:"No active session"});return}if(e==="GET"){m(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){if((t.headers["content-type"]||"").includes("multipart/form-data")){dw(s,t,n);return}G(t,r=>{try{let{type:i,content:a}=JSON.parse(r);if(!i){m(n,400,{error:"type is required"});return}if(i==="humanify"){s.brandAssets||(s.brandAssets={}),s.brandAssets.humanify=a==="on",s.updatedAt=Date.now(),D(),m(n,200,{ok:!0});return}if(!a){m(n,400,{error:"content is required"});return}if(!_g(i)){m(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}Pg(s,i,a,n)}catch(i){m(n,500,{error:N(i)})}});return}if(e==="DELETE"){G(t,o=>{try{let{type:r}=JSON.parse(o);if(r!=="styleguide"&&r!=="brandvoice"&&r!=="themeContext"){m(n,400,{error:`Invalid type: ${r}`});return}let i=r;s.brandAssets&&delete s.brandAssets[i],s.updatedAt=Date.now();let a=i==="themeContext"?"theme-context.md":`${i}.md`,l=Oe(s.themePath,".vibespot",a);Ur(l)&&fg(l),D(),m(n,200,{ok:!0})}catch(r){m(n,500,{error:N(r)})}});return}m(n,405,{error:"Method not allowed"})}var cw=1024*1024;function _g(e){return e==="styleguide"||e==="brandvoice"||e==="themeContext"}function Pg(e,t,n,s){e.brandAssets||(e.brandAssets={});let o=t==="themeContext"?"theme-context.md":`${t}.md`;e.brandAssets[t]=n,e.updatedAt=Date.now();let r=Oe(e.themePath,".vibespot");$e(r),U(Oe(r,o),n);let i=null;t==="styleguide"&&(i=il(e,n)),D(),m(s,200,{ok:!0,brandKit:i})}function dw(e,t,n){let s;try{s=aw({headers:t.headers,limits:{fileSize:cw,files:1,fields:5}})}catch{m(n,400,{error:"Malformed upload"});return}let o="",r=[],i=!1,a=!1,l=!1,c=(d,u)=>{l||(l=!0,m(n,d,{error:u}))};s.on("field",(d,u)=>{d==="type"&&(o=u)}),s.on("file",(d,u)=>{i=!0,u.on("data",p=>r.push(p)),u.on("limit",()=>{a=!0,u.resume()})}),s.on("finish",()=>{if(!l)try{if(!_g(o)){c(400,`Invalid type: ${o||"(missing)"}. Must be "styleguide", "brandvoice", or "themeContext"`);return}if(!i){c(400,"file is required");return}if(a){c(413,"File too large \u2014 brand assets are text files up to 1 MB.");return}let d=Buffer.concat(r);if(d.length===0){c(400,"content is required");return}if(d.includes(0)){c(400,"File doesn't look like plain text. Please upload a UTF-8 .md or .txt file.");return}let u;try{u=new TextDecoder("utf-8",{fatal:!0}).decode(d)}catch{c(400,"File is not valid UTF-8 text. Please upload a UTF-8 .md or .txt file.");return}l=!0,Pg(e,o,u,n)}catch(d){c(500,N(d))}}),s.on("error",()=>c(400,"Upload failed")),t.pipe(s)}var Eg=[{name:"System Default",stack:"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",category:"system"},{name:"Inter",stack:"Inter, system-ui, sans-serif",category:"sans-serif"},{name:"DM Sans",stack:"'DM Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Open Sans",stack:"'Open Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Roboto",stack:"Roboto, system-ui, sans-serif",category:"sans-serif"},{name:"Lato",stack:"Lato, system-ui, sans-serif",category:"sans-serif"},{name:"Montserrat",stack:"Montserrat, system-ui, sans-serif",category:"sans-serif"},{name:"Poppins",stack:"Poppins, system-ui, sans-serif",category:"sans-serif"},{name:"Nunito",stack:"Nunito, system-ui, sans-serif",category:"sans-serif"},{name:"Raleway",stack:"Raleway, system-ui, sans-serif",category:"sans-serif"},{name:"Work Sans",stack:"'Work Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Source Sans 3",stack:"'Source Sans 3', system-ui, sans-serif",category:"sans-serif"},{name:"Manrope",stack:"Manrope, system-ui, sans-serif",category:"sans-serif"},{name:"Plus Jakarta Sans",stack:"'Plus Jakarta Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Outfit",stack:"Outfit, system-ui, sans-serif",category:"sans-serif"},{name:"Space Grotesk",stack:"'Space Grotesk', system-ui, sans-serif",category:"sans-serif"},{name:"Albert Sans",stack:"'Albert Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Figtree",stack:"Figtree, system-ui, sans-serif",category:"sans-serif"},{name:"Helvetica",stack:"Helvetica, Arial, sans-serif",category:"sans-serif"},{name:"Arial",stack:"Arial, Helvetica, sans-serif",category:"sans-serif"},{name:"Verdana",stack:"Verdana, Geneva, sans-serif",category:"sans-serif"},{name:"Georgia",stack:"Georgia, 'Times New Roman', serif",category:"serif"},{name:"Playfair Display",stack:"'Playfair Display', Georgia, serif",category:"serif"},{name:"Merriweather",stack:"Merriweather, Georgia, serif",category:"serif"},{name:"Lora",stack:"Lora, Georgia, serif",category:"serif"},{name:"PT Serif",stack:"'PT Serif', Georgia, serif",category:"serif"},{name:"Libre Baskerville",stack:"'Libre Baskerville', Georgia, serif",category:"serif"},{name:"Source Serif 4",stack:"'Source Serif 4', Georgia, serif",category:"serif"},{name:"Cormorant Garamond",stack:"'Cormorant Garamond', Garamond, serif",category:"serif"},{name:"Times New Roman",stack:"'Times New Roman', Times, serif",category:"serif"},{name:"Sora",stack:"Sora, system-ui, sans-serif",category:"display"},{name:"Clash Display",stack:"'Clash Display', system-ui, sans-serif",category:"display"},{name:"Cabinet Grotesk",stack:"'Cabinet Grotesk', system-ui, sans-serif",category:"display"},{name:"Satoshi",stack:"Satoshi, system-ui, sans-serif",category:"display"},{name:"General Sans",stack:"'General Sans', system-ui, sans-serif",category:"display"},{name:"JetBrains Mono",stack:"'JetBrains Mono', 'Fira Code', monospace",category:"monospace"},{name:"Fira Code",stack:"'Fira Code', 'Courier New', monospace",category:"monospace"},{name:"Source Code Pro",stack:"'Source Code Pro', monospace",category:"monospace"},{name:"Courier New",stack:"'Courier New', Courier, monospace",category:"monospace"}];function Ig(e,t){m(t,200,Eg)}var uw=/#[0-9a-fA-F]{6}\b/g,ug=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;function pw(e){let t=[],n=[],s=e.split(`
2810
+ `),o=!1,r=!1;for(let i of s){let a=i.trim();if(/^##\s+color/i.test(a)){o=!0,r=!1;continue}if(/^##\s+typography/i.test(a)){r=!0,o=!1;continue}if(/^##\s+/.test(a)&&!(/color/i.test(a)||/typography/i.test(a))){o=!1,r=!1;continue}if(o){let l=a.match(uw);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(r){let l=ug.exec(a);if(ug.lastIndex=0,l){let c=l[1].trim().replace(/['"`]/g,"").split(",")[0].trim();c&&!n.includes(c)&&n.push(c)}if(/\bheading|body|display|monospace\b/i.test(a)&&!l){let c=a.split(":").slice(1).join(":").trim();if(c){let d=c.replace(/['"`*]/g,"").split(",")[0].trim().split("(")[0].trim();d&&d.length<60&&!/^\d/.test(d)&&!n.includes(d)&&n.push(d)}}}}return{colors:t.slice(0,6),fonts:n.slice(0,4)}}function il(e,t){let{colors:n,fonts:s}=pw(t);if(n.length===0&&s.length===0)return null;e.brandAssets||(e.brandAssets={});let o=e.brandAssets.brandKit||{};if(n.length>0&&(o.colors||(o.colors={}),n[0]&&(o.colors.primary=n[0]),n[1]&&(o.colors.secondary=n[1]),n[2]&&(o.colors.accent=n[2])),s.length>0){o.fonts||(o.fonts={});let i=a=>{let l=a.toLowerCase(),c=Eg.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=i(s[0])),s[1]?o.fonts.body=i(s[1]):s[0]&&(o.fonts.body=i(s[0]))}e.brandAssets.brandKit=o;let r=Oe(e.themePath,".vibespot");return $e(r),U(Oe(r,"brand-kit.json"),JSON.stringify(o,null,2)),o}var mw=/^#[0-9a-fA-F]{6}$/;function Mg(e,t,n){let s=x();if(!s){m(n,404,{error:"No active session"});return}if(e==="GET"){m(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){G(t,o=>{try{let r=JSON.parse(o);s.brandAssets||(s.brandAssets={});let i={};if(r.colors&&typeof r.colors=="object"){let l={};for(let c of["primary","secondary","accent"])typeof r.colors[c]=="string"&&mw.test(r.colors[c])&&(l[c]=r.colors[c]);Object.keys(l).length>0&&(i.colors=l)}if(r.fonts&&typeof r.fonts=="object"){let l={};for(let c of["heading","body"])typeof r.fonts[c]=="string"&&r.fonts[c].trim()&&(l[c]=r.fonts[c].trim());Object.keys(l).length>0&&(i.fonts=l)}typeof r.logoUrl=="string"&&r.logoUrl.trim()&&(i.logoUrl=r.logoUrl.trim()),s.brandAssets.brandKit=i,s.updatedAt=Date.now();let a=Oe(s.themePath,".vibespot");$e(a),U(Oe(a,"brand-kit.json"),JSON.stringify(i,null,2)),D(),m(n,200,{ok:!0,brandKit:i})}catch(r){m(n,500,{error:N(r)})}});return}if(e==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Oe(s.themePath,".vibespot","brand-kit.json");Ur(o)&&fg(o),D(),m(n,200,{ok:!0});return}m(n,405,{error:"Method not allowed"})}function pg(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Oe(e.themePath,".vibespot");$e(o),U(Oe(o,s),n)}function mg(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function gg(e,t,n){if(t==="styleguide"){let{extractDesignContext:p}=await Promise.resolve().then(()=>(no(),to));return p(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(os(),Ga)),{loadConfig:o}=await Promise.resolve().then(()=>(te(),Dl)),r=o(),{engine:i,apiKey:a,model:l}=s(r),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Xn(),yr)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:p}=await Promise.resolve().then(()=>(Ja(),Ba));return p(d,i,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(Ir(),Er));return u(d,e.brandAssets?.themeContext,i,a,l)}function $g(e,t){let n=x();if(!n){m(t,404,{error:"No active session"});return}G(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},r=o.type||"styleguide",i=o.sourcePath;if(r==="all"){let c=["styleguide","brandvoice","themeContext"],d=await qe({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>ce(mg(g),()=>gg(n,g,i))))),u={};for(let g=0;g<c.length;g++){let f=d[g],h=f.status==="fulfilled"?f.value:null;h&&pg(n,c[g],h),u[c[g]]=h}let p=null;u.styleguide&&(p=il(n,u.styleguide)),D(),m(t,200,{ok:!0,type:"all",extracted:u,brandKit:p});return}if(r!=="styleguide"&&r!=="brandvoice"&&r!=="themeContext"){m(t,400,{error:`Invalid type: ${r}`});return}let a=await qe({name:"brand_extract",sessionId:n.themeName,metadata:{type:r},tags:["vibespot","brand-extract"]},()=>ce(mg(r),()=>gg(n,r,i)));if(!a){m(t,200,{ok:!1,type:r,error:"No content to extract from"});return}pg(n,r,a);let l=null;r==="styleguide"&&(l=il(n,a)),D(),m(t,200,{ok:!0,type:r,content:a,brandKit:l})}catch(o){m(t,500,{error:N(o)})}})()})}function Rg(e,t){let n=x();if(!n){m(t,404,{error:"No active session"});return}G(e,s=>{(async()=>{try{let{source:o,themeName:r,localPath:i}=JSON.parse(s),a;if(o==="hubspot"){if(!r){m(t,400,{error:"themeName is required for HubSpot import"});return}let u=Je();if(!u){m(t,400,{error:"No HubSpot account connected"});return}let p=r.replace(/^\/+|\/+$/g,"");if(!p){m(t,400,{error:"Invalid theme name"});return}let g=p.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:f}=await import("os"),h=Oe(f(),"vibespot-themes",".references",g);$e(h);let{fetchTheme:b}=await Promise.resolve().then(()=>($o(),rc));await b(u,p,h),a=h}else if(o==="local"){if(!i){m(t,400,{error:"localPath is required for local import"});return}if(!Ur(i)){m(t,400,{error:`Path not found: ${i}`});return}a=i}else{m(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(no(),to)),c=await qe({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>ce("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Oe(n.themePath,".vibespot");$e(d),U(Oe(d,"styleguide.md"),c),D(),m(t,200,{ok:!0,styleguide:c,source:a})}catch(o){m(t,500,{error:N(o)})}})()})}y();At();Re();me();import{join as gw}from"path";Hn();function Ng(e,t){let n=x();if(!n){m(t,404,{error:"No active session"});return}m(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function Og(e,t,n){let s=x();if(!s){m(n,404,{error:"No active session"});return}if(e==="GET"){let o=pe();m(n,200,{modules:o.map(r=>({moduleName:r.moduleName,fieldsJson:r.fieldsJson,moduleHtml:r.moduleHtml,moduleCss:r.moduleCss,moduleJs:r.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){Ze(t,n,o=>{o.deleteEntirely?Bc(o.moduleName):Jc(o.moduleName),D(),m(n,200,{ok:!0})});return}m(n,405,{error:"Method not allowed"})}function Fg(e,t){let n=x();if(!n){m(t,404,{error:"No active session"});return}G(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{m(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(),lt(),D(),Ae(),m(t,200,{ok:!0});return}let{moduleName:r,fileType:i,content:a}=o;if(!r||!i){m(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===r);if(!l){m(t,404,{error:`Module "${r}" not found`});return}switch(i){case"html":l.moduleHtml=a;break;case"css":l.moduleCss=a;break;case"js":l.moduleJs=a||void 0;break;case"fields":try{JSON.parse(a)}catch{m(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:m(t,400,{error:`Invalid fileType: ${i}`});return}n.updatedAt=Date.now(),lt(),D(),Ae(),m(t,200,{ok:!0})}catch(o){m(t,400,{error:String(o)})}})}function Dg(e,t){Ze(e,t,n=>{Array.isArray(n.order)?(Yt(n.order),D(),m(t,200,{ok:!0})):m(t,400,{error:"order must be an array"})})}async function jg(e){let t=x();if(!t){m(e,404,{error:"No active session"});return}try{Ae();let n=pr(t.themePath);if(!Dn(t.themeName)){m(e,400,{error:"Theme name contains unsupported characters and cannot be uploaded via the HubSpot CLI."});return}let s=Hr("hs",["cms","upload",t.themePath,t.themeName],"Uploading to HubSpot",{cwd:gw(t.themePath,".."),timeout:18e4});m(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){m(e,500,{error:String(n)})}}function Lg(e,t){G(e,n=>{try{let{moduleName:s,fieldPath:o,value:r}=JSON.parse(n);Hc(s,o,r),D(),m(t,200,{ok:!0})}catch(s){m(t,400,{error:String(s)})}})}function Bg(e,t){G(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){m(t,400,{error:"url is required"});return}let o=nc(s),r=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2811
+ `),i={sourceDir:o.sourceDir,componentCount:o.components.length,components:o.components.map(a=>({name:a.name,description:a.description})),hasTailwind:o.hasTailwind,cssVarCount:o.cssVarCount,fonts:o.fonts,interactions:o.interactions,conversionPrompt:`Import and convert the React landing page from ${s} to native HubSpot modules.
2812
+
2813
+ Source analysis found ${o.components.length} components:
2814
+ ${r}
2815
+
2816
+ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CSS variables
2817
+ Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
2818
+ Interactions: ${o.interactions.join(", ")}
2819
+
2820
+ Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};m(t,200,i)}catch(s){m(t,500,{error:N(s)})}})}function Jg(e,t){let n=x();if(!n){m(t,404,{error:"No active session"});return}if(!at()){m(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),r=o?Rc(n.themePath,o,50):$c(n.themePath,50);m(t,200,{available:!0,commits:r,filtered:!!o})}function Hg(e,t){G(e,n=>{try{let s=x();if(!s){m(t,404,{error:"No active session"});return}let{hash:o,templateId:r}=JSON.parse(n);if(!o||typeof o!="string"){m(t,400,{error:"Commit hash is required"});return}if(ct("assistant",`Rolled back to version ${o.slice(0,7)}.`),r){let i=s.templates.find(c=>c.id===r);if(!i){m(t,404,{error:"Template not found"});return}let a=i.moduleOrder.map(c=>`modules/${c}.module`);i.templateFile&&a.push(i.templateFile);let l=Oc(s.themePath,r,o,a);if(!l.success){m(t,500,{error:l.error||"Rollback failed"});return}gd()}else{let i=Nc(s.themePath,o);if(!i.success){m(t,500,{error:i.error||"Rollback failed"});return}md()}D(),m(t,200,{ok:!0,modules:pe().map(i=>i.moduleName)})}catch(s){m(t,500,{error:N(s)})}})}va();pl();y();Re();me();y();ae();import{readdirSync as fl,statSync as Lw}from"fs";import{join as Q,relative as Bw}from"path";var nn=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],Jw=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],Hw=["enable_domain_stylesheets","is_available_for_new_content"],Wt="marketplace.json";function ls(e){let t=Q(e,Wt);if(!w(t))return null;try{return JSON.parse(I(t))}catch{return null}}function Yr(e,t){let n=Q(e,Wt);U(n,JSON.stringify(t,null,2)+`
2821
+ `)}function ao(e){let t=[];if(!w(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),ml(e,t,null);let n=gl(Q(e,"theme.json"));if(!n)return t.push({severity:"error",rule:"theme.json.missing",file:"theme.json",message:"theme.json is missing or invalid JSON",fix:"Recreate the theme so theme.json is generated, or restore it from version control."}),ml(e,t,ls(e));Uw(e,n,t),Gw(e,n,t),Ww(e,t),Vw(e,t),zw(e,t),qw(e,t);let s=ls(e);return Yw(s,t),ml(e,t,s)}function ml(e,t,n){let s=t.filter(i=>i.severity==="error").length,o=t.filter(i=>i.severity==="warning").length,r=t.filter(i=>i.severity==="info").length;return{themePath:e,passed:s===0,errorCount:s,warningCount:o,infoCount:r,findings:t,metadata:n}}function Uw(e,t,n){let s={documentation_url:'Add a "documentation_url" entry pointing to public docs for the theme.',license:'Add a "license" entry \u2014 an SPDX identifier or URL (e.g. "MIT").',example_url:'Add an "example_url" entry pointing to a public live preview of the theme.'};for(let i of Jw)Pt(t,i)||n.push({severity:"error",rule:`theme.json.${i}.missing`,file:"theme.json",message:`theme.json is missing required field "${i}"`,fix:s[i]??`Add a "${i}" entry to theme.json.`});for(let i of Hw)(!(i in t)||typeof t[i]!="boolean")&&n.push({severity:"error",rule:`theme.json.${i}.missing`,file:"theme.json",message:`theme.json must declare boolean "${i}"`,fix:`Add "${i}": true (or false) to theme.json.`});let o=t.author;!o||typeof o!="object"?n.push({severity:"error",rule:"theme.json.author.missing",file:"theme.json",message:'theme.json is missing required "author" block',fix:'Add { "author": { "name": "...", "email": "...", "url": "..." } } to theme.json.'}):(Pt(o,"name")||n.push({severity:"error",rule:"theme.json.author.name.missing",file:"theme.json",message:"theme.json author.name is missing",fix:"Provide a publisher name in theme.json author.name."}),Pt(o,"email")||n.push({severity:"error",rule:"theme.json.author.email.missing",file:"theme.json",message:"theme.json author.email is missing",fix:"Provide a contact email in theme.json author.email."}),Pt(o,"url")||n.push({severity:"error",rule:"theme.json.author.url.missing",file:"theme.json",message:"theme.json author.url is missing",fix:"Add a public URL for the publisher (homepage or support page)."}));let r=t.preview_path;if(typeof r=="string"&&r.length>0){let i=cf(e,r);w(i)||n.push({severity:"error",rule:"theme.json.preview_path.invalid",file:"theme.json",message:`preview_path "${r}" does not point to an existing file`,fix:"Update preview_path to a real template, e.g. ./templates/home.html."})}}function Gw(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=cf(e,s);if(!w(o)){n.push({severity:"error",rule:"theme.json.screenshot.missing",file:"theme.json",message:`Screenshot not found at ${s}`,fix:"Place a 1500\xD71000 PNG at the screenshot_path declared in theme.json."});return}/\.(png|jpg|jpeg)$/i.test(s)||n.push({severity:"warning",rule:"theme.json.screenshot.format",file:s,message:"Screenshot should be a PNG or JPG",fix:"Re-export the screenshot as PNG (1500\xD71000) or JPG."})}function Ww(e,t){let n=Q(e,"modules");if(!w(n)){t.push({severity:"warning",rule:"modules.empty",message:"Theme has no modules/ directory",fix:"Generate at least one module before submitting to Marketplace."});return}let s=0,o=[];try{o=fl(n)}catch{return}for(let r of o){if(!r.endsWith(".module"))continue;s++;let i=Q(n,r);Kw(e,i,r,t)}s===0&&t.push({severity:"warning",rule:"modules.empty",message:"Theme has no .module directories",fix:"Generate at least one module before submitting to Marketplace."})}function Kw(e,t,n,s){let o=gl(Q(t,"meta.json")),r=ht(e,Q(t,"meta.json"));o?(Pt(o,"label")||s.push({severity:"error",rule:"module.meta.label.missing",file:r,message:`${n}: meta.json is missing "label"`,fix:`Add a "label" entry to the module's meta.json.`,autoFixable:!0}),o.is_available_for_new_content===!1&&s.push({severity:"info",rule:"module.meta.unavailable",file:r,message:`${n}: is_available_for_new_content=false (won\u2019t be selectable in HubSpot UI)`})):s.push({severity:"error",rule:"module.meta.missing",file:r,message:`${n}: meta.json is missing or invalid`,fix:"Recreate the module so meta.json is generated."});let i=Q(t,"fields.json"),a=ht(e,i);if(!w(i))s.push({severity:"warning",rule:"module.fields.missing",file:a,message:`${n}: fields.json is missing`,fix:"Add a fields.json (an empty array [] is acceptable for static modules)."});else{let c=gl(i);Array.isArray(c)?af(c,n,a,s):s.push({severity:"warning",rule:"module.fields.invalid",file:a,message:`${n}: fields.json is not a JSON array`})}let l=Q(t,"module.html");w(l)||s.push({severity:"error",rule:"module.html.missing",file:ht(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function af(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let r=o,i=typeof r.name=="string"?r.name:"(unnamed)";Pt(r,"label")||s.push({severity:"error",rule:"module.field.label.missing",file:n,message:`${t}.${i}: field is missing "label"`,fix:`Add a human-readable "label" to the "${i}" field in fields.json.`,autoFixable:!0}),!Pt(r,"help_text")&&r.type!=="group"&&s.push({severity:"info",rule:"module.field.help_text.missing",file:n,message:`${t}.${i}: consider adding "help_text"`,fix:`Add a short "help_text" describing what "${i}" controls.`}),Array.isArray(r.children)&&af(r.children,t,n,s)}}function Vw(e,t){let n=[],s=Q(e,"css");qr(s,".css").forEach(r=>{rf(r,n,e)});let o=Q(e,"modules");if(w(o))for(let r of lo(o)){if(!r.endsWith(".module"))continue;let i=Q(o,r);["module.css","module.html"].forEach(a=>{let l=Q(i,a);w(l)&&rf(l,n,e)})}for(let r of n)t.push({severity:"error",rule:"asset.cdn-import",file:r.file,message:`External CDN reference found: ${r.match}`,fix:"Remove external @import / <link> URLs and bundle the asset locally.",autoFixable:!0})}function rf(e,t,n){let s;try{s=I(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:ht(n,e),match:o[0]});let r=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:ht(n,e),match:r[0]});let i=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:ht(n,e),match:i[0]})}function zw(e,t){let n=[{rule:"asset.hardcoded.hubfs",re:/https?:\/\/[\w.-]*hubfs[\w.-]*\/(\d+)\//i,message:"Hardcoded portal-specific HubFS URL detected"},{rule:"asset.hardcoded.usercontent",re:/hubspotusercontent[-\w]*\.net\/(\w+\/)?(\d+)\//i,message:"Hardcoded portal-specific HubSpot user-content URL detected"},{rule:"asset.hardcoded.preview",re:/\d+\.hs-sites\.com|hubspotpagebuilder\.com\/\d+/i,message:"Hardcoded portal preview URL detected"}],s=[],o=Q(e,"css");qr(o,".css").forEach(a=>s.push(a));let r=Q(e,"js");qr(r,".js").forEach(a=>s.push(a));let i=Q(e,"modules");if(w(i))for(let a of lo(i))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=Q(i,a,l);w(c)&&s.push(c)});for(let a of s){let l;try{l=I(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:ht(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function qw(e,t){let n=Q(e,"modules");if(w(n))for(let s of lo(n)){if(!s.endsWith(".module"))continue;let o=Q(n,s,"module.html");if(!w(o))continue;let r;try{r=I(o)}catch{continue}let i=/<img\b([^>]*)>/gi,a;for(;a=i.exec(r);){let c=a[1];/\balt\s*=/.test(c)||t.push({severity:"warning",rule:"a11y.img.alt-missing",file:ht(e,o),message:`${s}: <img> without alt attribute`,fix:'Add an alt attribute (alt="" is fine for purely decorative images).'})}/<(section|article|header|footer|main|nav|aside|h[1-6])\b/i.test(r)||t.push({severity:"info",rule:"a11y.semantics.missing",file:ht(e,o),message:`${s}: module.html has no semantic landmarks (section/article/header/etc.)`,fix:"Wrap the module's main content in a <section> with a heading."})}}function Yw(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Wt,message:"marketplace.json sidecar not found",fix:"Run `vibespot marketplace edit` (CLI) or open the Marketplace panel in the editor to fill in listing details."});return}e.category?nn.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Wt,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${nn.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Wt,message:"marketplace.json has no category",fix:`Pick one of: ${nn.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Wt,message:"marketplace.json description is missing or short (<40 chars)",fix:"Provide a 1\u20132 sentence description of the theme for the Marketplace listing."}),e.supportUrl||t.push({severity:"warning",rule:"marketplace.json.supportUrl.missing",file:Wt,message:"marketplace.json has no supportUrl",fix:"Add a public support URL where buyers can reach the publisher."});let n=e.features?.length??0;n<2?t.push({severity:"warning",rule:"marketplace.json.features.too_few",file:Wt,message:`marketplace.json needs at least 2 features (has ${n})`,fix:"Add 2\u20135 short bullet points highlighting what the theme does well."}):n>5&&t.push({severity:"warning",rule:"marketplace.json.features.too_many",file:Wt,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function Xr(e){let t=[],n=[],s=Q(e,"modules");if(w(s))for(let r of lo(s)){if(!r.endsWith(".module"))continue;let i=Q(s,r),a=r.replace(/\.module$/,""),l=Q(i,"meta.json");if(w(l))try{let d=JSON.parse(I(l));Pt(d,"label")||(d.label=df(a),U(l,JSON.stringify(d,null,2)+`
2822
+ `),t.push(`${r}: filled meta.label = "${d.label}"`))}catch{n.push(`${r}: meta.json could not be parsed`)}let c=Q(i,"fields.json");if(w(c))try{let d=JSON.parse(I(c));if(Array.isArray(d)){let u=lf(d);u>0&&(U(c,JSON.stringify(d,null,2)+`
2823
+ `),t.push(`${r}: filled ${u} missing field label(s)`))}}catch{n.push(`${r}: fields.json could not be parsed`)}}let o=Xw(e);for(let r of o)t.push(`${r}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function Xw(e){let t=[],n=/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,s=/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,o=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*><\/script>/gi,r=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*\/>/gi;function i(c){let d;try{d=I(c)}catch{return}let u=d.replace(n,"");u!==d&&(U(c,u),t.push(ht(e,c)))}function a(c){let d;try{d=I(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(r,""),u=u.replace(n,""),u!==d&&(U(c,u),t.push(ht(e,c)))}qr(Q(e,"css"),".css").forEach(i);let l=Q(e,"modules");if(w(l))for(let c of lo(l)){if(!c.endsWith(".module"))continue;let d=Q(l,c),u=Q(d,"module.css"),p=Q(d,"module.html");w(u)&&i(u),w(p)&&a(p)}return t}function lf(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!Pt(s,"label")&&Pt(s,"name")&&(s.label=df(String(s.name)),t++),Array.isArray(s.children)&&(t+=lf(s.children))}return t}function gl(e){if(!w(e))return null;try{let t=JSON.parse(I(e));return t&&typeof t=="object"?t:null}catch{return null}}function Pt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function cf(e,t){let n=t.replace(/^\.?\//,"");return Q(e,n)}function ht(e,t){return Bw(e,t).split("\\").join("/")}function lo(e){try{return fl(e)}catch{return[]}}function qr(e,t){if(!w(e))return[];try{let n=[];for(let s of fl(e)){let o=Q(e,s);Lw(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function df(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function hl(e){let t=x();if(!t)return m(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Ae()}catch{}return t.themePath}function uf(e,t){let n=hl(t);if(!n)return;let s=ao(n);m(t,200,{report:s,categories:nn})}function pf(e,t){let n=hl(t);if(!n)return;let s=Xr(n),o=ao(n);m(t,200,{fix:s,report:o})}function mf(e,t,n){let s=hl(n);if(s){if(e==="GET"){m(n,200,{metadata:ls(s),categories:nn});return}if(e==="POST"){Ze(t,n,o=>{let r={category:typeof o.category=="string"?o.category:void 0,description:typeof o.description=="string"?o.description:void 0,features:Array.isArray(o.features)?o.features.filter(i=>typeof i=="string"&&i.trim().length>0):void 0,supportUrl:typeof o.supportUrl=="string"?o.supportUrl:void 0,documentationUrl:typeof o.documentationUrl=="string"?o.documentationUrl:void 0,pricingTier:o.pricingTier==="free"||o.pricingTier==="paid"?o.pricingTier:void 0,tags:Array.isArray(o.tags)?o.tags.filter(i=>typeof i=="string"):void 0};Yr(s,r),m(n,200,{ok:!0,metadata:r})});return}m(n,405,{error:"Method not allowed"})}}y();Re();me();Os();function Zw(e){let t=x();if(!t)return m(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Ae()}catch{}return t.themePath}function gf(e,t){let n=Zw(t);if(!n)return;let s=er(n);m(t,200,{report:s})}function ff(e,t){let n=x();if(!n){m(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=Qt(n.themePath),o=gn(s);if(!o){m(t,200,{applied:!1,reason:"No tokens to apply."});return}if(!n.sharedCss||n.sharedCss.trim().length===0){n.sharedCss=o,n.updatedAt=Date.now(),D(),m(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let r=tr(n.themePath,n.themeName);r?m(t,200,{applied:!0,written:r,rootBlock:o}):m(t,200,{applied:!1,reason:"Theme already has shared CSS."})}y();At();Re();me();Xt();te();re();import{existsSync as vf,mkdirSync as lk,writeFileSync as ck,rmSync as dk}from"fs";import{join as xf}from"path";y();import{readFileSync as Qw,readdirSync as ek,existsSync as tk}from"fs";import{dirname as nk,join as Zr}from"path";import{fileURLToPath as sk}from"url";var hf=nk(sk(import.meta.url)),ok=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;function rk(e){let t=e.match(ok);if(!t)return null;let[,n,s]=t,o={};for(let r of n.split(/\r?\n/)){let i=r.indexOf(":");if(i===-1)continue;let a=r.slice(0,i).trim(),l=r.slice(i+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),a&&(o[a]=l)}return{fields:o,body:s.trimStart()}}function ik(e){let t=rk(e);if(!t)return null;let{fields:n,body:s}=t,o=n.id,r=n.label,i=n.description??"";if(!o||!r)return null;let a=n.order?Number(n.order):NaN,l=n.contentType==="email"?"email":void 0;return{id:o,label:r,description:i,icon:n.icon||void 0,order:Number.isFinite(a)?a:9999,contentType:l,body:s.trimEnd()+`
2824
+ `}}var sn=null;function ak(){let e=[Zr(hf,"../../assets/plan-templates"),Zr(hf,"../assets/plan-templates"),Zr(process.cwd(),"assets/plan-templates")];for(let t of e)if(tk(t))return t;return null}function yf(){if(sn)return sn;let e=ak();if(!e)return sn=[],sn;let t=[],n=[];try{n=ek(e)}catch{return sn=[],sn}for(let s of n)if(s.endsWith(".md"))try{let o=Qw(Zr(e,s),"utf-8"),r=ik(o);r&&t.push(r)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),sn=t,sn}function bf(e){return yf().find(t=>t.id===e)??null}function Sf(){return yf().map(({id:e,label:t,description:n,icon:s,order:o,contentType:r})=>({id:e,label:t,description:n,icon:s,order:o,contentType:r}))}var uk="plan.md";function wf(e){return xf(e,".vibespot",uk)}function Qr(e){let t=x();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=xe();n&&(n.plan=e);try{let s=xf(t.themePath,".vibespot");vf(s)||lk(s,{recursive:!0}),ck(wf(t.themePath),e,"utf-8")}catch(s){A.warn("plan",`Failed to write plan.md: ${N(s)}`)}return D(),e}function yl(){let e=x();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=xe();t&&delete t.plan;try{let n=wf(e.themePath);vf(n)&&dk(n)}catch(n){A.warn("plan",`Failed to remove plan.md: ${N(n)}`)}D()}function kf(e,t){Ze(e,t,n=>{if(!x()){m(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){m(t,400,{error:"Plan content cannot be empty"});return}Qr(o),m(t,200,{ok:!0,plan:o})})}function Cf(e,t){Ze(e,t,()=>{yl(),Y({planMode:!1}),m(t,200,{ok:!0})})}function Tf(e,t){m(t,200,{templates:Sf()})}function Af(e,t){Ze(e,t,n=>{if(!x()){m(t,400,{error:"No active session"});return}let o=typeof n.templateId=="string"?n.templateId.trim():"";if(!o){m(t,400,{error:"templateId is required"});return}let r=bf(o);if(!r){m(t,404,{error:`Unknown plan template: ${o}`});return}Qr(r.body),Y({planMode:!0}),m(t,200,{ok:!0,templateId:r.id,label:r.label,plan:r.body})})}y();Re();hn();function _f(e,t){let n=pu();if(!n){m(t,200,{origin:null});return}if(n.publicOrigin){m(t,200,{origin:n.publicOrigin,token:n.token});return}let s=e.headers.host||`${n.host}:0`,o=s.startsWith("[")?s.slice(0,s.indexOf("]")+1):s.split(":")[0];m(t,200,{origin:`http://${o}:${n.port}`,token:n.token})}var pk={"/api/session":{handler:({method:e,res:t})=>Ng(e,t)},"/api/preview-origin":{handler:({req:e,res:t})=>_f(e,t)},"/api/modules":{handler:({method:e,req:t,res:n})=>Og(e,t,n)},"/api/modules/reorder":{handler:({req:e,res:t})=>Dg(e,t)},"/api/modules/code":{handler:({req:e,res:t})=>Fg(e,t)},"/api/upload":{handler:({res:e})=>jg(e)},"/api/upload-files":{methods:["POST"],handler:({req:e,res:t})=>Mu(e,t)},"/api/field":{handler:({req:e,res:t})=>Lg(e,t)},"/api/import":{handler:({req:e,res:t})=>Bg(e,t)},"/api/setup":{handler:({res:e})=>xm(e)},"/api/setup/create":{handler:({req:e,res:t})=>wm(e,t)},"/api/setup/fetch":{handler:({req:e,res:t})=>Cm(e,t)},"/api/setup/open":{handler:({req:e,res:t})=>Tm(e,t)},"/api/setup/resume":{handler:({req:e,res:t})=>Am(e,t)},"/api/setup/apikey":{handler:({req:e,res:t})=>_m(e,t)},"/api/setup/remote-themes":{methods:["GET"],handler:({res:e})=>Pm(e)},"/api/starters":{methods:["GET"],handler:({res:e})=>km(e)},"/api/whats-new":{methods:["GET"],handler:({res:e})=>eg(e)},"/api/whats-new/dismiss":{methods:["POST"],handler:({req:e,res:t})=>tg(e,t)},"/api/changelog":{methods:["GET"],handler:({res:e})=>ng(e)},"/api/settings/status":{methods:["GET"],handler:({res:e})=>Lm(e)},"/api/settings/models":{methods:["GET"],handler:({req:e,res:t})=>Bm(e,t)},"/api/settings/tools":{methods:["GET"],handler:({req:e,res:t})=>Jm(e,t)},"/api/settings/engine":{methods:["POST"],handler:({req:e,res:t})=>Hm(e,t)},"/api/settings/apikey":{methods:["POST"],handler:({req:e,res:t})=>Um(e,t)},"/api/settings/install":{methods:["POST"],handler:({req:e,res:t})=>Gm(e,t)},"/api/settings/hs-auth":{methods:["POST"],handler:({req:e,res:t})=>Wm(e,t)},"/api/settings/gh-auth":{methods:["POST"],handler:({req:e,res:t})=>Km(e,t)},"/api/settings/hs-switch":{methods:["POST"],handler:({req:e,res:t})=>Vm(e,t)},"/api/settings/gh-logout":{methods:["POST"],handler:({res:e})=>zm(e)},"/api/settings/cli-auth":{methods:["POST"],handler:({req:e,res:t})=>qm(e,t)},"/api/settings/hs-mode":{methods:["POST"],handler:({req:e,res:t})=>Ym(e,t)},"/api/settings/cli-toggle":{methods:["POST"],handler:({req:e,res:t})=>Xm(e,t)},"/api/settings/claude-oauth/save":{methods:["POST"],handler:({req:e,res:t})=>sg(e,t)},"/api/settings/claude-oauth/status":{methods:["GET"],handler:({req:e,res:t})=>og(e,t)},"/api/settings/claude-oauth/logout":{methods:["POST"],handler:({req:e,res:t})=>rg(e,t)},"/api/settings":{methods:["POST"],handler:({req:e,res:t})=>Zm(e,t)},"/api/themes":{handler:({method:e,req:t,res:n})=>ig(e,t,n)},"/api/themes/switch":{methods:["POST"],handler:({req:e,res:t})=>ag(e,t)},"/api/themes/delete-local":{methods:["POST"],handler:({req:e,res:t})=>lg(e,t)},"/api/themes/rename":{methods:["POST"],handler:({req:e,res:t})=>cg(e,t)},"/api/themes/duplicate":{methods:["POST"],handler:({req:e,res:t})=>dg(e,t)},"/api/history":{methods:["GET"],handler:({req:e,res:t})=>Jg(e,t)},"/api/rollback":{methods:["POST"],handler:({req:e,res:t})=>Hg(e,t)},"/api/dashboard":{methods:["GET"],handler:({res:e})=>hg(e)},"/api/templates":{handler:({method:e,req:t,res:n})=>Sg(e,t,n)},"/api/templates/activate":{methods:["POST"],handler:({req:e,res:t})=>vg(e,t)},"/api/templates/rename":{methods:["POST"],handler:({req:e,res:t})=>xg(e,t)},"/api/templates/clone":{methods:["POST"],handler:({req:e,res:t})=>kg(e,t)},"/api/templates/reorder":{methods:["POST"],handler:({req:e,res:t})=>wg(e,t)},"/api/module-library":{methods:["GET"],handler:({res:e})=>Cg(e)},"/api/brand-assets":{handler:({method:e,req:t,res:n})=>Ag(e,t,n)},"/api/brand-kit":{handler:({method:e,req:t,res:n})=>Mg(e,t,n)},"/api/fonts":{methods:["GET"],handler:({req:e,res:t})=>Ig(e,t)},"/api/brand-assets/extract":{methods:["POST"],handler:({req:e,res:t})=>$g(e,t)},"/api/brand-assets/import-reference":{methods:["POST"],handler:({req:e,res:t})=>Rg(e,t)},"/api/download-zip":{methods:["GET"],handler:({res:e})=>bg(e)},"/api/figma/test-token":{methods:["POST"],handler:({req:e,res:t})=>cl(e,t)},"/api/figma/extract":{methods:["POST"],handler:({req:e,res:t})=>dl(e,t)},"/api/figma/generate":{methods:["POST"],handler:({req:e,res:t})=>ul(e,t)},"/api/plan/edit":{methods:["POST"],handler:({req:e,res:t})=>kf(e,t)},"/api/plan/discard":{methods:["POST"],handler:({req:e,res:t})=>Cf(e,t)},"/api/plan/templates":{methods:["GET"],handler:({req:e,res:t})=>Tf(e,t)},"/api/plan/template":{methods:["POST"],handler:({req:e,res:t})=>Af(e,t)},"/api/marketplace/check":{methods:["GET"],handler:({req:e,res:t})=>uf(e,t)},"/api/marketplace/fix":{methods:["POST"],handler:({req:e,res:t})=>pf(e,t)},"/api/marketplace/listing":{handler:({method:e,req:t,res:n})=>mf(e,t,n)},"/api/inverse/analyze":{methods:["GET"],handler:({req:e,res:t})=>gf(e,t)},"/api/inverse/apply-tokens":{methods:["POST"],handler:({req:e,res:t})=>ff(e,t)}},mk=[{matches:e=>e.startsWith("/api/settings/job/"),method:"GET",handler:({path:e,res:t})=>Qm(e,t)},{matches:e=>/^\/api\/templates\/[^/]+\/add-module$/.test(e),method:"POST",handler:({path:e,req:t,res:n})=>Tg(e,t,n)}];function Pf(e,t,n,s){let o=n.headers.origin,r=br(o,n.headers.host);if(o&&r&&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, Authorization, X-Vibespot-Token"),e==="OPTIONS"){s.writeHead(204),s.end();return}if(o&&!r&&e!=="GET"&&e!=="HEAD"){m(s,403,{error:"Origin not allowed"});return}let i={method:e,path:t,req:n,res:s},a=pk[t];if(a){if(a.methods&&!a.methods.includes(e)){m(s,405,{error:"Method not allowed"});return}a.handler(i);return}for(let l of mk)if(l.method===e&&l.matches(t)){l.handler(i);return}m(s,404,{error:"Not found"})}y();me();Hn();os();Da();import{existsSync as If}from"fs";import{join as co}from"path";import{WebSocket as gk}from"ws";y();var bl=/```vibespot-plan\s*\n([\s\S]*?)```/g,Sl=/```vibespot-choices\s*\n([\s\S]*?)```/g;function Ef(e){let t,n,s;for(bl.lastIndex=0;(s=bl.exec(e))!==null;)t=s[1].trim();let o;for(Sl.lastIndex=0;(o=Sl.exec(e))!==null;)try{let i=JSON.parse(o[1].trim());i&&typeof i.question=="string"&&Array.isArray(i.options)&&i.options.every(a=>typeof a=="string")&&i.options.length>0&&(n={question:i.question,options:i.options})}catch{}return{cleanedContent:e.replace(bl,"").replace(Sl,"").replace(/\n{3,}/g,`
2825
+
2826
+ `).trim(),plan:t,choices:n}}te();At();Ue();hn();var ti=null,si=[];function X(e){ti&&ti.readyState===gk.OPEN&&ti.send(JSON.stringify(e))}function ei(e){si.push(e),X(e)}function Fe(){si=[]}function ni(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;ei(o)}else ei(n);if(n.type==="agent_step")e.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=e[e.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?Ge({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(Ge({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Yt(n.moduleOrder),ei({type:"modules_updated",modules:pe().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(Ge({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),ei({type:"modules_updated",modules:pe().map(s=>s.moduleName)}),t.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&t.push({name:n.module,status:"failed"})}}function uo(e){let t=e.cost;if(!t||t.calls===0)return;let n=x();X({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}function Nf(e,t){xn(e,{steps:t.steps,modules:t.modules,stats:e.stats,cost:e.cost}),uo(e);let n=x();if(n){Ae();let s=xe(),o=null;if(s){let r=s.moduleOrder.map(i=>`modules/${i}.module`);s.templateFile&&r.push(s.templateFile),s.sharedCss&&r.push(`css/${n.themeName}-theme.css`),s.sharedJs&&r.push(`js/${n.themeName}-animations.js`),o=ji(n.themePath,s.id,t.commitLabel,r)}else o=pn(n.themePath,t.commitLabel);o&&X({type:"version_created",hash:o})}X({type:"generation_complete"});{let s=x();X({type:"modules_updated",modules:pe().map(o=>o.moduleName),templateId:s?.activeTemplateId||null,templates:(s?.templates||[]).map(o=>({id:o.id,label:o.label,pageType:o.pageType,moduleCount:o.modules.length}))})}Fe()}async function Mf(e,t){ct("user",e),D();try{X({type:"stream_status",content:"Planning..."});let n="",s=await el(e,r=>{n+=r,X({type:"stream",content:r})},t),o=Ef(s||n);if(o.plan){Qr(o.plan),X({type:"plan_updated",plan:o.plan});let r=x();r&&(r.pendingCheckpoint={kind:"plan",resumeToken:"plan",preview:{kind:"plan",headline:"Plan ready for review",data:{plan:o.plan}},createdAt:new Date().toISOString()},D())}o.choices&&X({type:"plan_choices",question:o.choices.question,options:o.choices.options}),ct("assistant",o.cleanedContent),D(),X({type:"plan_complete",cleanedContent:o.cleanedContent}),X({type:"generation_complete"})}catch(n){X({type:"error",message:N(n)})}}async function $f(){let e=x();if(!e){X({type:"error",message:"No active session"});return}let t=e.brandAssets?.plan;if(!t||!t.trim()){X({type:"error",message:"No plan to approve. Send a chat message first."});return}Y({planMode:!1}),e.pendingCheckpoint?.kind==="plan"&&(e.pendingCheckpoint=void 0);let n="Implement the approved plan.";ct("user",n),D();try{Fe();let s=[],o=[],r=await Fr(n,ni(s,o));if(r.canceled){Fe();return}Nf(r,{steps:s,modules:o,commitLabel:"Approved plan: implementation"})}catch(s){Fe(),X({type:"error",message:N(s)})}}function Rf(){let e=x();e?.pendingCheckpoint?.kind==="plan"&&(e.pendingCheckpoint=void 0),yl(),Y({planMode:!1}),D(),X({type:"plan_discarded"})}function Of(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 r=Array.isArray(s.fileIds)?s.fileIds:void 0;Gt()&&Ya()&&X({type:"generation_superseded"});{let a=x();a?.pendingCheckpoint&&(Sn(a.pendingCheckpoint.resumeToken),a.pendingCheckpoint=void 0,D())}if(tl()){await Mf(o,r);break}ct("user",o),D();let i=nl();i.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(i.useAgentic){Fe();let l=[],c=[],d=!s.oneShot,u=await Fr(o,ni(l,c),r,d);if(u.canceled){Fe();break}if(u.pendingCheckpoint){let p=x();p&&(p.pendingCheckpoint=u.pendingCheckpoint,D()),uo(u),Fe();break}xn(u,{steps:l,modules:c,stats:u.stats,cost:u.cost}),uo(u)}else za(l=>{X({type:"parse_warning",message:l})}),await oo(o,l=>{X({type:"stream",content:l})},l=>{X({type:"stream_status",content:l})},r);let a=x();if(a){Ae();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/${a.themeName}-theme.css`),l.sharedJs&&d.push(`js/${a.themeName}-animations.js`),c=ji(a.themePath,l.id,o,d)}else c=pn(a.themePath,o);c&&X({type:"version_created",hash:c})}X({type:"generation_complete"});{let l=x();X({type:"modules_updated",modules:pe().map(c=>c.moduleName),templateId:l?.activeTemplateId||null,templates:(l?.templates||[]).map(c=>({id:c.id,label:c.label,pageType:c.pageType,moduleCount:c.modules.length}))})}Fe();{let l=x();l&&i.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&X({type:"suggest_brand_extraction"})}}catch(a){Fe(),X({type:"error",message:N(a)})}break}case"figma_import":{let o=String(s.extractionId||""),r=String(s.themeName||"");if(!o||!r){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:i}=await Promise.resolve().then(()=>(pl(),of)),a=i(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=x();if(!l||l.themeName!==r){let{join:p}=await import("path"),{homedir:g}=await import("os"),{existsSync:f}=await import("fs"),{createThemeScaffold:h}=await Promise.resolve().then(()=>(xs(),sc)),b=p(g(),"vibespot-themes"),S=p(b,r);if(!f(b)){let{mkdirSync:v}=await import("fs");v(b,{recursive:!0})}f(S)||h(S,r),Gn(S,r),D()}X({type:"figma_import_started",fileName:a.fileName}),Fe();let c=[],d=[],u=await ro(a,r,ni(c,d));xn(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),uo(u),Ae(),pn(x().themePath,`Figma import: ${a.fileName}`),X({type:"generation_complete"});{let p=x();X({type:"modules_updated",modules:pe().map(g=>g.moduleName),templateId:p?.activeTemplateId||null,templates:(p?.templates||[]).map(g=>({id:g.id,label:g.label,pageType:g.pageType,moduleCount:g.modules.length}))})}Fe()}catch(l){Fe(),X({type:"error",message:N(l)})}break}case"extract_brand_assets":{let o=x();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let r=$(),{engine:i,apiKey:a,model:l}=vn(r),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Xn(),yr)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(Ir(),Er)),p=await qe({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>ce("extract-theme-context",()=>u(d,o.brandAssets?.themeContext,i,a,l))),{mkdirSync:g,writeFileSync:f}=await import("fs");if(p){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=p,o.updatedAt=Date.now();let h=co(o.themePath,".vibespot");If(h)||g(h,{recursive:!0}),f(co(h,"theme-context.md"),p),D(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:h}=await Promise.resolve().then(()=>(no(),to)),b=await qe({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>ce("extract-styleguide",()=>h(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=co(o.themePath,".vibespot");If(S)||g(S,{recursive:!0}),f(co(S,"styleguide.md"),b),D(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(r){e.send(JSON.stringify({type:"brand_extraction_error",message:N(r)}))}})();break}case"start_upload":{let o=x();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Ae();let r=pr(o.themePath);if(r.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:r})),($().hubspotUploadMode||"api")==="api"){let l=Je();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 mr(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2827
+ `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
2828
+ `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
2829
+ `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Vt();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:tn()}))}else{let d=dr(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2830
+ `),errors:d}))}}else{if(!Dn(o.themeName)){e.send(JSON.stringify({type:"upload_failed",output:"Theme name contains unsupported characters and cannot be uploaded via the HubSpot CLI.",errors:[{file:"",message:"Unsafe theme name",fixable:!1}]}));break}let l=Hr("hs",["cms","upload",o.themePath,o.themeName],"Uploading to HubSpot",{cwd:co(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}))};Im(l,c);let d=setInterval(()=>{let u=Jr(l);if(!(!u||u.status==="running"))if(clearInterval(d),Mm(l,c),u.status==="completed"){let p=vt(),g=p.portalId?hs(p.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:p.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:tn()}))}else{let p=ur(u.output);e.send(JSON.stringify({type:"upload_failed",output:u.output,errors:p,exitCode:u.exitCode}))}},500)}}catch(r){e.send(JSON.stringify({type:"error",message:N(r)}))}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 r=`The HubSpot upload ("hs cms upload") failed. Below is the upload log output containing the errors.
2831
+
2832
+ IMPORTANT: Be verbose in your response. For each error:
2833
+ 1. State exactly which file has the problem and what the error is
2834
+ 2. Explain WHY this error occurs (e.g. "HubSpot doesn't support textarea field type" or "field name 'name' is reserved in HubSpot modules")
2835
+ 3. Describe the specific fix you're applying (e.g. "Changing field type from textarea to text" or "Renaming field from 'name' to 'item_name'")
2836
+ 4. Apply the fix to the module files
2837
+
2838
+ CRITICAL: After fixing the reported errors, scan ALL other module files in the theme for the same issues. For example, if you fix "name" \u2192 "item_name" in one module, check every other module's fields.json for the same problem. Fix all occurrences, not just the ones in the error log.
2839
+
2840
+ After fixing all errors, summarize the changes you made.
2841
+
2842
+ Upload log:
2843
+ ${o}`;ct("user",r),D(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await oo(r,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let i=x();if(i){Ae();let a=pn(i.themePath,"AI fix: upload errors");a&&e.send(JSON.stringify({type:"version_created",hash:a}))}e.send(JSON.stringify({type:"upload_fix_complete"}));{let a=x();e.send(JSON.stringify({type:"modules_updated",modules:pe().map(l=>l.moduleName),templateId:a?.activeTemplateId||null,templates:(a?.templates||[]).map(l=>({id:l.id,label:l.label,pageType:l.pageType,moduleCount:l.modules.length}))}))}}catch(i){e.send(JSON.stringify({type:"upload_failed",output:N(i),errors:[{file:"AI fix",message:N(i),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{await $f();break}case"plan_discard":{Rf();break}case"checkpoint_resolve":{let o=x();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let r=o.pendingCheckpoint;if(!r){e.send(JSON.stringify({type:"error",message:"No checkpoint is awaiting resolution."}));break}let i=String(s.action||"");if(!["approve","steer","skip","cancel"].includes(i)){e.send(JSON.stringify({type:"error",message:`Invalid checkpoint action: ${i}`}));break}let a=Array.isArray(s.outline)?s.outline.filter(d=>!!d&&typeof d.name=="string").map(d=>({name:String(d.name),description:typeof d.description=="string"?d.description:void 0,sourceIndex:Number.isInteger(d.sourceIndex)?d.sourceIndex:void 0})):void 0,l={kind:r.kind,action:i,note:typeof s.note=="string"?s.note:void 0,outline:a,...r.kind==="brand_intake"&&s.brandIntake&&typeof s.brandIntake=="object"?{brandIntake:s.brandIntake}:{}};if(r.kind==="plan"){o.pendingCheckpoint=void 0,D(),i==="cancel"?Rf():i==="steer"?await Mf(l.note?.trim()||"Refine the plan further."):await $f();break}let c=r.resumeToken;o.pendingCheckpoint=void 0,D();try{Fe();let d=[],u=[],p=await Qa(c,l,ni(d,u),r.resumeState);if(p.canceled){X({type:"checkpoint_cancelled"}),X({type:"generation_complete"}),Fe();break}if(p.pendingCheckpoint){let g=x();g&&(g.pendingCheckpoint=p.pendingCheckpoint,D()),uo(p),Fe();break}Nf(p,{steps:d,modules:u,commitLabel:"Checkpoint approved: implementation"})}catch(d){Fe(),X({type:"error",message:N(d)})}break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),ti=e;let t=x();if(t){let n=$(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Gt(),r=xe();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:pe().map(i=>i.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:at(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",updatedAt:t.updatedAt,templateId:r?.id||null,pageType:r?.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||"",isGenerating:o,pendingCheckpoint:t.pendingCheckpoint?{...t.pendingCheckpoint,resumeState:void 0}:null,costTotal:t.costTotal||null})),o&&si.length>0)for(let i of si)e.send(JSON.stringify(i))}else e.send(JSON.stringify({type:"needs_setup"}))}hn();var jf={".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"},Ke=ma();function ri(e){let{port:t,uiDir:n}=e;uu(e.contentMode||"page"),Ke=ma(e.host);let s=bu(Ke);if(s.severity==="refuse")throw new Error(s.message);s.severity==="warn"&&console.warn(s.message);let o=fk((a,l)=>yk(a,l,n)),r=new hk({server:o,verifyClient:a=>br(a.origin,a.req.headers.host)?ga(a.req,Ke).ok:!1});r.on("connection",a=>Of(a));let i=async a=>{let l=null;if(e.enablePreviewOrigin!==!1){let c=ha(process.env.VIBESPOT_PREVIEW_PUBLIC_ORIGIN,"VIBESPOT_PREVIEW_PUBLIC_ORIGIN"),d=ha(process.env.VIBESPOT_PUBLIC_ORIGIN,"VIBESPOT_PUBLIC_ORIGIN"),u=Ke.host==="127.0.0.1"||Ke.host==="localhost"||Ke.host==="::1",p=u?[`http://127.0.0.1:${a}`,`http://localhost:${a}`,...d?[d]:[]]:d?[d]:["*"];c&&!d&&!u&&console.warn("VIBESPOT_PREVIEW_PUBLIC_ORIGIN is set without VIBESPOT_PUBLIC_ORIGIN \u2014 the preview's frame-ancestors falls back to *; set VIBESPOT_PUBLIC_ORIGIN to pin embedding to your app origin."),l=await Tu({port:a+2,host:Ke.host,frameAncestors:p,uiDir:n,publicOrigin:c})}return mu(l),{port:a,host:Ke.host,authToken:Ke.authToken,previewOrigin:l,close:()=>{o.close(),r.close(),l?.close(),gu(l)}}};return new Promise((a,l)=>{o.on("error",c=>{c.code==="EADDRINUSE"?o.listen(t+1,Ke.host,()=>{i(t+1).then(a,l)}):l(c)}),o.listen(t,Ke.host,()=>{i(t).then(a,l)})})}function yk(e,t,n){let s=new URL(e.url||"/",`http://${e.headers.host}`),o=e.method||"GET";if(t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("X-XSS-Protection","1; mode=block"),t.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname==="/healthz"){t.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify({status:"ok"}));return}if(o!=="OPTIONS"){let r=ga(e,Ke);if(!r.ok){s.pathname.startsWith("/api/")?m(t,401,{error:"Authentication required"}):(t.writeHead(401,{"Content-Type":"text/html; charset=utf-8"}),t.end('<!doctype html><title>vibeSpot</title><body style="font-family:system-ui;padding:2rem"><h1>Authentication required</h1><p>Open vibeSpot using the exact URL printed in the terminal where it was started (it includes a <code>?token=</code> secret).</p></body>'));return}if(r.viaQueryToken&&o==="GET"&&!s.pathname.startsWith("/api/")&&Ke.authToken){s.searchParams.delete("token"),t.writeHead(302,{"Set-Cookie":`${pa}=${Ke.authToken}; HttpOnly; SameSite=Strict; Path=/`,Location:s.pathname+s.search}),t.end();return}}if(s.pathname.startsWith("/api/")){Pf(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let r=Us();t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r);return}if(s.pathname==="/module-preview"){let r=s.searchParams.get("module")||"",i=ua(r);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(i||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){bk(s.pathname.slice(14),t);return}if(s.pathname==="/docs"){t.writeHead(301,{Location:"/docs/"}),t.end();return}if(s.pathname.startsWith("/docs/")){let r=s.pathname.slice(5)||"/index.html";Ff(r,oi(n,"docs"),e,t);return}Ff(s.pathname,n,e,t)}function bk(e,t){let n=x();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=oi(n.themePath,"assets",e);if(!xl(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=Df(s),r=jf[o]||"application/octet-stream",i=vl(s);t.writeHead(200,{"Content-Type":r,"Cache-Control":"no-cache"}),t.end(i)}function Ff(e,t,n,s){let r=oi(t,e==="/"?"/index.html":e);if(!xl(r)){let c=oi(t,"index.html");if(xl(c)){let d=vl(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 i=Df(r),a=jf[i]||"application/octet-stream",l=i===".html";try{let c=vl(r);s.writeHead(200,{"Content-Type":a,"Cache-Control":"no-store"}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}me();var Lf=Sk(xk(import.meta.url)),wk=4200;async function Bf(){let e=ai.hex("#e8613a"),t=ai.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
2844
+ `));let n=kk();n||(console.error(ai.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||wk;try{let{port:o,host:r,authToken:i,close:a}=await ri({port:s,uiDir:n}),c=`http://${r==="0.0.0.0"||r==="::"?"localhost":r}:${o}${i?`/?token=${i}`:""}`;if(console.log(e(` v ${c}`)),i&&console.log(t(" Access requires this exact URL \u2014 the token is your auth secret.")),console.log(t(` Press Ctrl+C to stop
2845
+ `)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?wl("open",[c],{stdio:"ignore"}):process.platform==="win32"?wl("cmd",["/c","start","",c],{stdio:"ignore"}):wl("xdg-open",[c],{stdio:"ignore"})}catch{}await new Promise(d=>{process.on("SIGINT",()=>{console.log(t(`
2846
+ Saving session...`)),D(),a(),console.log(t(` Goodbye!
2847
+ `)),d(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(ai.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function kk(){let e=[ii(Lf,"../../ui"),ii(Lf,"../ui"),ii(process.cwd(),"ui")];for(let t of e)if(vk(ii(t,"index.html")))return t;return null}y();import{resolve as Jf}from"path";import{existsSync as kl}from"fs";te();async function Hf(e={}){let t=await Gf(e.path);if(e.fix){let o=Xr(t);if(o.applied.length>0){K(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let r of o.applied)B(` ${r}`)}else B(E.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let r of o.skipped)se(r)}let n=ao(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
2848
+ `),n.passed||process.exit(1);return}Pe(),await fe("Marketplace check");let s=`${n.errorCount} error${Tl(n.errorCount)}, ${n.warningCount} warning${Tl(n.warningCount)}, ${n.infoCount} note${Tl(n.infoCount)}`;n.passed?K(`Theme passes Marketplace checks (${s}).`):Z(`Theme is not yet ready: ${s}.`),Cl("Errors",n.findings.filter(o=>o.severity==="error")),Cl("Warnings",n.findings.filter(o=>o.severity==="warning")),Cl("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(B(""),B(`Tip: run ${E.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await he("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function Uf(e={}){let t=await Gf(e.path);Pe(),await fe("Marketplace listing details");let n=ls(t)??{},s=await Nt({message:"Category",options:nn.map(u=>({value:u,label:u}))}),o=await ve({message:"Description (1\u20132 sentences shown on the listing)",placeholder:"A clean, fast SaaS landing page theme...",defaultValue:n.description??"",validate:u=>u.trim().length<40?"Aim for at least 40 characters.":void 0}),i=(await ve({message:"Key features (comma-separated, 2\u20135 items)",placeholder:"Hero, Pricing, Testimonials, Footer",defaultValue:(n.features??[]).join(", "),validate:u=>{let p=u.split(",").map(g=>g.trim()).filter(Boolean).length;if(p<2)return"Provide at least 2 features.";if(p>5)return"Provide at most 5 features."}})).split(",").map(u=>u.trim()).filter(Boolean),a=await ve({message:"Public support URL",placeholder:"https://example.com/support",defaultValue:n.supportUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),l=await ve({message:"Documentation URL (optional)",placeholder:"https://example.com/docs",defaultValue:n.documentationUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),c=await Nt({message:"Pricing tier",options:[{value:"free",label:"Free"},{value:"paid",label:"Paid"}]}),d={category:s,description:o.trim(),features:i,supportUrl:a.trim()||void 0,documentationUrl:l.trim()||void 0,pricingTier:c,tags:n.tags};Yr(t,d),K("Saved marketplace.json"),await he(`Run ${E.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function Gf(e){if(e){let o=Jf(e);if(!kl(o))throw new Error(`Theme not found: ${o}`);return o}let t=$();if(t.lastThemePath&&kl(t.lastThemePath))return t.lastThemePath;Pe();let n=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Jf(n);if(!kl(s))throw new Error(`Theme not found: ${s}`);return s}function Cl(e,t){if(t.length!==0){B(""),B(E.heading(e));for(let n of t){let s=n.file?E.muted(`[${n.file}] `):"",o=n.severity==="error"?E.error("\u2717"):n.severity==="warning"?E.warn("!"):E.muted("\xB7");B(` ${o} ${s}${n.message}`),n.fix&&B(` ${E.muted("\u2192 "+n.fix)}`)}}}function Tl(e){return e===1?"":"s"}y();import{resolve as Wf}from"path";import{existsSync as Al}from"fs";import{basename as Ck}from"path";te();Os();async function Kf(e={}){let t=await Tk(e.path),n=Ck(t);if(e.applyTokens){let r=tr(t,n);r?K(`Wrote design tokens to ${r}`):B(E.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let r=Gi(t);e.json||K(`Wrote imported theme snapshot to ${r}`)}let s=er(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
2849
+ `),process.exit(0)),Pe(),await fe("Inverse pipeline analyzer");let o=s.summary;if(B(`${E.heading("Summary")} ${o.moduleCount} module(s), ${o.templateCount} template(s), ${o.orphanCount} orphan, ${o.paletteSize} colour(s), ${o.cssVarCount} CSS var(s), ${o.customMacroCount} macro(s)`),s.designTokens.palette.length>0){B(""),B(E.heading("Palette (top by frequency)"));for(let r of s.designTokens.palette.slice(0,6)){let i=r.varName?E.muted(` (${r.varName})`):"";B(` ${r.value} ${E.muted(`\xD7${r.count}`)}${i}`)}}if(s.designTokens.fontFamilies.length>0){B(""),B(E.heading("Typography"));for(let r of s.designTokens.fontFamilies.slice(0,4))B(` ${r}`)}if(s.graph.templates.length>0){B(""),B(E.heading("Template \u2192 modules"));for(let r of s.graph.templates)B(` ${r.id}: ${r.modules.length===0?E.muted("(empty)"):r.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){B(""),B(E.heading("Orphan modules"));for(let r of s.graph.orphanModules)B(` ${r}`)}if(s.roundTripDiff.hasSnapshot){B(""),B(E.heading("Round-trip diff"));let r=s.roundTripDiff;if(r.filesChanged===0)B(` ${E.muted("No changes from imported snapshot.")}`);else{B(` ${r.filesChanged} changed file(s): ${r.added} added, ${r.modified} modified, ${r.deleted} deleted`);for(let i of r.files.slice(0,12))B(` ${i.status.padEnd(8)} ${i.file}`);r.files.length>12&&B(` ${E.muted(`...and ${r.files.length-12} more`)}`)}}_l("Errors",s.findings.filter(r=>r.severity==="error")),_l("Warnings",s.findings.filter(r=>r.severity==="warning")),_l("Notes",s.findings.filter(r=>r.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(B(""),B(`Tip: run ${E.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await he("Analysis complete."),process.exit(0)}async function Tk(e){if(e){let o=Wf(e);if(!Al(o))throw new Error(`Theme not found: ${o}`);return o}let t=$();if(t.lastThemePath&&Al(t.lastThemePath))return t.lastThemePath;Pe();let n=await ve({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Wf(n);if(!Al(s))throw new Error(`Theme not found: ${s}`);return s}function _l(e,t){if(t.length!==0){B(""),B(E.heading(e));for(let n of t){let s=n.file?E.muted(`[${n.file}] `):"",o=n.severity==="error"?E.error("\u2717"):n.severity==="warning"?E.warn("!"):E.muted("\xB7");B(` ${o} ${s}${n.message}`),n.fix&&B(` ${E.muted("\u2192 "+n.fix)}`)}}}y();import{dirname as Ak,join as li}from"path";import{existsSync as _k}from"fs";import{fileURLToPath as Pk}from"url";import{execFileSync as Pl}from"child_process";import ci from"chalk";me();var Vf=Ak(Pk(import.meta.url)),Ek=4200;async function zf(){let e=ci.hex("#e8613a"),t=ci.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
2850
+ `));let n=Ik();n||(console.error(ci.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,host:o,authToken:r,close:i}=await ri({port:Ek,uiDir:n,contentMode:"email"}),l=`http://${o==="0.0.0.0"||o==="::"?"localhost":o}:${s}${r?`/?token=${r}`:""}`;console.log(e(` v ${l}`)),r&&console.log(t(" Access requires this exact URL \u2014 the token is your auth secret.")),console.log(t(` Email template mode \u2014 Press Ctrl+C to stop
2851
+ `));try{process.platform==="darwin"?Pl("open",[l],{stdio:"ignore"}):process.platform==="win32"?Pl("cmd",["/c","start","",l],{stdio:"ignore"}):Pl("xdg-open",[l],{stdio:"ignore"})}catch{}await new Promise(c=>{process.on("SIGINT",()=>{console.log(t(`
2852
+ Saving session...`)),D(),i(),console.log(t(` Goodbye!
2853
+ `)),c(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(ci.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Ik(){let e=[li(Vf,"../../ui"),li(Vf,"../ui"),li(process.cwd(),"ui")];for(let t of e)if(_k(li(t,"index.html")))return t;return null}ae();function qf(){let e=new Mk;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Mt()).action(Bf),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Gd),e.command("init").description("Check and install required tools").action(Wd),e.command("convert").description("Convert a React project to HubSpot modules").action(Kd),e.command("upload").description("Upload theme to HubSpot").action(Vd),e.command("doctor").description("Diagnose environment issues").action(zd);let t=e.command("marketplace").description("Prepare a theme for HubSpot Marketplace submission");return t.command("check").description("Audit the theme against Marketplace requirements").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--fix","Apply auto-fixable findings before checking").action(n=>Hf(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>Uf(n)),e.command("email").description("Launch email template generation mode").action(zf),e.command("inverse").description("Analyze an imported HubSpot theme: design tokens, module graph, field flags, round-trip risks").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--apply-tokens","Seed css/<theme>-theme.css with the inferred :root block when missing").option("--snapshot","Capture the current theme as the imported round-trip baseline before analysis").action(n=>Kf(n)),e}var $k=qf();$k.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
2956
2854
  //# sourceMappingURL=index.js.map