vibespot 1.7.7 → 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 (42) hide show
  1. package/README.md +11 -0
  2. package/assets/whats-new.json +27 -0
  3. package/dist/index.js +482 -648
  4. package/dist/index.js.map +1 -1
  5. package/package.json +7 -4
  6. package/ui/chat.js +21 -8
  7. package/ui/dashboard.js +53 -12
  8. package/ui/docs/index.html +10 -1
  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 +6 -3
  14. package/ui/inline-edit.js +116 -570
  15. package/ui/plan.js +19 -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 +177 -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-checkpoints.png +0 -0
  27. package/assets/readme/02-plan-mode.png +0 -0
  28. package/assets/readme/03-figma-import.png +0 -0
  29. package/assets/readme/04-multi-page-sites.png +0 -0
  30. package/assets/readme/05-inline-wysiwyg.png +0 -0
  31. package/assets/readme/06-hubspot-upload.png +0 -0
  32. package/ui/docs/screenshots/brand-kit-preview.png +0 -0
  33. package/ui/docs/screenshots/checkpoint-card.png +0 -0
  34. package/ui/docs/screenshots/content-type-dropdown.png +0 -0
  35. package/ui/docs/screenshots/editor-full-layout.png +0 -0
  36. package/ui/docs/screenshots/inline-wysiwyg-editing.png +0 -0
  37. package/ui/docs/screenshots/module-overview-slideout.png +0 -0
  38. package/ui/docs/screenshots/multi-page-tree.png +0 -0
  39. package/ui/docs/screenshots/onboarding-walkthrough.png +0 -0
  40. package/ui/docs/screenshots/split-pane-view.png +0 -0
  41. package/ui/docs/screenshots/visual-controls-toolbar.png +0 -0
  42. package/ui/docs/screenshots/workspace-tabs.png +0 -0
package/dist/index.js CHANGED
@@ -1,12 +1,5 @@
1
- var ef=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var We=(e,t)=>{for(var n in t)ef(e,n,{get:t[n],enumerable:!0})};import Px from"path";import{fileURLToPath as Mx}from"url";var y=R(()=>{"use strict"});import xn from"chalk";function Et(e){return ml?xn:xn.hex(e)}var yt,ml,E,bt=R(()=>{"use strict";y();yt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ml=!!process.env.NO_COLOR;E={accent:Et(yt.accent),accentBright:Et(yt.accentBright),success:Et(yt.success),info:Et(yt.info),warn:Et(yt.warn),error:Et(yt.error),muted:Et(yt.muted),vibes:Et(yt.vibes),heading:ml?xn.bold:xn.bold.hex(yt.accent),command:Et(yt.accentBright),dim:xn.dim,bold:xn.bold}});import{readFileSync as zi,writeFileSync as tf,mkdirSync as pl,existsSync as so}from"fs";import{dirname as gl,join as Mt}from"path";import{fileURLToPath as nf}from"url";function M(e){return zi(e,"utf-8")}function H(e,t){pl(gl(e),{recursive:!0}),tf(e,t,"utf-8")}function v(e){return so(e)}function Ie(e){pl(e,{recursive:!0})}function Cn(e){let t=[Mt(kn,"../../assets",e),Mt(kn,"../assets",e),Mt(process.cwd(),"assets",e)];for(let n of t)if(so(n))return n;throw new Error(`Asset not found: ${e}`)}function Tn(){if(wn)return wn;let e=[Mt(kn,"../../package.json"),Mt(kn,"../package.json"),Mt(process.cwd(),"package.json")];for(let t of e)if(so(t))try{let n=JSON.parse(zi(t,"utf-8"));if(n.name==="vibespot"&&n.version)return wn=n.version,wn}catch{}return wn="dev",wn}function fl(){if(no)return no;let e=[Mt(kn,"../../CHANGELOG.md"),Mt(kn,"../CHANGELOG.md"),Mt(process.cwd(),"CHANGELOG.md")];for(let t of e)if(so(t))try{return no=zi(t,"utf-8"),no}catch{}return""}var kn,wn,no,ae=R(()=>{"use strict";y();kn=gl(nf(import.meta.url));wn="";no=""});import{execSync as hl,execFileSync as sf}from"child_process";function le(e,t={}){try{return{stdout:hl(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 te(e,t={}){try{return{stdout:sf("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 yl(e,t={}){try{return hl(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var tn=R(()=>{"use strict";y()});var vl={};We(vl,{addHubSpotAccount:()=>ns,getActiveHubSpotAccount:()=>Gt,getApiKeyForEngine:()=>De,getConfigDir:()=>af,getHubSpotPak:()=>Be,isCliToolEnabled:()=>it,loadConfig:()=>N,maskApiKey:()=>io,removeHubSpotAccount:()=>Yi,saveConfig:()=>q,setActiveHubSpotAccount:()=>qi,setCliToolEnabled:()=>Xi});import{join as bl}from"path";import{homedir as of}from"os";import{chmodSync as rf}from"fs";function N(){let e={};if(v(oo))try{e=JSON.parse(M(oo)),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||N();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;case"langdock-api":return n.langdockApiKey||process.env.LANGDOCK_API_KEY;default:return}}function io(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function q(e){let n={...N(),...e};if(H(oo,JSON.stringify(n,null,2)),process.platform!=="win32")try{rf(oo,384)}catch{}}function af(){return Sl}function Gt(){let e=N();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function ns(e,t,n,s){let i=N().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),q({hubspotAccounts:i,activeHubSpotAccount:t})}function Yi(e){let t=N(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),q(s)}function qi(e){q({activeHubSpotAccount:e})}function Be(){return Gt()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function it(e){return N().enabledCLITools?.includes(e)??!1}function Xi(e,t){let n=N(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),q({enabledCLITools:[...s]})}var Sl,oo,oe=R(()=>{"use strict";y();ae();Sl=bl(of(),".vibespot"),oo=bl(Sl,"config.json")});var er={};We(er,{OAUTH_EXTRA_HEADERS:()=>ss,OAUTH_SYSTEM_PREFIX:()=>_n,clearOAuthTokens:()=>lo,getOAuthTokenInfo:()=>nn,getValidAccessToken:()=>Qi,hasValidOAuthToken:()=>tt,saveInitialToken:()=>Zi});import{join as lf}from"path";import{homedir as cf}from"os";import{chmodSync as df,unlinkSync as uf}from"fs";function ao(){if(!v(An))return null;try{return JSON.parse(M(An))}catch{return null}}function xl(e){if(H(An,JSON.stringify(e,null,2)),process.platform!=="win32")try{df(An,384)}catch{}}async function ff(e){let t=await fetch(pf,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:mf})});if(!t.ok)throw lo(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();xl({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Zi(e,t=""){xl({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function tt(){let e=ao();return e?e.expires_at>Date.now():!1}async function Qi(){let e=ao();if(!e)return null;if(e.expires_at-Date.now()>gf)return e.access_token;if(e.refresh_token){ro||(ro=ff(e.refresh_token).finally(()=>{ro=null}));try{await ro}catch{return null}return ao()?.access_token??null}return e.access_token}function nn(){let e=ao();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function lo(){if(v(An))try{uf(An)}catch{}}var mf,pf,An,gf,ss,_n,ro,It=R(()=>{"use strict";y();ae();mf="9d1c250a-e61b-44d9-88ed-5944d1962f5e",pf="https://console.anthropic.com/v1/oauth/token",An=lf(cf(),".vibespot","claude-oauth.json"),gf=300*1e3,ss={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},_n="You are Claude Code, Anthropic's official CLI for Claude.";ro=null});import{join as co}from"path";import{homedir as uo}from"os";import{readFileSync as wl,existsSync as mo,readdirSync as hf}from"fs";function os(){let e=le("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:le(`${sn} node`).stdout}}function is(){let e=le("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:le(`${sn} git`).stdout}}function St(){let e=le("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:le(`${sn} hs`).stdout}}function En(){let e=le("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=co(uo(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(mo(t)){let o=hf(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:le(`${sn} claude`).stdout,authenticated:n,authDetail:s}}function rs(e){try{let t=co(uo(),".hscli","config.yml");if(!mo(t))return"na1";let n=wl(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 vt(){let e=le("hs accounts list",{timeout:kl});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 Mn(){let e=le("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=co(uo(),".config","gcloud","application_default_credentials.json"),n=mo(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:le(`${sn} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function In(){let e=le("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=co(uo(),".codex","auth.json");mo(i)&&(n=wl(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:le(`${sn} codex`).stdout,authenticated:s,authDetail:o}}function po(){let e=le("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
3
- `)[0]?.replace("gh version ","").split(" ")[0]||"",path:le(`${sn} gh`).stdout}}function go(){let e=le("gh auth status 2>&1",{timeout:kl});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 Cl(){return!!process.env.ANTHROPIC_API_KEY}function fo(e){return parseInt(e.split(".")[0],10)>=18}function Tl(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function yf(){let e=N(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Gt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function $n(e,...t){if(e)return{configured:!0,masked:io(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:io(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function tr(e){return{anthropic:$n(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:$n(e.openaiApiKey,"OPENAI_API_KEY"),gemini:$n(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:$n(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:$n(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:$n(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function nr(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 sr(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?rs(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...yf()}}function Al(){let e=N(),t=e.hubspotUploadMode||"api",n=tr(e),s={authenticated:tt(),expiresAt:nn()?.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:sr(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:nr({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:it("claude-code"),geminiCli:it("gemini-cli"),codexCli:it("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function _l(){let e=N(),t=tr(e),n={authenticated:tt(),expiresAt:nn()?.expiresAt},s=it("claude-code")?En():{...Pn,name:"Claude Code"},o=it("gemini-cli")?Mn():{...Pn,name:"Gemini CLI"},i=it("codex-cli")?In():{...Pn,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:i,claudeOAuth:n,availableEngines:nr({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:i.found&&i.authenticated})}}function $l(){let t=N().hubspotUploadMode||"api",n=po(),s=n.found?go():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:sr(t,!0)}}function ho(){let e=N(),t=e.hubspotUploadMode||"api",n=os(),s=is(),o=sr(t,!0),i=po(),r=i.found?go():{authenticated:!1,username:""},a={authenticated:tt(),expiresAt:nn()?.expiresAt},l=it("claude-code")?En():{...Pn,name:"Claude Code"},c=it("gemini-cli")?Mn():{...Pn,name:"Gemini CLI"},d=it("codex-cli")?In():{...Pn,name:"OpenAI Codex CLI"},u=tr(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:nr({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 sn,kl,Pn,on=R(()=>{"use strict";y();tn();oe();It();sn=process.platform==="win32"?"where":"which",kl=4e3;Pn={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as bf}from"fs";import{basename as Sf}from"path";async function El(e){let t=Pl.get(e);if(t&&t.expiresAt-Date.now()>wf)return t;let n=await fetch(`${Rt}/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 Pl.set(e,o),o}async function Rn(e){let{accessToken:t}=await El(e);return{Authorization:`Bearer ${t}`}}function yo(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function kf(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Cf(e){return new Promise(t=>setTimeout(t,e))}async function as(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 ls(e,t,n=vf){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=xf*Math.pow(2,s);await Cf(i);continue}return o}return fetch(e,t)}async function bo(e){let t=await El(e),n=`${Rt}/account-info/v3/details`,s=await ls(n,{headers:await Rn(e)});if(!s.ok){let a=await as(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:kf(e)}}async function Ml(e,t,n){let s=bf(n),o=Sf(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${Rt}/cms/v3/source-code/published/content/${yo(t)}`,l=await ls(a,{method:"PUT",headers:await Rn(e),body:i});if(!l.ok){let c=await as(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function or(e,t){let n=`${Rt}/cms/v3/source-code/published/content/${yo(t)}`,s=await ls(n,{method:"DELETE",headers:await Rn(e)});if(!s.ok&&s.status!==404){let o=await as(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function Il(e,t){let n=`${Rt}/cms/v3/source-code/published/content/${yo(t)}`,s=await ls(n,{method:"GET",headers:await Rn(e)});if(!s.ok){let i=await as(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function So(e,t){let n=`${Rt}/cms/v3/source-code/published/metadata/${yo(t)}`,s=await ls(n,{method:"GET",headers:await Rn(e)});if(s.status===404)return null;if(!s.ok){let o=await as(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function Rl(e){let t=await Rn(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 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 Rt,vf,xf,wf,Pl,rn=R(()=>{"use strict";y();Rt="https://api.hubapi.com",vf=3,xf=1e3,wf=300*1e3,Pl=new Map});import*as ce from"@clack/prompts";function ir(e){ce.isCancel(e)&&(ce.cancel(E.muted("Operation cancelled.")),process.exit(0))}async function fe(e){ce.intro(E.heading(e))}async function he(e){ce.outro(E.success(e))}async function xt(e,t){ce.note(e,t?E.heading(t):void 0)}async function ve(e){let t=e.validate,n=await ce.text({message:E.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:t?s=>t(s??""):void 0});return ir(n),n}async function Pe(e){let t=await ce.confirm({message:E.accent(e.message),initialValue:e.initialValue??!0});return ir(t),t}async function Nt(e){let t=await ce.select({message:E.accent(e.message),options:e.options});return ir(t),t}async function je(){let e=ce.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){ce.log.info(e)}function W(e){ce.log.success(E.success(e))}function ie(e){ce.log.warn(E.warn(e))}function Y(e){ce.log.error(E.error(e))}var nt=R(()=>{"use strict";y();bt()});import{readdirSync as rr,statSync as Tf}from"fs";import{join as ye,basename as ar,extname as Af}from"path";function Nl(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 Ol(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(v(s))try{let o=rr(s);for(let i of o){let r=ye(s,i);if(!Tf(r).isFile())continue;let l=Af(i);if(![".tsx",".jsx"].includes(l))continue;let c=ar(i,l);if(c.startsWith("ui")||c==="index")continue;let d=M(r),u=_f(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function _f(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 Fl(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(!v(o))continue;let i=M(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 Dl(e){let t=[],n=ye(e,"src/hooks");if(v(n))try{let o=rr(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=ye(e,"src/components/landing");if(v(s))try{let o=rr(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=M(ye(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 jl(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!Nl(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=ar(e.replace(/\.git$/,""))||"react-source";if(t=ye(process.cwd(),"workspace",l),!v(t)){let c=te(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!v(t))throw new Error(`Directory not found: ${t}`);let s=Ol(t),o=v(ye(t,"tailwind.config.ts"))||v(ye(t,"tailwind.config.js")),{varCount:i,fonts:r}=Fl(t),a=Dl(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function xo(){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:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){Nl(e)||(Y("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=ar(e.replace(/\.git$/,""))||"react-source";if(t=ye(process.cwd(),"workspace",h),v(t))W(`Using existing clone: ${E.dim(t)}`);else{let f=await je();f.start("Cloning repository..."),te(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),Y(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${E.dim(t)}`)}}else t=e,v(t)||(Y(`Directory not found: ${t}`),process.exit(1)),W(`Using local source: ${E.dim(t)}`);let s=await je();s.start("Analyzing project structure...");let o=Ol(t),i=v(ye(t,"tailwind.config.ts"))||v(ye(t,"tailwind.config.js")),{varCount:r,fonts:a}=Fl(t),l=Dl(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(ie("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${E.dim(`${f+1}.`)} ${E.bold(h.name)} ${E.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 xt(`${c}
5
-
6
- CSS: ${d}
7
- JS: ${m}
8
- Font: ${u}`,`${o.length} components detected`),await Pe({message:"Does this look right?"})||(Y("Please adjust your source directory and try again."),process.exit(0)),await he("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var wo=R(()=>{"use strict";y();tn();ae();nt();bt()});var Ll={};We(Ll,{addEmailTemplateToTheme:()=>Nn,createThemeScaffold:()=>ds});import{mkdirSync as Ot,writeFileSync as cs}from"fs";import{join as Ke}from"path";function ds(e,t){Ot(e,{recursive:!0}),Ot(Ke(e,"templates"),{recursive:!0}),Ot(Ke(e,"modules"),{recursive:!0}),Ot(Ke(e,"css"),{recursive:!0}),Ot(Ke(e,"js"),{recursive:!0}),Ot(Ke(e,"images"),{recursive:!0}),Ot(Ke(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"}};cs(Ke(e,"theme.json"),JSON.stringify(n,null,2)+`
9
- `),cs(Ke(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 ef=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var We=(e,t)=>{f
22
15
  %}
23
16
  {% end_dnd_area %}
24
17
  {% endblock body %}
25
- `;cs(Ke(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 ef=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var We=(e,t)=>{f
45
38
  {{ standard_footer_includes }}
46
39
  </body>
47
40
  </html>
48
- `;Ot(Ke(e,"templates","layouts"),{recursive:!0}),cs(Ke(e,"templates","layouts","base.html"),o)}function Nn(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 ef=Object.defineProperty;var R=(e,t)=>()=>(e&&(t=e(e=0)),t);var We=(e,t)=>{f
84
77
  {{ standard_footer_includes }}
85
78
  </body>
86
79
  </html>
87
- `;Ot(Ke(e,"templates"),{recursive:!0}),cs(Ke(e,"templates","email.html"),n)}var us=R(()=>{"use strict";y()});var Jl={};We(Jl,{fetchTheme:()=>ms});import{mkdirSync as Bl,writeFileSync as $f}from"fs";import{join as Pf,dirname as Ef}from"path";async function lr(e,t){let n=await So(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 lr(e,a));else{let l=i;l.folder?s.push(...await lr(e,l.path||a)):s.push(l.path||a)}}return s}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 ms(e,t,n,s={}){let o=s.concurrency??5,i=await lr(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);Bl(n,{recursive:!0}),await Mf(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=Pf(n,a);Bl(Ef(l),{recursive:!0});let c=await Il(e,r);$f(l,c),s.onFile?.(a)})}var ko=R(()=>{"use strict";y();rn()});function Wt(e){let t=Hl.get(e);if(t!==void 0)return t;try{t=M(Cn(e))}catch{t=""}return Hl.set(e,t),t}function be(){return Wt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function gs(){return Wt("design-guide.md")}function cr(){return Wt("content-guide.md")}function Je(){return Wt("hubspot-rules.md")}function dr(){return Wt("humanify-guide.md")}function Ul(){return Wt("email-rules.md")}function Gl(){return Wt("blog-rules.md")}function ur(e){let t=Wt("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 Wl(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 Kl(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 Vl(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 zl(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 Yl(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 Hl,Ve=R(()=>{"use strict";y();ae();Hl=new Map});import{appendFileSync as Ff,mkdirSync as Df,readdirSync as jf,unlinkSync as Lf}from"fs";import{join as fr}from"path";import{homedir as Bf}from"os";function Hf(){if(!pr)try{Df(Ao,{recursive:!0}),pr=!0}catch{}}function Uf(){if(!gr){gr=!0;try{let e=Date.now()-Jf*864e5;for(let t of jf(Ao)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{Lf(fr(Ao,t))}catch{}}}catch{}}}function Gf(){let t=new Date().toISOString().slice(0,10);return fr(Ao,`vibespot-${t}.log`)}function Wf(){return new Date().toISOString().slice(11,23)}function mr(e,t){if(Hf(),!!pr){gr||Uf();try{Ff(Gf(),`${Wf()} ${e} ${t}
181
- `)}catch{}}}var Ao,Jf,pr,gr,T,de=R(()=>{"use strict";y();Ao=fr(Bf(),".vibespot","logs"),Jf=7,pr=!1,gr=!1;T={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),mr("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),mr("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),mr("ERROR",o)}}});function Vf(e){let t=(e||"").toLowerCase();return Kf.find(n=>t.includes(n.match))}function fs(e,t){let n=Vf(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 st(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 On(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 Fn(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 Xl(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 Kf,an=R(()=>{"use strict";y();Kf=[{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 zf}from"async_hooks";function Yf(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function Zl(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 _o(e){let t=Yf();return{result:await hr.run(t,e),cost:Zl(t)}}function Ql(e,t){if(!t)return;let n=hr.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=fs(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}function ec(){let e=hr.getStore();return e?Zl(e):null}var hr,$o=R(()=>{"use strict";y();an();hr=new zf});import{randomUUID as Ft}from"crypto";import{AsyncLocalStorage as qf}from"async_hooks";function sc(){let e=N(),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||Xf).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function Po(){return sc()!==null}function ys(e,t=Zf){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 ze(e,t){if(!Po())return t();let n=Ft();Kt.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:ys(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await hs.run({traceId:n,sessionId:e.sessionId},t)}finally{await oc()}}function Eo(e){if(!Po())return;let t=hs.getStore();t?.traceId&&Kt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:t.traceId,timestamp:new Date().toISOString(),output:ys(e)}})}async function se(e,t,n){let s=hs.getStore();if(!Po()||!s?.traceId)return t();let o=Ft(),i=s.spanId,r=new Date,a,l;try{return await hs.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{Kt.push({id:Ft(),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:ys(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function Qf(e){if(Po())try{let t=hs.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Ft(),o=!0,Kt.push({id:Ft(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let i=e.usage?Xl(e.usage):void 0,r=e.usage?fs(e.model,e.usage):void 0;Kt.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:ys(e.input,tc)}:{},...e.output!==void 0?{output:ys(e.output,tc)}:{},...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 oc()}catch(t){T.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function kt(e){let{engine:t,model:n,name:s,usage:o,startTime:i,endTime:r}=e,a=r.getTime()-i.getTime(),l=o?fs(n,o):void 0;if(o&&T.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),nc.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:i,endTime:r,durationMs:a};for(let d of nc)try{d(c)}catch{}}Ql(n,o),Qf({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 oc(){let e=sc();if(!e||Kt.length===0)return;let t=Kt;Kt=[];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(()=>"");T.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else T.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){T.warn("langfuse",`ingestion failed: ${n.message}`)}}var Xf,Zf,tc,hs,Kt,nc,He=R(()=>{"use strict";y();oe();de();an();$o();Xf="https://cloud.langfuse.com",Zf=24e3,tc=2e5,hs=new qf,Kt=[],nc=new Set});import{join as pe}from"path";import{readdirSync as at,rmSync as uh}from"fs";function Do(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 jo(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 Lo(e){let t=[];return dc(e)&&t.push("textarea \u2192 text"),uc(e)&&t.push("name \u2192 item_name"),mc(e)&&t.push("now() \u2192 local_dt"),pc(e)&&t.push("Removed HubDB templates"),gc(e)&&t.push("Fixed link field defaults"),fc(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),mh(e)&&t.push("Stripped CDN @import statements"),yc(e)&&t.push('dnd_area \u2192 "main" in email templates'),bc(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function cc(e,t){return t.message.includes("textarea")?dc(e):t.message.includes("reserved field name")?uc(e):t.message.includes("now()")?mc(e):t.message.includes("HubDB")?pc(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?gc(e):t.message.includes("invalid format")&&t.message.includes("color")?fc(e):t.message.includes("dnd")||t.message.includes("Dnd area")?yc(e):t.message.includes("dnd_area_stylesheet")?bc(e):!1}function dc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(!v(o))continue;let i=M(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),H(o,i),t=!0)}return t}function uc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(!v(o))continue;let i=M(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),H(o,i),t=!0)}return t}function mc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"module.html");if(!v(o))continue;let i=M(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),H(o,i),t=!0)}return t}function pc(e){let t=!1,n=pe(e,"templates");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".html"))continue;let o=pe(n,s),i=M(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(uh(o),t=!0)}return t}function gc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(v(o))try{let i=JSON.parse(M(o));Sc(i)&&(H(o,JSON.stringify(i,null,2)+`
182
- `),t=!0)}catch{}}return t}function mh(e){let t=!1,n=pe(e,"css");if(v(n))for(let o of at(n)){if(!o.endsWith(".css"))continue;let i=pe(n,o),r=M(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(H(i,a),t=!0)}let s=pe(e,"modules");if(v(s))for(let o of at(s)){if(!o.endsWith(".module"))continue;let i=pe(s,o,"module.css");if(!v(i))continue;let r=M(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(H(i,a),t=!0)}if(v(s))for(let o of at(s)){if(!o.endsWith(".module"))continue;let i=pe(s,o,"module.html");if(!v(i))continue;let r=M(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(H(i,a),t=!0)}return t}function fc(e){let t=!1,n=pe(e,"modules");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".module"))continue;let o=pe(n,s,"fields.json");if(v(o))try{let i=JSON.parse(M(o));hc(i)&&(H(o,JSON.stringify(i,null,2)+`
183
- `),t=!0)}catch{}}return t}function hc(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"&&!ph(i)){let r=gh(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&hc(s.children)&&(t=!0)}return t}function ph(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function gh(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 yc(e){let t=!1,n=pe(e,"templates");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".html"))continue;let o=pe(n,s),i=M(o);if(!/templateType:\s*email/i.test(i))continue;let r=i.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');r!==i&&(H(o,r),t=!0)}return t}function bc(e){let t=!1,n=pe(e,"templates");if(!v(n))return!1;for(let s of at(n)){if(!s.endsWith(".html"))continue;let o=pe(n,s),i=M(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&&(H(o,r),t=!0)}return t}function Sc(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)&&Sc(s.children)&&(t=!0)}return t}var Bo=R(()=>{"use strict";y();ae()});import{readdirSync as fh}from"fs";import{join as hh,relative as yh}from"path";function vc(e){let t=[];for(let n of fh(e,{withFileTypes:!0})){if(bh.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=hh(e,n.name);n.isDirectory()?t.push(...vc(s)):n.isFile()&&t.push(s)}return t}async function Sh(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 Jo(e,t,n,s={}){let o=s.concurrency??5,i=vc(t),r=i.length,a=0,l=0,c=[];return await Sh(i,o,async d=>{let u=yh(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await Ml(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 bh,yr=R(()=>{"use strict";y();rn();rn();bh=new Set([".git","node_modules",".vibespot",".DS_Store"])});var Pc=R(()=>{"use strict";y()});import{existsSync as Dt,writeFileSync as kh,mkdirSync as Ch}from"fs";import{join as Ct}from"path";function Mc(e){return/^[0-9a-f]{4,40}$/i.test(e)}function Ic(e){return Number.isInteger(e)&&e>0&&e<1e3}function lt(){return Ho!==null||(Ho=te(["--version"]).success),Ho}function Uo(e){if(!lt())return!1;if(Dt(Ct(e,".git")))return Ec(e),!0;let t=te(["init"],{cwd:e});return t.success?(Th(e),Ec(e),te(["add","-A"],{cwd:e}),te(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function Ec(e){let t=Ct(e,".vibespot");Dt(t)||Ch(t,{recursive:!0})}function Th(e){let t=Ct(e,".gitignore");kh(t,[".vibespot/","node_modules/",""].join(`
185
- `),"utf-8")}function ln(e,t){if(!lt()||!Dt(Ct(e,".git"))||(te(["add","-A"],{cwd:e}),te(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=te(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=te(["rev-parse","--short","HEAD"],{cwd:e});return i.success?i.stdout:null}function Sr(e,t,n,s){if(!lt()||!Dt(Ct(e,".git")))return null;for(let u of s){let m=Ct(e,u);Dt(m)&&te(["add","--",u],{cwd:e})}if(te(["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=te(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=te(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function Rc(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 Nc(e,t=50){if(!lt())return[];if(!Dt(Ct(e,".git")))return[];if(!Ic(t))return[];let n=te(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:Rc(n.stdout)}function Oc(e,t,n=50){if(!lt())return[];if(!Dt(Ct(e,".git")))return[];if(!Ic(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=te(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:Rc(o.stdout)}function Fc(e,t){if(!lt())return{success:!1,error:"Git not available"};if(!Dt(Ct(e,".git")))return{success:!1,error:"Not a git repo"};if(!Mc(t))return{success:!1,error:"Invalid commit hash"};let n=te(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=te(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=te(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return te(["commit","-m",r],{cwd:e}),{success:!0}}function Dc(e,t,n,s){if(!lt())return{success:!1,error:"Git not available"};if(!Dt(Ct(e,".git")))return{success:!1,error:"Not a git repo"};if(!Mc(n))return{success:!1,error:"Invalid commit hash"};let o=te(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=te(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)te(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};te(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return te(["commit","-m",c],{cwd:e}),{success:!0}}var Ho,jn=R(()=>{"use strict";y();tn();Ho=null});import{readFileSync as Ah,existsSync as Lc,writeFileSync as _h,mkdirSync as $h,rmSync as Ph}from"fs";import{join as Go}from"path";function cn(e){let t=w();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 ct(){let e=w();if(!e)return;let t=Te();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 dt(e,t,n){let s=w();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),ct(),Mh()}function Bc(e){let t=w();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),F())}function Jc(e){let t=w();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 jc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function Eh(e,t){let n=jc(e),s=jc(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 Ue(e){let t=w();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=>Eh(r.moduleName,n.moduleName));i&&T.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(),ct()}}function Vt(e){let t=w();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),ct())}function Hc(e){let t=w();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=Go(t.themePath,"modules",`${e}.module`);Lc(n)&&Ph(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),ct()}}function Uc(e){let t=w();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),ct())}function Gc(e,t,n){let s=w();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);Vc(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),ct()}catch{}}function xe(){let e=w();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 Mh(){let e=w();if(e)try{let t=Go(e.themePath,".vibespot");$h(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};_h(Go(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Wc(e){let t=Go(e,".vibespot","chat.json");if(!Lc(t))return[];try{let n=JSON.parse(Ah(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Kc(e){let t=w();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=jt(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&&vs(e.pages[0].templateId),t.updatedAt=Date.now()}}function Vc(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&&Vc(i.children,s.slice(1).join("."),n))}var Ss=R(()=>{"use strict";y();xs();zt();de()});import{existsSync as Wo,rmSync as Ko}from"fs";import{join as Ln}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 Te(){let e=w();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function vs(e){let t=w();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,cn(n),t.updatedAt=Date.now(),!0):!1}function jt(e,t,n){let s=w();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,cn(l),s.updatedAt=Date.now(),l}function zc(e,t){let n=w();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,cn(l),n.updatedAt=Date.now(),l}function Yc(e){let t=w();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 qc(e,t){let n=w();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 Xc(e,t=!1){let n=w();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=Ln(n.themePath,"templates"),r=`${o.id}.html`,a=Ln(i,r);if(Wo(a)&&Ko(a,{force:!0}),o.pageType==="blog_post"){let l=Ln(i,`${o.id}-listing.html`);Wo(l)&&Ko(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=Ln(n.themePath,"modules");for(let l of r){let c=Ln(a,`${l}.module`);Wo(c)&&Ko(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?vs(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=Ln(n.themePath,".vibespot","plan.md");Wo(r)&&Ko(r,{force:!0})}return n.updatedAt=Date.now(),!0}function Lt(){let e=w();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 zt=R(()=>{"use strict";y();xs();Ss()});import{readFileSync as Tt,readdirSync as Cr,existsSync as Ee,writeFileSync as ws,mkdirSync as zo,rmSync as vr,renameSync as xr,cpSync as Ih}from"fs";import{join as ge,dirname as Zc}from"path";import{homedir as Rh}from"os";function Yo(){if(Bn)return Bn;try{return Ee(wr)?(Bn=JSON.parse(Tt(wr,"utf-8")),Bn):kr()}catch{return kr()}}function qo(e){Bn=e;try{zo(me,{recursive:!0}),ws(wr,JSON.stringify(e),"utf-8")}catch{}}function kr(){if(!Ee(me))return[];let e=[];for(let t of Cr(me).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(Tt(ge(me,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 Bn=e,qo(e),e}function Qc(e){let t=Yo(),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),qo(t)}function Nh(e){let t=Yo().filter(n=>n.id!==e);qo(t)}function Oh(e){let t=Yo().filter(n=>n.themeName!==e);qo(t)}function w(){return Ge}function ed(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Jn(e,t,n={}){let s={id:ed(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Ge=s,Uo(e),s}function F(){if(!Ge)return;zo(me,{recursive:!0});let e=ge(me,`${Ge.id}.json`);ws(e,JSON.stringify(Ge,null,2),"utf-8"),Qc(Ge)}function Xo(e){let t=ge(me,e+".json");if(!Ee(t))return null;try{let n=JSON.parse(Tt(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 Ge=n,n}catch{return null}}function Hn(){return Ee(me)?Yo():[]}function td(e,t=!1){let n=ge(me,e+".json"),s="";if(t)try{let o=JSON.parse(Tt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ee(o.themePath)&&vr(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(Tt(n,"utf-8")).themeName||""}catch{}try{Ee(n)&&vr(n)}catch{}if(s&&Ee(me)){for(let o of Cr(me).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(Tt(ge(me,o),"utf-8")).themeName===s&&vr(ge(me,o))}catch{}Oh(s)}else Nh(e);Ge?.id===e&&(Ge=null)}function nd(e,t){let n=ge(me,e+".json");if(!Ee(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(Tt(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=ge(Zc(i),t);if(Ee(i)){if(Ee(r))return{ok:!1,error:"A project with that name already exists"};try{xr(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=ge(r,"css",`${o}-theme.css`),l=ge(r,"css",`${t}-theme.css`);if(Ee(a))try{xr(a,l)}catch{}let c=ge(r,"js",`${o}-animations.js`),d=ge(r,"js",`${t}-animations.js`);if(Ee(c))try{xr(c,d)}catch{}let u=ge(r,"theme.json");if(Ee(u))try{let m=JSON.parse(Tt(u,"utf-8"));m.label=t,m.name=t,ws(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ee(me))for(let a of Cr(me).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(Tt(ge(me,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),ws(ge(me,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Ge&&Ge.themeName===o&&(Ge.themeName=t,Ge.themePath=r,Ge.updatedAt=Date.now()),kr(),{ok:!0}}function sd(e){let t=ge(me,e+".json");if(!Ee(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(Tt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=Zc(n.themePath),i=`${s}-copy`,r=1;for(;Ee(ge(o,i));)r++,i=`${s}-copy-${r}`;let a=ge(o,i);if(Ee(n.themePath))try{Ih(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=ed(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return zo(me,{recursive:!0}),ws(ge(me,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Qc(c),{ok:!0,newName:i,newSessionId:l}}var me,wr,Bn,Ge,xs=R(()=>{"use strict";y();jn();zt();me=ge(Rh(),".vibespot","sessions"),wr=ge(me,"_index.json"),Bn=null;Ge=null});import{readFileSync as Fh,readdirSync as rd,statSync as Tr}from"fs";import{createHash as Dh}from"crypto";import{join as Se,relative as jh}from"path";function ei(e){let t=[];if(!v(e))return cy(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=qt(e),s=iy(e),o=ay(e),i=ly(e),r=Uh(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 dn(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 ti(e,t){let n=Se(e,"css");if(v(n))try{for(let r of rd(n))if(r.endsWith("-theme.css"))return null}catch{}let s=qt(e),o=dn(s);if(!o)return null;let i=Se(n,`${t}-theme.css`);return H(i,o),i}function ks(e){return Se(e,Lh)}function Jh(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:cd(e)}}function Ar(e,t){let n=Jh(e,t),s=ks(e);return H(s,JSON.stringify(n,null,2)+`
191
- `),s}function ad(e){let t=ks(e);return v(t)?null:Ar(e)}function Hh(e){let t=ks(e);if(!v(t))return null;try{let n=JSON.parse(M(t));return uy(n)?n:null}catch{return null}}function Uh(e){let t=ks(e),n=Hh(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),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:Qo(d.text),afterLines:Qo(u.text)}):r.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)||r.push({file:d.path,status:"added",afterSha256:d.sha256,afterSize:d.size,afterLines:Qo(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 qt(e){let t=oy(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=M(u)}catch{continue}let g,h=new RegExp(Zh.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(Qh.source,"g"),S;for(;(S=b.exec(f))!==null;){let x=S[1].trim(),k=S[2].trim();n[x]||(n[x]=k);let $=k.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if($){let L=od($[0]);o.set(L,x)}}}for(let f of[Gh,Wh,Kh]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let x=od(S[0]);x&&s.set(x,(s.get(x)??0)+1)}}Zo(m,Vh,i,ty),Zo(m,zh,r,f=>f.trim()),ey(m,a),Zo(m,qh,l,f=>f.trim()),Zo(m,Xh,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!sy(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 Zo(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 ey(e,t){let n=new RegExp(Yh.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 ty(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 sy(e){return ny.has(e)}function oy(e){let t=[],n=Se(e,"css");if(v(n))for(let o of Yt(n))o.endsWith(".css")&&t.push(Se(n,o));let s=Se(e,"modules");if(v(s))for(let o of Yt(s)){if(!o.endsWith(".module"))continue;let i=Se(s,o,"module.css");v(i)&&t.push(i)}return t}function iy(e){let t=Se(e,"modules"),n=Se(e,"templates"),s=new Set,o=new Map;if(v(t))for(let c of Yt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,v(Se(t,c,"module.js")))}let i=[],r=new Map;if(v(n))for(let c of Yt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=Se(n,c),u;try{u=Tr(d)}catch{continue}if(!u.isFile())continue;let m;try{m=M(d)}catch{continue}let g=_r(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:my(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 _r(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 ay(e){let t=[],n=Se(e,"modules");if(!v(n))return t;for(let s of Yt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=Se(n,s,"fields.json");if(!v(i))continue;let r;try{r=JSON.parse(M(i))}catch{continue}Array.isArray(r)&&ld(r,o,t,0)}return t}function ld(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&&!ry.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)&&ld(i.children,t,n,s+1)}}function ly(e){let t=[],n=Se(e,"modules");if(v(n))for(let i of Yt(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=Se(n,i,"module.html");v(a)&&id(a,e,r,t);let l=Se(n,i,"module.js");if(v(l))try{M(l).trim().length>0&&t.push({file:$r(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=Se(e,"templates");if(v(s))for(let i of Yt(s)){if(!i.endsWith(".html"))continue;let r=Se(s,i);if(!v(r))continue;let a;try{a=Tr(r)}catch{continue}a.isFile()&&id(r,e,i,t)}let o=Se(e,"import_modules.json");return v(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 id(e,t,n,s){let o;try{o=M(e)}catch{return}let i=$r(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 cy(e,t){let n={hasSnapshot:!1,snapshotPath:ks(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 Yt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=Se(s,o),r;try{r=Tr(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=$r(e,i),l=Fh(i),c={path:a,sha256:Dh("sha256").update(l).digest("hex"),size:l.length};dy(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function dy(e){let t=e.lastIndexOf(".");return t<0?!1:Bh.has(e.slice(t).toLowerCase())}function uy(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 Yt(e){try{return rd(e)}catch{return[]}}function $r(e,t){return jh(e,t).split("\\").join("/")}function my(e){return[...new Set(e)]}var Lh,Bh,Gh,Wh,Kh,Vh,zh,Yh,qh,Xh,Zh,Qh,ny,ry,Cs=R(()=>{"use strict";y();ae();Lh=".vibespot/import-snapshot.json",Bh=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);Gh=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Wh=/\brgba?\([^)]+\)/g,Kh=/\bhsla?\([^)]+\)/g,Vh=/font-family\s*:\s*([^;}\n]+)/g,zh=/font-size\s*:\s*([^;}\n]+)/g,Yh=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,qh=/border-radius\s*:\s*([^;}\n]+)/g,Xh=/box-shadow\s*:\s*([^;}\n]+)/g,Zh=/:root\s*\{([\s\S]*?)\}/g,Qh=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;ny=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);ry=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 Pr,readdirSync as As,existsSync as we,writeFileSync as Xe,mkdirSync as Ts,rmSync as dd}from"fs";import{join as G}from"path";function ke(e){try{return Pr(e,"utf-8")}catch{return""}}function md(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 py(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),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=_r(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function gy(e,t,n,s,o){if(!we(e))return[];let i=[],r=As(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=G(e,a),c=py(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 ni(e){let t=w();if(!t)return;let n=Wc(e);n.length>0&&t.messages.length===0&&(t.messages=n),Uo(e),ad(e);let s=G(e,"modules");if(!we(s))return;let o=As(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let x=G(s,S.name),k=S.name.replace(/\.module$/,""),$={moduleName:k,fieldsJson:ke(G(x,"fields.json")),metaJson:ke(G(x,"meta.json")),moduleHtml:ke(G(x,"module.html")),moduleCss:ke(G(x,"module.css")),moduleJs:ke(G(x,"module.js"))||void 0};$.fieldsJson&&$.moduleHtml&&(t.modules.push($),t.moduleOrder.push(k))}let i=G(e,"css"),r=G(e,"js"),a="",l="";if(we(i)){let S=As(i).filter(x=>x.endsWith("-theme.css"));S.length>0&&(a=ke(G(i,S[0])),t.sharedCss=a)}if(we(r)){let S=As(r).filter(x=>x.endsWith("-animations.js"));S.length>0&&(l=ke(G(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=qt(e),x=dn(S);x&&(t.sharedCss=x,a=x)}let c=G(e,".vibespot","styleguide.md"),d=G(e,".vibespot","brandvoice.md"),u=G(e,".vibespot","theme-context.md"),m=G(e,".vibespot","plan.md"),g=G(e,".vibespot","brand-kit.json");if((we(c)||we(d)||we(u)||we(m)||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(m)&&(t.brandAssets.plan=ke(m)),we(g)))try{t.brandAssets.brandKit=JSON.parse(ke(g))}catch{}let h=G(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=gy(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 x=new Set(t.moduleOrder),k=S.filter($=>x.has($));for(let $ of t.moduleOrder)k.includes($)||k.push($);t.moduleOrder=k}cn(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),Vo(t)}function Ae(){let e=w();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=G(t,"modules");Ts(s,{recursive:!0});for(let l of n.values())Ts(G(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=G(s,`${l.moduleName}.module`);Xe(G(c,"fields.json"),l.fieldsJson,"utf-8"),Xe(G(c,"meta.json"),l.metaJson,"utf-8"),Xe(G(c,"module.html"),l.moduleHtml,"utf-8"),Xe(G(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Xe(G(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=G(t,"css");Ts(l,{recursive:!0}),Xe(G(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=G(t,"js");Ts(l,{recursive:!0}),Xe(G(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=G(t,"templates");Ts(o,{recursive:!0});let i=G(o,"home.html");(e.templates.length>0||e.modules.length>0)&&we(i)&&dd(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=by(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Xe(G(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||yy(l),d=ud(c,l.label,l.pageType),u=`${l.id}.html`;Xe(G(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(Sy(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||vy(),c=ud(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Xe(G(o,d),c,"utf-8"),a.add(d)}try{for(let l of As(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&dd(G(o,l),{force:!0})}catch{}fy(),hy()}function pd(){let e=w();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",ni(e.themePath),e.updatedAt=Date.now(),ct())}function gd(){let e=w();if(!e)return;let t=Te();if(!t)return;let n=e.themePath,s=G(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=G(s,`${o}.module`);if(!we(i))continue;let r={moduleName:o,fieldsJson:ke(G(i,"fields.json")),metaJson:ke(G(i,"meta.json")),moduleHtml:ke(G(i,"module.html")),moduleCss:ke(G(i,"module.css")),moduleJs:ke(G(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=G(n,t.templateFile);we(o)&&(t.template=ke(o))}cn(t),e.updatedAt=Date.now()}function fy(){let e=w();if(!e)return;let t=G(e.themePath,"templates","layouts","base.html");if(we(t))try{let n=Pr(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 }}`),Xe(t,n,"utf-8")}catch{}}function hy(){let e=w();if(!e)return;let t=G(e.themePath,"theme.json");if(we(t))try{let n=JSON.parse(Pr(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Xe(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function ud(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 yy(e){if(e.modules.length===0)return"";let n=w().themeName,o=md(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 by(e){let n=md(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 Sy(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
- `;Xe(G(e,`${t.id}-listing.html`),n,"utf-8")}function vy(){let e=w();if(!e||e.modules.length===0)return"";let t=e.themeName,s=xe().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 Er=R(()=>{"use strict";y();xs();Ss();zt();jn();Cs()});var fd=R(()=>{"use strict";y();Pc();xs();Ss();Er();zt()});var Ce=R(()=>{"use strict";y();fd()});function un(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]=un(n.children):t[n.name]=n.default??"";return t}function Gn(e,t){let n=e;return n=Py(n),n=Sd(n,t),n=vd(n,t),n=xd(n,t),n=My(n),n}function Rr(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 Py(e){return e=e.replace(xy,""),e=e.replace(wy,""),e=e.replace(ky,""),hd.lastIndex=0,e=e.replace(hd,(t,n)=>`/theme-assets/${n}`),yd.lastIndex=0,e=e.replace(yd,""),e=e.replace(Cy,""),e=e.replace(Ty,""),e=e.replace(Ay,""),e=e.replace(_y,""),e=e.replace($y,""),e}function Sd(e,t){let n=e,s=0;for(;s<30;){s++;let o=Ey(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Iy(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=Sd(a,h);return f=vd(f,h),f=xd(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Ey(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 vd(e,t){let n=e,s=0;for(;Mr.test(n)&&s<50;)s++,n=n.replace(Mr,(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(Un(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(Un(m,t))return g}return c}return Un(i,t)?l:c}),Mr.lastIndex=0;return n}function xd(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Ry(t,r);for(let c=1;c<i.length;c++)a=kd(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 My(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Iy(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=bd(n[1],t),i=bd(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=Xt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return Xt(t,e)}function bd(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=Xt(t,o);for(let r=1;r<s.length;r++)i=kd(i,s[r].trim());return Number(i)||0}function Xt(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 Ry(e,t){let n=t.match(/^(.+?)\s*([*/])\s*([\d.]+)$/);if(n){let s=Xt(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 Xt(e,t)}function Un(e,t){let n=e.trim();if(n.startsWith("not "))return!Un(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>Un(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>Un(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=Xt(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=Xt(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=Xt(t,n);return wd(o)}function wd(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function kd(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 wd(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=Ir(e);return r?Oy(r):""}default:return e}}function Ir(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?Ny(t[1]):null}if(typeof e=="object"){let t=e;if(typeof t.color=="string")return Ir(t.color);if(typeof t.hex=="string")return Ir(t.hex)}return null}function Ny(e){let t=e.toLowerCase();return t.length===3?t.split("").map(n=>n+n).join(""):t}function Oy(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 xy,wy,ky,hd,yd,Cy,Ty,Ay,_y,$y,Mr,Nr=R(()=>{"use strict";y();xy=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,wy=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,ky=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,hd=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,yd=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Cy=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Ty=/\{%[-\s]*module\b.*?%\}/gs,Ay=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,_y=/\{#.*?#\}/gs,$y=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Mr=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var si={};We(si,{buildModulePreviewHtml:()=>Dr,buildPreviewHtml:()=>Fr});function Fy(e){if(Wn()==="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 Dy(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 Or(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 Fr(){let e=w();if(!e)return Cd();let t=xe(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return Cd();if(Fy(t))return jy(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:un(u)}}catch{d={module:{}}}let m=Or(c.moduleHtml,u),g=Gn(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=Dy(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 Rr({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function Cd(){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 Dr(e){let t=w();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:un(o)}}catch{s={module:{}}}let i=Or(n.moduleHtml,o),r=Gn(i,s);return Rr({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 jy(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:un(a)}}catch{r={module:{}}}let l=Or(i.moduleHtml,a),c=Gn(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 _s=R(()=>{"use strict";y();Nr();Ce();$s()});function ut(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 Ps(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 ut(c)}function jr(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 Td(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{T.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ut(s[1]);if(!i||typeof i!="object")throw T.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let r=i;r.modules&&Array.isArray(r.modules)&&(Ue({modules:r.modules.map(a=>jr(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){T.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let r=ut(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(Ue({modules:a.modules.map(l=>jr(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){T.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"')){T.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=Ps(a);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(T.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),Ue({modules:c.modules.map(d=>jr(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){T.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),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.";T.warn("parse",a),t&&t(a)}}}var oi=R(()=>{"use strict";y();Ce();de()});function Vn(){let e=w();return e?{pageType:Te()?.pageType,brandAssets:e.brandAssets}:{}}function _d(e,t,n=!1,s,o){let r=[{type:"text",text:By(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
- ${gs()}
353
+ ${No()}
516
354
 
517
355
  ## Content & Copywriting Guide
518
- ${cr()}
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=Ly(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 Ly(e,t){let n=[];if(e){let s=ur(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=dr();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 By(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 Es(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?ur(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=dr();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
- ${gs()}
732
-
733
- ## Content & Copywriting Guide
734
- ${cr()}
735
-
736
- ## HubSpot CMS Rules
737
- ${Je()}
738
-
739
- ## Conversion Guide Reference
740
- ${e}`+c}function Kn(e,t){return e.length<=t?e:e.slice(0,t)+`
741
- /* \u2026truncated ${e.length-t} chars to fit the context budget\u2026 */`}function Ms(){let e=w(),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(Ad/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
- ${Kn(u.fieldsJson,c)}
465
+ ${Kn(f.fieldsJson,p)}
757
466
  \`\`\`
758
467
  **module.html:**
759
468
  \`\`\`html
760
- ${Kn(u.moduleHtml,c)}
469
+ ${Kn(f.moduleHtml,p)}
761
470
  \`\`\`
762
471
  **module.css:**
763
472
  \`\`\`css
764
- ${Kn(u.moduleCss,c)}
473
+ ${Kn(f.moduleCss,p)}
765
474
  \`\`\`
766
- `+(u.moduleJs?`**module.js:**
475
+ `+(f.moduleJs?`**module.js:**
767
476
  \`\`\`js
768
- ${Kn(u.moduleJs,c)}
477
+ ${Kn(f.moduleJs,p)}
769
478
  \`\`\`
770
- `:"");a+=m.length,t.push(m),a>Ad&&(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
- ${Kn(e.sharedCss,c)}
482
+ ${Kn(e.sharedCss,p)}
774
483
  \`\`\`
775
484
  `),e.sharedJs&&t.push(`
776
485
  ### Shared JS
777
486
  \`\`\`js
778
- ${Kn(e.sharedJs,c)}
487
+ ${Kn(e.sharedJs,p)}
779
488
  \`\`\`
780
- `)}let o=Lt(),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 Lr(e,t){let n=w(),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=Ms(),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 Ad,$d=R(()=>{"use strict";y();Ve();Ce();Ad=2e5});import{spawn as Ed}from"child_process";import{mkdtempSync as Jy}from"fs";import{tmpdir as Pd}from"os";import{join as Hy}from"path";async function Md(){return Br||(Br=(await import("@anthropic-ai/sdk")).default),Br}function Id(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 Rd(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(Le[0]);let g=setInterval(()=>{u++,m(Le[Math.min(u,Le.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=st((await h.finalMessage()).usage)}catch{}kt({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>=Jr.length)throw d;let h=Jr[l];T.warn("ai-engine",`Rate limited (429), attempt ${l+1}/${Jr.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 Nd(e,t,n){let s=be(),i=w().modules.length>0,r=Lr(e,n),a=Vn(),l=_d(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function Hr(e,t,n,s,o,i,r,a,l){let c=await Md(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:m}=Nd(e,n,a);T.info("anthropic","API call",{model:s,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:u.length}),await Rd(d,m,u,s,o,i,r)}async function Od(e,t,n,s,o,i,r){let a=await Qi();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await Md(),c=new l({authToken:a,defaultHeaders:ss}),{messages:d,systemBlocks:u}=Nd(e,t,r),m=[{type:"text",text:_n},...u];T.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await Rd(c,m,d,n,s,o,i,"claude-oauth")}async function Ur(e,t,n,s,o,i,r,a,l){let c=be(),d=w().modules.length>0,u=Lr(e,a),m=Vn(),g=u.map(C=>typeof C.content=="string"?C:{role:C.role,content:C.content.map(P=>P.type==="text"?{type:"text",text:P.text}:{type:"image_url",image_url:{url:`data:${P.source.media_type};base64,${P.source.data}`}})}),h=Es(c,n,d,m.pageType,m.brandAssets),f=l||"https://api.openai.com/v1/chat/completions",b=!/\/mistral(\/|$|\?)/.test(f),S=new Date,x=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(!x.ok){let C=await x.text();throw new Error(`API error (${x.status}): ${C}`)}let k=0,$=i||(()=>{});$(Le[0]);let L=setInterval(()=>{k++,$(Le[Math.min(k,Le.length-1)])},6e3),j="",J,V=x.body.getReader(),D=new TextDecoder,U="";try{for(;;){let{done:C,value:P}=await V.read();if(C)break;U+=D.decode(P,{stream:!0});let O=U.split(`
806
- `);U=O.pop()||"";for(let I of O){if(!I.startsWith("data: "))continue;let Q=I.slice(6).trim();if(Q==="[DONE]")break;try{let et=JSON.parse(Q),Fe=et.choices?.[0]?.delta?.content;Fe&&(j+=Fe,o(Fe)),et.usage&&(J=et.usage)}catch{}}}}finally{clearInterval(L)}kt({engine:"openai-api",model:s,name:"vibe-chat",input:{system:h,messages:g},output:j,usage:On(J),startTime:S,endTime:new Date}),r&&r(j)}async function Gr(e,t,n,s,o,i,r,a,l){let c=be(),d=w(),u=d.modules.length>0,m=Ms(),g=Vn(),h=[];for(let I of d.messages.slice(-20))h.push({role:I.role==="assistant"?"model":"user",parts:[{text:I.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 I of r)I.type==="document"&&I.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: ${I.originalName}]
813
- ${I.extractedText}`),I.type==="image"&&I.usage==="asset"&&I.assetPath&&(f+=`
814
-
815
- [Uploaded image: ${I.originalName} \u2192 available as get_asset_url("${I.assetPath}")]`);let b=[];if(r?.length)for(let I of r)I.type==="image"&&I.base64&&b.push({inlineData:{mimeType:I.mimeType,data:I.base64}});b.push({text:f}),h.push({role:"user",parts:b});let S=l||"gemini-2.5-flash",x=a||`https://generativelanguage.googleapis.com/v1beta/models/${S}:streamGenerateContent?alt=sse&key=${t}`,k=Es(c,n,u,g.pageType,g.brandAssets),$=new Date,L=await fetch(x,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:k}]},contents:h,generationConfig:{maxOutputTokens:48e3}})});if(!L.ok){let I=await L.text();throw new Error(`Gemini API error (${L.status}): ${I}`)}let j=0,J=o||(()=>{});J(Le[0]);let V=setInterval(()=>{j++,J(Le[Math.min(j,Le.length-1)])},6e3),D="",U,C=L.body.getReader(),P=new TextDecoder,O="";try{for(;;){let{done:I,value:Q}=await C.read();if(I)break;O+=P.decode(Q,{stream:!0});let et=O.split(`
816
- `);O=et.pop()||"";for(let Fe of et){if(!Fe.startsWith("data: "))continue;let ee=Fe.slice(6).trim();try{let re=JSON.parse(ee),Z=re.candidates?.[0]?.content?.parts?.[0]?.text;Z&&(D+=Z,s(Z)),re.usageMetadata&&(U=re.usageMetadata)}catch{}}}}finally{clearInterval(V)}kt({engine:"gemini-api",model:S,name:"vibe-chat",input:{system:k,contents:h},output:D,usage:Fn(U),startTime:$,endTime:new Date}),i&&i(D)}function Uy(){if(Is)return Is;try{Is=Jy(Hy(Pd(),"vibespot-claude-"))}catch{Is=Pd()}return Is}function Gy(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 Kr(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=Ed("claude",e,{stdio:["pipe","pipe","pipe"],env:r,cwd:Uy()}),l="",c="",d="",u=!1,m=null,g=k=>{u||(u=!0,k())},h=k=>{try{if(k.type==="assistant"&&k.message?.content){for(let $ of k.message.content)if($.type==="text"&&typeof $.text=="string"){let L=$.text;l+=L,n.onChunk&&n.onChunk(L)}else if($.type==="tool_use"){let L=$;L.name&&n.onToolUse&&n.onToolUse(L.name,L.input)}}k.type==="result"&&(m=k,!l&&typeof k.result=="string"&&(l=k.result,n.onChunk&&n.onChunk(k.result))),n.onEvent&&n.onEvent(k)}catch{}};a.stdout.on("data",k=>{d+=k.toString();let $;for(;($=d.indexOf(`
817
- `))>=0;){let L=d.slice(0,$).trim();if(d=d.slice($+1),!!L)try{h(JSON.parse(L))}catch{}}}),a.stderr.on("data",k=>{c+=k.toString()}),a.on("error",k=>g(()=>i(new Error(`claude failed to start: ${k.message}`)))),a.on("close",k=>{if(d.trim()){try{h(JSON.parse(d.trim()))}catch{}d=""}g(()=>{if(k!==0||m&&m.is_error){let L=`${c}
818
- ${l}`,j=Gy(L);i(j!==L?new Error(j):new Error(`claude exited with code ${k}.
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),x=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(x))})}function Vr(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=Ed(e,t,{stdio:["pipe","pipe","pipe"],env:a}),c="",d="",u=!1,m=S=>{u||(u=!0,S())};l.stdout.on("data",S=>{let x=S.toString();c+=x,s&&s(x)}),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 Fd(e,t,n,s,o,i){let r=be(),a=N(),l=w().modules.length>0,c=Vn(),d=Es(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+=Ms(),d+=Id(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print",...Wr];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(Le[0]);let h=setInterval(()=>{m++;let f=Le[Math.min(m,Le.length-1)];g(f)},6e3);try{let f=await Kr(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(Wy(b,S))}});o&&o(f)}finally{clearInterval(h)}}function Wy(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 zr(e,t,n,s,o,i,r){let a=be(),l=w().modules.length>0,c=Vn(),d=Es(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+=Ms(),d+=Id(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(Le[0]);let f=setInterval(()=>{g++;let b=Le[Math.min(g,Le.length-1)];h(b)},6e3);try{let b=await Vr(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Br,Le,Jr,Wr,Is,Yr=R(()=>{"use strict";y();Ve();oe();It();Ce();$d();de();He();an();Br=null;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..."],Jr=[10,20,40,60,120];Wr=["--strict-mcp-config"],Is=null});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function K(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function Ze(e,t,n){K(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Qe=R(()=>{"use strict";y()});import{createWriteStream as Ky,mkdirSync as Dd,existsSync as qr,readFileSync as Xr}from"fs";import{join as mn,extname as Vy}from"path";import{randomUUID as zy}from"crypto";import Yy from"busboy";function Qy(e,t){if(Ld.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return Zy[n]??t}function eb(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function tb(e,t){if(!qr(mn(e,t)))return t;let n=Vy(t),s=t.slice(0,-n.length||void 0),o=1;for(;qr(mn(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function nb(e){let{PDFParse:t}=await import("pdf-parse"),n=Xr(e),s=new t({data:n});try{return(await s.getText()).text}finally{await s.destroy()}}async function sb(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function ob(e){return Xr(e,"utf-8")}function Bd(e,t){let n=w();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=Yy({headers:e.headers,limits:{fileSize:qy,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=Qy(m,g);if(!Ld.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=jd.has(h),b=eb(m),S=zy(),x,k;f?(x=mn(n.themePath,"assets"),Dd(x,{recursive:!0}),k=tb(x,b)):(x=mn(n.themePath,".vibespot","uploads"),Dd(x,{recursive:!0}),k=`${S}-${b}`);let $=mn(x,k),L=Ky($),j=0,J=!1;d.on("data",V=>{j+=V.length}),d.on("limit",()=>{J=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(L),a.push(new Promise(V=>{L.on("finish",()=>{if(!J){let D={id:S,filename:k,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:j,addedAt:new Date().toISOString()};o.push(D),Bc(D)}V()}),L.on("error",()=>{i.push(`Failed to write: ${m}`),V()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=mn(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await nb(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await sb(d):c.extractedText=ob(d),T.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){T.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(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=>{T.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function ii(e){let t=w();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=mn(t.themePath,"assets",s.filename);qr(i)&&(o.base64=Xr(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 qy,jd,Xy,Ld,Zy,Zr=R(()=>{"use strict";y();Qe();Ce();de();qy=10*1024*1024,jd=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),Xy=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),Ld=new Set([...jd,...Xy]),Zy={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});function Rs(e){if(e instanceof Re)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 ri(e,t){let n=0,s=[];return t&&t.addEventListener("abort",()=>{for(;s.length>0;)s.shift().reject(new Re)},{once:!0}),async function(i){if(t?.aborted)throw new Re;if(n>=e&&(await new Promise((r,a)=>s.push({resolve:r,reject:a})),t?.aborted))throw new Re;n++;try{return await i()}finally{n--,s.length>0&&s.shift().resolve()}}}var Re,zn=R(()=>{"use strict";y();Re=class extends Error{aborted=!0;constructor(t="Pipeline aborted"){super(t),this.name="PipelineAbortError"}}});var Vd={};We(Vd,{LANGDOCK_BASE_URLS:()=>Ns,callAgent:()=>_e,callAgentAPI:()=>Kd,isAgenticCapable:()=>Fs,isCLIEngine:()=>Yn,resolveThinkingBudget:()=>pn});async function ai(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>=Qr.length)throw s;let a=Qr[n];T.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${Qr.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 Os(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 Gd(){return ea||(ea=(await import("@anthropic-ai/sdk")).default),ea}async function Jd(e,t,n,s,o,i){let r=await Gd(),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 ai(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}),m=st(u.usage);for(let h of u.content)if(h.type==="tool_use")return{type:"structured",data:Os(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 ai(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 m;try{m=st((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:m}},n.onStatus)}async function ib(e,t,n){let s=await Gd(),o=new s({authToken:e,defaultHeaders:ss}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:_n},...n.systemBlocks]:r=[{type:"text",text:_n},{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 ai(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}}:{}},{signal:n.signal}),c=st(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:Os(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 ai(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}}:{}},{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=st((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus)}function ta(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"?ta(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=ta(t.items)),t}async function Hd(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:ta(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),signal:n.signal});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=On(l.usage);if(n.structuredOutput)try{return{type:"structured",data:Os(JSON.parse(c)),usage:d}}catch{return T.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 Ud(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),signal:n.signal});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=Fn(c.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:Os(JSON.parse(d)),usage:u}}catch{return T.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 rb(e,t,n){switch(e){case"claude-code":{let s=["--print",...Wr];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 ab(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=Wd(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 Wd(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}": ${Wd(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
843
- `)}function lb(e){let t=e.trim(),n=ut(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=ut(a);if(l&&typeof l=="object")return l;let c=Ps(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=ut(a);if(l&&typeof l=="object")return l;let c=Ps(a);if(c&&typeof c=="object")return c}let r=Ps(t);return r&&typeof r=="object"?r:null}async function cb(e,t,n){let{bin:s,args:o}=rb(e,t,n),i=ab(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Kr(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=db(c,d);n.onStatus(u)}})}else r=await Vr(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=lb(r);return a?{type:"structured",data:Os(a)}:(T.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function db(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 Kd(e,t,n,s){T.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 Jd(t,n,s);case"claude-oauth":{let{getValidAccessToken:r}=await Promise.resolve().then(()=>(It(),er)),a=await r();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return ib(a,n,s)}case"openai-api":return Hd(t,n,s);case"gemini-api":return Ud(t,n,s);case"langdock-api":{let r=N(),a=r.langdockProvider||"anthropic",l=r.langdockBaseUrl;switch(a){case"openai":case"mistral":{let c=l||Ns[a];return Hd(t,n,s,`${c}/v1/chat/completions`)}case"google":{let c=l||Ns.google;return Ud(t,n,s,`${c}/v1beta/models/${n}:generateContent`)}default:{let c=l||Ns.anthropic;return Jd(t,n,s,void 0,void 0,c)}}}default:throw new Error(`Unsupported API engine: ${e}`)}})();return mb(e,n,s,i,o,new Date),i}function mb(e,t,n,s,o,i){kt({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 _e(e,t,n,s){if(s.signal?.aborted)throw new Re;return ub.has(e)?Kd(e,t,n,s):(T.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),cb(e,n,s))}function pn(e){if(e==="langdock-api"){if((N().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=N();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Fs(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 Yn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var Ns,sA,Qr,ea,ub,mt=R(()=>{"use strict";y();Yr();oi();oe();It();de();an();He();zn();Ns={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},sA=Ns.anthropic,Qr=[10,20,40,60,120];ea=null;ub=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});var na,zd=R(()=>{"use strict";y();na={"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 fb(){if(Yd!==void 0)return Yd;if(Ds!==void 0)return Ds;try{let e=JSON.parse(M(Cn(gb)));Ds=e&&typeof e=="object"&&e.prompts?e:null}catch{Ds=null}return Ds}function hb(e){let t=new Set;for(let n of e.matchAll(qd))t.add(n[1]);return[...t]}function Xd(e){let t=na[e],n=fb()?.prompts?.[e];if(n&&n.version===t.version&&typeof n.template=="string"){let s=new Set(t.placeholders);if(hb(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 yb(e,t,n){let s=new Set(na[e].placeholders);return t.replace(qd,(o,i)=>s.has(i)?n[i]??"":o)}function pt(e){let t=Xd(e);return{name:`${pb}${e}`,version:t.version,source:t.source}}function Bt(e,t){return yb(e,Xd(e).template,t)}var pb,gb,qd,Ds,Yd,Jt=R(()=>{"use strict";y();ae();zd();pb="vibespot-stage-",gb="prompts.bundle.json",qd=/\{\{\s*([a-zA-Z][\w]*)\s*\}\}/g});function Zd(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 Bt("intent-analyzer",{themeName:e,contextData:c})}var Qd,eu=R(()=>{"use strict";y();Jt();Qd={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 tu(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=Zd(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 se("intent-analyzer",()=>_e(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Qd,name:"pipeline_plan"},maxTokens:2e3,prompt:pt("intent-analyzer")}));if(u.type!=="structured"){T.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]: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",T.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:bb(m)}),m}function bb(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 nu=R(()=>{"use strict";y();mt();eu();Jt();de();He()});function li(e,t){let n=[];n.push(Bt("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
- ${iu()}`),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
- ${ou()}`),n.join("")}function sa(e,t){let n=li(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
- ${iu()}`,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
- ${ou()}`),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 Sb(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 ia(e,t,n,s){let o=[],i=Sb(t);return o.push(Bt("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
- ${vb()}`),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
- ${xb()}`),o.join("")}function ou(){let e=gs(),t=su(e,"## 4. Color System","## 5."),n=su(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 su(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 iu(){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 vb(){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 xb(){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 oa,ra,ru=R(()=>{"use strict";y();Ve();Jt();oa={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"]};ra={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?"":`
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 ci(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
- ${au()}`),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=aa(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 la(e,t){let n=ci(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
- ${au()}`,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=aa(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 da(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
- ${wb()}`),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
- ${kb()}`);let r=aa(n?.brandKit);return r&&o.push(r),o.join("")}function au(){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 wb(){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 kb(){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,76 +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 ca,lu=R(()=>{"use strict";y();ca={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 js(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?ci(n.themeName,n.brandAssets):li(n.themeName,n.brandAssets),d=l?a?la(n.themeName,n.brandAssets):sa(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=pn(s),g=a?ca:oa,h=await se("design-system",()=>_e(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:pt("design-system")}})),f;h.type!=="structured"?(T.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,T.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(([L,j])=>` ${L.startsWith("--")?L:`--${L}`}: ${j};`).join(`
1799
- `)}
1800
- }
1801
-
1802
- ${b}`));let x=Object.keys(S||{}).length,k=a?[`Email design tokens: ${f.aesthetic||"created"} | ${x} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${x} variables, ${b.length} chars CSS`];return r({type:"agent_decision",step:"designing",decision:k.join(`
1803
- `)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function cu(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?ci(n.themeName,n.brandAssets):li(n.themeName,n.brandAssets),d=l?a?la(n.themeName,n.brandAssets):sa(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=pn(s),g=a?ca:oa,h=await se("design-system",()=>_e(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:pt("design-system")}})),f;h.type!=="structured"?(T.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,T.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(([O,I])=>` ${O.startsWith("--")?O:`--${O}`}: ${I};`).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 x=[],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,$=[...new Set((e.match(k)||[]).map(P=>P.trim()))];if($.length>0){let P=$.filter(I=>b.toLowerCase().includes(I.toLowerCase())),O=$.filter(I=>!P.includes(I));O.length>0&&x.push(`Note: ${O.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let L=Object.keys(S||{}).length,j=a?[`Email design tokens: ${f.aesthetic||"created"} | ${L} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${L} variables, ${b.length} chars CSS`,...x];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 J=a?da(n.themeName,S||{},n.brandAssets,t.guidesNeeded):ia(n.themeName,b,n.brandAssets,t.guidesNeeded),V=`## User Request
1816
- ${e}`;if(t.newModules.length>0&&(V+=`
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((P,O)=>`${O+1}. **${P.name}** \u2014 ${P.description}`).join(`
1820
- `)}`),n.modules.length>0){let P=new Set(t.affectedModules),O=n.modules.filter(Q=>P.has(Q.moduleName)),I=n.modules.filter(Q=>!P.has(Q.moduleName));O.length>0&&(V+=`
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
- `+O.map(Q=>`- \`${Q.moduleName}\``).join(`
1825
- `)),I.length>0&&(V+=`
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
- `+I.map(Q=>`- \`${Q.moduleName}\``).join(`
1830
- `))}let D=await se("module-planner",()=>_e(s,o,i,{systemPrompt:J,messages:[{role:"user",content:V}],structuredOutput:{schema:ra,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:pt("module-planner")}})),U,C={modules:t.newModules.map(P=>({name:P.name,description:P.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(P=>P.name),narrative:"Page generated from user request"};if(D.type!=="structured")T.warn("page-architect","Module planner: did not get structured output, using fallback"),U=C;else{let P=D.data;Array.isArray(P?.modules)&&P.modules.length>0?(U=P,U.moduleOrder=U.moduleOrder||U.modules.map(O=>O.name),U.narrative=U.narrative||"Page generated from user request"):(T.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:P?Object.keys(P):[]}),U=C),T.info("page-architect","Module plan",{moduleCount:U.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${U.narrative} | ${U.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:U.modules,moduleOrder:U.moduleOrder,narrative:U.narrative}}async function ua(e,t,n,s,o,i,r,a,l){let c=t.contentType==="email",d=s.cssVariables,u=pn(i);l({type:"agent_step",step:"designing",label:"Planning modules..."});let m=c?da(n.themeName,d||{},n.brandAssets,t.guidesNeeded):ia(n.themeName,o,n.brandAssets,t.guidesNeeded),g=`## User Request
1831
- ${e}`;if(t.newModules.length>0&&(g+=`
1832
-
1833
- ## Planned Modules
1834
- ${t.newModules.map((S,x)=>`${x+1}. **${S.name}** \u2014 ${S.description}`).join(`
1835
- `)}`),n.modules.length>0){let S=new Set(t.affectedModules),x=n.modules.filter($=>S.has($.moduleName)),k=n.modules.filter($=>!S.has($.moduleName));x.length>0&&(g+=`
1836
-
1837
- ## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
1838
- 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.
1839
- `+x.map($=>`- \`${$.moduleName}\``).join(`
1840
- `)),k.length>0&&(g+=`
1841
-
1842
- ## Existing Modules to Keep (do not re-plan)
1843
- 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).
1844
- `+k.map($=>`- \`${$.moduleName}\``).join(`
1845
- `))}let h=await se("module-planner",()=>_e(i,r,a,{systemPrompt:m,messages:[{role:"user",content:g}],structuredOutput:{schema:ra,name:"module_plan"},maxTokens:8e3,...u>0?{thinkingBudgetTokens:u}:{},...c?{}:{prompt:pt("module-planner")}})),f,b={modules:t.newModules.map(S=>({name:S.name,description:S.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(S=>S.name),narrative:"Page generated from user request"};if(h.type!=="structured")T.warn("page-architect","Module planner: did not get structured output, using fallback"),f=b;else{let S=h.data;Array.isArray(S?.modules)&&S.modules.length>0?(f=S,f.moduleOrder=f.moduleOrder||f.modules.map(x=>x.name),f.narrative=f.narrative||"Page generated from user request"):(T.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:S?Object.keys(S):[]}),f=b),T.info("page-architect","Module plan",{moduleCount:f.modules.length})}return l({type:"agent_decision",step:"designing",decision:`Page: ${f.narrative} | ${f.modules.length} modules planned`}),{designSystem:{cssVariables:s.cssVariables||{},sharedCss:o,sharedJs:s.sharedJs},modules:f.modules,moduleOrder:f.moduleOrder,narrative:f.narrative}}var du=R(()=>{"use strict";y();mt();ru();lu();Jt();de();He()});function Cb(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(`
1846
- `)}function uu(e,t,n,s,o){let i=Cb(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(`
1847
1682
  `),a=n.map(d=>`- **${d}**`).join(`
1848
1683
  `),l=[],c=t.map(d=>` - "${d.label}" \u2192 href="/${d.slug}"`).join(`
1849
- `);return l.push(Bt("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(`
1850
1685
 
1851
1686
  ## Brand Voice
1852
1687
  ${o.brandvoice}`),o?.themeContext&&l.push(`
1853
1688
 
1854
1689
  ## Product Context
1855
- ${o.themeContext}`),l.join("")}var mu,pu=R(()=>{"use strict";y();Jt();mu={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 fu(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=uu(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
1856
1691
  ${e}
1857
1692
 
1858
1693
  ## Site Map
1859
- ${l.map(x=>`- ${x.label} (${x.slug}): ${x.purpose}`).join(`
1860
- `)}`,m=pn(o),g=await se("site-module-planner",()=>_e(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:mu,name:"site_module_plan"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},prompt:pt("site-module-planner")}));if(g.type!=="structured")return T.warn("site-planner","Did not get structured output, building fallback"),gu(t,c,s);let h=g.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return T.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),gu(t,c,s);let f=h.sharedModules.map(x=>({name:x.name,description:x.description,contentBrief:x.contentBrief,layoutNotes:x.layoutNotes})),b=h.pages.map(x=>({pageId:x.pageId,modules:(x.modules||[]).map(k=>({name:k.name,description:k.description,contentBrief:k.contentBrief,layoutNotes:k.layoutNotes})),moduleOrder:x.moduleOrder||[]})),S=f.length+b.reduce((x,k)=>x+k.modules.length,0);return T.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(x=>{let k=l.find($=>$.id===x.pageId);return{pageId:x.pageId,label:k?.label||x.pageId,moduleCount:x.modules.length}}),sharedModuleCount:f.length}),{designSystem:{cssVariables:{},sharedCss:s},pages:b,sharedModules:f,narrative:h.narrative||"Multi-page site generated from user request"}}function gu(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 hu=R(()=>{"use strict";y();mt();pu();Jt();de();He()});function Ls(e,t,n,s){let o=[];return o.push(Bt("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(`
1861
1696
 
1862
1697
  ## Theme Shared CSS (use these custom properties)
1863
1698
  \`\`\`css
@@ -1865,29 +1700,29 @@ ${t}
1865
1700
  \`\`\``),(!n||n.includes("hubspot_rules"))&&o.push(`
1866
1701
 
1867
1702
  ## HubSpot CMS Rules
1868
- ${Je()}`),(!n||n.includes("conversion"))&&o.push(`
1703
+ ${et()}`),(!n||n.includes("conversion"))&&o.push(`
1869
1704
 
1870
1705
  ## Conversion Guide
1871
- ${be()}`),s?.themeContext&&o.push(`
1706
+ ${Ce()}`),s?.themeContext&&o.push(`
1872
1707
 
1873
1708
  ## Product Context
1874
1709
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
1875
1710
 
1876
1711
  ## Anti-AI Copy Rules
1877
- ${yu()}`),o.join("")}function di(e,t,n,s){let o=[],i=Ls(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+=`
1878
1713
 
1879
1714
  ## Theme Shared CSS (use these custom properties)
1880
1715
  \`\`\`css
1881
1716
  ${t}
1882
- \`\`\``),o.push({type:"text",text:i});let r=[];(!n||n.includes("hubspot_rules"))&&r.push(`## HubSpot CMS Rules
1883
- ${Je()}`),(!n||n.includes("conversion"))&&r.push(`## Conversion Guide
1884
- ${be()}`),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(`
1885
1720
 
1886
1721
  `),cache_control:{type:"ephemeral"}});let a=[];return s?.themeContext&&a.push(`## Product Context
1887
1722
  ${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&a.push(`## Anti-AI Copy Rules
1888
- ${yu()}`),a.length>0&&o.push({type:"text",text:a.join(`
1723
+ ${fp()}`),a.length>0&&o.push({type:"text",text:a.join(`
1889
1724
 
1890
- `)}),o}function yu(){return`### Banned Punctuation
1725
+ `)}),o}function fp(){return`### Banned Punctuation
1891
1726
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
1892
1727
  - **Semicolons**: Use periods instead in marketing copy.
1893
1728
  - **Exclamation marks**: One per page max. Zero ideal for B2B.
@@ -1926,7 +1761,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
1926
1761
  - Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
1927
1762
  - Full names, specific roles (not "John D., CEO")
1928
1763
  - Never start with "This product is..." \u2014 start with the person's situation
1929
- - Vary length and voice across testimonials`}function bu(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
1930
1765
  ${e}`),s.push(`
1931
1766
 
1932
1767
  ## Module Specification
@@ -1953,7 +1788,7 @@ ${n.moduleCss}
1953
1788
  **module.js:**
1954
1789
  \`\`\`js
1955
1790
  ${n.moduleJs}
1956
- \`\`\``)),s.join("")}var Bs,ma=R(()=>{"use strict";y();Ve();Jt();Bs={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 pa(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.
1957
1792
 
1958
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.
1959
1794
 
@@ -2111,17 +1946,17 @@ Modules that serve as email footers MUST include:
2111
1946
  ${t.themeContext}`),t?.humanify!==!1&&n.push(`
2112
1947
 
2113
1948
  ## Anti-AI Copy Rules
2114
- ${vu()}`),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(`
2115
1950
 
2116
1951
  ## Brand Kit \u2014 MANDATORY Design Constraints
2117
1952
  The following brand identity values MUST be used. Do NOT substitute or override them:
2118
1953
  ${s.join(`
2119
- `)}`)}return n.join("")}function Su(e,t){let n=[],s=pa(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=Ul()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
2120
- ${o}`,cache_control:{type:"ephemeral"}});let i=[];return t?.themeContext&&i.push(`## Product Context
2121
- ${t.themeContext}`),t?.humanify!==!1&&i.push(`## Anti-AI Copy Rules
2122
- ${vu()}`),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(`
2123
1958
 
2124
- `)}),n}function vu(){return`### Banned Punctuation
1959
+ `)}),n}function bp(){return`### Banned Punctuation
2125
1960
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2126
1961
  - **Semicolons**: Use periods instead.
2127
1962
  - **Exclamation marks**: One per email max. Zero ideal for B2B.
@@ -2140,7 +1975,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2140
1975
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2141
1976
  - Use plain words: use > utilize, start > commence, help > facilitate
2142
1977
  - Front-load the benefit in the first 5 words
2143
- - Email subject lines: specific, benefit-first, under 50 chars`}function xu(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
2144
1979
  ${e}`),s.push(`
2145
1980
 
2146
1981
  ## Email Module Specification
@@ -2160,7 +1995,7 @@ ${n.fieldsJson}
2160
1995
  **module.html:**
2161
1996
  \`\`\`html
2162
1997
  ${n.moduleHtml}
2163
- \`\`\``),s.join("")}var wu,ku=R(()=>{"use strict";y();Ve();wu={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 ga(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.
2164
1999
 
2165
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.
2166
2001
 
@@ -2345,22 +2180,22 @@ The blog post body module wraps \`{{ content.post_body }}\` with reading-optimiz
2345
2180
  ${s.themeContext}`),s?.humanify!==!1&&o.push(`
2346
2181
 
2347
2182
  ## Anti-AI Copy Rules
2348
- ${Tu()}`);let i=[];if(n?.includes("conversion"))try{let r=be();r&&i.push(`## Conversion Guide
2349
- ${r}`)}catch{}if(n?.includes("hubspot_rules"))try{let r=Je();r&&i.push(`## HubSpot Rules
2350
- ${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(`
2351
2186
 
2352
- ${i.join(`
2187
+ ${r.join(`
2353
2188
 
2354
- `)}`),o.join("")}function Cu(e,t,n,s){let o=[],i=ga(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=Gl()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
2355
- ${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=be();c&&a.push(`## Conversion Guide
2356
- ${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
2357
2192
  ${c}`)}catch{}a.length>0&&o.push({type:"text",text:a.join(`
2358
2193
 
2359
2194
  `),cache_control:{type:"ephemeral"}});let l=[];return s?.themeContext&&l.push(`## Product Context
2360
2195
  ${s.themeContext}`),s?.humanify!==!1&&l.push(`## Anti-AI Copy Rules
2361
- ${Tu()}`),l.length>0&&o.push({type:"text",text:l.join(`
2196
+ ${kp()}`),l.length>0&&o.push({type:"text",text:l.join(`
2362
2197
 
2363
- `)}),o}function Tu(){return`### Banned Punctuation
2198
+ `)}),o}function kp(){return`### Banned Punctuation
2364
2199
  - **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
2365
2200
  - **Semicolons**: Use periods instead.
2366
2201
  - **Exclamation marks**: Maximum one per page. Zero ideal for B2B.
@@ -2379,7 +2214,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
2379
2214
  - Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
2380
2215
  - Use plain words: use > utilize, start > commence, help > facilitate
2381
2216
  - Front-load the benefit in the first 5 words
2382
- - Blog headlines: specific, benefit-first, no clickbait`}function Au(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
2383
2218
  ${e}`),s.push(`
2384
2219
 
2385
2220
  ## Blog Module Specification
@@ -2404,17 +2239,17 @@ ${n.moduleHtml}
2404
2239
  **module.css:**
2405
2240
  \`\`\`css
2406
2241
  ${n.moduleCss}
2407
- \`\`\``),s.join("")}var _u,$u=R(()=>{"use strict";y();Ve();Ve();_u={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 Js(e,t,n,s,o,i,r,a,l,c,d,u,m){let g=u==="email",h=u==="blog",f=g?"email module":h?"blog module":"module";l({type:"agent_step",step:"developing",label:`Generating ${t.length} ${f}${t.length===1?"":"s"}...`});let b=o==="anthropic-api"||o==="claude-oauth",S=g?pa(s,d):h?ga(s,n,c,d):Ls(s,n,c,d),x=b?g?Su(s,d):h?Cu(s,n,c,d):di(s,n,c,d):void 0,k=ri(a,m),$=t.length,L=g?wu:h?_u:Bs,j=g||h?void 0:pt("module-developer"),J=t.map((D,U)=>k(async()=>{l({type:"module_progress",module:D.name,status:"generating",current:U+1,total:$});let C="";for(let P=0;P<2;P++){if(m?.aborted)throw new Re;try{P>0&&(T.warn("module-developer",`${D.name}: retrying after failure (attempt ${P+1})`),l({type:"module_progress",module:D.name,status:"retrying",current:U+1,total:$}));let O=await Pu(e,D,S,o,i,r,0,x,g,L,h,j,m);return l({type:"module_progress",module:D.name,status:"complete",current:U+1,total:$,moduleFiles:O}),{moduleName:D.name,module:O}}catch(O){if(Rs(O))throw O instanceof Re?O:new Re;C=O instanceof Error?O.message:typeof O=="object"&&O!==null?JSON.stringify(O):String(O),T.error("module-developer",`Failed: ${D.name} (attempt ${P+1})`,{error:C})}}return l({type:"module_progress",module:D.name,status:"failed",current:U+1,total:$}),{moduleName:D.name,error:C}})),V=await Promise.allSettled(J);if(m?.aborted)throw new Re;return V.map(D=>D.status==="fulfilled"?D.value:{moduleName:"unknown",error:D.reason instanceof Error?D.reason.message:String(D.reason)})}async function Pu(e,t,n,s,o,i,r=0,a,l=!1,c=Bs,d=!1,u,m){let g=l?xu(e,t,t.existingCode):d?Au(e,t,t.existingCode):bu(e,t,t.existingCode),h=await _e(s,o,i,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:g}],structuredOutput:{schema:c,name:"module_output"},maxTokens:16e3,...u?{prompt:u}:{},signal:m});if(h.type!=="structured"){if(r<2)return T.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),Pu(e,t,n,s,o,i,r+1,a,l,c,d,u,m);throw new Error(`Module "${t.name}" failed to produce structured output after ${r+1} attempts`)}let f=h.data,b=typeof f.fieldsJson=="string"?f.fieldsJson:JSON.stringify(f.fieldsJson,null,2),S=typeof f.metaJson=="string"?f.metaJson:JSON.stringify(f.metaJson,null,2);return{moduleName:t.name,fieldsJson:b,metaJson:S,moduleHtml:String(f.moduleHtml||""),moduleCss:l?"":String(f.moduleCss||""),moduleJs:l?void 0:f.moduleJs?String(f.moduleJs):void 0}}var Eu=R(()=>{"use strict";y();mt();zn();ma();ku();$u();Jt();de()});function gn(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=Mu(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=Mu(c.metaJson,c.moduleName,"metaJson",l,i,r);let d={};c.fieldsJson=Ab(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=_b(c.moduleHtml,d),c.fieldsJson=$b(c.fieldsJson,c.moduleName,l),i?c=Lb(c,l):(c.moduleCss=Pb(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=Mb(c.moduleCss,c.moduleName,t,l),c.moduleHtml=Ib(c.moduleHtml,c.moduleName,t,l),r&&(c=Bb(c,l))),c.moduleHtml=Nb(c.moduleHtml,c.moduleName,l),i||Ob(c,l),c.metaJson=Fb(c.metaJson,c.moduleName,l,i,r),o&&jb(c,o,l);let u=l.every(m=>m.autoFixed);return l.length>0&&T.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 Mu(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):ut(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 Ab(e,t,n,s){let o=e;for(let[i,r]of Tb)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 _b(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 $b(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 Pb(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 Ru(e){return Eb.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Mb(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)&&!Ru(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${Rb(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 Ib(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)&&!Ru(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 Rb(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Nb(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(`
2408
2243
  `);s=`${s}
2409
- ${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 Iu(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 Ob(e,t){let n=ut(e.fieldsJson),s=Array.isArray(n)?un(n):{},o=e.moduleHtml||"";try{o=Gn(e.moduleHtml||"",{module:s})}catch{}let i=[...Iu(o),...Iu(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 Fb(e,t,n,s=!1,o=!1){let i=ut(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 Nu(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 jb(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(Db))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 Lb(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 Bb(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 Tb,Eb,Db,fa=R(()=>{"use strict";y();oi();de();Nr();Tb=[["name","item_name"],["label","section_label"],["body","body_text"]];Eb=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);Db=/#[0-9a-fA-F]{6}\b/g});function Jb(e){return e.replace(/^--/,"").replace(/[-_]/g," ").replace(/\b\w/g,t=>t.toUpperCase()).trim()}function ui(e,t,n){for(let s of t)for(let[o,i]of Object.entries(e))if(o.toLowerCase().includes(s)&&Fu.test(String(i).trim()))return String(i).trim();return n}function Ou(e,t,n){for(let s of t)for(let[o,i]of Object.entries(e)){let r=o.toLowerCase();if(r.includes("font")&&r.includes(s)&&String(i).trim())return String(i).trim()}for(let[s,o]of Object.entries(e))if(s.toLowerCase().includes("font")&&String(o).trim())return String(o).trim();return n}function Hb(e){let t=[],n=new Set;for(let[s,o]of Object.entries(e)){let i=String(o).trim();if(!(!Fu.test(i)||i.startsWith("var("))&&!n.has(i.toLowerCase())&&(n.add(i.toLowerCase()),t.push({label:Jb(s),value:i}),t.length>=6))break}return t}function fn(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Ub(e,t,n){let s=ui(e,["background","bg","surface","dark"],"#0f1115"),o=ui(e,["text","foreground","fg","ink","light"],"#f5f5f7"),i=ui(e,["primary","brand","accent","cta"],"#e8613a"),r=ui(e,["on-primary","button-text","light","background"],"#ffffff");return`<!doctype html><html><head><meta charset="utf-8"><style>
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>
2410
2245
  *{margin:0;box-sizing:border-box}
2411
- body{font-family:${fn(n)};background:${fn(s)};color:${fn(o)}}
2246
+ body{font-family:${bn(n)};background:${bn(s)};color:${bn(o)}}
2412
2247
  .hero{padding:48px 40px;display:flex;flex-direction:column;gap:18px;align-items:flex-start}
2413
2248
  .eyebrow{font-size:12px;letter-spacing:.12em;text-transform:uppercase;opacity:.7}
2414
- h1{font-family:${fn(t)};font-size:38px;line-height:1.08;font-weight:700;max-width:14ch}
2249
+ h1{font-family:${bn(t)};font-size:38px;line-height:1.08;font-weight:700;max-width:14ch}
2415
2250
  p{font-size:16px;line-height:1.55;opacity:.85;max-width:46ch}
2416
2251
  .btn{margin-top:6px;display:inline-block;padding:13px 26px;border-radius:8px;
2417
- background:${fn(i)};color:${fn(r)};font-family:${fn(t)};
2252
+ background:${bn(r)};color:${bn(i)};font-family:${bn(t)};
2418
2253
  font-weight:600;font-size:15px;text-decoration:none}
2419
2254
  </style></head><body>
2420
2255
  <section class="hero">
@@ -2423,78 +2258,78 @@ p{font-size:16px;line-height:1.55;opacity:.85;max-width:46ch}
2423
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>
2424
2259
  <a class="btn" href="#">Get started</a>
2425
2260
  </section>
2426
- </body></html>`}function Du(e){let t=e.cssVariables||{},n=Hb(t),s=Ou(t,["head","display","title","serif"],"Space Grotesk, system-ui, sans-serif"),o=Ou(t,["body","text","base","sans"],"DM Sans, system-ui, sans-serif"),i=Ub(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:i}}}function ju(){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
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
2427
2262
  Ink #0f1115
2428
- 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 Fu,Lu=R(()=>{"use strict";y();Fu=/^(#|rgb|hsl|var\()/i});function ha(e){return[...new Set(e.map(t=>t.trim()).filter(Boolean))]}function ya(){return{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]}}function Bu(e){let t=ya(),n,s=new RegExp(Gb.source,"g");for(;(n=s.exec(e))!==null;){let d=new RegExp(Wb.source,"g"),u;for(;(u=d.exec(n[1]))!==null;){let m=u[1].trim(),g=u[2].trim();m&&g&&!t.cssVariables[m]&&(t.cssVariables[m]=g)}}let o=new Map,i,r=new RegExp(Hu.source,"g");for(;(i=r.exec(e))!==null;){let d=i[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(Kb.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=ha(a).slice(0,8),t}function Vb(e){let t=ya(),n=e.split(/[\n,]/).map(o=>o.trim()).filter(Boolean),s=0;for(let o of n){let r=new RegExp(Hu.source,"g").exec(o);if(!r)continue;let a=r[0].trim(),l=o.slice(0,r.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 zb(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:Ju});if(!o.ok)return T.warn("brand-intake",`site fetch ${t} \u2192 HTTP ${o.status}`),"";let i=await o.text(),r="";for(let l of i.matchAll(/<style[^>]*>([\s\S]*?)<\/style>/gi))r+=`
2429
- ${l[1]}`;for(let l of i.matchAll(/<meta[^>]+name=["']theme-color["'][^>]*>/gi)){let c=/content=["']([^"']+)["']/i.exec(l[0])?.[1];c&&(r+=`
2430
- --theme-color: ${c};`)}for(let l of i.matchAll(/style=["']([^"']+)["']/gi))r+=`
2431
- .inline{${l[1]}}`;let a=[];for(let l of i.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:Ju});d.ok&&(r+=`
2432
- ${await d.text()}`)}catch{}return r.trim()||(r=i),r}catch(o){return T.warn("brand-intake",`site fetch failed for ${t}: ${o instanceof Error?o.message:String(o)}`),""}finally{clearTimeout(s)}}function mi(e,t,n,s){for(let[o,i]of Object.entries(s.cssVariables))e[o]||(e[o]=i);t.push(...s.palette.map(o=>o.value)),n.push(...s.fontFamilies)}async function Uu(e){let t={},n=[],s=[],o=[],i=[];if(e.colors?.trim()){let d=Vb(e.colors);Object.keys(d.cssVariables).length>0&&(mi(t,n,s,d),o.push("colors"),i.push(`### Brand colors (provided)
2433
- ${Object.entries(d.cssVariables).map(([u,m])=>`- ${u}: ${m}`).join(`
2434
- `)}`))}if(e.code?.trim()){let d=Bu(e.code);(Object.keys(d.cssVariables).length>0||d.palette.length>0||d.fontFamilies.length>0)&&(mi(t,n,s,d),o.push("code"),i.push(`### From pasted code
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
2435
2270
  - Variables: ${Object.keys(d.cssVariables).length}
2436
2271
  - Colors: ${d.palette.slice(0,6).map(u=>u.value).join(", ")||"none"}
2437
- - 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)&&(mi(t,n,s,d),o.push("theme"),i.push(`### From imported theme
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
2438
2273
  - Variables: ${Object.keys(d.cssVariables).length}
2439
2274
  - Colors: ${d.palette.slice(0,6).map(u=>u.value).join(", ")||"none"}
2440
- - Fonts: ${d.fontFamilies.join(", ")||"none"}`))}catch(d){T.warn("brand-intake",`theme token extraction failed: ${d instanceof Error?d.message:String(d)}`)}if(e.siteUrl?.trim()){let d=await zb(e.siteUrl.trim());if(d){let u=Bu(d);(Object.keys(u.cssVariables).length>0||u.palette.length>0||u.fontFamilies.length>0)&&(mi(t,n,s,u),o.push("site"),i.push(`### From site (${e.siteUrl.trim()})
2441
- - Colors: ${u.palette.slice(0,6).map(m=>m.value).join(", ")||"none"}
2442
- - Fonts: ${u.fontFamilies.join(", ")||"none"}`))}}Object.keys(t).length===0&&ha(n).slice(0,6).forEach((d,u)=>{let m=u===0?"primary":u===1?"secondary":`accent-${u-1}`;t[`--color-${m}`]=d});let r=ha(s);r[0]&&!Object.keys(t).some(d=>d.includes("font")&&d.includes("head"))&&(t["--font-heading"]=r[0]),r[1]&&!Object.keys(t).some(d=>d.includes("font")&&d.includes("body"))&&(t["--font-body"]=r[1]||r[0]);let a=Object.keys(t).length?dn({...ya(),cssVariables:t}):"",l=e.voice?.trim()||void 0;l&&o.push("voice");let c;if(i.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."];i.length&&d.push(i.join(`
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(`
2443
2278
 
2444
2279
  `)),l&&d.push(`### Tone of voice
2445
2280
  ${l}`),c=d.join(`
2446
2281
 
2447
- `)}return{cssVariables:t,rootCss:a,styleguide:c,brandvoice:l,channels:o}}var Hu,Gb,Wb,Kb,Ju,Gu=R(()=>{"use strict";y();Cs();de();Hu=/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/g,Gb=/:root\s*\{([^}]*)\}/g,Wb=/(--[A-Za-z0-9-_]+)\s*:\s*([^;]+?)\s*(?:;|$)/g,Kb=/font-family\s*:\s*([^;}]+)[;}]/gi;Ju={"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 Yb(e){return String(e||"").trim().toLowerCase().replace(/['"]/g,"").replace(/[^a-z0-9]+/g,"-").replace(/^-+|-+$/g,"")}function Wu(e){let t=new Map;e.modules.forEach((i,r)=>{t.has(i.name)||t.set(i.name,r)});let n=[],s=new Set;for(let i of e.moduleOrder||[]){let r=t.get(i);if(r==null||s.has(r))continue;s.add(r);let a=e.modules[r];n.push({name:a.name,description:a.description||"",sourceIndex:r})}return e.modules.forEach((i,r)=>{s.has(r)||n.push({name:i.name,description:i.description||"",sourceIndex:r})}),{kind:"structure",headline:"Here's the structure \u2014 reorder, cut, or add sections before I build",data:{narrative:e.narrative||"",modules:n}}}function Ku(e,t){if(!t||t.length===0)return e;let n=[],s=new Set;for(let o of t){let i=o.sourceIndex!=null?e.modules[o.sourceIndex]:void 0,r=Yb(o.name)||i?.name;r&&(s.has(r)||(s.add(r),i?n.push({name:r,description:o.description??i.description,contentBrief:i.contentBrief,layoutNotes:i.layoutNotes}):n.push({name:r,description:o.description||`User-added section: ${r}`,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 Vu=R(()=>{"use strict";y()});import{execSync as qb}from"child_process";function Yu(){return`cp_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,10)}`}function Hs(e){Us.delete(e)}function qu(){let e=ec();if(!(!e||e.costUsd<=0))return Math.round(e.costUsd*Xb*100)/100}async function Xu(e,t,n,s,o,i,r,a,l=!1,c){let d=Date.now(),u=i;if(Yn(n)){let x={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(x)try{qb(`command -v ${x}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${x}" to be installed and on your PATH.`)}}let m=await tu(e,t,n,s,o,r,a);if(c?.aborted)throw new Re;if(m.intent==="question"&&m.answer){let S=Date.now()-d;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:S,answer:m.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:m.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:S}}}if(m.intent==="create_site"&&m.pages&&m.pages.length>0)return tS(e,m,t,n,s,o,i,r,d,c);let g=null,h=t.sharedCss,f=t.sharedJs;if(m.intent==="create"||m.designSystemChanges){if(l&&m.contentType!=="email"){if(m.intent==="create"&&!Zb(t))return Qb({kind:"brand_intake",userMessage:e,plan:m,sharedCss:h,sharedJs:f,startTime:d,libraryModules:a},t,r);let S=await js(e,m,t,n,s,o,r);return Sa({kind:"design",userMessage:e,plan:m,designSystem:S,sharedCss:S.sharedCss,sharedJs:S.sharedJs||f,startTime:d,libraryModules:a},t,r)}g=await cu(e,m,t,n,s,o,r),m.contentType!=="email"&&(h=g.designSystem.sharedCss||h,f=g.designSystem.sharedJs||f),r({type:"blueprint_ready",moduleOrder:g.moduleOrder,sharedCss:h,sharedJs:f})}if(c?.aborted)throw new Re;return ba(e,m,t,g,h,f,n,s,o,u,r,a,d,c)}function Zu(e,t,n,s,o){let i=Yu();Us.set(i,t);let r=qu();return o({type:"checkpoint_requested",kind:e,preview:n,...r!=null?{estCostNext:r}:{}}),{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:i,preview:n,createdAt:new Date().toISOString(),resumeState:t}}}function Sa(e,t,n){if(!e.designSystem)throw new Error("Cannot park at the design checkpoint without a design system.");return Zu("design",e,Du(e.designSystem),t,n)}function zu(e,t,n){return Zu("structure",e,Wu(e.blueprint),t,n)}function Zb(e){return!!(e.brandAssets?.styleguide&&e.brandAssets.styleguide.trim()||e.sharedCss&&e.sharedCss.includes(":root"))}function Qb(e,t,n){let s=Yu();Us.set(s,e);let o=ju(),i=qu();return n({type:"checkpoint_requested",kind:"brand_intake",preview:o,...i!=null?{estCostNext:i}:{}}),{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 eS(e,t,n,s,o,i,r,a){Hs(e);let l=n.action==="approve"?n.brandIntake:void 0,c=s,d,u=null;if(l)if(u=await Uu(l),u.channels.length>0){let h=[s.brandAssets?.styleguide,u.styleguide].filter(f=>f&&f.trim()).join(`
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(`
2448
2283
 
2449
- `);d={...h?{styleguide:h}:{},...u.brandvoice?{brandvoice:u.brandvoice}:{}},c={...s,brandAssets:{...s.brandAssets,...h?{styleguide:h}:{},...u.brandvoice?{brandvoice:u.brandvoice}:{}},sharedCss:u.rootCss||s.sharedCss},a({type:"agent_decision",step:"designing",decision:`Brand intake: using ${u.channels.join(", ")} \u2192 ${Object.keys(u.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 m=await js(t.userMessage,t.plan,c,o,i,r,a);u&&Object.keys(u.cssVariables).length>0&&(m.cssVariables={...m.cssVariables||{},...u.cssVariables},u.rootCss&&!m.sharedCss.includes(u.rootCss.trim())&&(m.sharedCss=`${m.sharedCss}
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}
2450
2285
 
2451
2286
  /* Brand intake overrides (VIB-1878) */
2452
- ${u.rootCss}`));let g=Sa({kind:"design",userMessage:t.userMessage,plan:t.plan,designSystem:m,sharedCss:m.sharedCss,sharedJs:m.sharedJs||t.sharedJs,startTime:t.startTime,libraryModules:t.libraryModules},s,a);return d&&(g.brandAssetsUpdate=d),g}async function Qu(e,t,n,s,o,i,r,a,l,c){let d=Us.get(e);if(!d&&c&&(d=c,Us.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 Hs(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 eS(e,d,t,n,s,o,i,a);if(d.kind==="structure"){if(Hs(e),t.action==="steer"){let f=(t.note||"").trim(),b=f?`${d.userMessage}
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}
2453
2288
 
2454
2289
  ## Structure steer (revise the module plan to honor this)
2455
- ${f}`:d.userMessage,S=await ua(b,d.plan,n,d.designSystem,d.sharedCss,s,o,i,a);return zu({...d,userMessage:b,blueprint:S},n,a)}let h=Ku(d.blueprint,t.outline);return a({type:"blueprint_ready",moduleOrder:h.moduleOrder,sharedCss:d.sharedCss,sharedJs:d.sharedJs}),ba(d.userMessage,d.plan,n,h,d.sharedCss,d.sharedJs??"",s,o,i,r,a,d.libraryModules,d.startTime,l)}if(t.action==="steer"){Hs(e);let h=(t.note||"").trim(),f=h?`${d.userMessage}
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}
2456
2291
 
2457
2292
  ## Design steer (revise the design system to honor this)
2458
- ${h}`:d.userMessage,b=await js(f,d.plan,n,s,o,i,a);return Sa({...d,userMessage:f,designSystem:b,sharedCss:b.sharedCss,sharedJs:b.sharedJs||d.sharedJs},n,a)}if(Hs(e),!d.designSystem)throw new Error("Checkpoint resume state is missing its design system. Send your request again to start over.");let u=await ua(d.userMessage,d.plan,n,d.designSystem,d.sharedCss,s,o,i,a),m=d.plan.contentType!=="email"&&u.designSystem.sharedCss||d.sharedCss,g=d.plan.contentType!=="email"&&u.designSystem.sharedJs||d.sharedJs;return t.action!=="skip"?zu({kind:"structure",userMessage:d.userMessage,plan:d.plan,designSystem:d.designSystem,blueprint:u,sharedCss:m,sharedJs:g??"",startTime:d.startTime,libraryModules:d.libraryModules},n,a):(a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}),ba(d.userMessage,d.plan,n,u,m,g??"",s,o,i,r,a,d.libraryModules,d.startTime,l))}async function ba(e,t,n,s,o,i,r,a,l,c,d,u,m,g){let h=[];if(s)for(let D of s.modules)h.push({name:D.name,description:D.description,contentBrief:D.contentBrief,layoutNotes:D.layoutNotes});else{for(let D of t.newModules)h.push({name:D.name,description:D.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let D of t.affectedModules){let U=n.modules.find(C=>C.moduleName===D);U&&h.push({name:D,description:`Modify existing module: ${D}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:U})}}let f=[],b=[];if(h.length>0){let D=await se("module-development",()=>Js(e,h,o,n.themeName,r,a,l,c,d,t.guidesNeeded,n.brandAssets,t.contentType,g),{metadata:{moduleCount:h.length}});for(let U of D)U.module?f.push(U.module):b.push(U.moduleName)}let S=null;if(f.length>0){S=gn(f,n.themeName,d,t.contentType,n.brandAssets?.brandKit);let D=S.filter(C=>C.issues.some(P=>P.field==="fieldsJson"&&P.message.includes("reset to empty"))).map(C=>C.module.moduleName);if(D.length>0){let C=D.map(P=>h.find(O=>O.name===P)).filter(P=>P!=null);if(C.length>0){T.info("pipeline",`Retrying ${C.length} module(s) with broken fieldsJson: ${C.map(O=>O.name).join(", ")}`),d({type:"agent_decision",step:"quality_check",decision:`Regenerating ${C.length} module(s) with invalid fields JSON...`});let P=await se("module-development-retry",()=>Js(e,C,o,n.themeName,r,a,l,c,d,t.guidesNeeded,n.brandAssets,t.contentType,g),{metadata:{moduleCount:C.length}});for(let O of P)if(O.module){let I=f.findIndex(Q=>Q.moduleName===O.moduleName);I>=0&&(f[I]=O.module)}S=gn(f,n.themeName,d,t.contentType,n.brandAssets?.brandKit)}}f=S.map(C=>C.module);let U=S.reduce((C,P)=>C+P.issues.length,0);if(U>0){let C=S.reduce((O,I)=>O+I.issues.filter(Q=>Q.autoFixed).length,0);T.info("pipeline",`Quality check: ${U} issues, ${C} auto-fixed`);let P=S.flatMap(O=>O.issues).map(O=>`${O.autoFixed?"\u2713":"\u26A0"} ${O.module}: ${O.message}`).join(`
2459
- `);d({type:"agent_decision",step:"quality_check",decision:`${U} issues found, ${C} auto-fixed
2460
- ${P}`})}else d({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let x=sS(n,t,f,s,u),k=oS(n,t,s,x);if(s?.moduleOrder?.length){let D=new Set(s.moduleOrder),U=x.filter(C=>!D.has(C.moduleName)).map(C=>C.moduleName);U.length>0&&d({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${U.length} module${U.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${U.join(", ")}`})}let $=Date.now()-m,L=f.length,j=t.unchangedModules.length,J=S?S.flatMap(D=>D.issues):[],V=iS(t,L,j,b,$,s,J);return b.length>0?d({type:"pipeline_partial",succeeded:f.map(D=>D.moduleName),failed:b,durationMs:$}):d({type:"pipeline_complete",modulesGenerated:L,modulesUnchanged:j,durationMs:$,assistantMessage:V}),{modules:x,moduleOrder:k,sharedCss:o,sharedJs:i,assistantMessage:V,contentType:t.contentType,stats:{modulesGenerated:L,modulesUnchanged:j,modulesFailed:b.length,durationMs:$}}}async function tS(e,t,n,s,o,i,r,a,l,c){let d=t.pages,u=t.sharedModules||["site-header","site-footer"],m=await js(e,t,n,s,o,i,a),g=m.sharedCss||n.sharedCss,h=m.sharedJs||n.sharedJs;a({type:"blueprint_ready",moduleOrder:u,sharedCss:g,sharedJs:h});let f=await fu(e,t,n,g,s,o,i,a);a({type:"agent_step",step:"developing",label:`Generating modules for ${d.length} pages...`});let b=[];for(let I of f.sharedModules)b.push({...I});for(let I of f.pages)for(let Q of I.modules)b.push({name:Q.name,description:Q.description,contentBrief:Q.contentBrief,layoutNotes:Q.layoutNotes});let S=d.map(I=>`- "${I.label}" \u2192 /${I.slug}`).join(`
2461
- `);for(let I of b)(I.name.includes("header")||I.name.includes("nav"))&&(I.layoutNotes+=`
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+=`
2462
2297
 
2463
2298
  ## Site Navigation
2464
2299
  This is a multi-page site. Include navigation links to all pages:
2465
2300
  ${S}
2466
- Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let x=await se("module-development",()=>Js(e,b,g,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType,c),{metadata:{moduleCount:b.length}}),k=[],$=[];for(let I of x)I.module?k.push(I.module):$.push(I.moduleName);let L=k,j=[];if(k.length>0){let I=gn(k,n.themeName,a,t.contentType,n.brandAssets?.brandKit),Q=I.filter(ee=>ee.issues.some(re=>re.field==="fieldsJson"&&re.message.includes("reset to empty"))).map(ee=>ee.module.moduleName);if(Q.length>0){let ee=Q.map(re=>b.find(Z=>Z.name===re)).filter(re=>re!=null);if(ee.length>0){T.info("pipeline",`Retrying ${ee.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${ee.length} module(s) with invalid fields JSON...`});let re=await se("module-development-retry",()=>Js(e,ee,g,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType,c),{metadata:{moduleCount:ee.length}});for(let Z of re)if(Z.module){let ts=k.findIndex(Qg=>Qg.moduleName===Z.moduleName);ts>=0&&(k[ts]=Z.module)}I=gn(k,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}L=I.map(ee=>ee.module),j=I.flatMap(ee=>ee.issues);let et=Nu(L,d.map(ee=>ee.slug));j.push(...et);let Fe=j.length;if(Fe>0){let ee=j.filter(re=>re.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${Fe} issues found, ${ee} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let J=new Map(L.map(I=>[I.moduleName,I])),V=f.sharedModules.map(I=>J.get(I.name)).filter(I=>!!I),D=new Map(d.map(I=>[I.id,I])),U=f.pages.map(I=>{let Q=I.modules.map(Z=>J.get(Z.name)).filter(Z=>!!Z),et=u.filter(Z=>Z.includes("header")||Z.includes("nav")),Fe=u.filter(Z=>Z.includes("footer")),ee=[...et,...I.moduleOrder,...Fe],re=D.get(I.pageId);return{pageId:I.pageId,templateId:I.pageId,label:re?.label||I.pageId,pageType:re?.pageType||"website_page",modules:[...V,...Q],moduleOrder:ee}}),C=Date.now()-l,P=nS(d,k.length,$,C,f.narrative,j);return $.length>0?a({type:"pipeline_partial",succeeded:k.map(I=>I.moduleName),failed:$,durationMs:C}):a({type:"pipeline_complete",modulesGenerated:k.length,modulesUnchanged:0,durationMs:C,assistantMessage:P}),{modules:L,moduleOrder:L.map(I=>I.moduleName),sharedCss:g,sharedJs:h||"",assistantMessage:P,stats:{modulesGenerated:k.length,modulesUnchanged:0,modulesFailed:$.length,durationMs:C},multiPage:{pages:U,sharedModules:V,sharedCss:g,sharedJs:h||"",assistantMessage:P,stats:{pagesGenerated:d.length,modulesGenerated:k.length,modulesFailed:$.length,durationMs:C}}}}function nS(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(`
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(`
2467
2302
 
2468
2303
  **Pages:** ${e.map(d=>d.label).join(", ")}`),o&&a.push(`
2469
2304
 
2470
2305
  ${o}`),n.length>0&&a.push(`
2471
2306
 
2472
- **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(`
2473
2308
 
2474
2309
  ${d.join(`
2475
- `)}`)}return a.join("")}function sS(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 oS(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),T.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 iS(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(`
2476
2311
 
2477
- ${i.narrative}`),s.length>0&&l.push(`
2312
+ ${r.narrative}`),s.length>0&&l.push(`
2478
2313
 
2479
- **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(`
2480
2315
 
2481
2316
  ${u.join(`
2482
- `)}`)}return l.join("")}var Xb,Us,em=R(()=>{"use strict";y();mt();zn();nu();du();hu();Eu();fa();Lu();Gu();Vu();$o();de();He();mt();Xb=6,Us=new Map});var Ws={};We(Ws,{collectThemeFiles:()=>nm,extractDesignContext:()=>dS});import{existsSync as pi,readdirSync as gi,readFileSync as rS}from"fs";import{join as At}from"path";import{spawn as aS}from"child_process";async function tm(){return va||(va=(await import("@anthropic-ai/sdk")).default),va}function Gs(e){try{return rS(e,"utf-8")}catch{return""}}function nm(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
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=`
2483
2318
  ### ${a}
2484
2319
  \`\`\`
2485
2320
  ${l}
2486
2321
  \`\`\`
2487
- `;return n+c.length>lS?!1:(t.push(c),n+=c.length,!0)}let o=Gs(At(e,"theme.json"));o&&s("theme.json",o);let i=At(e,"css");if(pi(i)){for(let a of gi(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,Gs(At(i,a))))break}let r=At(e,"modules");if(pi(r))for(let a of gi(r).filter(l=>l.endsWith(".module"))){let l=At(r,a),c=Gs(At(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(pi(r))for(let a of gi(r).filter(l=>l.endsWith(".module"))){let l=At(r,a),c=Gs(At(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(pi(r))for(let a of gi(r).filter(l=>l.endsWith(".module"))){let l=At(r,a),c=Gs(At(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function cS(){if(!fi)try{fi=M(Cn("extraction-prompt.md"))}catch{fi=""}return fi}function xa(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=aS(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 dS(e,t){t?.({status:"Collecting theme files..."});let n=nm(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=cS();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:
2488
- ${n}`;t?.({status:"Analyzing design patterns..."});let i=N(),r=i.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(r){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 m=await tm(),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=st(h.usage);break}case"claude-oauth":{let{getValidAccessToken:u,OAUTH_EXTRA_HEADERS:m,OAUTH_SYSTEM_PREFIX:g}=await Promise.resolve().then(()=>(It(),er)),h=await u();if(!h)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let f=await tm(),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(x=>x.type==="text"?x.text:"").join(""),c=st(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=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=On(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=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=Fn(g.usageMetadata);break}case"claude-code":{let u=`${s}
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}
2489
2324
 
2490
2325
  ## User Request
2491
- ${o}`,m=["--print"];i.claudeCodeModel&&m.push("--model",i.claudeCodeModel),a=await xa("claude",m,u);break}case"gemini-cli":{let u=`${s}
2326
+ ${o}`,p=["--print"];r.claudeCodeModel&&p.push("--model",r.claudeCodeModel),a=await La("claude",p,u);break}case"gemini-cli":{let u=`${s}
2492
2327
 
2493
2328
  ## User Request
2494
- ${o}`;a=await xa("gemini",[],u);break}case"codex-cli":{let u=`${s}
2329
+ ${o}`;a=await La("gemini",[],u);break}case"codex-cli":{let u=`${s}
2495
2330
 
2496
2331
  ## User Request
2497
- ${o}`;a=await xa("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&&kt({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 va,lS,fi,Ks=R(()=>{"use strict";y();ae();oe();He();an();va=null;lS=8e4;fi=""});var wa={};We(wa,{extractBrandvoice:()=>uS});async function uS(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.
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.
2498
2333
 
2499
2334
  Return a markdown document with these sections (skip any section where the content provides no signal):
2500
2335
 
@@ -2514,7 +2349,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
2514
2349
  ## Dos and Don'ts
2515
2350
  3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
2516
2351
 
2517
- Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await _e(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:(T.info("brandvoice-extractor",`Extracted brand voice (${r.length} chars)`),r.trim())}catch(i){let r=i instanceof Error?i.message:String(i);return T.warn("brandvoice-extractor",`Brand voice extraction failed: ${r}`),null}}var ka=R(()=>{"use strict";y();mt();de()});var hi={};We(hi,{extractThemeContext:()=>mS});async function mS(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.
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.
2518
2353
 
2519
2354
  Return a markdown document with these sections (skip any section where the content provides no information):
2520
2355
 
@@ -2536,10 +2371,10 @@ Specific terms, product names, or branded language used consistently.
2536
2371
  Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
2537
2372
 
2538
2373
  Existing product context (update if the new content adds info, keep what's still accurate):
2539
- ${t}`:""}`;try{let a=await _e(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:(T.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return T.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var yi=R(()=>{"use strict";y();mt();de()});import{join as sm}from"path";function pS(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function bi(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=sm(e.themePath,".vibespot");Ie(o),H(sm(o,s),n)}async function om(e,t){let n=pS(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:ze({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>gS(e,t,n,s))}async function gS(e,t,n,s){let o=fS(t)?t:{...await hS(e),...t??{}};n.includes("styleguide")&&await Ca(e,"styleguide",s,()=>se("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 Ca(e,"brandvoice",s,()=>se("extract-brandvoice",()=>o.extractBrandvoice(e,r))),n.includes("themeContext")&&await Ca(e,"themeContext",s,()=>se("extract-theme-context",()=>o.extractThemeContext(e,r))),s}async function Ca(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}bi(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}),T.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function fS(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function hS(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(Ks(),Ws)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(_s(),si)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(qn(),Aa)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(ka(),wa)),{extractThemeContext:i}=await Promise.resolve().then(()=>(yi(),hi)),r=N();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 Ta=R(()=>{"use strict";y();ae();oe();de();He()});var cm={};We(cm,{runFigmaConversion:()=>yS});import{basename as am}from"path";async function yS(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}=bS(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}=vS(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=Ls(t,d,["hubspot_rules","conversion"],a),b=h?di(t,d,["hubspot_rules","conversion"],a):void 0,S=ri(i),x=m.length,$=(await se("module-development",()=>{let P=m.map((O,I)=>{let Q=e.sections[I];return S(async()=>{r({type:"module_progress",module:O.name,status:"generating",current:I+1,total:x});let et=kS(Q,O,e.assets,t,l!==!1),Fe="";for(let ee=0;ee<2;ee++)try{ee>0&&(T.warn("figma-pipeline",`${O.name}: retrying (attempt ${ee+1})`),r({type:"module_progress",module:O.name,status:"retrying",current:I+1,total:x}));let re=await _e(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:et}],structuredOutput:{schema:Bs,name:"module_output"},maxTokens:16e3});if(re.type!=="structured")throw new Error("No structured output returned");let Z=re.data,ts={moduleName:O.name,fieldsJson:typeof Z.fieldsJson=="string"?Z.fieldsJson:JSON.stringify(Z.fieldsJson,null,2),metaJson:typeof Z.metaJson=="string"?Z.metaJson:JSON.stringify(Z.metaJson,null,2),moduleHtml:String(Z.moduleHtml||""),moduleCss:String(Z.moduleCss||""),moduleJs:Z.moduleJs?String(Z.moduleJs):void 0};return r({type:"module_progress",module:O.name,status:"complete",current:I+1,total:x,moduleFiles:ts}),{moduleName:O.name,module:ts}}catch(re){Fe=re instanceof Error?re.message:String(re),T.error("figma-pipeline",`Failed: ${O.name} (attempt ${ee+1}): ${Fe}`)}return r({type:"module_progress",module:O.name,status:"failed",current:I+1,total:x}),{moduleName:O.name,error:Fe}})});return Promise.allSettled(P)},{metadata:{moduleCount:x}})).map(P=>P.status==="fulfilled"?P.value:{moduleName:"unknown",error:String(P.reason)}),L=$.filter(P=>P.module).map(P=>P.module),j=$.filter(P=>P.error).map(P=>P.moduleName),V=gn(L,t,r).map(P=>P.module),D=Date.now()-c,U=Math.round(D/1e3),C=`Imported ${V.length} modules from Figma design "${e.fileName}" in ${U}s.`;return j.length>0?r({type:"pipeline_partial",succeeded:V.map(P=>P.moduleName),failed:j,durationMs:D}):r({type:"pipeline_complete",modulesGenerated:V.length,modulesUnchanged:0,durationMs:D,assistantMessage:C}),{modules:V,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:C,stats:{modulesGenerated:V.length,modulesUnchanged:0,modulesFailed:j.length,durationMs:D}}}function Si(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 bS(e,t){let n=[],s=t,o=[...e.colors].sort((C,P)=>P.occurrences-C.occurrences),i=o.filter(C=>C.usage==="background"||C.usage==="fill"),r=o.filter(C=>C.usage==="text"),a=i[0]||o[0],l=a?Si(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(C=>Si(C.hex).l>.7):o.find(C=>Si(C.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(C=>!d.has(C.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(C=>!d.has(C.hex)).slice(0,6).forEach((C,P)=>n.push(` --${s}-color-${P+1}: ${C.hex}`)),a){let C=Si(a.hex).l;n.push(` --${s}-color-surface: ${l?im(a.hex,.05):rm(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?im(a.hex,.15):rm(a.hex,.12)}`)}let g=e.typography.filter(C=>C.role==="heading"||C.role==="subheading"),h=e.typography.filter(C=>C.role==="body"||C.role==="label"||C.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((C,P)=>P.fontSize-C.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 x=h.sort((C,P)=>P.occurrences-C.occurrences)[0];x&&n.push(` --${s}-size-body: ${x.fontSize}px`);let k=[...new Set(e.spacing.map(C=>C.value))].sort((C,P)=>C-P),$=["xs","sm","md","lg","xl","2xl","section"];k.slice(0,$.length).forEach((C,P)=>{n.push(` --${s}-space-${$[P]}: ${C}px`)});let L=e.effects.filter(C=>C.type==="shadow"),j=e.effects.filter(C=>C.type==="radius");L[0]&&n.push(` --${s}-shadow: ${L[0].cssValue}`),j.sort((C,P)=>parseFloat(C.cssValue)-parseFloat(P.cssValue)),j[0]&&n.push(` --${s}-radius: ${j[0].cssValue}`),j[1]&&n.push(` --${s}-radius-lg: ${j[1].cssValue}`);let J=`:root {
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 {
2540
2375
  ${n.join(`;
2541
2376
  `)};
2542
- }`,V=`
2377
+ }`,O=`
2543
2378
  /* Reset */
2544
2379
  *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
2545
2380
 
@@ -2624,7 +2459,7 @@ body {
2624
2459
  h2 { font-size: 1.5rem; }
2625
2460
  h3 { font-size: 1.25rem; }
2626
2461
  }`;return{sharedCss:J+`
2627
- `+V,sharedJs:`(function() {
2462
+ `+O,sharedJs:`(function() {
2628
2463
  var observer = new IntersectionObserver(function(entries) {
2629
2464
  entries.forEach(function(entry) {
2630
2465
  if (entry.isIntersecting) {
@@ -2634,11 +2469,11 @@ body {
2634
2469
  });
2635
2470
  }, { threshold: 0.1 });
2636
2471
  document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
2637
- })();`}}function im(e,t){return lm(e,t)}function rm(e,t){return lm(e,-t)}function lm(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 SS(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function vS(e,t,n){let s=new Set,o=[];for(let i of e){let r=SS(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=xS(i.textContent),l=wS(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 xS(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(`
2638
- `)}function wS(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(`
2639
- 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(`
2640
- Available image assets:`);for(let o of t){let i=am(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
2641
- `)}function kS(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
2642
2477
 
2643
2478
  TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
2644
2479
  - Use the EXACT text content from the design as field default values
@@ -2658,17 +2493,17 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
2658
2493
  - Hide purely decorative elements if they break mobile layout
2659
2494
  - Add a \`@media (max-width: 1023px)\` block for tablet if the layout has 3+ columns
2660
2495
 
2661
- ## Section: "${e.name}" (${e.width}x${e.height}px)`),e.backgroundColor&&i.push(`Background: ${e.backgroundColor}`),(e.layoutMode||e.itemSpacing||e.paddingTop)&&(i.push(`
2662
- ### 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(`
2663
- ### 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(`
2664
- ### 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+=`
2665
- text: "${r.characters.slice(0,100)}"`),i.push(a)}}if(n.length>0)if(o){i.push(`
2666
- ### 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=am(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
2667
- ### 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(`
2668
2503
  ## Module Specification
2669
2504
  - **Name**: ${t.name}
2670
- - **Description**: ${t.description}`),i.join(`
2671
- `)}var dm=R(()=>{"use strict";y();mt();zn();ma();fa();de();He()});var um={};We(um,{buildPlanModePrompt:()=>CS});function CS(e,t,n,s,o){let i=TS(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}".
2672
2507
 
2673
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.
2674
2509
 
@@ -2732,47 +2567,47 @@ Drive toward filling these gaps in priority order:
2732
2567
  4. **Sections / modules** \u2014 high-level page structure (hero, features, testimonials, pricing, FAQ, footer, etc.)
2733
2568
  5. **Content** \u2014 actual copy, value props, social proof, key messages
2734
2569
  6. **Brand voice and visual style** \u2014 formal/casual, palette preferences, reference sites
2735
- 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
2736
2571
 
2737
2572
  The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
2738
2573
 
2739
2574
  \`\`\`
2740
- ${_a(t.styleguide,1500)}
2741
- \`\`\``),t?.brandvoice&&r.push(`## Available brand voice
2575
+ ${Wa(t.styleguide,1500)}
2576
+ \`\`\``),t?.brandvoice&&i.push(`## Available brand voice
2742
2577
 
2743
2578
  \`\`\`
2744
- ${_a(t.brandvoice,1e3)}
2745
- \`\`\``),t?.themeContext&&r.push(`## Theme context
2579
+ ${Wa(t.brandvoice,1e3)}
2580
+ \`\`\``),t?.themeContext&&i.push(`## Theme context
2746
2581
 
2747
2582
  \`\`\`
2748
- ${_a(t.themeContext,1e3)}
2749
- \`\`\``),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
2750
2585
 
2751
2586
  These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
2752
2587
 
2753
2588
  ${n.map(a=>`- ${a}`).join(`
2754
- `)}`),s.length>0&&r.push(`## Module library (reusable across templates)
2589
+ `)}`),s.length>0&&i.push(`## Module library (reusable across templates)
2755
2590
 
2756
2591
  These modules exist in other templates and could be reused here. Reference them by name in the plan if appropriate.
2757
2592
 
2758
2593
  ${s.map(a=>`- **${a.name}** (used in: ${a.usedIn.join(", ")})`).join(`
2759
- `)}`),t?.plan&&r.push(`## Current plan (continue refining)
2594
+ `)}`),t?.plan&&i.push(`## Current plan (continue refining)
2760
2595
 
2761
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.
2762
2597
 
2763
2598
  \`\`\`markdown
2764
2599
  ${t.plan}
2765
- \`\`\``),r.push(`## Phase guidance for this turn
2600
+ \`\`\``),i.push(`## Phase guidance for this turn
2766
2601
 
2767
- ${i}`),r.join(`
2602
+ ${r}`),i.join(`
2768
2603
 
2769
- `)}function TS(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:
2770
2605
  - Briefly acknowledge the template and that you'll work from this structure (1\u20132 sentences in chat).
2771
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.
2772
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.
2773
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.
2774
- - 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 _a(e,t){return e.length<=t?e:e.slice(0,t)+`
2775
- ... [truncated]`}var mm=R(()=>{"use strict";y()});var Aa={};We(Aa,{applyPipelineResult:()=>yn,cancelActiveGeneration:()=>Ma,handleAgenticGenerate:()=>vi,handleAgenticResume:()=>Oa,handleFigmaImport:()=>Ys,handleGenerate:()=>_S,handleGenerateStream:()=>zs,handlePlanModeStream:()=>Fa,isGenerating:()=>$t,isPlanModeActive:()=>Da,resolveAgenticEngine:()=>hn,setParseWarningCallback:()=>Ea,shouldUseAgenticMode:()=>ja});import{execSync as $a}from"child_process";function Ea(e){Pa=e}function $t(){return gt!==null}function pm(){let e={id:++AS,abort:new AbortController};return Vs=e,{run:e,signal:e.abort.signal}}function gm(e){Vs===e&&(Vs=null)}function Ma(){return Vs?(Vs.abort.abort(),!0):!1}function _t(e){if(gt){let t=w();if(!t||t.id!==gt){T.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}dt("assistant",e),Td(e,Pa||void 0),F()}async function zs(e,t,n,s){let o=w();if(!o)throw new Error("No active session");gt=o.id;let r=s?.length?ii(s):void 0;try{let a=N(),l=a.aiEngine||Ia();switch(l){case"anthropic-api":case"api":{let c=De("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await Hr(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,_t,r);break}case"claude-oauth":{await Od(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,_t,r);break}case"openai-api":{let c=De("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await Ur(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,_t,r);break}case"gemini-api":{let c=De("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await Gr(e,c,o.themeName,t,n,_t,r);break}case"claude-code":await Fd(e,o.themeName,t,n,_t,r);break;case"gemini-cli":await zr("gemini",e,o.themeName,t,n,_t,r);break;case"codex-cli":await zr("codex",e,o.themeName,t,n,_t,r);break;case"langdock-api":{let c=De("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 Ur(e,c,o.themeName,g||"gpt-4.1",t,n,_t,r,`${m}/v1/chat/completions`);break;case"google":await Gr(e,c,o.themeName,t,n,_t,r,`${m}/v1beta/models/${g||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,g);break;default:await Hr(e,c,o.themeName,g||"claude-sonnet-4-6",t,n,_t,r,m);break}break}default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{gt=null,Pa=null}}function Ia(){let e=N();if(tt())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 $a("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return $a("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return $a("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function _S(e){let t="";return await zs(e,n=>{t+=n}),t}function Ra(){let e=w(),t=Te(),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 hn(e){let t=e.aiEngine||Ia();if(!Fs(t))throw new Error("Agentic pipeline is not available for this engine.");if(Yn(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!tt())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 Na(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 vi(e,t,n,s=!1){let o=w();if(!o)throw new Error("No active session");let i=o.id;gt=i;let{run:r,signal:a}=pm();try{let l=N(),{engine:c,apiKey:d,model:u}=hn(l),m=l.agenticConcurrency||20,g=Ra(),h=g.brandAssets?.plan,f=e;h&&h.trim()&&(f=`## 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
2776
2611
 
2777
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.
2778
2613
 
@@ -2782,65 +2617,26 @@ ${h}
2782
2617
 
2783
2618
  ## User message
2784
2619
 
2785
- ${e}`);let b=n?.length?ii(n):void 0;if(b?.length)for(let J of b)J.type==="document"&&J.extractedText&&(f+=`
2620
+ ${e}`);let S=n?.length?vr(n):void 0;if(S?.length)for(let O of S)O.type==="document"&&O.extractedText&&(b+=`
2786
2621
 
2787
2622
  ---
2788
- [Attached document: ${J.originalName}]
2789
- ${J.extractedText}`),J.type==="image"&&J.usage==="asset"&&J.assetPath&&(f+=`
2623
+ [Attached document: ${O.originalName}]
2624
+ ${O.extractedText}`),O.type==="image"&&O.usage==="asset"&&O.assetPath&&(b+=`
2790
2625
 
2791
- [Uploaded image: ${J.originalName} \u2192 available as get_asset_url("${J.assetPath}")]`);let S=Lt(),x=new Set(g.modules.map(J=>J.moduleName)),k=S.filter(J=>!x.has(J.module.moduleName)).map(J=>({name:J.module.moduleName,usedIn:J.usedIn})),{result:$,cost:L}=await _o(()=>ze({name:"agent_pipeline",sessionId:g.themeName,input:e,metadata:{engine:c,model:u,concurrency:m},tags:["vibespot","agentic-pipeline"]},async()=>{let J=await Xu(f,g,c,d,u,m,t,k,s,a);return Eo(Na(J)),J})).catch(J=>{if(Rs(J))return T.info("ai-handler","Agentic run cancelled (barge-in)"),{result:fm(g),cost:void 0};throw J});if($.cost=L,$.canceled)return $;let j=w();if(!j||j.id!==i)throw T.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return $}finally{gt=null,gm(r)}}function fm(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 Oa(e,t,n,s){let o=w();if(!o)throw new Error("No active session");let i=o.id;gt=i;let{run:r,signal:a}=pm();try{let l=N(),{engine:c,apiKey:d,model:u}=hn(l),m=l.agenticConcurrency||20,g=Ra(),{result:h,cost:f}=await _o(()=>ze({name:"agent_pipeline_resume",sessionId:g.themeName,input:{action:t.action,kind:t.kind},metadata:{engine:c,model:u,concurrency:m},tags:["vibespot","agentic-pipeline","checkpoint-resume"]},async()=>{let S=await Qu(e,t,g,c,d,u,m,n,a,s);return Eo(Na(S)),S})).catch(S=>{if(Rs(S))return T.info("ai-handler","Checkpoint resume cancelled (barge-in)"),{result:fm(g),cost:void 0};throw S});if(h.cost=f,h.canceled)return h;let b=w();if(!b||b.id!==i)throw T.warn("ai-handler","Session changed during checkpoint resume \u2014 discarding output"),new Error("Session changed during generation");return h.brandAssetsUpdate&&(h.brandAssetsUpdate.styleguide&&bi(b,"styleguide",h.brandAssetsUpdate.styleguide),h.brandAssetsUpdate.brandvoice&&bi(b,"brandvoice",h.brandAssetsUpdate.brandvoice),F()),h}finally{gt=null,gm(r)}}async function Ys(e,t,n,s){let o=w();if(!o)throw new Error("No active session");let i=o.id;gt=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(dm(),cm)),a=N(),{engine:l,apiKey:c,model:d}=hn(a),u=a.agenticConcurrency||20,m=Ra(),{result:g,cost:h}=await _o(()=>ze({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 Eo(Na(b)),b}));g.cost=h;let f=w();if(!f||f.id!==i)throw T.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{gt=null}}function yn(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"});Kc({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(Ue({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Vt(e.moduleOrder),e.contentType==="email"){let o=Te();o&&!o.contentMode&&(o.contentMode="email")}t?.cost&&Jc(t.cost),dt("assistant",e.assistantMessage,t),F()}async function Fa(e,t,n){let s=w();if(!s)throw new Error("No active session");let o=N(),{engine:i,apiKey:r,model:a}=hn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(mm(),um)),Promise.resolve().then(()=>(mt(),Vd))]),d=s.messages.filter(k=>k.role==="assistant").length,u=s.modules.map(k=>k.moduleName),m=Lt(),g=new Set(u),h=m.filter(k=>!g.has(k.module.moduleName)).map(k=>({name:k.module.moduleName,usedIn:k.usedIn})),f=l(s.themeName,s.brandAssets,u,h,d),b=n?.length?ii(n):void 0,S=e;if(b?.length)for(let k of b)k.type==="document"&&k.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+=`
2792
2627
 
2793
2628
  ---
2794
2629
  [Attached document: ${k.originalName}]
2795
- ${k.extractedText}`);let x=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return x.type==="text"?x.text:JSON.stringify(x.data)}function Da(){return!!N().planMode}function ja(){let e=N(),t=e.aiEngine||Ia();return Fs(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 Pa,gt,Vs,AS,qn=R(()=>{"use strict";y();oe();Ce();oi();de();$o();Yr();It();Zr();em();Ta();zn();He();Pa=null;gt=null;Vs=null,AS=0});import{readFileSync as $S,readdirSync as PS,existsSync as ES}from"fs";import{dirname as MS,join as xi}from"path";import{fileURLToPath as IS}from"url";function NS(e){let t=e.match(RS);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 OS(e){let t=NS(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()+`
2796
- `}}function FS(){let e=[xi(hm,"../../assets/plan-templates"),xi(hm,"../assets/plan-templates"),xi(process.cwd(),"assets/plan-templates")];for(let t of e)if(ES(t))return t;return null}function ym(){if(Zt)return Zt;let e=FS();if(!e)return Zt=[],Zt;let t=[],n=[];try{n=PS(e)}catch{return Zt=[],Zt}for(let s of n)if(s.endsWith(".md"))try{let o=$S(xi(e,s),"utf-8"),i=OS(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),Zt=t,Zt}function bm(e){return ym().find(t=>t.id===e)??null}function Sm(){return ym().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 hm,RS,Zt,vm=R(()=>{"use strict";y();hm=MS(IS(import.meta.url)),RS=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;Zt=null});import{existsSync as xm,mkdirSync as DS,writeFileSync as jS,rmSync as LS}from"fs";import{join as wm}from"path";function km(e){return wm(e,".vibespot",BS)}function wi(e){let t=w();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=Te();n&&(n.plan=e);try{let s=wm(t.themePath,".vibespot");xm(s)||DS(s,{recursive:!0}),jS(km(t.themePath),e,"utf-8")}catch(s){T.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return F(),e}function La(){let e=w();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=Te();t&&delete t.plan;try{let n=km(e.themePath);xm(n)&&LS(n)}catch(n){T.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}F()}function Cm(e,t){Ze(e,t,n=>{if(!w()){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}wi(o),p(t,200,{ok:!0,plan:o})})}function Tm(e,t){Ze(e,t,()=>{La(),q({planMode:!1}),p(t,200,{ok:!0})})}function Am(e,t){p(t,200,{templates:Sm()})}function _m(e,t){Ze(e,t,n=>{if(!w()){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=bm(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}wi(i.body),q({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var BS,$m=R(()=>{"use strict";y();Qe();Ce();zt();oe();de();vm();BS="plan.md"});function Pm(e){let t,n,s;for(Ba.lastIndex=0;(s=Ba.exec(e))!==null;)t=s[1].trim();let o;for(Ja.lastIndex=0;(o=Ja.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(Ba,"").replace(Ja,"").replace(/\n{3,}/g,`
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)}
2797
2631
 
2798
- `).trim(),plan:t,choices:n}}var Ba,Ja,Em=R(()=>{"use strict";y();Ba=/```vibespot-plan\s*\n([\s\S]*?)```/g,Ja=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as Ha}from"child_process";function Mm(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+=`
2799
- Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
2800
- Process timed out`,t.completedAt=Date.now())},n||3e5)}function qs(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};Qt.set(o,i);let r=Ha(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()),Mm(r,i,s?.timeout),o}function bn(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};Qt.set(s,o);let i=e.split(" "),r=Ha(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Mm(r,o,n?.timeout),s}function ki(e){return Qt.get(e)}function JS(){let e=Date.now()-18e5;for(let[t,n]of Qt)n.completedAt&&n.completedAt<e&&Qt.delete(t)}function Ci(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};Qt.set(s,o);let i=e.split(" "),r=Ha(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+=`
2801
- 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+=`
2802
- Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Im(e,t){let n=Qt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Rm(e,t){let n=Qt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var Qt,Ti=R(()=>{"use strict";y();Qt=new Map;setInterval(JS,600*1e3)});import{readFileSync as HS,readdirSync as US,existsSync as GS}from"fs";import{dirname as WS,join as Ai}from"path";import{fileURLToPath as KS}from"url";function VS(){let e=[Ai(Nm,"../../starters"),Ai(Nm,"../starters"),Ai(process.cwd(),"starters")];for(let t of e)if(GS(t))return t;return null}function Om(){if(Xn!==null)return Xn;let e=VS();if(!e)return Xn=[],Xn;let t=[];for(let n of US(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse(HS(Ai(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 Xn=t,Xn}function Fm(){return Om().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function Ua(e){return Om().find(t=>t.id===e)||null}var Nm,Xn,Dm=R(()=>{"use strict";y();Nm=WS(KS(import.meta.url)),Xn=null});import{existsSync as Zn,readdirSync as jm,rmSync as zS,writeFileSync as Sn,mkdirSync as _i}from"fs";import{join as Me,basename as YS}from"path";import{homedir as qS}from"os";import{execFileSync as Bm}from"child_process";function Pi(){if($i&&Date.now()-$i.ts<XS)return $i.data;let e=[];if(Zn(ft))try{for(let t of jm(ft,{withFileTypes:!0}))if(t.isDirectory()){let n=Me(ft,t.name,"theme.json");if(Zn(n)){let s=0,o=Me(ft,t.name,"modules");if(Zn(o))try{s=jm(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return $i={data:e,ts:Date.now()},e}function Hm(e){let t=w(),n=ho(),s=!1;try{Bm("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Jm}),s=!0}catch{}let o=Hn().sort((r,a)=>a.updatedAt-r.updatedAt),i=Pi();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:Wn()})}function Um(e,t){K(e,n=>{try{if($t()){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=Me(ft,r);if(Ie(ft),Zn(a)&&zS(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!Ua(o)){p(t,400,{error:`Starter template "${o}" not found`});return}ds(a,r),Jn(a,r),o&&typeof o=="string"?(ZS(a,r,o),Ae()):i==="email"&&(jt("module_only","Email","email"),Nn(a,r)),F(),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 ZS(e,t,n){let s=Ua(n);if(!s)return;let o=w();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&&Nn(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Me(e,"modules");_i(d,{recursive:!0});for(let u of s.modules){let m=Me(d,`${u.moduleName}.module`);_i(m,{recursive:!0}),Sn(Me(m,"fields.json"),u.fieldsJson,"utf-8"),Sn(Me(m,"meta.json"),u.metaJson,"utf-8"),Sn(Me(m,"module.html"),u.moduleHtml,"utf-8"),Sn(Me(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&Sn(Me(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Me(e,"css");_i(u,{recursive:!0}),Sn(Me(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Me(e,"js");_i(u,{recursive:!0}),Sn(Me(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function Gm(e){p(e,200,{starters:Fm()})}function Wm(e,t){K(e,n=>{try{if($t()){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=Be(),r=N(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Me(ft,a);Ie(ft),r.hubspotUploadMode==="cli"||!i?(async()=>{Bm("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Jm});let c=await Lm(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)})}):ms(i,o,l).then(async()=>{let c=await Lm(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 Lm(e,t){Jn(e,t,{isImported:!0}),ni(e),F();let n=w(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await om(n),F()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function Km(e,t){K(e,n=>{try{if($t()){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=Me(ft,s)),!Zn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=YS(o);Jn(o,i),ni(o),F(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:w()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Vm(e,t){K(e,n=>{try{if($t()){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=Xo(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 zm(e,t){K(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}q({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Ym(e){let t=Be();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Rl(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 So(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=Pi(),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 Jm,ft,$i,XS,Ei=R(()=>{"use strict";y();Qe();oe();us();ko();rn();Ce();zt();qn();on();oe();ae();Dm();$s();Ta();Jm=process.platform==="win32"?{shell:!0}:{},ft=Me(qS(),"vibespot-themes"),$i=null,XS=5e3});import{existsSync as QS,readFileSync as ev,appendFileSync as tv}from"fs";import{join as qm}from"path";import{homedir as Xm}from"os";function ov(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 Wa(e,t={},n=np){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function iv(e){let t=await Wa("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 rv(e){let t=await Wa("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function Qm(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:ov(n)}))}async function av(e){let t=await Wa(`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 lv(e=!1){if(!e&&Date.now()-Qn.ts<nv&&Object.keys(Qn.data).length>0)return Qn.data;let t=N(),n={...Ga},s=[],o=De("anthropic-api",t);o&&s.push(iv(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c,n["claude-code"]=c)}).catch(()=>{}));let i=De("openai-api",t);i&&s.push(rv(i).then(c=>{if(!c.length)return;let d=Qm(c,tp);d.length&&(n["openai-api"]=d);let u=Qm(c,sv);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let r=De("gemini-api",t);r&&s.push(av(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,np+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=Zm[l]||Zm.anthropic,a&&(Qn.data=n,Qn.ts=Date.now()),n}function sp(e){let t=Al(),n=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};p(e,200,{version:Tn(),environment:t,config:s,models:Ga,sessionCount:Hn().length,localThemeCount:Pi().length})}function op(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");lv(n).then(s=>p(t,200,{models:s})).catch(()=>p(t,200,{models:Ga}))}function ip(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=ep[o];if(!i&&Date.now()-r.ts<cv&&Object.keys(r.data).length>0){p(t,200,{...r.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=_l();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:$l()};else{let l=ho();a={tools:l.tools,availableEngines:l.availableEngines}}ep[o]={data:a,ts:Date.now()},p(t,200,{...a,group:o,cached:!1})}function rp(e,t){K(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}q(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function ap(e,t){K(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}q(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}q(i);let r=null;if(!N().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(q({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 lp(e,t){K(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=bn(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 cp(e,t){K(e,n=>{try{let s=JSON.parse(n||"{}"),o=N(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){bo(s.personalAccessKey).then(r=>{ns(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(!St().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=qs("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(!St().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=vt();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 dp(e,t){K(e,n=>{try{let s=JSON.parse(n||"{}");if(!po().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=go();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=qs("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=bn("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 up(e,t){K(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((N().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Yi(s),p(t,200,{ok:!0});return}if(s){qi(s),p(t,200,{ok:!0});return}}else{if(!St().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=qs("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=qs("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 mp(e){let t=bn("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function pp(e,t){K(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=bn("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=bn("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,q({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")?qm(Xm(),".zshrc"):qm(Xm(),".bashrc");try{(QS(l)?ev(l,"utf-8"):"").includes("OPENAI_API_KEY")||tv(l,`
2803
- # Added by vibeSpot
2804
- ${a}
2805
- `)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=bn("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 gp(e,t){K(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}q({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function fp(e,t){K(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}Xi(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 hp(e,t){K(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]||"",Qn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}q(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function yp(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=ki(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 Qn,nv,Ga,Zm,tp,sv,np,cv,ep,bp=R(()=>{"use strict";y();Qe();oe();Ce();Ei();on();rn();ae();Ti();Qn={data:{},ts:0},nv=600*1e3,Ga={"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"}]},Zm={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"}]},tp=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,sv=tp;np=2500;cv=60*1e3,ep={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}}});function Sp(e,t){K(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}Zi(s.trim(),(o||"").trim());let i=N();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&q({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function vp(e,t){let n=tt(),s=nn();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function xp(e,t){try{lo(),N().aiEngine==="claude-oauth"&&q({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var wp=R(()=>{"use strict";y();Qe();oe();It()});import{existsSync as dv,rmSync as uv}from"fs";import{join as mv}from"path";function kp(e,t,n){if(e==="GET"){let s=w(),o=Hn().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"){K(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);td(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 Cp(e,t){K(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=Xo(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 Tp(e,t){K(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=mv(ft,s);if(!dv(o)){p(t,404,{error:"Theme not found on disk"});return}uv(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Ap(e,t){K(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=nd(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 _p(e,t){K(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=sd(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 $p=R(()=>{"use strict";y();Qe();Ce();Ei()});import{existsSync as Mi,readFileSync as pv,readdirSync as gv,rmSync as Rp}from"fs";import{join as Ne,basename as fv,relative as hv,sep as yv}from"path";import bv from"jszip";function Np(e){let t=w();if(!t){p(e,404,{error:"No active session"});return}let n=Lt();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 Op(e,t=[]){for(let n of gv(e,{withFileTypes:!0}))if(n.isDirectory()){if(Sv.has(n.name))continue;Op(Ne(e,n.name),t)}else n.isFile()&&t.push(Ne(e,n.name));return t}async function Fp(e){let t=w();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!Mi(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=fv(n);try{let i=new bv;for(let a of Op(n)){let l=Ne(o,hv(n,a)).split(yv).join("/");i.file(l,pv(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){T.error("download-zip","Failed to create zip archive",i),p(e,500,{error:"Failed to create zip archive"})}}function Dp(e,t,n){let s=w();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"){K(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=jt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&Nn(s.themePath,s.themeName),F(),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"){K(t,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Xc(i,!!r)){p(n,404,{error:"Template not found"});return}F(),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 jp(e,t){K(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!vs(s)){p(t,404,{error:"Template not found"});return}F();let i=w();p(t,200,{ok:!0,modules:xe().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Lp(e,t){K(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(!qc(s,o.trim())){p(t,404,{error:"Template not found"});return}F(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Bp(e,t){K(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(!Yc(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}F(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Jp(e,t){K(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=zc(s,o);if(!i){p(t,404,{error:"Template not found"});return}F(),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 Hp(e){let t=Lt();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Up(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}K(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=Lt().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()),F(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function Gp(e,t,n){let s=w();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"){K(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(),F(),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=Ne(s.themePath,".vibespot");Ie(c),H(Ne(c,l),r);let d=null;a==="styleguide"&&(d=Ka(s,r)),F(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){K(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=Ne(s.themePath,".vibespot",a);Mi(l)&&Rp(l),F(),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 Kp(e,t){p(t,200,Wp)}function xv(e){let t=[],n=[],s=e.split(`
2806
- `),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(vv);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Pp.exec(a);if(Pp.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 Ka(e,t){let{colors:n,fonts:s}=xv(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=Wp.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=Ne(e.themePath,".vibespot");return Ie(i),H(Ne(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function Vp(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){K(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"&&wv.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=Ne(s.themePath,".vibespot");Ie(a),H(Ne(a,"brand-kit.json"),JSON.stringify(r,null,2)),F(),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=Ne(s.themePath,".vibespot","brand-kit.json");Mi(o)&&Rp(o),F(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Ep(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=Ne(e.themePath,".vibespot");Ie(o),H(Ne(o,s),n)}function Mp(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function Ip(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Ks(),Ws));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(qn(),Aa)),{loadConfig:o}=await Promise.resolve().then(()=>(oe(),vl)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(_s(),si)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(ka(),wa));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(yi(),hi));return u(d,e.brandAssets?.themeContext,r,a,l)}function zp(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}K(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 ze({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>se(Mp(g),()=>Ip(n,g,r))))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Ep(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=Ka(n,u.styleguide)),F(),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 ze({name:"brand_extract",sessionId:n.themeName,metadata:{type:i},tags:["vibespot","brand-extract"]},()=>se(Mp(i),()=>Ip(n,i,r)));if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Ep(n,i,a);let l=null;i==="styleguide"&&(l=Ka(n,a)),F(),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 Yp(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}K(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=Be();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=Ne(h(),"vibespot-themes",".references",g);Ie(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(ko(),Jl));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(!Mi(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(()=>(Ks(),Ws)),c=await ze({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>se("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ne(n.themePath,".vibespot");Ie(d),H(Ne(d,"styleguide.md"),c),F(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var Sv,Wp,vv,Pp,wv,qp=R(()=>{"use strict";y();Qe();de();He();oe();us();Ce();ae();Sv=new Set([".git",".vibespot","node_modules"]);Wp=[{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"}];vv=/#[0-9a-fA-F]{6}\b/g,Pp=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;wv=/^#[0-9a-fA-F]{6}$/});import{join as kv}from"path";function Xp(e,t){let n=w();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 Zp(e,t,n){let s=w();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=xe();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"){Ze(t,n,o=>{o.deleteEntirely?Hc(o.moduleName):Uc(o.moduleName),F(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function Qp(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}K(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=Te();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),ct(),F(),Ae(),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(),ct(),F(),Ae(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function eg(e,t){Ze(e,t,n=>{Array.isArray(n.order)?(Vt(n.order),F(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function tg(e){let t=w();if(!t){p(e,404,{error:"No active session"});return}try{Ae();let n=Lo(t.themePath),s=Ci(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:kv(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function ng(e,t){K(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Gc(s,o,i),F(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function sg(e,t){K(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=jl(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
2807
- `),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.
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)}
2808
2634
 
2809
- Source analysis found ${o.components.length} components:
2810
- ${i}
2811
-
2812
- Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CSS variables
2813
- Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
2814
- Interactions: ${o.interactions.join(", ")}
2815
-
2816
- 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 og(e,t){let n=w();if(!n){p(t,404,{error:"No active session"});return}if(!lt()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?Oc(n.themePath,o,50):Nc(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function ig(e,t){K(e,n=>{try{let s=w();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(dt("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=Dc(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}gd()}else{let r=Fc(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}pd()}F(),p(t,200,{ok:!0,modules:xe().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var rg=R(()=>{"use strict";y();Qe();Ce();Bo();Ti();wo();jn()});import{writeFileSync as Cv,mkdirSync as lg}from"fs";import{join as Ii}from"path";import{randomUUID as Tv}from"crypto";function cg(e){let t=e.match(Av);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 Ni(e,t){let n=await fetch(`${_v}${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 za(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=ag.length)throw s;let r=ag[n];T.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 vn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)vn(s,t,n+1)}function dg(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=dg(n,t);if(s)return s}return null}function $v(e,t){if(t){let s=dg(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>Va.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>Va.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>Va.has(s.type)):[]}function Ri(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 Pv(e){let t=new Map;for(let n of e)vn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=Ri(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=Ri(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 Ev(e){let t=new Map;for(let n of e)vn(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 Mv(e){let t=[],n=new Set;for(let s of e)vn(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 Iv(e){let t=[],n=new Set;for(let s of e)vn(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 Rv(e,t){let n=[];return vn(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 Nv(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 Ov(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return Ri(t.color)}if(e.backgroundColor)return Ri(e.backgroundColor)}function Fv(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:Rv(t,t.name),children:(t.children||[]).slice(0,20).map(Nv),backgroundColor:Ov(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 Dv(e){let t=[];for(let n of e)vn(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 ug(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());Cv(t,s)}async function jv(e,t,n,s,o){if(t.length===0)return new Map;lg(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await za(()=>Ni(`/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=Ii(s,`frame-${u}.png`);try{await ug(d,m),l.set(c,m),T.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){T.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function Lv(e,t,n,s,o){if(t.length===0)return[];lg(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 za(()=>Ni(`/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()}-${Tv().slice(0,6)}.png`,f=Ii(s,h);try{await ug(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),T.info("figma",`Downloaded asset: ${h}`)}catch(b){T.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function mg(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 za(()=>Ni(i,n),o);T.info("figma",`Fetched file: ${r.name}`);let a=$v(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.");T.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:Pv(a),typography:Ev(a),spacing:Mv(a),effects:Iv(a)};T.info("figma","Design tokens extracted",{colors:l.colors.length,typography:l.typography.length,spacing:l.spacing.length,effects:l.effects.length}),o&&o("Mapping page structure...");let c=Fv(a),d=Ii(s,".vibespot","figma-frames"),u=await jv(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=Dv(a),h=Ii(s,"assets"),f=await Lv(e,g,n,h,o);return T.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 pg(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 gg(e){return await Ni("/v1/me",e)}var Av,_v,ag,Va,fg=R(()=>{"use strict";y();de();Av=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;_v="https://api.figma.com",ag=[10,20,40,60,120];Va=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var xg={};We(xg,{getCachedExtraction:()=>vg,handleFigmaExtractRoute:()=>qa,handleFigmaGenerateRoute:()=>Xa,handleFigmaTestTokenRoute:()=>Ya});import{randomUUID as hg}from"crypto";import{existsSync as yg,mkdirSync as bg,writeFileSync as Bv,copyFileSync as Jv}from"fs";import{join as Oi,basename as Hv}from"path";function Sg(){let e=Date.now();for(let[t,n]of Xs)n.expires<e&&Xs.delete(t)}function vg(e){Sg();let t=Xs.get(e);return t?(Xs.delete(e),t.extraction):null}function Ya(e,t){Ze(e,t,async n=>{let s=n.token||N().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await gg(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);T.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function qa(e,t){Ze(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||N().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=cg(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=w()?.themePath||`/tmp/vibespot-figma-${hg().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)}
2817
-
2818
- `)};try{let c=await mg(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=hg();Sg(),Xs.set(d,{extraction:c,expires:Date.now()+Uv});let u=pg(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);T.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function Gv(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(`
2819
- `)}function Xa(e,t){Ze(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=vg(s);if(!r){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=w();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)}
2820
-
2821
- `)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=Gv(r),d=Oi(a.themePath,".vibespot");if(yg(d)||bg(d,{recursive:!0}),Bv(Oi(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,F(),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 f=a.templates.find(b=>b.id===a.activeTemplateId);f&&(f.modules=[],f.moduleOrder=[],f.sharedCss="",f.sharedJs="")}if(F(),i&&r.assets.length>0){let f=Oi(a.themePath,"assets");bg(f,{recursive:!0});let b=0;for(let S of r.assets)if(yg(S.localPath)){let x=Oi(f,Hv(S.localPath));try{Jv(S.localPath,x),S.localPath=x,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 Ys(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"?Ue({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(Ue({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Vt(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?(Ue({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});yn(g,{steps:u,modules:m,stats:g.stats}),Ae(),ln(a.themePath,`Figma import: ${r.fileName}`);let h=xe().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);T.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Xs,Uv,Za=R(()=>{"use strict";y();Qe();oe();de();fg();Ce();Ss();Er();jn();qn();zt();Xs=new Map,Uv=1800*1e3});import{readdirSync as tl,statSync as Wv}from"fs";import{join as X,relative as Kv}from"path";function es(e){let t=X(e,Ht);if(!v(t))return null;try{return JSON.parse(M(t))}catch{return null}}function Di(e,t){let n=X(e,Ht);H(n,JSON.stringify(t,null,2)+`
2822
- `)}function Zs(e){let t=[];if(!v(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),Qa(e,t,null);let n=el(X(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."}),Qa(e,t,es(e));Yv(e,n,t),qv(e,n,t),Xv(e,t),Qv(e,t),ex(e,t),tx(e,t);let s=es(e);return nx(s,t),Qa(e,t,s)}function Qa(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 Yv(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 Vv)Pt(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 zv)(!(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.'}):(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 i=t.preview_path;if(typeof i=="string"&&i.length>0){let r=Tg(e,i);v(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 qv(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Tg(e,s);if(!v(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 Xv(e,t){let n=X(e,"modules");if(!v(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=tl(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=X(n,i);Zv(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 Zv(e,t,n,s){let o=el(X(t,"meta.json")),i=ht(e,X(t,"meta.json"));o?(Pt(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=X(t,"fields.json"),a=ht(e,r);if(!v(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=el(r);Array.isArray(c)?kg(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=X(t,"module.html");v(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 kg(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)";Pt(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}),!Pt(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)&&kg(i.children,t,n,s)}}function Qv(e,t){let n=[],s=X(e,"css");Fi(s,".css").forEach(i=>{wg(i,n,e)});let o=X(e,"modules");if(v(o))for(let i of Qs(o)){if(!i.endsWith(".module"))continue;let r=X(o,i);["module.css","module.html"].forEach(a=>{let l=X(r,a);v(l)&&wg(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 wg(e,t,n){let s;try{s=M(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:ht(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:ht(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:ht(n,e),match:r[0]})}function ex(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=X(e,"css");Fi(o,".css").forEach(a=>s.push(a));let i=X(e,"js");Fi(i,".js").forEach(a=>s.push(a));let r=X(e,"modules");if(v(r))for(let a of Qs(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=X(r,a,l);v(c)&&s.push(c)});for(let a of s){let l;try{l=M(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 tx(e,t){let n=X(e,"modules");if(v(n))for(let s of Qs(n)){if(!s.endsWith(".module"))continue;let o=X(n,s,"module.html");if(!v(o))continue;let i;try{i=M(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: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(i)||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 nx(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Ht,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?en.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Ht,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${en.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Ht,message:"marketplace.json has no category",fix:`Pick one of: ${en.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Ht,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:Ht,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:Ht,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:Ht,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function ji(e){let t=[],n=[],s=X(e,"modules");if(v(s))for(let i of Qs(s)){if(!i.endsWith(".module"))continue;let r=X(s,i),a=i.replace(/\.module$/,""),l=X(r,"meta.json");if(v(l))try{let d=JSON.parse(M(l));Pt(d,"label")||(d.label=Ag(a),H(l,JSON.stringify(d,null,2)+`
2823
- `),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=X(r,"fields.json");if(v(c))try{let d=JSON.parse(M(c));if(Array.isArray(d)){let u=Cg(d);u>0&&(H(c,JSON.stringify(d,null,2)+`
2824
- `),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=sx(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function sx(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=M(c)}catch{return}let u=d.replace(n,"");u!==d&&(H(c,u),t.push(ht(e,c)))}function a(c){let d;try{d=M(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(H(c,u),t.push(ht(e,c)))}Fi(X(e,"css"),".css").forEach(r);let l=X(e,"modules");if(v(l))for(let c of Qs(l)){if(!c.endsWith(".module"))continue;let d=X(l,c),u=X(d,"module.css"),m=X(d,"module.html");v(u)&&r(u),v(m)&&a(m)}return t}function Cg(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=Ag(String(s.name)),t++),Array.isArray(s.children)&&(t+=Cg(s.children))}return t}function el(e){if(!v(e))return null;try{let t=JSON.parse(M(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 Tg(e,t){let n=t.replace(/^\.?\//,"");return X(e,n)}function ht(e,t){return Kv(e,t).split("\\").join("/")}function Qs(e){try{return tl(e)}catch{return[]}}function Fi(e,t){if(!v(e))return[];try{let n=[];for(let s of tl(e)){let o=X(e,s);Wv(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Ag(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var en,Vv,zv,Ht,nl=R(()=>{"use strict";y();ae();en=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],Vv=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],zv=["enable_domain_stylesheets","is_available_for_new_content"],Ht="marketplace.json"});function sl(e){let t=w();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Ae()}catch{}return t.themePath}function _g(e,t){let n=sl(t);if(!n)return;let s=Zs(n);p(t,200,{report:s,categories:en})}function $g(e,t){let n=sl(t);if(!n)return;let s=ji(n),o=Zs(n);p(t,200,{fix:s,report:o})}function Pg(e,t,n){let s=sl(n);if(s){if(e==="GET"){p(n,200,{metadata:es(s),categories:en});return}if(e==="POST"){Ze(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};Di(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Eg=R(()=>{"use strict";y();Qe();Ce();nl()});function ox(e){let t=w();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Ae()}catch{}return t.themePath}function Mg(e,t){let n=ox(t);if(!n)return;let s=ei(n);p(t,200,{report:s})}function Ig(e,t){let n=w();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=qt(n.themePath),o=dn(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(),F(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=ti(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 Rg=R(()=>{"use strict";y();Qe();Ce();Cs()});import{createServer as ix}from"http";import{readFileSync as ol,existsSync as to}from"fs";import{join as Ut,extname as jg}from"path";import{WebSocketServer as rx,WebSocket as ax}from"ws";function z(e){Bi&&Bi.readyState===ax.OPEN&&Bi.send(JSON.stringify(e))}function Li(e){Hi.push(e),z(e)}function Oe(){Hi=[]}function Ji(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;Li(o)}else Li(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"?Ue({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(Ue({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Vt(n.moduleOrder),Li({type:"modules_updated",modules:xe().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(Ue({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),Li({type:"modules_updated",modules:xe().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 eo(e){let t=e.cost;if(!t||t.calls===0)return;let n=w();z({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}async function lx(e=1e4){let t=Date.now();for(;$t()&&Date.now()-t<e;)await new Promise(n=>setTimeout(n,50))}function Bg(e,t){yn(e,{steps:t.steps,modules:t.modules,stats:e.stats,cost:e.cost}),eo(e);let n=w();if(n){Ae();let s=Te(),o=null;if(s){let i=s.moduleOrder.map(r=>`modules/${r}.module`);s.templateFile&&i.push(s.templateFile),s.sharedCss&&i.push(`css/${n.themeName}-theme.css`),s.sharedJs&&i.push(`js/${n.themeName}-animations.js`),o=Sr(n.themePath,s.id,t.commitLabel,i)}else o=ln(n.themePath,t.commitLabel);o&&z({type:"version_created",hash:o})}z({type:"generation_complete"});{let s=w();z({type:"modules_updated",modules:xe().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}))})}Oe()}async function Ng(e,t){dt("user",e),F();try{z({type:"stream_status",content:"Planning..."});let n="",s=await Fa(e,i=>{n+=i,z({type:"stream",content:i})},t),o=Pm(s||n);if(o.plan){wi(o.plan),z({type:"plan_updated",plan:o.plan});let i=w();i&&(i.pendingCheckpoint={kind:"plan",resumeToken:"plan",preview:{kind:"plan",headline:"Plan ready for review",data:{plan:o.plan}},createdAt:new Date().toISOString()},F())}o.choices&&z({type:"plan_choices",question:o.choices.question,options:o.choices.options}),dt("assistant",o.cleanedContent),F(),z({type:"plan_complete",cleanedContent:o.cleanedContent}),z({type:"generation_complete"})}catch(n){z({type:"error",message:n instanceof Error?n.message:String(n)})}}async function Og(){let e=w();if(!e){z({type:"error",message:"No active session"});return}let t=e.brandAssets?.plan;if(!t||!t.trim()){z({type:"error",message:"No plan to approve. Send a chat message first."});return}q({planMode:!1}),e.pendingCheckpoint?.kind==="plan"&&(e.pendingCheckpoint=void 0);let n="Implement the approved plan.";dt("user",n),F();try{Oe();let s=[],o=[],i=await vi(n,Ji(s,o));if(i.canceled){Oe();return}Bg(i,{steps:s,modules:o,commitLabel:"Approved plan: implementation"})}catch(s){Oe(),z({type:"error",message:s instanceof Error?s.message:String(s)})}}function Fg(){let e=w();e?.pendingCheckpoint?.kind==="plan"&&(e.pendingCheckpoint=void 0),La(),q({planMode:!1}),F(),z({type:"plan_discarded"})}function Wn(){return Jg}function Ui(e){let{port:t,uiDir:n}=e;Jg=e.contentMode||"page";let s=ix((i,r)=>cx(i,r,n)),o=new rx({server:s});return o.on("connection",i=>ux(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 cx(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/")){dx(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=Fr();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=Dr(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){mx(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";Dg(i,Ut(n,"docs"),e,t);return}Dg(s.pathname,n,e,t)}function dx(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":Xp(e,s);break;case"/api/modules":Zp(e,n,s);break;case"/api/modules/reorder":eg(n,s);break;case"/api/modules/code":Qp(n,s);break;case"/api/upload":tg(s);break;case"/api/upload-files":e==="POST"?Bd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":ng(n,s);break;case"/api/import":sg(n,s);break;case"/api/setup":Hm(s);break;case"/api/setup/create":Um(n,s);break;case"/api/setup/fetch":Wm(n,s);break;case"/api/setup/open":Km(n,s);break;case"/api/setup/resume":Vm(n,s);break;case"/api/setup/apikey":zm(n,s);break;case"/api/setup/remote-themes":e==="GET"?Ym(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?Gm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?sp(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/models":e==="GET"?op(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/tools":e==="GET"?ip(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?rp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?ap(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?lp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?cp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?dp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?up(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?mp(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?pp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?gp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?fp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Sp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?vp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?xp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:fl()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":kp(e,n,s);break;case"/api/themes/switch":e==="POST"?Cp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Tp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Ap(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?_p(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?og(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?ig(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Np(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Dp(e,n,s);break;case"/api/templates/activate":e==="POST"?jp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?Lp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?Jp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?Bp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?Hp(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":Gp(e,n,s);break;case"/api/brand-kit":Vp(e,n,s);break;case"/api/fonts":e==="GET"?Kp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?zp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?Yp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Fp(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?Ya(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?qa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?Xa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Cm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Am(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?_m(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?_g(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?$g(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Pg(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Mg(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Ig(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?yp(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?Up(t,n,s):p(s,404,{error:"Not found"})}}function ux(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;$t()&&(Ma()&&z({type:"generation_superseded"}),await lx());{let a=w();a?.pendingCheckpoint&&(a.pendingCheckpoint=void 0,F())}if(Da()){await Ng(o,i);break}dt("user",o),F();let r=ja();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Oe();let l=[],c=[],d=!s.oneShot,u=await vi(o,Ji(l,c),i,d);if(u.canceled){Oe();break}if(u.pendingCheckpoint){let m=w();m&&(m.pendingCheckpoint=u.pendingCheckpoint,F()),eo(u),Oe();break}yn(u,{steps:l,modules:c,stats:u.stats,cost:u.cost}),eo(u)}else Ea(l=>{z({type:"parse_warning",message:l})}),await zs(o,l=>{z({type:"stream",content:l})},l=>{z({type:"stream_status",content:l})},i);let a=w();if(a){Ae();let l=Te(),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=Sr(a.themePath,l.id,o,d)}else c=ln(a.themePath,o);c&&z({type:"version_created",hash:c})}z({type:"generation_complete"});{let l=w();z({type:"modules_updated",modules:xe().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}))})}Oe();{let l=w();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&z({type:"suggest_brand_extraction"})}}catch(a){Oe(),z({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(()=>(Za(),xg)),a=r(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=w();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(()=>(us(),Ll)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!h(b)){let{mkdirSync:x}=await import("fs");x(b,{recursive:!0})}h(S)||f(S,i),Jn(S,i),F()}z({type:"figma_import_started",fileName:a.fileName}),Oe();let c=[],d=[],u=await Ys(a,i,Ji(c,d));yn(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),eo(u),Ae(),ln(w().themePath,`Figma import: ${a.fileName}`),z({type:"generation_complete"});{let m=w();z({type:"modules_updated",modules:xe().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}))})}Oe()}catch(l){Oe(),z({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=w();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=N(),{engine:r,apiKey:a,model:l}=hn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(_s(),si)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(yi(),hi)),m=await ze({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>se("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=Ut(o.themePath,".vibespot");to(f)||g(f,{recursive:!0}),h(Ut(f,"theme-context.md"),m),F(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(Ks(),Ws)),b=await ze({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>se("extract-styleguide",()=>f(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=Ut(o.themePath,".vibespot");to(S)||g(S,{recursive:!0}),h(Ut(S,"styleguide.md"),b),F(),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=w();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Ae();let i=Lo(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(N().hubspotUploadMode||"api")==="api"){let l=Be();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 Jo(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
2825
- `}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
2826
- `}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
2827
- `}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Gt();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:Wn()}))}else{let d=Do(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
2828
- `),errors:d}))}}else{let l=Ci(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:Ut(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=ki(l);if(!(!u||u.status==="running"))if(clearInterval(d),Rm(l,c),u.status==="completed"){let m=vt(),g=m.portalId?rs(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:Wn()}))}else{let m=jo(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.
2829
-
2830
- IMPORTANT: Be verbose in your response. For each error:
2831
- 1. State exactly which file has the problem and what the error is
2832
- 2. Explain WHY this error occurs (e.g. "HubSpot doesn't support textarea field type" or "field name 'name' is reserved in HubSpot modules")
2833
- 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'")
2834
- 4. Apply the fix to the module files
2835
-
2836
- 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.
2837
-
2838
- After fixing all errors, summarize the changes you made.
2839
-
2840
- Upload log:
2841
- ${o}`;dt("user",i),F(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await zs(i,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=w();if(r){Ae();let a=ln(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=w();e.send(JSON.stringify({type:"modules_updated",modules:xe().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":{await Og();break}case"plan_discard":{Fg();break}case"checkpoint_resolve":{let o=w();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.pendingCheckpoint;if(!i){e.send(JSON.stringify({type:"error",message:"No checkpoint is awaiting resolution."}));break}let r=String(s.action||"");if(!["approve","steer","skip","cancel"].includes(r)){e.send(JSON.stringify({type:"error",message:`Invalid checkpoint action: ${r}`}));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:i.kind,action:r,note:typeof s.note=="string"?s.note:void 0,outline:a,...i.kind==="brand_intake"&&s.brandIntake&&typeof s.brandIntake=="object"?{brandIntake:s.brandIntake}:{}};if(i.kind==="plan"){o.pendingCheckpoint=void 0,F(),r==="cancel"?Fg():r==="steer"?await Ng(l.note?.trim()||"Refine the plan further."):await Og();break}let c=i.resumeToken;o.pendingCheckpoint=void 0,F();try{Oe();let d=[],u=[],m=await Oa(c,l,Ji(d,u),i.resumeState);if(m.canceled){z({type:"checkpoint_cancelled"}),z({type:"generation_complete"}),Oe();break}if(m.pendingCheckpoint){let g=w();g&&(g.pendingCheckpoint=m.pendingCheckpoint,F()),eo(m),Oe();break}Bg(m,{steps:d,modules:u,commitLabel:"Checkpoint approved: implementation"})}catch(d){Oe(),z({type:"error",message:d instanceof Error?d.message:String(d)})}break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),Bi=e;let t=w();if(t){let n=N(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=$t(),i=Te();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:xe().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:lt(),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,pendingCheckpoint:t.pendingCheckpoint?{...t.pendingCheckpoint,resumeState:void 0}:null,costTotal:t.costTotal||null})),o&&Hi.length>0)for(let r of Hi)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function mx(e,t){let n=w();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=Ut(n.themePath,"assets",e);if(!to(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=jg(s),i=Lg[o]||"application/octet-stream",r=ol(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Dg(e,t,n,s){let i=Ut(t,e==="/"?"/index.html":e);if(!to(i)){let c=Ut(t,"index.html");if(to(c)){let d=ol(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=jg(i),a=Lg[r]||"application/octet-stream",l=r===".html";try{let c=ol(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 Lg,Bi,Hi,Jg,$s=R(()=>{"use strict";y();Ce();jn();_s();qn();$m();Em();oe();on();Bo();Ti();yr();Qe();ae();He();Ei();bp();wp();$p();qp();rg();Zr();Za();Eg();Rg();Lg={".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"},Bi=null,Hi=[];Jg="page"});y();y();import{Command as Tx}from"commander";y();y();bt();ae();function $e(){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${Tn()}`)}`),console.log()}y();on();It();tn();oe();rn();nt();bt();async function vo(){await fe("Checking your environment");let e=os();e.found||(Y("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),fo(e.version)||(Y(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),W(`Node.js v${e.version}`);let t=is();t.found||(Y("Git not found. Install it from https://git-scm.com"),process.exit(1)),W(`Git ${t.version}`);let n=N(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Be(),S=Gt();if(b)o=S?.portalId||"",i=S?.portalName||"",W(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{ie("No HubSpot account connected"),await xt(`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.
2842
2638
  Create one at: https://app.hubspot.com/l/personal-access-key
2843
- Make sure the Content scope is enabled.`,"HubSpot connection required");let x=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 bo(x);ns(x,$.portalId,$.portalName,$.dataCenter),b=x,o=$.portalId,i=$.portalName,k.stop(`Connected to ${$.portalName} (${$.portalId})`)}catch($){k.stop("Validation failed"),Y(`Invalid key: ${$ instanceof Error?$.message:String($)}`),process.exit(1)}}}else{let b=St();if(b.found)W(`HubSpot CLI v${b.version}`);else{ie("HubSpot CLI not found"),await Pe({message:"Install HubSpot CLI globally?"})||(Y("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..."),le("npm install -g @hubspot/cli").success||(k.stop("Failed"),Y("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)W(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{ie("HubSpot not authenticated"),await Pe({message:"Run `hs init` now?"})||(Y("Run `hs init` manually."),process.exit(1));let k=await je();k.start("Waiting for HubSpot authentication..."),yl("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,i=S.portalName}let r=En(),a=Mn(),l=In(),c=Cl(),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=tt(),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,W(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await Nt({message:"Choose your AI engine:",options:h});else if(await xt(`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.
2844
2640
 
2845
2641
  ${E.bold("Option 1:")} Install Claude Code ${E.muted("(recommended)")}
2846
2642
  https://claude.ai/code
@@ -2853,30 +2649,35 @@ ${E.bold("Option 3:")} Install OpenAI Codex
2853
2649
 
2854
2650
  ${E.bold("Option 4:")} Set an Anthropic API key
2855
2651
  export ANTHROPIC_API_KEY=sk-ant-...
2856
- (get one at https://console.anthropic.com)`,"AI engine required"),m=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"}]}),m==="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,q({anthropicApiKey:b})}let f;return m==="claude-code"&&(f=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"}]})),q({aiEngine:m}),await he("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}wo();y();tn();ae();nt();bt();oe();us();ko();import{join as ps}from"path";async function Co(){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=ps(process.cwd(),"workspace");if(Ie(s),e==="fetch"){t=await ve({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=ps(s,t);let l=await je();l.start("Fetching theme from HubSpot...");let c=N(),d=Be();if(c.hubspotUploadMode==="cli"||!d)le(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),Y(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await ms(d,t,n)}catch(u){l.stop("Fetch failed"),Y(`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=ps(s,t);let l=await je();l.start("Creating theme...");try{ds(n,t)}catch(c){l.stop("Creation failed"),Y(`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=ps(n,"templates/layouts/base.html");v(o)||(Y(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),W("base.html found");let i=M(o),r=!1;if(i.includes("template_css"))W("template_css support");else{ie("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
2857
- `,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
2858
- `,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)+`
2859
2660
  {% if template_css %}
2860
2661
  {{ require_css(get_asset_url(template_css)) }}
2861
- {% endif %}`+i.slice(c),r=!0}}if(i.includes("template_js"))W("template_js support");else{ie("Missing template_js support in base.html");let l=i.indexOf("require_js");if(l>0){let c=i.indexOf(`
2862
- `,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(`
2863
2664
  `,c+1),u=`
2864
2665
  {% if template_js %}
2865
2666
  {{ require_js(get_asset_url(template_js)) }}
2866
- {% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
2867
- `)+1;i=i.slice(0,i.indexOf(`
2868
- `,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
2869
- `,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await je();l.start("Patching base.html..."),H(o,i),l.stop("base.html patched with template_css/template_js support")}let a=ps(n,".hsignore");if(v(a)){let l=M(a);l.includes("docs/")||(H(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+`
2870
2671
  docs/
2871
- `),W("Added docs/ to .hsignore"))}else H(a,`docs/
2672
+ `),K("Added docs/ to .hsignore"))}else U(a,`docs/
2872
2673
  *.md
2873
2674
  node_modules/
2874
2675
  .git
2875
- `),W("Created .hsignore");return await he("Theme ready!"),{themePath:n,themeName:t}}y();import{join as ot}from"path";import{readdirSync as bs,rmSync as rc}from"fs";y();Ve();ae();import{spawn as If}from"child_process";import{join as ne,basename as Rf}from"path";import{readdirSync as wt,statSync as ql,writeFileSync as Nf}from"fs";var Of=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"]),To=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||be();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=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,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((x,k)=>{let $={...process.env};delete $.CLAUDECODE;let L=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&L.push("--model",this.model);let j=If("claude",L,{cwd:s,stdio:["pipe","pipe","pipe"],env:$,shell:!0});j.stdout.on("data",J=>{m+=J.toString()}),j.stderr.on("data",J=>{g+=J.toString()}),j.on("error",J=>k(new Error(`Claude Code failed to start: ${J.message}`))),j.on("close",J=>{J!==0?k(new Error(`Claude Code exited with code ${J}.
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}.
2876
2677
  `+(g?`Stderr: ${g.slice(0,500)}
2877
- `:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):x()}),j.stdin.on("error",()=>{}),j.stdin.write(u),j.stdin.end(),setTimeout(()=>{j.kill(),k(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let f=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)+`
2878
- ... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
2879
- `);Nf(f,k,"utf-8"),o("status",`Log written to ${Rf(f)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(x=>!a.has(x.moduleName+".module")).length===0){let x=m.slice(0,1500)||"(no output)",k=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.
2880
2681
 
2881
2682
  This usually means the model described the conversion instead of using Write tool to create files.
2882
2683
 
@@ -2892,7 +2693,7 @@ Stderr:
2892
2693
  ${k}
2893
2694
  `:"")+`
2894
2695
  Claude output:
2895
- ${x}`)}return b}reportProgress(t,n,s,o,i,r){let a=0,l=this.listDir(ne(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(ne(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(ne(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.
2896
2697
 
2897
2698
  SOURCE DIRECTORY: ${t}
2898
2699
  THEME DIRECTORY: ${n}
@@ -2935,31 +2736,16 @@ CSS QUALITY: The converted page must visually match the original React page. Eve
2935
2736
  Do NOT run hs upload \u2014 I will handle that separately.
2936
2737
 
2937
2738
  HUBSPOT CMS RULES:
2938
- ${Je()}
2739
+ ${et()}
2939
2740
 
2940
2741
  CONVERSION GUIDE:
2941
- ${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ne(t,"css");if(v(s)){for(let a of wt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(ne(s,a));break}}let o=ne(t,"js");if(v(o)){for(let a of wt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(ne(o,a));break}}let i=ne(t,"templates");if(v(i)){for(let a of wt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=M(ne(i,a));break}if(!n.template){for(let a of wt(i))if(a.endsWith(".html")&&!Of.has(a)&&!a.startsWith("system")){let l=M(ne(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of wt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(ne(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=ne(t,"modules");if(v(r))for(let a of wt(r)){if(!a.endsWith(".module"))continue;let l=ne(r,a);if(!ql(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=ne(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=ne(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=ne(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=ne(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=ne(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=ne(t,"modules");return v(n)?new Set(wt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return v(t)?new Set(wt(t)):new Set}detectExpectedModules(t,n){let s=ne(t,"templates");if(!v(s))return 0;for(let o of wt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=M(ne(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=ne(t,"src");return v(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of wt(t)){let o=ne(t,s);try{ql(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();Ve();ae();He();an();import eh from"@anthropic-ai/sdk";import{join as ue,basename as th}from"path";import{readdirSync as ic}from"fs";var Mo=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new eh({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=Wl(o),a=th(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,Vl(c,d,l)),m=ue(s,"css",`${l}-theme.css`);H(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,zl(g,h,l)),b=ue(s,"js",`${l}-animations.js`);H(b,f),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let S=this.findComponents(n),x=[];for(let j=0;j<S.length;j++){let J=S[j],V=J.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${V}.module (${j+1}/${S.length})...`);let D=M(J.path),U=await this.complete(r,Kl(D,V,`See css/${l}-theme.css`));try{let C=JSON.parse(U),P={moduleName:V,fieldsJson:typeof C.fieldsJson=="string"?C.fieldsJson:JSON.stringify(C.fieldsJson,null,2),metaJson:typeof C.metaJson=="string"?C.metaJson:JSON.stringify(C.metaJson,null,2),moduleHtml:C.moduleHtml||"",moduleCss:C.moduleCss||"",moduleJs:C.moduleJs||void 0},O=ue(s,"modules",`${V}.module`);Ie(O),H(ue(O,"fields.json"),P.fieldsJson),H(ue(O,"meta.json"),P.metaJson),H(ue(O,"module.html"),P.moduleHtml),H(ue(O,"module.css"),P.moduleCss),P.moduleJs&&H(ue(O,"module.js"),P.moduleJs),x.push(P),i("module-done",`${V}.module (${this.countFiles(P)} files)`)}catch{i("module-error",`Failed to parse ${V} \u2014 skipping`)}}i("template","Creating page template...");let k=x.map(j=>j.moduleName),$=await this.complete(r,Yl(k,a,l)),L=ue(s,"templates",`lp-${l}.html`);return H(L,$),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:$,modules:x}}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 kt({engine:"anthropic-api",model:this.model,name:"react-conversion",input:{system:t,messages:[{role:"user",content:n}]},output:r,usage:st(o.usage),startTime:s,endTime:new Date}),r}findAndReadCSS(t){let n=[ue(t,"src/index.css"),ue(t,"src/globals.css"),ue(t,"src/app/globals.css"),ue(t,"app/globals.css")];for(let s of n)if(v(s))return M(s);return""}findAndReadTailwind(t){let n=[ue(t,"tailwind.config.ts"),ue(t,"tailwind.config.js"),ue(t,"tailwind.config.mjs")];for(let s of n)if(v(s))return M(s);return""}findAndReadHooks(t){let n=ue(t,"src/hooks");if(!v(n))return"";try{return ic(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
2942
- ${M(ue(n,s))}`).join(`
2943
-
2944
- `)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=M(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
2945
- ${i}`)}return s.join(`
2946
-
2947
- `)}findComponents(t){let n=[ue(t,"src/components/landing"),ue(t,"src/components/sections"),ue(t,"src/components")];for(let s of n)if(v(s))try{return ic(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:ue(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();Ve();ae();import{spawn as nh}from"child_process";import{join as Ye}from"path";import{readdirSync as Io,statSync as sh}from"fs";var Ro=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||be(),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=nh("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}.
2948
-
2949
- INSTRUCTIONS:
2950
- 1. Analyze all .tsx/.jsx components in the React source
2951
- 2. Create a shared CSS file in css/ with design system variables, utilities, and theme-override countermeasures
2952
- 3. Create a shared JS file in js/ for scroll animations and interactive features
2953
- 4. For each visual section, create a HubSpot module in modules/ with fields.json, meta.json, module.html, module.css
2954
- 5. Add a styles group with "tab": "STYLE" and color pickers to each module
2955
- 6. Create a page template in templates/ that assembles all modules
2956
- 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(`
2957
2744
 
2958
- CONVERSION GUIDE:
2959
- ${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(`
2960
2747
 
2961
- Do NOT run hs upload \u2014 I will handle that separately.
2962
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ye(t,"css");if(v(s)){for(let a of Io(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(Ye(s,a));break}}let o=Ye(t,"js");if(v(o)){for(let a of Io(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(Ye(o,a));break}}let i=Ye(t,"templates");if(v(i)){for(let a of Io(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(Ye(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ye(t,"modules");if(v(r))for(let a of Io(r)){if(!a.endsWith(".module"))continue;let l=Ye(r,a);if(!sh(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ye(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=Ye(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=Ye(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=Ye(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=Ye(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ve();ae();import{spawn as oh}from"child_process";import{join as qe}from"path";import{readdirSync as No,statSync as ih}from"fs";var Oo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||be(),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=oh("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}.
2963
2749
 
2964
2750
  INSTRUCTIONS:
2965
2751
  1. Analyze all .tsx/.jsx components in the React source
@@ -2974,27 +2760,30 @@ CONVERSION GUIDE:
2974
2760
  ${s}
2975
2761
 
2976
2762
  Do NOT run hs upload \u2014 I will handle that separately.
2977
- Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=qe(t,"css");if(v(s)){for(let a of No(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=M(qe(s,a));break}}let o=qe(t,"js");if(v(o)){for(let a of No(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=M(qe(o,a));break}}let i=qe(t,"templates");if(v(i)){for(let a of No(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=M(qe(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=qe(t,"modules");if(v(r))for(let a of No(r)){if(!a.endsWith(".module"))continue;let l=qe(r,a);if(!ih(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=qe(l,"fields.json");v(d)&&(c.fieldsJson=M(d));let u=qe(l,"meta.json");v(u)&&(c.metaJson=M(u));let m=qe(l,"module.html");v(m)&&(c.moduleHtml=M(m));let g=qe(l,"module.css");v(g)&&(c.moduleCss=M(g));let h=qe(l,"module.js");v(h)&&(c.moduleJs=M(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ve();ae();nt();function rh(e,t){switch(e){case"claude-code":return new To(t);case"gemini-cli":return new Ro;case"codex-cli":return new Oo;case"api":case"anthropic-api":case"claude-oauth":return new Mo;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 Fo(e){await fe("Converting React to HubSpot Modules"),await xt(`AI will now analyze your React code and create
2978
- HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=rh(e.aiEngine,e.model),n=be(),s=await je();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"?W(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=ah(e.themePath);for(let h of a)W(`Auto-fixed: ${h}`);let l=lh(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(`
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(`
2979
2765
  ${d}/${l.length} checks passed`),await xt(c.join(`
2980
- `),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(Y(`${u.length} critical issue(s) \u2014 upload will likely fail:
2981
- `+u.map(f=>` - ${f.label}`).join(`
2982
- `)),!await Pe({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&ie(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
2983
- `+m.map(h=>` - ${h.label}`).join(`
2984
- `));let g=ot(e.themePath,"..","vibespot-conversion.log");return v(g)&&(await Pe({message:"Keep conversion log file for debugging?",initialValue:!1})?W(`Log saved: ${g}`):rc(g)),await he("Files ready for upload!"),i}function ah(e){let t=[];ch(e),dh(e);let n=ot(e,"modules");if(v(n))for(let o of bs(n)){if(!o.endsWith(".module"))continue;let i=ot(n,o,"fields.json");if(!v(i))continue;let r=o.replace(".module",""),a=M(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;ac(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),lc(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
2985
- `,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&H(i,a);let c=ot(n,o,"module.html");if(v(c)){let d=M(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),H(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=ot(e,"templates");if(v(s))for(let o of bs(s)){if(!o.endsWith(".html"))continue;let i=ot(s,o),r=M(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(rc(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function ac(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)&&ac(s.children)&&(t=!0)}return t}function lc(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)&&lc(s.children)&&(t=!0)}return t}function lh(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=ot(e,"templates"),d=!1;if(v(c))for(let u of bs(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=M(ot(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 ch(e){let t=ot(e,"templates");if(v(t))for(let n of bs(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=ot(t,n),o=M(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+=`
2986
- templateType: page`),r||(c+=`
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+=`
2987
2773
  isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
2988
2774
  label: ${a}`),o=c+o.slice(l)}else o=`<!--
2989
2775
  templateType: page
2990
2776
  isAvailableForNewContent: true
2991
2777
  label: ${a}
2992
2778
  -->
2993
- `+o;H(s,o),W(`Template "${n}" \u2014 annotations verified`)}}function dh(e){let t=ot(e,"modules");if(v(t))for(let n of bs(t)){if(!n.endsWith(".module"))continue;let s=ot(t,n,"meta.json");if(v(s))try{let o=JSON.parse(M(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&H(s,JSON.stringify(o,null,2)+`
2994
- `)}catch{}}}y();tn();nt();Bo();oe();yr();import{join as xc,basename as vh}from"path";function xh(e){return(e.match(/^Uploaded file /gm)||[]).length}async function Dn(e){await fe("Uploading to HubSpot");let t=vh(e)||e,n=N(),s=Be(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await je(),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 Jo(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=Do(m.errors)}else{let m=le(`hs cms upload "${e}" "${t}"`,{cwd:xc(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
2995
- `);c=xh(g),d=m.success,d||(l=jo(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await he("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(Y("Upload failed with unknown error."),c>0&&(ie(`Most files uploaded successfully. The theme may already be usable in HubSpot.
2996
- You can check your HubSpot Design Manager to verify.`),await Pe({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Pe({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?cc(e,m)?(W(`Auto-fixed: ${m.message}`),u=!0):ie(`Could not auto-fix: ${m.message}`):Y(m.message);if(!(u&&a<r)){if(c>0&&(ie(`${c} files uploaded successfully despite errors.
2997
- The theme may work \u2014 check HubSpot Design Manager.`),await Pe({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await or(s,`${t}/modules`)}catch{}else le(`hs cms delete "${t}/modules"`,{cwd:xc(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return Y("Upload failed after multiple attempts."),!1}y();nt();bt();on();ae();import{execFileSync as br}from"child_process";import{rmSync as wh}from"fs";import{basename as wc}from"path";async function kc(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await fe("You're all set!");let r=rs(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await xt(`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.
2998
2787
  The theme and modules are now in your account, but you still
2999
2788
  need to ${E.bold("create a new landing page")} that uses them.
3000
2789
 
@@ -3006,15 +2795,60 @@ Next steps:
3006
2795
  ${E.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
3007
2796
  ${E.bold("5.")} Click each section to edit text, images, and colors
3008
2797
  ${E.bold("6.")} Upload images via File Manager ${E.muted("(Settings \u2192 Files)")}
3009
- ${E.bold("7.")} Preview and publish!`,"What's next"),await Pe({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"?br("open",[c],{stdio:"ignore"}):d==="win32"?br("cmd",["/c","start","",c],{stdio:"ignore"}):br("xdg-open",[c],{stdio:"ignore"}),W("Opening HubSpot Landing Pages...")}catch{B(`Open this URL in your browser: ${E.info(c)}`)}}let l=[];if(o&&v(n)&&l.push({path:n,label:`Cloned source (${wc(n)})`}),v(s)&&l.push({path:s,label:`Theme directory (${wc(s)})`}),l.length>0&&await Pe({message:"Clean up local working directories?"}))for(let d of l)try{wh(d.path,{recursive:!0,force:!0}),W(`Removed ${d.label}`)}catch{ie(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await he(`Thanks for using hub${E.vibes("Vibes")}! ${E.vibes("~")}`)}oe();async function Cc(){$e();let e=await vo(),t=await xo();q({lastSourcePath:t.sourceDir});let n=await Co();q({lastThemePath:n.themePath}),await Fo({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await Dn(n.themePath),await kc({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function Tc(){$e(),await vo()}y();wo();oe();nt();async function Ac(){$e();let e=N();e.aiEngine||(Y("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await xo(),n=await Co();await Fo({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();oe();nt();async function _c(){$e();let e=N();if(e.lastThemePath)if(await Pe({message:`Upload from ${e.lastThemePath}?`}))await Dn(e.lastThemePath);else{let n=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Dn(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 Dn(t)}}y();on();oe();nt();bt();async function $c(){$e(),await fe("Environment Diagnostics");let e=0,t=os();t.found?fo(t.version)?W(`Node.js v${t.version}`):(ie(`Node.js v${t.version} \u2014 too old (need 18+)`),B(" Update at https://nodejs.org"),e++):(Y("Node.js \u2014 not installed"),B(" Install from https://nodejs.org"),e++);let n=is();n.found?W(`Git ${n.version}`):(Y("Git \u2014 not installed"),B(" Install from https://git-scm.com"),e++);let s=St();if(!s.found)ie("HubSpot CLI \u2014 not installed (only needed for deployment)"),B(" Install: npm install -g @hubspot/cli");else if(!Tl(s.version))ie(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),B(" Update: npm install -g @hubspot/cli@latest"),e++;else{W(`HubSpot CLI v${s.version}`);let m=vt();m.authenticated?W(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(ie("HubSpot \u2014 not authenticated"),B(" Run: hs init"))}let o=En();o.found?W(`Claude Code ${o.version} at ${o.path}`):B(E.muted("Claude Code \u2014 not installed"));let i=Mn();i.found?W(`Gemini CLI ${i.version} at ${i.path}`):B(E.muted("Gemini CLI \u2014 not installed"));let r=In();r.found?W(`OpenAI Codex ${r.version} at ${r.path}`):B(E.muted("OpenAI Codex \u2014 not installed"));let a=N(),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?W("Anthropic API key configured"):B(E.muted("Anthropic API key \u2014 not set")),c?W("OpenAI API key configured"):B(E.muted("OpenAI API key \u2014 not set")),d?W("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&&W(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&B(E.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(ie("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();$s();Ce();import{dirname as px,join as Gi}from"path";import{existsSync as gx}from"fs";import{fileURLToPath as fx}from"url";import{execFileSync as il}from"child_process";import Wi from"chalk";var Hg=px(fx(import.meta.url)),hx=4200;async function Ug(){let e=Wi.hex("#e8613a"),t=Wi.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
3010
- `));let n=yx();n||(console.error(Wi.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||hx;try{let{port:o,close:i}=await Ui({port:s,uiDir:n}),r=`http://localhost:${o}`;if(console.log(e(` v ${r}`)),console.log(t(` Press Ctrl+C to stop
3011
- `)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?il("open",[r],{stdio:"ignore"}):process.platform==="win32"?il("cmd",["/c","start","",r],{stdio:"ignore"}):il("xdg-open",[r],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
3012
- Saving session...`)),F(),i(),console.log(t(` Goodbye!
3013
- `)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(Wi.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function yx(){let e=[Gi(Hg,"../../ui"),Gi(Hg,"../ui"),Gi(process.cwd(),"ui")];for(let t of e)if(gx(Gi(t,"index.html")))return t;return null}y();import{resolve as Gg}from"path";import{existsSync as rl}from"fs";bt();nt();oe();nl();async function Wg(e={}){let t=await Vg(e.path);if(e.fix){let o=ji(t);if(o.applied.length>0){W(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)B(` ${i}`)}else B(E.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)ie(i)}let n=Zs(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
3014
- `),n.passed||process.exit(1);return}$e(),await fe("Marketplace check");let s=`${n.errorCount} error${ll(n.errorCount)}, ${n.warningCount} warning${ll(n.warningCount)}, ${n.infoCount} note${ll(n.infoCount)}`;n.passed?W(`Theme passes Marketplace checks (${s}).`):Y(`Theme is not yet ready: ${s}.`),al("Errors",n.findings.filter(o=>o.severity==="error")),al("Warnings",n.findings.filter(o=>o.severity==="warning")),al("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 Kg(e={}){let t=await Vg(e.path);$e(),await fe("Marketplace listing details");let n=es(t)??{},s=await Nt({message:"Category",options:en.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}),r=(await ve({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 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:r,supportUrl:a.trim()||void 0,documentationUrl:l.trim()||void 0,pricingTier:c,tags:n.tags};Di(t,d),W("Saved marketplace.json"),await he(`Run ${E.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function Vg(e){if(e){let o=Gg(e);if(!rl(o))throw new Error(`Theme not found: ${o}`);return o}let t=N();if(t.lastThemePath&&rl(t.lastThemePath))return t.lastThemePath;$e();let n=await ve({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=Gg(n);if(!rl(s))throw new Error(`Theme not found: ${s}`);return s}function al(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 ll(e){return e===1?"":"s"}y();import{resolve as zg}from"path";import{existsSync as cl}from"fs";import{basename as bx}from"path";bt();nt();oe();Cs();async function Yg(e={}){let t=await Sx(e.path),n=bx(t);if(e.applyTokens){let i=ti(t,n);i?W(`Wrote design tokens to ${i}`):B(E.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=Ar(t);e.json||W(`Wrote imported theme snapshot to ${i}`)}let s=ei(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
3015
- `),process.exit(0)),$e(),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 i of s.designTokens.palette.slice(0,6)){let r=i.varName?E.muted(` (${i.varName})`):"";B(` ${i.value} ${E.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){B(""),B(E.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))B(` ${i}`)}if(s.graph.templates.length>0){B(""),B(E.heading("Template \u2192 modules"));for(let i of s.graph.templates)B(` ${i.id}: ${i.modules.length===0?E.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){B(""),B(E.heading("Orphan modules"));for(let i of s.graph.orphanModules)B(` ${i}`)}if(s.roundTripDiff.hasSnapshot){B(""),B(E.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)B(` ${E.muted("No changes from imported snapshot.")}`);else{B(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))B(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&B(` ${E.muted(`...and ${i.files.length-12} more`)}`)}}dl("Errors",s.findings.filter(i=>i.severity==="error")),dl("Warnings",s.findings.filter(i=>i.severity==="warning")),dl("Notes",s.findings.filter(i=>i.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 Sx(e){if(e){let o=zg(e);if(!cl(o))throw new Error(`Theme not found: ${o}`);return o}let t=N();if(t.lastThemePath&&cl(t.lastThemePath))return t.lastThemePath;$e();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=zg(n);if(!cl(s))throw new Error(`Theme not found: ${s}`);return s}function dl(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();$s();Ce();import{dirname as vx,join as Ki}from"path";import{existsSync as xx}from"fs";import{fileURLToPath as wx}from"url";import{execFileSync as ul}from"child_process";import Vi from"chalk";var qg=vx(wx(import.meta.url)),kx=4200;async function Xg(){let e=Vi.hex("#e8613a"),t=Vi.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
3016
- `));let n=Cx();n||(console.error(Vi.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await Ui({port:kx,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
3017
- `));try{process.platform==="darwin"?ul("open",[i],{stdio:"ignore"}):process.platform==="win32"?ul("cmd",["/c","start","",i],{stdio:"ignore"}):ul("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
3018
- Saving session...`)),F(),o(),console.log(t(` Goodbye!
3019
- `)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Vi.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Cx(){let e=[Ki(qg,"../../ui"),Ki(qg,"../ui"),Ki(process.cwd(),"ui")];for(let t of e)if(xx(Ki(t,"index.html")))return t;return null}ae();function Zg(){let e=new Tx;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Tn()).action(Ug),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Cc),e.command("init").description("Check and install required tools").action(Tc),e.command("convert").description("Convert a React project to HubSpot modules").action(Ac),e.command("upload").description("Upload theme to HubSpot").action(_c),e.command("doctor").description("Diagnose environment issues").action($c);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=>Wg(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>Kg(n)),e.command("email").description("Launch email template generation mode").action(Xg),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=>Yg(n)),e}var Ax=Zg();Ax.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
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)});
3020
2854
  //# sourceMappingURL=index.js.map