vibespot 1.6.3 → 1.6.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +207 -207
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
- package/ui/docs/index.html +1 -1
- package/ui/settings.js +3 -0
- package/ui/docs/screenshots.zip +0 -0
package/dist/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
var
|
|
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
|
|
3
|
-
`)[0]?.replace("gh version ","").split(" ")[0]||"",path:ie(`${Zt} gh`).stdout}}function to(){let e=ie("gh auth status 2>&1",{timeout:Za});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 Qa(){return!!process.env.ANTHROPIC_API_KEY}function no(e){return parseInt(e.split(".")[0],10)>=18}function el(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function wg(){let e=R(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Lt();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function vn(e,...t){if(e)return{configured:!0,masked:Vs(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:Vs(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function ji(e){return{anthropic:vn(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:vn(e.openaiApiKey,"OPENAI_API_KEY"),gemini:vn(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:vn(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:vn(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:vn(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function Li(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 Ji(e,t){if(e==="cli"){if(!t)return{name:"HubSpot CLI",found:!1,version:"",path:"",authenticated:!1,portalName:"",portalId:"",dataCenter:"na1",accounts:[],uploadMode:"cli"};let n=ft(),s=n.found?ht():{authenticated:!1,portalName:"",portalId:"",accounts:[]},o=s.portalId?es(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...wg()}}function tl(){let e=R(),t=e.hubspotUploadMode||"api",n=ji(e),s={authenticated:Ze(),expiresAt:Xt()?.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:Ji(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:Li({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:st("claude-code"),geminiCli:st("gemini-cli"),codexCli:st("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function nl(){let e=R(),t=ji(e),n={authenticated:Ze(),expiresAt:Xt()?.expiresAt},s=st("claude-code")?wn():{...xn,name:"Claude Code"},o=st("gemini-cli")?Cn():{...xn,name:"Gemini CLI"},i=st("codex-cli")?kn():{...xn,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:i,claudeOAuth:n,availableEngines:Li({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:i.found&&i.authenticated})}}function sl(){let t=R().hubspotUploadMode||"api",n=eo(),s=n.found?to():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:Ji(t,!0)}}function so(){let e=R(),t=e.hubspotUploadMode||"api",n=Zn(),s=Qn(),o=Ji(t,!0),i=eo(),r=i.found?to():{authenticated:!1,username:""},a={authenticated:Ze(),expiresAt:Xt()?.expiresAt},l=st("claude-code")?wn():{...xn,name:"Claude Code"},c=st("gemini-cli")?Cn():{...xn,name:"Gemini CLI"},d=st("codex-cli")?kn():{...xn,name:"OpenAI Codex CLI"},u=ji(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:Li({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 Zt,Za,xn,Qt=N(()=>{"use strict";y();qt();ee();_t();Zt=process.platform==="win32"?"where":"which",Za=4e3;xn={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as Cg}from"fs";import{basename as kg}from"path";async function il(e){let t=ol.get(e);if(t&&t.expiresAt-Date.now()>_g)return t;let n=await fetch(`${$t}/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 ol.set(e,o),o}async function Tn(e){let{accessToken:t}=await il(e);return{Authorization:`Bearer ${t}`}}function oo(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function $g(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Eg(e){return new Promise(t=>setTimeout(t,e))}async function ts(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 ns(e,t,n=Tg){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=Ag*Math.pow(2,s);await Eg(i);continue}return o}return fetch(e,t)}async function io(e){let t=await il(e),n=`${$t}/account-info/v3/details`,s=await ns(n,{headers:await Tn(e)});if(!s.ok){let a=await ts(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:$g(e)}}async function rl(e,t,n){let s=Cg(n),o=kg(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${$t}/cms/v3/source-code/published/content/${oo(t)}`,l=await ns(a,{method:"PUT",headers:await Tn(e),body:i});if(!l.ok){let c=await ts(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function Bi(e,t){let n=`${$t}/cms/v3/source-code/published/content/${oo(t)}`,s=await ns(n,{method:"DELETE",headers:await Tn(e)});if(!s.ok&&s.status!==404){let o=await ts(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function al(e,t){let n=`${$t}/cms/v3/source-code/published/content/${oo(t)}`,s=await ns(n,{method:"GET",headers:await Tn(e)});if(!s.ok){let i=await ts(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function ro(e,t){let n=`${$t}/cms/v3/source-code/published/metadata/${oo(t)}`,s=await ns(n,{method:"GET",headers:await Tn(e)});if(s.status===404)return null;if(!s.ok){let o=await ts(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function ll(e){let t=await Tn(e),n=[`${$t}/cms/v3/source-code/published/metadata`,`${$t}/cms/v3/source-code/published/metadata/`,`${$t}/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 $t,Tg,Ag,_g,ol,en=N(()=>{"use strict";y();$t="https://api.hubapi.com",Tg=3,Ag=1e3,_g=300*1e3,ol=new Map});import*as ae from"@clack/prompts";function Hi(e){ae.isCancel(e)&&(ae.cancel(I.muted("Operation cancelled.")),process.exit(0))}async function ge(e){ae.intro(I.heading(e))}async function fe(e){ae.outro(I.success(e))}async function yt(e,t){ae.note(e,t?I.heading(t):void 0)}async function Se(e){let t=await ae.text({message:I.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:e.validate});return Hi(t),t}async function Me(e){let t=await ae.confirm({message:I.accent(e.message),initialValue:e.initialValue??!0});return Hi(t),t}async function Et(e){let t=await ae.select({message:I.accent(e.message),options:e.options});return Hi(t),t}async function De(){let e=ae.spinner();return{start:t=>e.start(I.muted(t)),stop:t=>e.stop(I.success(t)),message:t=>e.message(I.muted(t))}}function D(e){ae.log.info(e)}function G(e){ae.log.success(I.success(e))}function se(e){ae.log.warn(I.warn(e))}function V(e){ae.log.error(I.error(e))}var Qe=N(()=>{"use strict";y();gt()});import{readdirSync as Ui,statSync as Mg}from"fs";import{join as he,basename as Gi,extname as Ig}from"path";function cl(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 dl(e){let t=[],n=[he(e,"src/components/landing"),he(e,"src/components/sections"),he(e,"src/components"),he(e,"src/pages"),he(e,"app/components"),he(e,"components")];for(let s of n)if(x(s))try{let o=Ui(s);for(let i of o){let r=he(s,i);if(!Mg(r).isFile())continue;let l=Ig(i);if(![".tsx",".jsx"].includes(l))continue;let c=Gi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=P(r),u=Pg(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function Pg(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 ul(e){let t=[he(e,"src/index.css"),he(e,"src/globals.css"),he(e,"src/app/globals.css"),he(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!x(o))continue;let i=P(o),r=i.match(/--[\w-]+:/g);r&&(n+=r.length);let a=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(a)for(let c of a){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function ml(e){let t=[],n=he(e,"src/hooks");if(x(n))try{let o=Ui(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=he(e,"src/components/landing");if(x(s))try{let o=Ui(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=P(he(s,i));/carousel|embla|swiper/i.test(r)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(r)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(r)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(r)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function pl(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!cl(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=Gi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",l),!x(t)){let c=Z(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!x(t))throw new Error(`Directory not found: ${t}`);let s=dl(t),o=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:i,fonts:r}=ul(t),a=ml(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function lo(){await ge("Source Project");let e=await Se({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){cl(e)||(V("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let h=Gi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",h),x(t))G(`Using existing clone: ${I.dim(t)}`);else{let f=await De();f.start("Cloning repository..."),Z(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${I.dim(t)}`)}}else t=e,x(t)||(V(`Directory not found: ${t}`),process.exit(1)),G(`Using local source: ${I.dim(t)}`);let s=await De();s.start("Analyzing project structure...");let o=dl(t),i=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:r,fonts:a}=ul(t),l=ml(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(se("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${I.dim(`${f+1}.`)} ${I.bold(h.name)} ${I.muted(`\u2014 ${h.description}`)}`).join(`
|
|
1
|
+
var dg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{for(var n in t)dg(e,n,{get:t[n],enumerable:!0})};import Av from"path";import{fileURLToPath as $v}from"url";var y=N(()=>{"use strict"});import fn from"chalk";function At(e){return Ha?fn:fn.hex(e)}var pt,Ha,I,gt=N(()=>{"use strict";y();pt={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},Ha=!!process.env.NO_COLOR;I={accent:At(pt.accent),accentBright:At(pt.accentBright),success:At(pt.success),info:At(pt.info),warn:At(pt.warn),error:At(pt.error),muted:At(pt.muted),vibes:At(pt.vibes),heading:Ha?fn.bold:fn.bold.hex(pt.accent),command:At(pt.accentBright),dim:fn.dim,bold:fn.bold}});import{readFileSync as Pi,writeFileSync as ug,mkdirSync as Ua,existsSync as Vs}from"fs";import{dirname as Ga,join as _t}from"path";import{fileURLToPath as mg}from"url";function P(e){return Pi(e,"utf-8")}function B(e,t){Ua(Ga(e),{recursive:!0}),ug(e,t,"utf-8")}function x(e){return Vs(e)}function Re(e){Ua(e,{recursive:!0})}function bn(e){let t=[_t(yn,"../../assets",e),_t(yn,"../assets",e),_t(process.cwd(),"assets",e)];for(let n of t)if(Vs(n))return n;throw new Error(`Asset not found: ${e}`)}function Sn(){if(hn)return hn;let e=[_t(yn,"../../package.json"),_t(yn,"../package.json"),_t(process.cwd(),"package.json")];for(let t of e)if(Vs(t))try{let n=JSON.parse(Pi(t,"utf-8"));if(n.name==="vibespot"&&n.version)return hn=n.version,hn}catch{}return hn="dev",hn}function Wa(){if(Ks)return Ks;let e=[_t(yn,"../../CHANGELOG.md"),_t(yn,"../CHANGELOG.md"),_t(process.cwd(),"CHANGELOG.md")];for(let t of e)if(Vs(t))try{return Ks=Pi(t,"utf-8"),Ks}catch{}return""}var yn,hn,Ks,oe=N(()=>{"use strict";y();yn=Ga(mg(import.meta.url));hn="";Ks=""});import{execSync as Ka,execFileSync as pg}from"child_process";function ie(e,t={}){try{return{stdout:Ka(e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Z(e,t={}){try{return{stdout:pg("git",e,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...t}).toString().trim(),stderr:"",success:!0}}catch(n){let s=n,o=(s.stdout??"").toString().trim(),i=(s.stderr??"").toString().trim();return{stdout:o,stderr:i,success:!1}}}function Va(e,t={}){try{return Ka(e,{stdio:"inherit",timeout:3e5,...t}),!0}catch{return!1}}var Qt=N(()=>{"use strict";y()});var qa={};Ge(qa,{addHubSpotAccount:()=>Xn,getActiveHubSpotAccount:()=>Ht,getApiKeyForEngine:()=>Fe,getConfigDir:()=>hg,getHubSpotPak:()=>Le,isCliToolEnabled:()=>st,loadConfig:()=>R,maskApiKey:()=>Ys,removeHubSpotAccount:()=>Ni,saveConfig:()=>Y,setActiveHubSpotAccount:()=>Ri,setCliToolEnabled:()=>Oi});import{join as za}from"path";import{homedir as gg}from"os";import{chmodSync as fg}from"fs";function R(){let e={};if(x(zs))try{e=JSON.parse(P(zs)),e.aiEngine==="api"&&(e.aiEngine="anthropic-api")}catch{e={}}return process.env.VIBESPOT_AI_ENGINE&&!e.aiEngine&&(e.aiEngine=process.env.VIBESPOT_AI_ENGINE),process.env.ANTHROPIC_API_KEY&&!e.anthropicApiKey&&(e.anthropicApiKey=process.env.ANTHROPIC_API_KEY),process.env.OPENAI_API_KEY&&!e.openaiApiKey&&(e.openaiApiKey=process.env.OPENAI_API_KEY),(process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)&&!e.geminiApiKey&&(e.geminiApiKey=process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY),process.env.LANGDOCK_API_KEY&&!e.langdockApiKey&&(e.langdockApiKey=process.env.LANGDOCK_API_KEY),process.env.LANGDOCK_BASE_URL&&!e.langdockBaseUrl&&(e.langdockBaseUrl=process.env.LANGDOCK_BASE_URL),process.env.LANGDOCK_PROVIDER&&!e.langdockProvider&&(e.langdockProvider=process.env.LANGDOCK_PROVIDER),process.env.FIGMA_TOKEN&&!e.figmaToken&&(e.figmaToken=process.env.FIGMA_TOKEN),process.env.VIBESPOT_AGENTIC_MODE!==void 0&&e.agenticMode===void 0&&(e.agenticMode=process.env.VIBESPOT_AGENTIC_MODE==="true"),process.env.LANGFUSE_PUBLIC_KEY&&!e.langfusePublicKey&&(e.langfusePublicKey=process.env.LANGFUSE_PUBLIC_KEY),process.env.LANGFUSE_SECRET_KEY&&!e.langfuseSecretKey&&(e.langfuseSecretKey=process.env.LANGFUSE_SECRET_KEY),process.env.LANGFUSE_BASE_URL&&!e.langfuseBaseUrl&&(e.langfuseBaseUrl=process.env.LANGFUSE_BASE_URL),process.env.LANGFUSE_ENABLED!==void 0&&e.langfuseEnabled===void 0&&(e.langfuseEnabled=process.env.LANGFUSE_ENABLED==="true"),e}function Fe(e,t){let n=t||R();switch(e){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;case"langdock-api":return n.langdockApiKey||process.env.LANGDOCK_API_KEY;default:return}}function Ys(e){return e.length<=12?"***":e.slice(0,7)+"..."+e.slice(-4)}function Y(e){let n={...R(),...e};if(B(zs,JSON.stringify(n,null,2)),process.platform!=="win32")try{fg(zs,384)}catch{}}function hg(){return Ya}function Ht(){let e=R();if(!e.hubspotAccounts?.length)return null;let t=e.activeHubSpotAccount;if(t){let n=e.hubspotAccounts.find(s=>s.portalId===t);if(n)return n}return e.hubspotAccounts[0]||null}function Xn(e,t,n,s){let i=R().hubspotAccounts||[],r=i.findIndex(l=>l.portalId===t),a={portalId:t,portalName:n,personalAccessKey:e,dataCenter:s,addedAt:new Date().toISOString()};r>=0?i[r]=a:i.push(a),Y({hubspotAccounts:i,activeHubSpotAccount:t})}function Ni(e){let t=R(),n=(t.hubspotAccounts||[]).filter(o=>o.portalId!==e),s={hubspotAccounts:n};t.activeHubSpotAccount===e&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),Y(s)}function Ri(e){Y({activeHubSpotAccount:e})}function Le(){return Ht()?.personalAccessKey||process.env.HUBSPOT_PERSONAL_ACCESS_KEY||null}function st(e){return R().enabledCLITools?.includes(e)??!1}function Oi(e,t){let n=R(),s=new Set(n.enabledCLITools||[]);t?s.add(e):s.delete(e),Y({enabledCLITools:[...s]})}var Ya,zs,ee=N(()=>{"use strict";y();oe();Ya=za(gg(),".vibespot"),zs=za(Ya,"config.json")});var ji={};Ge(ji,{OAUTH_EXTRA_HEADERS:()=>Zn,OAUTH_SYSTEM_PREFIX:()=>xn,clearOAuthTokens:()=>Zs,getOAuthTokenInfo:()=>en,getValidAccessToken:()=>Di,hasValidOAuthToken:()=>Ze,saveInitialToken:()=>Fi});import{join as yg}from"path";import{homedir as bg}from"os";import{chmodSync as Sg,unlinkSync as vg}from"fs";function Xs(){if(!x(vn))return null;try{return JSON.parse(P(vn))}catch{return null}}function Xa(e){if(B(vn,JSON.stringify(e,null,2)),process.platform!=="win32")try{Sg(vn,384)}catch{}}async function kg(e){let t=await fetch(wg,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({grant_type:"refresh_token",refresh_token:e,client_id:xg})});if(!t.ok)throw Zs(),new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let n=await t.json();Xa({access_token:n.access_token,refresh_token:n.refresh_token||e,expires_at:Date.now()+(n.expires_in||28800)*1e3})}function Fi(e,t=""){Xa({access_token:e,refresh_token:t,expires_at:Date.now()+28800*1e3})}function Ze(){let e=Xs();return e?e.expires_at>Date.now():!1}async function Di(){let e=Xs();if(!e)return null;if(e.expires_at-Date.now()>Cg)return e.access_token;if(e.refresh_token){qs||(qs=kg(e.refresh_token).finally(()=>{qs=null}));try{await qs}catch{return null}return Xs()?.access_token??null}return e.access_token}function en(){let e=Xs();return e?{expiresAt:new Date(e.expires_at).toISOString()}:null}function Zs(){if(x(vn))try{vg(vn)}catch{}}var xg,wg,vn,Cg,Zn,xn,qs,$t=N(()=>{"use strict";y();oe();xg="9d1c250a-e61b-44d9-88ed-5944d1962f5e",wg="https://console.anthropic.com/v1/oauth/token",vn=yg(bg(),".vibespot","claude-oauth.json"),Cg=300*1e3,Zn={"user-agent":"claude-cli/2.1.75","x-app":"cli","anthropic-beta":"oauth-2025-04-20"},xn="You are Claude Code, Anthropic's official CLI for Claude.";qs=null});import{join as Qs}from"path";import{homedir as eo}from"os";import{readFileSync as Za,existsSync as to,readdirSync as Tg}from"fs";function Qn(){let e=ie("node --version");return{name:"Node.js",found:e.success,version:e.stdout.replace(/^v/,""),path:ie(`${tn} node`).stdout}}function es(){let e=ie("git --version");return{name:"Git",found:e.success,version:e.stdout.replace("git version ",""),path:ie(`${tn} git`).stdout}}function ft(){let e=ie("hs --version");return{name:"HubSpot CLI",found:e.success,version:e.stdout,path:ie(`${tn} hs`).stdout}}function kn(){let e=ie("claude --version");if(!e.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Qs(eo(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(to(t)){let o=Tg(t);(o.some(r=>r.includes("credentials")||r.includes("auth")||r.includes("token")||r===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:e.stdout,path:ie(`${tn} claude`).stdout,authenticated:n,authDetail:s}}function ts(e){try{let t=Qs(eo(),".hscli","config.yml");if(!to(t))return"na1";let n=Za(t,"utf-8"),s=n.indexOf(`accountId: ${e}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let r=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!r)return"na1";if(r[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function ht(){let e=ie("hs accounts list",{timeout:Qa});if(!e.success||!e.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let t=[],n="",s="",o=e.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=e.stdout.split(`
|
|
2
|
+
`);for(let r of i){let a=r.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(a&&!/Account ID/i.test(r)&&!/^-+$/.test(r.trim())&&!/^Name\s/i.test(r.trim())){let l=a[1].trim(),c=a[2].trim(),d=a[3]?.trim()||"unknown";t.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:t}:t.length>0?{authenticated:!0,portalName:t[0].name,portalId:t[0].portalId,accounts:t}:{authenticated:e.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Tn(){let e=ie("gemini --version");if(!e.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=Qs(eo(),".config","gcloud","application_default_credentials.json"),n=to(t),s=!!(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_AI_API_KEY),o=n||s;return{name:"Gemini CLI",found:!0,version:e.stdout,path:ie(`${tn} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function An(){let e=ie("codex --version");if(!e.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let t=!!process.env.OPENAI_API_KEY,n=!1;try{let i=Qs(eo(),".codex","auth.json");to(i)&&(n=Za(i,"utf-8").length>10)}catch{}let s=t||n,o=n?"Authenticated (OAuth)":t?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:e.stdout,path:ie(`${tn} codex`).stdout,authenticated:s,authDetail:o}}function no(){let e=ie("gh --version");return{name:"GitHub CLI",found:e.success,version:e.stdout.split(`
|
|
3
|
+
`)[0]?.replace("gh version ","").split(" ")[0]||"",path:ie(`${tn} gh`).stdout}}function so(){let e=ie("gh auth status 2>&1",{timeout:Qa});if(!e.success&&!e.stdout)return{authenticated:!1,username:""};let t=e.stdout||e.stderr||"",n=t.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=t.match(/account\s+(\S+)/);return s&&t.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:t.includes("Logged in"),username:""}}function el(){return!!process.env.ANTHROPIC_API_KEY}function oo(e){return parseInt(e.split(".")[0],10)>=18}function tl(e){let t=parseInt(e.split(".")[0],10);return!isNaN(t)&&t>=8}function Ag(){let e=R(),t=e.hubspotUploadMode||"api",n=e.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(e.activeHubSpotAccount||n[0]?.portalId)})),o=Ht();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:t}}function wn(e,...t){if(e)return{configured:!0,masked:Ys(e),source:"config"};for(let n of t)if(process.env[n])return{configured:!0,masked:Ys(process.env[n]),source:"env"};return{configured:!1,masked:"",source:null}}function Li(e){return{anthropic:wn(e.anthropicApiKey,"ANTHROPIC_API_KEY"),openai:wn(e.openaiApiKey,"OPENAI_API_KEY"),gemini:wn(e.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),langdock:wn(e.langdockApiKey,"LANGDOCK_API_KEY"),langfusePublic:wn(e.langfusePublicKey,"LANGFUSE_PUBLIC_KEY"),langfuseSecret:wn(e.langfuseSecretKey,"LANGFUSE_SECRET_KEY")}}function Ji(e){let t=[];return e.claudeCode&&t.push("claude-code"),e.claudeOAuth&&t.push("claude-oauth"),e.apiKeys.anthropic.configured&&t.push("anthropic-api"),e.apiKeys.openai.configured&&t.push("openai-api"),e.geminiCli&&t.push("gemini-cli"),e.apiKeys.gemini.configured&&t.push("gemini-api"),e.codexCli&&t.push("codex-cli"),e.apiKeys.langdock.configured&&t.push("langdock-api"),t}function Bi(e,t){if(e==="cli"){if(!t)return{name:"HubSpot CLI",found:!1,version:"",path:"",authenticated:!1,portalName:"",portalId:"",dataCenter:"na1",accounts:[],uploadMode:"cli"};let n=ft(),s=n.found?ht():{authenticated:!1,portalName:"",portalId:"",accounts:[]},o=s.portalId?ts(s.portalId):"na1";return{...n,...s,dataCenter:o,uploadMode:"cli"}}return{name:"HubSpot API",found:!0,version:"v3",path:"",...Ag()}}function nl(){let e=R(),t=e.hubspotUploadMode||"api",n=Li(e),s={authenticated:Ze(),expiresAt:en()?.expiresAt},o=r=>({name:r,found:!1,version:"",path:"",authenticated:!1,authDetail:"Not scanned"}),i=r=>({name:r,found:!1,version:"",path:""});return{tools:{node:i("Node.js"),git:i("Git"),hubspot:Bi(t,!1),github:{...i("GitHub CLI"),authenticated:!1,username:""},claudeCode:o("Claude Code"),claudeOAuth:s,geminiCli:o("Gemini CLI"),codexCli:o("OpenAI Codex CLI")},apiKeys:n,activeEngine:e.aiEngine||null,availableEngines:Ji({apiKeys:n,claudeOAuth:s.authenticated,claudeCode:st("claude-code"),geminiCli:st("gemini-cli"),codexCli:st("codex-cli")}),enabledCLITools:e.enabledCLITools||[],scanned:!1}}function sl(){let e=R(),t=Li(e),n={authenticated:Ze(),expiresAt:en()?.expiresAt},s=st("claude-code")?kn():{...Cn,name:"Claude Code"},o=st("gemini-cli")?Tn():{...Cn,name:"Gemini CLI"},i=st("codex-cli")?An():{...Cn,name:"OpenAI Codex CLI"};return{claudeCode:s,geminiCli:o,codexCli:i,claudeOAuth:n,availableEngines:Ji({apiKeys:t,claudeOAuth:n.authenticated,claudeCode:s.found&&s.authenticated,geminiCli:o.found&&o.authenticated,codexCli:i.found&&i.authenticated})}}function ol(){let t=R().hubspotUploadMode||"api",n=no(),s=n.found?so():{authenticated:!1,username:""};return{github:{...n,...s},hubspot:Bi(t,!0)}}function io(){let e=R(),t=e.hubspotUploadMode||"api",n=Qn(),s=es(),o=Bi(t,!0),i=no(),r=i.found?so():{authenticated:!1,username:""},a={authenticated:Ze(),expiresAt:en()?.expiresAt},l=st("claude-code")?kn():{...Cn,name:"Claude Code"},c=st("gemini-cli")?Tn():{...Cn,name:"Gemini CLI"},d=st("codex-cli")?An():{...Cn,name:"OpenAI Codex CLI"},u=Li(e);return{tools:{node:n,git:s,hubspot:o,github:{...i,...r},claudeCode:l,claudeOAuth:a,geminiCli:c,codexCli:d},apiKeys:u,activeEngine:e.aiEngine||null,availableEngines:Ji({apiKeys:u,claudeOAuth:a.authenticated,claudeCode:l.found&&l.authenticated,geminiCli:c.found&&c.authenticated,codexCli:d.found&&d.authenticated}),enabledCLITools:e.enabledCLITools||[],scanned:!0}}var tn,Qa,Cn,nn=N(()=>{"use strict";y();Qt();ee();$t();tn=process.platform==="win32"?"where":"which",Qa=4e3;Cn={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"}});import{readFileSync as _g}from"fs";import{basename as $g}from"path";async function rl(e){let t=il.get(e);if(t&&t.expiresAt-Date.now()>Ig)return t;let n=await fetch(`${Et}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:e})});if(!n.ok){let i=await n.text().catch(()=>"");throw new Error(n.status===401||n.status===403?"Invalid or expired Personal Access Key":`Token exchange failed (${n.status}): ${i.slice(0,200)}`)}let s=await n.json(),o={accessToken:s.oauthAccessToken,expiresAt:s.expiresAtMillis,hubId:s.hubId,hubName:s.hubName||""};return il.set(e,o),o}async function _n(e){let{accessToken:t}=await rl(e);return{Authorization:`Bearer ${t}`}}function ro(e){return e.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function Pg(e){return e.startsWith("pat-eu1-")?"eu1":e.startsWith("pat-na1-")?"na1":e.startsWith("CiRldTE")?"eu1":"na1"}function Ng(e){return new Promise(t=>setTimeout(t,e))}async function ns(e,t){let n=`HTTP ${e.status}`,s,o;try{let i=await e.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let r=i.errors[0];o=r.message||JSON.stringify(r)}}catch{try{let i=await e.text();i&&(n=i.slice(0,500))}catch{}}return{status:e.status,message:t?`${n} (${t})`:n,category:s,detail:o}}async function ss(e,t,n=Eg){for(let s=0;s<=n;s++){let o=await fetch(e,t);if(o.status===429||o.status>=500&&s<n){let i=Mg*Math.pow(2,s);await Ng(i);continue}return o}return fetch(e,t)}async function ao(e){let t=await rl(e),n=`${Et}/account-info/v3/details`,s=await ss(n,{headers:await _n(e)});if(!s.ok){let a=await ns(s);throw new Error(`Failed to get account info: ${a.message}`)}let o=await s.json(),i=String(o.portalId||t.hubId||""),r=t.hubName||o.uiDomain||i;return{portalId:i,portalName:r,dataCenter:Pg(e)}}async function al(e,t,n){let s=_g(n),o=$g(n),i=new FormData,r=new Blob([s]);i.append("file",r,o);let a=`${Et}/cms/v3/source-code/published/content/${ro(t)}`,l=await ss(a,{method:"PUT",headers:await _n(e),body:i});if(!l.ok){let c=await ns(l,t);return{success:!1,path:t,error:c}}return{success:!0,path:t}}async function Hi(e,t){let n=`${Et}/cms/v3/source-code/published/content/${ro(t)}`,s=await ss(n,{method:"DELETE",headers:await _n(e)});if(!s.ok&&s.status!==404){let o=await ns(s,t);throw new Error(`Failed to delete ${t}: ${o.message}`)}}async function ll(e,t){let n=`${Et}/cms/v3/source-code/published/content/${ro(t)}`,s=await ss(n,{method:"GET",headers:await _n(e)});if(!s.ok){let i=await ns(s,t);throw new Error(`Failed to download ${t}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function lo(e,t){let n=`${Et}/cms/v3/source-code/published/metadata/${ro(t)}`,s=await ss(n,{method:"GET",headers:await _n(e)});if(s.status===404)return null;if(!s.ok){let o=await ns(s,t);throw new Error(`Failed to get metadata for ${t}: ${o.message}`)}return await s.json()}async function cl(e){let t=await _n(e),n=[`${Et}/cms/v3/source-code/published/metadata`,`${Et}/cms/v3/source-code/published/metadata/`,`${Et}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:t});if(o.ok){let i=await o.json(),r=i.children||i.objects||(Array.isArray(i)?i:null);if(r&&r.length>0)return r.filter(a=>a.folder)}}catch{}return[]}var Et,Eg,Mg,Ig,il,sn=N(()=>{"use strict";y();Et="https://api.hubapi.com",Eg=3,Mg=1e3,Ig=300*1e3,il=new Map});import*as ae from"@clack/prompts";function Ui(e){ae.isCancel(e)&&(ae.cancel(I.muted("Operation cancelled.")),process.exit(0))}async function ge(e){ae.intro(I.heading(e))}async function fe(e){ae.outro(I.success(e))}async function yt(e,t){ae.note(e,t?I.heading(t):void 0)}async function Se(e){let t=e.validate,n=await ae.text({message:I.accent(e.message),placeholder:e.placeholder,defaultValue:e.defaultValue,validate:t?s=>t(s??""):void 0});return Ui(n),n}async function Me(e){let t=await ae.confirm({message:I.accent(e.message),initialValue:e.initialValue??!0});return Ui(t),t}async function Mt(e){let t=await ae.select({message:I.accent(e.message),options:e.options});return Ui(t),t}async function De(){let e=ae.spinner();return{start:t=>e.start(I.muted(t)),stop:t=>e.stop(I.success(t)),message:t=>e.message(I.muted(t))}}function D(e){ae.log.info(e)}function G(e){ae.log.success(I.success(e))}function se(e){ae.log.warn(I.warn(e))}function V(e){ae.log.error(I.error(e))}var Qe=N(()=>{"use strict";y();gt()});import{readdirSync as Gi,statSync as Rg}from"fs";import{join as he,basename as Wi,extname as Og}from"path";function dl(e){return typeof e!="string"||e.length===0||e.length>2048||/[\s;&|`$()<>\\]/.test(e)?!1:!!(/^https?:\/\/[^\s]+$/.test(e)||/^git@[\w.-]+:[\w./~+-]+$/.test(e))}function ul(e){let t=[],n=[he(e,"src/components/landing"),he(e,"src/components/sections"),he(e,"src/components"),he(e,"src/pages"),he(e,"app/components"),he(e,"components")];for(let s of n)if(x(s))try{let o=Gi(s);for(let i of o){let r=he(s,i);if(!Rg(r).isFile())continue;let l=Og(i);if(![".tsx",".jsx"].includes(l))continue;let c=Wi(i,l);if(c.startsWith("ui")||c==="index")continue;let d=P(r),u=Fg(c,d);t.push({name:c,path:r,description:u})}}catch{}return t}function Fg(e,t){let n=[];return/carousel|slider|swiper|embla/i.test(t)&&n.push("carousel"),/accordion|collapsible|expand/i.test(t)&&n.push("accordion"),/form|submit|input.*email/i.test(t)&&n.push("form"),/nav|navigation|menu/i.test(t)&&n.push("navigation"),/hero|headline|tagline/i.test(t)&&n.push("hero"),/footer|copyright/i.test(t)&&n.push("footer"),/testimonial|quote|review/i.test(t)&&n.push("testimonials"),/pricing|plan|tier/i.test(t)&&n.push("pricing"),/faq|question.*answer/i.test(t)&&n.push("FAQ"),/feature|benefit|advantage/i.test(t)&&n.push("features"),/contact|get.in.touch/i.test(t)&&n.push("contact"),/cta|call.to.action/i.test(t)&&n.push("CTA"),/team|member|bio/i.test(t)&&n.push("team"),n.length===0?e.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function ml(e){let t=[he(e,"src/index.css"),he(e,"src/globals.css"),he(e,"src/app/globals.css"),he(e,"app/globals.css")],n=0,s=[];for(let o of t){if(!x(o))continue;let i=P(o),r=i.match(/--[\w-]+:/g);r&&(n+=r.length);let a=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(a)for(let c of a){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function pl(e){let t=[],n=he(e,"src/hooks");if(x(n))try{let o=Gi(n);for(let i of o)/scroll/i.test(i)&&t.push("Scroll animations"),/intersection/i.test(i)&&t.push("Scroll animations")}catch{}let s=he(e,"src/components/landing");if(x(s))try{let o=Gi(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let r=P(he(s,i));/carousel|embla|swiper/i.test(r)&&!t.includes("Carousel")&&t.push("Carousel"),/accordion|collapsible/i.test(r)&&!t.includes("Accordion")&&t.push("Accordion"),/typing|typewriter/i.test(r)&&!t.includes("Typing animation")&&t.push("Typing animation"),/parallax|requestAnimationFrame/i.test(r)&&!t.includes("Parallax")&&t.push("Parallax")}}catch{}return t.length===0&&t.push("Scroll animations"),t}function gl(e){let t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){if(!dl(e))throw new Error(`Refusing to clone unsafe source URL: ${e}. Only http(s):// and git@host:path URLs without shell metacharacters are allowed.`);n=!0;let l=Wi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",l),!x(t)){let c=Z(["clone","--depth","1","--",e,t]);if(!c.success)throw new Error(`Failed to clone ${e}: ${c.stderr}`)}}else if(t=e,!x(t))throw new Error(`Directory not found: ${t}`);let s=ul(t),o=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:i,fonts:r}=ml(t),a=pl(t);return{sourceDir:t,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:r,interactions:a}}async function uo(){await ge("Source Project");let e=await Se({message:"GitHub URL or local path to your React project:",placeholder:"https://github.com/user/my-lovable-page",validate:h=>{if(!h.trim())return"Please enter a URL or path"}}),t,n=!1;if(e.startsWith("http")||e.startsWith("git@")){dl(e)||(V("Refusing to clone unsafe source URL. Only http(s):// and git@host:path URLs without shell metacharacters are allowed."),process.exit(1)),n=!0;let h=Wi(e.replace(/\.git$/,""))||"react-source";if(t=he(process.cwd(),"workspace",h),x(t))G(`Using existing clone: ${I.dim(t)}`);else{let f=await De();f.start("Cloning repository..."),Z(["clone","--depth","1","--",e,t]).success||(f.stop("Clone failed"),V(`Failed to clone ${e}. Check the URL and your access permissions.`),process.exit(1)),f.stop(`Cloned to ${I.dim(t)}`)}}else t=e,x(t)||(V(`Directory not found: ${t}`),process.exit(1)),G(`Using local source: ${I.dim(t)}`);let s=await De();s.start("Analyzing project structure...");let o=ul(t),i=x(he(t,"tailwind.config.ts"))||x(he(t,"tailwind.config.js")),{varCount:r,fonts:a}=ml(t),l=pl(t);s.stop(`Found ${o.length} landing page components`),o.length===0&&(se("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,f)=>` ${I.dim(`${f+1}.`)} ${I.bold(h.name)} ${I.muted(`\u2014 ${h.description}`)}`).join(`
|
|
4
4
|
`),d=i?`Tailwind + custom CSS (${r} variables)`:`Custom CSS (${r} variables)`,u=a.length>0?a.join(", "):"System fonts",m=l.join(", ");return await yt(`${c}
|
|
5
5
|
|
|
6
6
|
CSS: ${d}
|
|
7
7
|
JS: ${m}
|
|
8
|
-
Font: ${u}`,`${o.length} components detected`),await Me({message:"Does this look right?"})||(V("Please adjust your source directory and try again."),process.exit(0)),await fe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var
|
|
9
|
-
`),
|
|
8
|
+
Font: ${u}`,`${o.length} components detected`),await Me({message:"Does this look right?"})||(V("Please adjust your source directory and try again."),process.exit(0)),await fe("Source analyzed!"),{sourceDir:t,wasCloned:n,components:o,hasTailwind:i,cssVarCount:r,fonts:a,interactions:l}}var mo=N(()=>{"use strict";y();Qt();oe();Qe();gt()});var fl={};Ge(fl,{addEmailTemplateToTheme:()=>$n,createThemeScaffold:()=>is});import{mkdirSync as It,writeFileSync as os}from"fs";import{join as We}from"path";function is(e,t){It(e,{recursive:!0}),It(We(e,"templates"),{recursive:!0}),It(We(e,"modules"),{recursive:!0}),It(We(e,"css"),{recursive:!0}),It(We(e,"js"),{recursive:!0}),It(We(e,"images"),{recursive:!0}),It(We(e,"assets"),{recursive:!0});let n={label:t,preview_path:"./templates/home.html",screenshot_path:"./images/template-previews/home.png",enable_domain_stylesheets:!1,version:"1.0.0",author:{name:"vibeSpot",url:"https://github.com/borismichel/vibespot"}};os(We(e,"theme.json"),JSON.stringify(n,null,2)+`
|
|
9
|
+
`),os(We(e,"fields.json"),`[]
|
|
10
10
|
`);let s=`<!--
|
|
11
11
|
templateType: page
|
|
12
12
|
isAvailableForNewContent: false
|
|
@@ -22,7 +22,7 @@ var rg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
|
|
|
22
22
|
%}
|
|
23
23
|
{% end_dnd_area %}
|
|
24
24
|
{% endblock body %}
|
|
25
|
-
`;
|
|
25
|
+
`;os(We(e,"templates","home.html"),s);let o=`<!--
|
|
26
26
|
templateType: none
|
|
27
27
|
isAvailableForNewContent: false
|
|
28
28
|
label: Base Layout
|
|
@@ -45,7 +45,7 @@ var rg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
|
|
|
45
45
|
{{ standard_footer_includes }}
|
|
46
46
|
</body>
|
|
47
47
|
</html>
|
|
48
|
-
`;
|
|
48
|
+
`;It(We(e,"templates","layouts"),{recursive:!0}),os(We(e,"templates","layouts","base.html"),o)}function $n(e,t){let n=`<!--
|
|
49
49
|
templateType: email
|
|
50
50
|
isAvailableForNewContent: true
|
|
51
51
|
label: ${t} Email Template
|
|
@@ -84,8 +84,8 @@ var rg=Object.defineProperty;var N=(e,t)=>()=>(e&&(t=e(e=0)),t);var Ge=(e,t)=>{f
|
|
|
84
84
|
{{ standard_footer_includes }}
|
|
85
85
|
</body>
|
|
86
86
|
</html>
|
|
87
|
-
`;
|
|
88
|
-
## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function
|
|
87
|
+
`;It(We(e,"templates"),{recursive:!0}),os(We(e,"templates","email.html"),n)}var rs=N(()=>{"use strict";y()});var yl={};Ge(yl,{fetchTheme:()=>as});import{mkdirSync as hl,writeFileSync as Dg}from"fs";import{join as jg,dirname as Lg}from"path";async function Ki(e,t){let n=await lo(e,t);if(!n)return[];if(!n.folder)return[n.path||t];let s=[],o=n.children||[];for(let i of o){let r=typeof i=="string"?i:i.name;if(!r)continue;let a=`${t}/${r}`;if(typeof i=="string")s.push(...await Ki(e,a));else{let l=i;l.folder?s.push(...await Ki(e,l.path||a)):s.push(l.path||a)}}return s}async function Jg(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function as(e,t,n,s={}){let o=s.concurrency??5,i=await Ki(e,t);if(i.length===0)throw new Error(`Theme "${t}" not found on HubSpot or is empty`);hl(n,{recursive:!0}),await Jg(i,o,async r=>{let a=r.startsWith(t+"/")?r.slice(t.length+1):r,l=jg(n,a);hl(Lg(l),{recursive:!0});let c=await ll(e,r);Dg(l,c),s.onFile?.(a)})}var po=N(()=>{"use strict";y();sn()});function Ut(e){let t=bl.get(e);if(t!==void 0)return t;try{t=P(bn(e))}catch{t=""}return bl.set(e,t),t}function ye(){return Ut("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function cs(){return Ut("design-guide.md")}function Vi(){return Ut("content-guide.md")}function Je(){return Ut("hubspot-rules.md")}function zi(){return Ut("humanify-guide.md")}function Sl(){return Ut("email-rules.md")}function vl(){return Ut("blog-rules.md")}function Yi(e){let t=Ut("page-types.md");if(!t)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[e];if(!s)return"";let o=t.indexOf(s);if(o<0)return"";let i=t.indexOf(`
|
|
88
|
+
## `,o+s.length);return i>=0?t.slice(o,i).trim():t.slice(o).trim()}function xl(e){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
|
|
89
89
|
|
|
90
90
|
## Rules
|
|
91
91
|
Follow the conversion guide below EXACTLY. Key rules:
|
|
@@ -105,7 +105,7 @@ Follow the conversion guide below EXACTLY. Key rules:
|
|
|
105
105
|
${Je()}
|
|
106
106
|
|
|
107
107
|
## Conversion Guide
|
|
108
|
-
${e}`}function
|
|
108
|
+
${e}`}function wl(e,t,n){return`Convert this React component to a HubSpot module named "${t}".
|
|
109
109
|
|
|
110
110
|
Return a JSON object with these keys:
|
|
111
111
|
- fieldsJson: complete fields.json content (as JSON string)
|
|
@@ -120,7 +120,7 @@ ${n}
|
|
|
120
120
|
React component source:
|
|
121
121
|
${e}
|
|
122
122
|
|
|
123
|
-
Return ONLY valid JSON, no markdown fences.`}function
|
|
123
|
+
Return ONLY valid JSON, no markdown fences.`}function Cl(e,t,n){return`Create a shared CSS file for a HubSpot CMS landing page.
|
|
124
124
|
|
|
125
125
|
Extract the design system from the source CSS and Tailwind config below.
|
|
126
126
|
Use the class prefix ".${n}-" for all custom classes.
|
|
@@ -144,7 +144,7 @@ ${e}
|
|
|
144
144
|
Tailwind config:
|
|
145
145
|
${t}
|
|
146
146
|
|
|
147
|
-
Return ONLY the CSS content, no markdown fences.`}function
|
|
147
|
+
Return ONLY the CSS content, no markdown fences.`}function kl(e,t,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
|
|
148
148
|
|
|
149
149
|
Convert the React hooks and interactive components below to plain JavaScript.
|
|
150
150
|
Use the class prefix "${n}-" to match the CSS.
|
|
@@ -162,7 +162,7 @@ ${e}
|
|
|
162
162
|
Interactive component sources:
|
|
163
163
|
${t}
|
|
164
164
|
|
|
165
|
-
Return ONLY the JavaScript content, no markdown fences.`}function
|
|
165
|
+
Return ONLY the JavaScript content, no markdown fences.`}function Tl(e,t,n){return`Create a HubSpot page template that assembles these modules:
|
|
166
166
|
|
|
167
167
|
${e.map((s,o)=>`${o+1}. ${s}.module`).join(`
|
|
168
168
|
`)}
|
|
@@ -177,29 +177,29 @@ Template requirements:
|
|
|
177
177
|
- Each module in its own dnd_section with padding zeroed and full_width=true
|
|
178
178
|
- dnd_area label: "${t} Landing Page"
|
|
179
179
|
|
|
180
|
-
Return ONLY the template HTML content, no markdown fences.`}var
|
|
181
|
-
`)}catch{}}}var go,Kg,qi,Xi,E,le=N(()=>{"use strict";y();go=Zi(Wg(),".vibespot","logs"),Kg=7,qi=!1,Xi=!1;E={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),Yi("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),Yi("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),Yi("ERROR",o)}}});function Zg(e){let t=(e||"").toLowerCase();return Xg.find(n=>t.includes(n.match))}function cs(e,t){let n=Zg(e);if(!n)return;let s=n.cacheReadPerM??n.inputPerM*.1,o=n.cacheWritePerM??n.inputPerM*1.25,i=(t.inputTokens??0)*n.inputPerM,r=(t.outputTokens??0)*n.outputPerM,a=(t.cacheReadTokens??0)*s,l=(t.cacheCreationTokens??0)*o,c={total:(i+r+a+l)/1e6};return t.inputTokens!=null&&(c.input=i/1e6),t.outputTokens!=null&&(c.output=r/1e6),t.cacheReadTokens&&(c.cache_read_input_tokens=a/1e6),t.cacheCreationTokens&&(c.cache_creation_input_tokens=l/1e6),c}function et(e){if(e)return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_input_tokens??void 0,cacheCreationTokens:e.cache_creation_input_tokens??void 0}}function _n(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 $n(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 Al(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 Xg,tn=N(()=>{"use strict";y();Xg=[{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 Qg}from"async_hooks";function ef(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function tf(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 Qi(e){let t=ef();return{result:await _l.run(t,e),cost:tf(t)}}function $l(e,t){if(!t)return;let n=_l.getStore();if(!n)return;n.inputTokens+=t.inputTokens??0,n.outputTokens+=t.outputTokens??0,n.cacheReadTokens+=t.cacheReadTokens??0,n.cacheCreationTokens+=t.cacheCreationTokens??0,n.calls+=1;let s=cs(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}var _l,er=N(()=>{"use strict";y();tn();_l=new Qg});import{randomUUID as Bt}from"crypto";import{AsyncLocalStorage as nf}from"async_hooks";function Ml(){let e=R(),t=e.langfusePublicKey||process.env.LANGFUSE_PUBLIC_KEY,n=e.langfuseSecretKey||process.env.LANGFUSE_SECRET_KEY;if(!(e.langfuseEnabled===!0||process.env.LANGFUSE_ENABLED==="true")||!t||!n)return null;let o=(e.langfuseBaseUrl||process.env.LANGFUSE_BASE_URL||sf).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function tr(){return Ml()!==null}function ho(e){if(typeof e=="string")return e.length>En?e.slice(0,En)+`\u2026[+${e.length-En} chars]`:e;try{let t=JSON.stringify(e);if(t&&t.length>En)return t.slice(0,En)+`\u2026[+${t.length-En} chars]`}catch{return"[unserializable]"}return e}async function tt(e,t){if(!tr())return t();let n=Bt();nn.push({id:Bt(),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:ho(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await fo.run({traceId:n,sessionId:e.sessionId},t)}finally{await Il()}}async function te(e,t,n){let s=fo.getStore();if(!tr()||!s?.traceId)return t();let o=Bt(),i=s.spanId,r=new Date,a,l;try{return await fo.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{nn.push({id:Bt(),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:ho(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function of(e){if(tr())try{let t=fo.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Bt(),o=!0,nn.push({id:Bt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let i=e.usage?Al(e.usage):void 0,r=e.usage?cs(e.model,e.usage):void 0;nn.push({id:Bt(),type:"generation-create",timestamp:new Date().toISOString(),body:{id:Bt(),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:ho(e.input)}:{},...e.output!==void 0?{output:ho(e.output)}:{},...i?{usageDetails:i}:{},...r?{costDetails:r}:{},...e.level?{level:e.level}:{},...e.statusMessage?{statusMessage:e.statusMessage}:{},metadata:{...e.engine?{engine:e.engine}:{},...e.metadata??{}}}}),o&&await Il()}catch(t){E.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function St(e){let{engine:t,model:n,name:s,usage:o,startTime:i,endTime:r}=e,a=r.getTime()-i.getTime(),l=o?cs(n,o):void 0;if(o&&E.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),El.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:i,endTime:r,durationMs:a};for(let d of El)try{d(c)}catch{}}$l(n,o),of({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})}async function Il(){let e=Ml();if(!e||nn.length===0)return;let t=nn;nn=[];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(()=>"");E.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else E.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){E.warn("langfuse",`ingestion failed: ${n.message}`)}}var sf,En,fo,nn,El,Be=N(()=>{"use strict";y();ee();le();tn();er();sf="https://cloud.langfuse.com",En=24e3,fo=new nf,nn=[],El=new Set});import{join as me}from"path";import{readdirSync as it,rmSync as yf}from"fs";function Co(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 ko(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 To(e){let t=[];return Dl(e)&&t.push("textarea \u2192 text"),jl(e)&&t.push("name \u2192 item_name"),Ll(e)&&t.push("now() \u2192 local_dt"),Jl(e)&&t.push("Removed HubDB templates"),Bl(e)&&t.push("Fixed link field defaults"),Hl(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),bf(e)&&t.push("Stripped CDN @import statements"),Gl(e)&&t.push('dnd_area \u2192 "main" in email templates'),Wl(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function Fl(e,t){return t.message.includes("textarea")?Dl(e):t.message.includes("reserved field name")?jl(e):t.message.includes("now()")?Ll(e):t.message.includes("HubDB")?Jl(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?Bl(e):t.message.includes("invalid format")&&t.message.includes("color")?Hl(e):t.message.includes("dnd")||t.message.includes("Dnd area")?Gl(e):t.message.includes("dnd_area_stylesheet")?Wl(e):!1}function Dl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),B(o,i),t=!0)}return t}function jl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),B(o,i),t=!0)}return t}function Ll(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"module.html");if(!x(o))continue;let i=P(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),B(o,i),t=!0)}return t}function Jl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(yf(o),t=!0)}return t}function Bl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));Kl(i)&&(B(o,JSON.stringify(i,null,2)+`
|
|
182
|
-
`),t=!0)}catch{}}return t}function
|
|
183
|
-
`),t=!0)}catch{}}return t}function
|
|
184
|
-
{{ dnd_area_stylesheet }}`);r!==i&&(B(o,r),t=!0)}return t}function
|
|
185
|
-
`),"utf-8")}function
|
|
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 ac(e,t=50){if(!rt())return[];if(!It(vt(e,".git")))return[];if(!ic(t))return[];let n=Z(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:rc(n.stdout)}function lc(e,t,n=50){if(!rt())return[];if(!It(vt(e,".git")))return[];if(!ic(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=Z(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:rc(o.stdout)}function cc(e,t){if(!rt())return{success:!1,error:"Git not available"};if(!It(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!oc(t))return{success:!1,error:"Invalid commit hash"};let n=Z(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=Z(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=Z(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return Z(["commit","-m",r],{cwd:e}),{success:!0}}function dc(e,t,n,s){if(!rt())return{success:!1,error:"Git not available"};if(!It(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!oc(n))return{success:!1,error:"Invalid commit hash"};let o=Z(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=Z(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)Z(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};Z(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return Z(["commit","-m",c],{cwd:e}),{success:!0}}var $o,In=N(()=>{"use strict";y();qt();$o=null});import{readFileSync as Pf,existsSync as mc,writeFileSync as Nf,mkdirSync as Rf,rmSync as Of}from"fs";import{join as Mo}from"path";function on(e){let t=C();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e.plan)}function at(){let e=C();if(!e)return;let t=ke();if(!t){if(e.modules.length===0)return;let n={modules:e.modules,moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,template:e.template,messages:e.messages,plan:e.brandAssets?.plan};t=Pt("landing_page",`${e.themeName} Landing Page`),e.activeTemplateId=t.id,e.modules=n.modules,e.moduleOrder=n.moduleOrder,e.sharedCss=n.sharedCss,e.sharedJs=n.sharedJs,e.template=n.template,e.messages=n.messages,e.brandAssets&&(e.brandAssets.plan=n.plan)}t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.plan=e.brandAssets?.plan}function lt(e,t,n){let s=C();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),at(),Df()}function pc(e){let t=C();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),L())}function gc(e){let t=C();if(!t)return;if(e.calls===0)return t.costTotal;let n=t.costTotal??{costUsd:0,totalTokens:0,generations:0,costComplete:!0},s={costUsd:n.costUsd+e.costUsd,totalTokens:n.totalTokens+e.totalTokens,generations:n.generations+1,costComplete:n.costComplete&&e.costComplete};return t.costTotal=s,t.updatedAt=Date.now(),s}function uc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function Ff(e,t){let n=uc(e),s=uc(t);if(n===s)return!0;if(n.length<4||s.length<4)return!1;let o=n.length<=s.length?n:s,i=n.length<=s.length?s:n;return i.includes(o)?o.length/i.length>=.8:!1}function He(e){let t=C();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let i=t.modules.find(r=>Ff(r.moduleName,n.moduleName));i&&E.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${i.moduleName}" \u2014 adding as a new module. This usually indicates the Module Planner re-named an existing module. Check the prompt's "preserve existing names" rule.`),t.modules.push(n),t.moduleOrder.some(r=>r.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),at()}}function Ht(e){let t=C();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),at())}function fc(e){let t=C();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=Mo(t.themePath,"modules",`${e}.module`);mc(n)&&Of(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),at()}}function hc(e){let t=C();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),at())}function yc(e,t,n){let s=C();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);vc(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),at()}catch{}}function ve(){let e=C();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Df(){let e=C();if(e)try{let t=Mo(e.themePath,".vibespot");Rf(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};Nf(Mo(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function bc(e){let t=Mo(e,".vibespot","chat.json");if(!mc(t))return[];try{let n=JSON.parse(Pf(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Sc(e){let t=C();if(t){for(let n of t.templates)n.sharedCss=e.sharedCss,n.sharedJs=e.sharedJs;t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs;for(let n of e.pages){let s=e.pageLabels.get(n.pageId),o=s?.label||n.pageId,i=s?.pageType||"website_page",r=t.templates.find(a=>a.id===n.templateId);r||(r=Pt(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&&ms(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 us=N(()=>{"use strict";y();ps();Ut();le()});import{existsSync as Io,rmSync as Po}from"fs";import{join as Pn}from"path";function No(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function ke(){let e=C();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function ms(e){let t=C();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,on(n),t.updatedAt=Date.now(),!0):!1}function Pt(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=n==="email",a=`${i?"email":e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:t,pageType:e,contentMode:n,templateFile:i?"templates/email.html":e==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,on(l),s.updatedAt=Date.now(),l}function xc(e,t){let n=C();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:a,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${a}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[],plan:s.plan};return n.templates.push(l),n.activeTemplateId=a,on(l),n.updatedAt=Date.now(),l}function wc(e){let t=C();if(!t||!Array.isArray(e)||e.length===0)return!1;let n=new Map(t.templates.map(i=>[i.id,i])),s=new Set,o=[];for(let i of e){let r=n.get(i);!r||s.has(i)||(o.push(r),s.add(i))}for(let i of t.templates)s.has(i.id)||o.push(i);return o.length!==t.templates.length?!1:(t.templates=o,t.updatedAt=Date.now(),!0)}function Cc(e,t){let n=C();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function kc(e,t=!1){let n=C();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Pn(n.themePath,"templates"),r=`${o.id}.html`,a=Pn(i,r);if(Io(a)&&Po(a,{force:!0}),o.pageType==="blog_post"){let l=Pn(i,`${o.id}-listing.html`);Io(l)&&Po(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=Pn(n.themePath,"modules");for(let l of r){let c=Pn(a,`${l}.module`);Io(c)&&Po(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?ms(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=Pn(n.themePath,".vibespot","plan.md");Io(r)&&Po(r,{force:!0})}return n.updatedAt=Date.now(),!0}function Nt(){let e=C();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of e.modules)t.has(n.moduleName)||t.set(n.moduleName,{module:n,usedIn:[]});return Array.from(t.values())}var Ut=N(()=>{"use strict";y();ps();us()});import{readFileSync as xt,readdirSync as cr,existsSync as Ie,writeFileSync as gs,mkdirSync as Ro,rmSync as ir,renameSync as rr,cpSync as jf}from"fs";import{join as pe,dirname as Tc}from"path";import{homedir as Lf}from"os";function Oo(){if(Nn)return Nn;try{return Ie(ar)?(Nn=JSON.parse(xt(ar,"utf-8")),Nn):lr()}catch{return lr()}}function Fo(e){Nn=e;try{Ro(de,{recursive:!0}),gs(ar,JSON.stringify(e),"utf-8")}catch{}}function lr(){if(!Ie(de))return[];let e=[];for(let t of cr(de).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(xt(pe(de,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length,pageCount:s.filter(o=>o.contentMode!=="email").length,emailCount:s.filter(o=>o.contentMode==="email").length,hasBrandAssets:!!(n.brandAssets&&(n.brandAssets.styleguide||n.brandAssets.brandvoice||n.brandAssets.brandKit)),isImported:!!n.isImported})}catch{}return Nn=e,Fo(e),e}function Ac(e){let t=Oo(),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),Fo(t)}function Jf(e){let t=Oo().filter(n=>n.id!==e);Fo(t)}function Bf(e){let t=Oo().filter(n=>n.themeName!==e);Fo(t)}function C(){return Ue}function _c(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Rn(e,t,n={}){let s={id:_c(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Ue=s,Eo(e),s}function L(){if(!Ue)return;Ro(de,{recursive:!0});let e=pe(de,`${Ue.id}.json`);gs(e,JSON.stringify(Ue,null,2),"utf-8"),Ac(Ue)}function Do(e){let t=pe(de,e+".json");if(!Ie(t))return null;try{let n=JSON.parse(xt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),No(n),n.brandAssets?.plan&&n.templates?.length>0){let s=n.templates.find(o=>o.id===n.activeTemplateId)||n.templates[0];s.plan||(s.plan=n.brandAssets.plan)}return Ue=n,n}catch{return null}}function On(){return Ie(de)?Oo():[]}function $c(e,t=!1){let n=pe(de,e+".json"),s="";if(t)try{let o=JSON.parse(xt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ie(o.themePath)&&ir(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(xt(n,"utf-8")).themeName||""}catch{}try{Ie(n)&&ir(n)}catch{}if(s&&Ie(de)){for(let o of cr(de).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(xt(pe(de,o),"utf-8")).themeName===s&&ir(pe(de,o))}catch{}Bf(s)}else Jf(e);Ue?.id===e&&(Ue=null)}function Ec(e,t){let n=pe(de,e+".json");if(!Ie(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(xt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,r=pe(Tc(i),t);if(Ie(i)){if(Ie(r))return{ok:!1,error:"A project with that name already exists"};try{rr(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=pe(r,"css",`${o}-theme.css`),l=pe(r,"css",`${t}-theme.css`);if(Ie(a))try{rr(a,l)}catch{}let c=pe(r,"js",`${o}-animations.js`),d=pe(r,"js",`${t}-animations.js`);if(Ie(c))try{rr(c,d)}catch{}let u=pe(r,"theme.json");if(Ie(u))try{let m=JSON.parse(xt(u,"utf-8"));m.label=t,m.name=t,gs(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ie(de))for(let a of cr(de).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(xt(pe(de,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),gs(pe(de,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Ue&&Ue.themeName===o&&(Ue.themeName=t,Ue.themePath=r,Ue.updatedAt=Date.now()),lr(),{ok:!0}}function Mc(e){let t=pe(de,e+".json");if(!Ie(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(xt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=Tc(n.themePath),i=`${s}-copy`,r=1;for(;Ie(pe(o,i));)r++,i=`${s}-copy-${r}`;let a=pe(o,i);if(Ie(n.themePath))try{jf(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else Ro(a,{recursive:!0});let l=_c(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return Ro(de,{recursive:!0}),gs(pe(de,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),Ac(c),{ok:!0,newName:i,newSessionId:l}}var de,ar,Nn,Ue,ps=N(()=>{"use strict";y();In();Ut();de=pe(Lf(),".vibespot","sessions"),ar=pe(de,"_index.json"),Nn=null;Ue=null});import{readFileSync as Hf,readdirSync as Nc,statSync as dr}from"fs";import{createHash as Uf}from"crypto";import{join as be,relative as Gf}from"path";function Jo(e){let t=[];if(!x(e))return fh(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=Fn(e),s=uh(e),o=ph(e),i=gh(e),r=Yf(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 fs(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 {
|
|
180
|
+
Return ONLY the template HTML content, no markdown fences.`}var bl,Ke=N(()=>{"use strict";y();oe();bl=new Map});import{appendFileSync as Wg,mkdirSync as Kg,readdirSync as Vg,unlinkSync as zg}from"fs";import{join as Qi}from"path";import{homedir as Yg}from"os";function Xg(){if(!Xi)try{Kg(ho,{recursive:!0}),Xi=!0}catch{}}function Zg(){if(!Zi){Zi=!0;try{let e=Date.now()-qg*864e5;for(let t of Vg(ho)){if(!t.startsWith("vibespot-")||!t.endsWith(".log"))continue;let n=t.slice(9,19),s=new Date(n).getTime();if(s&&s<e)try{zg(Qi(ho,t))}catch{}}}catch{}}}function Qg(){let t=new Date().toISOString().slice(0,10);return Qi(ho,`vibespot-${t}.log`)}function ef(){return new Date().toISOString().slice(11,23)}function qi(e,t){if(Xg(),!!Xi){Zi||Zg();try{Wg(Qg(),`${ef()} ${e} ${t}
|
|
181
|
+
`)}catch{}}}var ho,qg,Xi,Zi,M,le=N(()=>{"use strict";y();ho=Qi(Yg(),".vibespot","logs"),qg=7,Xi=!1,Zi=!1;M={info(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.log(s),qi("INFO",s)},warn(e,t,n){let s=n?`[${e}] ${t} ${JSON.stringify(n)}`:`[${e}] ${t}`;console.warn(s),qi("WARN",s)},error(e,t,n){let s=n instanceof Error?n.message:n?String(n):"",o=s?`[${e}] ${t}: ${s}`:`[${e}] ${t}`;console.error(o),qi("ERROR",o)}}});function nf(e){let t=(e||"").toLowerCase();return tf.find(n=>t.includes(n.match))}function ds(e,t){let n=nf(e);if(!n)return;let s=n.cacheReadPerM??n.inputPerM*.1,o=n.cacheWritePerM??n.inputPerM*1.25,i=(t.inputTokens??0)*n.inputPerM,r=(t.outputTokens??0)*n.outputPerM,a=(t.cacheReadTokens??0)*s,l=(t.cacheCreationTokens??0)*o,c={total:(i+r+a+l)/1e6};return t.inputTokens!=null&&(c.input=i/1e6),t.outputTokens!=null&&(c.output=r/1e6),t.cacheReadTokens&&(c.cache_read_input_tokens=a/1e6),t.cacheCreationTokens&&(c.cache_creation_input_tokens=l/1e6),c}function et(e){if(e)return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_input_tokens??void 0,cacheCreationTokens:e.cache_creation_input_tokens??void 0}}function En(e){if(!e)return;let t=e.prompt_tokens_details?.cached_tokens??0,n=e.prompt_tokens;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.completion_tokens,totalTokens:e.total_tokens,cacheReadTokens:t||void 0}}function Mn(e){if(!e)return;let t=e.cachedContentTokenCount??0,n=e.promptTokenCount;return{inputTokens:n!=null?Math.max(0,n-t):void 0,outputTokens:e.candidatesTokenCount,totalTokens:e.totalTokenCount,cacheReadTokens:t||void 0}}function _l(e){let t={};return e.inputTokens!=null&&(t.input=e.inputTokens),e.outputTokens!=null&&(t.output=e.outputTokens),e.cacheReadTokens&&(t.cache_read_input_tokens=e.cacheReadTokens),e.cacheCreationTokens&&(t.cache_creation_input_tokens=e.cacheCreationTokens),e.totalTokens!=null&&(t.total=e.totalTokens),t}var tf,on=N(()=>{"use strict";y();tf=[{match:"claude-opus-4",inputPerM:15,outputPerM:75},{match:"claude-sonnet-4",inputPerM:3,outputPerM:15},{match:"claude-haiku-4",inputPerM:1,outputPerM:5},{match:"claude-3-7-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-sonnet",inputPerM:3,outputPerM:15},{match:"claude-3-5-haiku",inputPerM:.8,outputPerM:4},{match:"claude-3-opus",inputPerM:15,outputPerM:75},{match:"gpt-5.5",inputPerM:5,outputPerM:30},{match:"gpt-5.4",inputPerM:2.5,outputPerM:15},{match:"gpt-5.3",inputPerM:1.75,outputPerM:14},{match:"gpt-4o-mini",inputPerM:.15,outputPerM:.6},{match:"gpt-4o",inputPerM:2.5,outputPerM:10},{match:"gpt-4.1-nano",inputPerM:.1,outputPerM:.4},{match:"gpt-4.1-mini",inputPerM:.4,outputPerM:1.6},{match:"gpt-4.1",inputPerM:2,outputPerM:8},{match:"gemini-2.5-pro",inputPerM:1.25,outputPerM:10},{match:"gemini-2.5-flash",inputPerM:.3,outputPerM:2.5},{match:"gemini-2.0-flash",inputPerM:.1,outputPerM:.4},{match:"gemini-1.5-pro",inputPerM:1.25,outputPerM:5},{match:"gemini-1.5-flash",inputPerM:.075,outputPerM:.3}]});import{AsyncLocalStorage as sf}from"async_hooks";function of(){return{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,costUsd:0,calls:0,unpricedCalls:0}}function rf(e){return{inputTokens:e.inputTokens,outputTokens:e.outputTokens,cacheReadTokens:e.cacheReadTokens,cacheCreationTokens:e.cacheCreationTokens,totalTokens:e.inputTokens+e.outputTokens+e.cacheReadTokens+e.cacheCreationTokens,costUsd:e.costUsd,calls:e.calls,costComplete:e.unpricedCalls===0}}async function er(e){let t=of();return{result:await $l.run(t,e),cost:rf(t)}}function El(e,t){if(!t)return;let n=$l.getStore();if(!n)return;n.inputTokens+=t.inputTokens??0,n.outputTokens+=t.outputTokens??0,n.cacheReadTokens+=t.cacheReadTokens??0,n.cacheCreationTokens+=t.cacheCreationTokens??0,n.calls+=1;let s=ds(e,t);s?n.costUsd+=s.total:n.unpricedCalls+=1}var $l,tr=N(()=>{"use strict";y();on();$l=new sf});import{randomUUID as Pt}from"crypto";import{AsyncLocalStorage as af}from"async_hooks";function Pl(){let e=R(),t=e.langfusePublicKey||process.env.LANGFUSE_PUBLIC_KEY,n=e.langfuseSecretKey||process.env.LANGFUSE_SECRET_KEY;if(!(e.langfuseEnabled===!0||process.env.LANGFUSE_ENABLED==="true")||!t||!n)return null;let o=(e.langfuseBaseUrl||process.env.LANGFUSE_BASE_URL||lf).replace(/\/+$/,"");return{publicKey:t,secretKey:n,baseUrl:o}}function yo(){return Pl()!==null}function ms(e,t=cf){if(typeof e=="string")return e.length>t?e.slice(0,t)+`\u2026[+${e.length-t} chars]`:e;try{let n=JSON.stringify(e);if(n&&n.length>t)return n.slice(0,t)+`\u2026[+${n.length-t} chars]`}catch{return"[unserializable]"}return e}async function tt(e,t){if(!yo())return t();let n=Pt();Gt.push({id:Pt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString(),...e.sessionId?{sessionId:e.sessionId}:{},...e.userId?{userId:e.userId}:{},...e.input!==void 0?{input:ms(e.input)}:{},...e.metadata?{metadata:e.metadata}:{},...e.tags?{tags:e.tags}:{}}});try{return await us.run({traceId:n,sessionId:e.sessionId},t)}finally{await Nl()}}function nr(e){if(!yo())return;let t=us.getStore();t?.traceId&&Gt.push({id:Pt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:t.traceId,timestamp:new Date().toISOString(),output:ms(e)}})}async function te(e,t,n){let s=us.getStore();if(!yo()||!s?.traceId)return t();let o=Pt(),i=s.spanId,r=new Date,a,l;try{return await us.run({...s,spanId:o},t)}catch(c){throw a="ERROR",l=c?.message,c}finally{Gt.push({id:Pt(),type:"span-create",timestamp:new Date().toISOString(),body:{id:o,traceId:s.traceId,name:e,startTime:r.toISOString(),endTime:new Date().toISOString(),...i?{parentObservationId:i}:{},...n?.input!==void 0?{input:ms(n.input)}:{},...n?.metadata?{metadata:n.metadata}:{},...a?{level:a}:{},...l?{statusMessage:l}:{}}})}}async function df(e){if(yo())try{let t=us.getStore(),n=t?.traceId,s=n?t?.spanId:void 0,o=!1;n||(n=Pt(),o=!0,Gt.push({id:Pt(),type:"trace-create",timestamp:new Date().toISOString(),body:{id:n,name:e.name,timestamp:new Date().toISOString()}}));let i=e.usage?_l(e.usage):void 0,r=e.usage?ds(e.model,e.usage):void 0;Gt.push({id:Pt(),type:"generation-create",timestamp:new Date().toISOString(),body:{id:Pt(),traceId:n,...s?{parentObservationId:s}:{},name:e.name,model:e.model,startTime:(e.startTime??new Date).toISOString(),endTime:(e.endTime??new Date).toISOString(),...e.input!==void 0?{input:ms(e.input,Ml)}:{},...e.output!==void 0?{output:ms(e.output,Ml)}:{},...i?{usageDetails:i}:{},...r?{costDetails:r}:{},...e.level?{level:e.level}:{},...e.statusMessage?{statusMessage:e.statusMessage}:{},...e.promptName?{promptName:e.promptName,...e.promptVersion!=null?{promptVersion:e.promptVersion}:{}}:{},metadata:{...e.engine?{engine:e.engine}:{},...e.metadata??{}}}}),o&&await Nl()}catch(t){M.warn("langfuse",`recordGeneration failed: ${t.message}`)}}function St(e){let{engine:t,model:n,name:s,usage:o,startTime:i,endTime:r}=e,a=r.getTime()-i.getTime(),l=o?ds(n,o):void 0;if(o&&M.info("agent-usage",`${t} ${s}`,{model:n,inputTokens:o.inputTokens,outputTokens:o.outputTokens,cacheReadTokens:o.cacheReadTokens,costUsd:l?.total,durationMs:a}),Il.size>0){let c={engine:t,model:n,name:s,usage:o,cost:l,startTime:i,endTime:r,durationMs:a};for(let d of Il)try{d(c)}catch{}}El(n,o),df({name:s,model:n,engine:t,input:e.input,output:e.output,usage:o,startTime:i,endTime:r,level:e.level,statusMessage:e.statusMessage,metadata:e.metadata,promptName:e.promptName,promptVersion:e.promptVersion})}async function Nl(){let e=Pl();if(!e||Gt.length===0)return;let t=Gt;Gt=[];try{let n=Buffer.from(`${e.publicKey}:${e.secretKey}`).toString("base64"),s=await fetch(`${e.baseUrl}/api/public/ingestion`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Basic ${n}`},body:JSON.stringify({batch:t})});if(!s.ok&&s.status!==207){let o=await s.text().catch(()=>"");M.warn("langfuse",`ingestion HTTP ${s.status}: ${o.slice(0,300)}`)}else M.info("langfuse",`flushed ${t.length} event(s)`)}catch(n){M.warn("langfuse",`ingestion failed: ${n.message}`)}}var lf,cf,Ml,us,Gt,Il,Be=N(()=>{"use strict";y();ee();le();on();tr();lf="https://cloud.langfuse.com",cf=24e3,Ml=2e5,us=new af,Gt=[],Il=new Set});import{join as me}from"path";import{readdirSync as it,rmSync as wf}from"fs";function ko(e){let t=[];for(let n of e){let s=`${n.message}${n.detail?` \u2014 ${n.detail}`:""}`,o=!1;/textarea|unknown.*field.*type/i.test(s)&&(o=!0),/reserved.*name|missing field name|field null/i.test(s)&&(o=!0),/could not resolve.*now/i.test(s)&&(o=!0),/hubdb|do not have access/i.test(s)&&(o=!0),/invalid default value|link.*invalid|deserializ/i.test(s)&&(o=!0),/color.*invalid/i.test(s)&&(o=!0),/dnd.area.*only.*have.*name.*main/i.test(s)&&(o=!0),t.push({file:n.file||"unknown",message:s,fixable:o})}return t}function To(e){let t=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(e)){let n=e.match(/(?:in|file:?)\s+(\S+fields\.json)/i);t.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(e)&&t.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(e)&&t.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(e)){let n=e.match(/field.*?(\w+)\s+has an invalid/i);t.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(e)){let n=e.match(/file '([^']+)'/i);t.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(e)&&t.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),/dnd.area.*only.*have.*name.*main/i.test(e)&&t.push({file:"templates/email.html",message:'Dnd area can only have name "main"',fixable:!0}),t}function Ao(e){let t=[];return Ll(e)&&t.push("textarea \u2192 text"),Jl(e)&&t.push("name \u2192 item_name"),Bl(e)&&t.push("now() \u2192 local_dt"),Hl(e)&&t.push("Removed HubDB templates"),Ul(e)&&t.push("Fixed link field defaults"),Gl(e)&&t.push("Fixed rgba/invalid color values \u2192 hex"),Cf(e)&&t.push("Stripped CDN @import statements"),Kl(e)&&t.push('dnd_area \u2192 "main" in email templates'),Vl(e)&&t.push("Added {{ dnd_area_stylesheet }} to email templates"),t}function jl(e,t){return t.message.includes("textarea")?Ll(e):t.message.includes("reserved field name")?Jl(e):t.message.includes("now()")?Bl(e):t.message.includes("HubDB")?Hl(e):t.message.includes("invalid default value")||t.message.includes("deserialization")?Ul(e):t.message.includes("invalid format")&&t.message.includes("color")?Gl(e):t.message.includes("dnd")||t.message.includes("Dnd area")?Kl(e):t.message.includes("dnd_area_stylesheet")?Vl(e):!1}function Ll(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),B(o,i),t=!0)}return t}function Jl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(!x(o))continue;let i=P(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),B(o,i),t=!0)}return t}function Bl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"module.html");if(!x(o))continue;let i=P(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),B(o,i),t=!0)}return t}function Hl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(wf(o),t=!0)}return t}function Ul(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));zl(i)&&(B(o,JSON.stringify(i,null,2)+`
|
|
182
|
+
`),t=!0)}catch{}}return t}function Cf(e){let t=!1,n=me(e,"css");if(x(n))for(let o of it(n)){if(!o.endsWith(".css"))continue;let i=me(n,o),r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(B(i,a),t=!0)}let s=me(e,"modules");if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.css");if(!x(i))continue;let r=P(i),a=r.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");a!==r&&(B(i,a),t=!0)}if(x(s))for(let o of it(s)){if(!o.endsWith(".module"))continue;let i=me(s,o,"module.html");if(!x(i))continue;let r=P(i),a=r.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");a!==r&&(B(i,a),t=!0)}return t}function Gl(e){let t=!1,n=me(e,"modules");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".module"))continue;let o=me(n,s,"fields.json");if(x(o))try{let i=JSON.parse(P(o));Wl(i)&&(B(o,JSON.stringify(i,null,2)+`
|
|
183
|
+
`),t=!0)}catch{}}return t}function Wl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="color"&&s.default&&typeof s.default=="object"){let o=s.default,i=o.color;if(typeof i=="string"&&!kf(i)){let r=Tf(i);r&&(o.color=r.hex,r.opacity!==void 0&&(o.opacity=r.opacity),t=!0)}}Array.isArray(s.children)&&Wl(s.children)&&(t=!0)}return t}function kf(e){return/^#[0-9a-fA-F]{6}$/.test(e)}function Tf(e){let t=e.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(t)return{hex:`#${t[1]}${t[1]}${t[2]}${t[2]}${t[3]}${t[3]}`};let n=e.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),r=Math.min(255,parseInt(n[2])),a=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=e.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function Kl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i))continue;let r=i.replace(/\{%\s*dnd_area\s+"(?!main")([^"]+)"/g,'{% dnd_area "main"');r!==i&&(B(o,r),t=!0)}return t}function Vl(e){let t=!1,n=me(e,"templates");if(!x(n))return!1;for(let s of it(n)){if(!s.endsWith(".html"))continue;let o=me(n,s),i=P(o);if(!/templateType:\s*email/i.test(i)||i.includes("dnd_area_stylesheet"))continue;let r=i.replace(/(\{\{\s*standard_header_includes\s*\}\})/,`$1
|
|
184
|
+
{{ dnd_area_stylesheet }}`);r!==i&&(B(o,r),t=!0)}return t}function zl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&zl(s.children)&&(t=!0)}return t}var _o=N(()=>{"use strict";y();oe()});import{readdirSync as Af}from"fs";import{join as _f,relative as $f}from"path";function Yl(e){let t=[];for(let n of Af(e,{withFileTypes:!0})){if(Ef.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=_f(e,n.name);n.isDirectory()?t.push(...Yl(s)):n.isFile()&&t.push(s)}return t}async function Mf(e,t,n){let s=0;async function o(){for(;s<e.length;){let r=s++;await n(e[r])}}let i=Array.from({length:Math.min(t,e.length)},()=>o());await Promise.all(i)}async function $o(e,t,n,s={}){let o=s.concurrency??5,i=Yl(t),r=i.length,a=0,l=0,c=[];return await Mf(i,o,async d=>{let u=$f(t,d).replace(/\\/g,"/"),m=`${n}/${u}`;s.onFileStart?.(u);let g=await al(e,m,d);if(g.success)a++,s.onFileComplete?.(u);else{l++;let h={file:u,status:g.error?.status||0,message:g.error?.message||"Unknown error",category:g.error?.category,detail:g.error?.detail};c.push(h),s.onFileError?.(u,h)}s.onProgress?.(a+l,r)}),{success:l===0,uploaded:a,failed:l,total:r,errors:c}}var Ef,sr=N(()=>{"use strict";y();sn();sn();Ef=new Set([".git","node_modules",".vibespot",".DS_Store"])});var oc=N(()=>{"use strict";y()});import{existsSync as Nt,writeFileSync as Rf,mkdirSync as Of}from"fs";import{join as vt}from"path";function rc(e){return/^[0-9a-f]{4,40}$/i.test(e)}function ac(e){return Number.isInteger(e)&&e>0&&e<1e3}function rt(){return Eo!==null||(Eo=Z(["--version"]).success),Eo}function Mo(e){if(!rt())return!1;if(Nt(vt(e,".git")))return ic(e),!0;let t=Z(["init"],{cwd:e});return t.success?(Ff(e),ic(e),Z(["add","-A"],{cwd:e}),Z(["commit","-m","Initial theme"],{cwd:e}),!0):(console.warn(`[project-git] git init failed in ${e}: ${t.stderr}`),!1)}function ic(e){let t=vt(e,".vibespot");Nt(t)||Of(t,{recursive:!0})}function Ff(e){let t=vt(e,".gitignore");Rf(t,[".vibespot/","node_modules/",""].join(`
|
|
185
|
+
`),"utf-8")}function rn(e,t){if(!rt()||!Nt(vt(e,".git"))||(Z(["add","-A"],{cwd:e}),Z(["diff","--cached","--quiet"],{cwd:e}).success))return null;let s=t.length>72?t.slice(0,69)+"...":t,o=Z(["commit","-m",s],{cwd:e});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=Z(["rev-parse","--short","HEAD"],{cwd:e});return i.success?i.stdout:null}function ir(e,t,n,s){if(!rt()||!Nt(vt(e,".git")))return null;for(let u of s){let m=vt(e,u);Nt(m)&&Z(["add","--",u],{cwd:e})}if(Z(["diff","--cached","--quiet"],{cwd:e}).success)return null;let i=`[${t}] `,r=72-i.length,a=n.length>r?n.slice(0,r-3)+"...":n,l=i+a,c=Z(["commit","-m",l],{cwd:e});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=Z(["rev-parse","--short","HEAD"],{cwd:e});return d.success?d.stdout:null}function lc(e){let t=[],n=null;for(let s of e.split(`
|
|
186
|
+
`)){let o=s.trimEnd();if(o.startsWith("COMMIT|")){n&&t.push(n);let i=o.slice(7).split("|");if(i.length<4){n=null;continue}let r=parseInt(i[3],10)*1e3;n={hash:i[0],fullHash:i[1],message:i[2],timestamp:r,date:new Date(r).toISOString(),changedFiles:[],changedModules:[]}}else o&&n&&n.changedFiles.push(o)}n&&t.push(n);for(let s of t){if(!s.changedFiles)continue;let o=new Set;for(let i of s.changedFiles){let r=i.match(/^modules\/([^/]+)\.module(?:\/|$)/);r&&o.add(r[1])}s.changedModules=[...o]}return t}function cc(e,t=50){if(!rt())return[];if(!Nt(vt(e,".git")))return[];if(!ac(t))return[];let n=Z(["log","--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(t)],{cwd:e});return!n.success||!n.stdout.trim()?[]:lc(n.stdout)}function dc(e,t,n=50){if(!rt())return[];if(!Nt(vt(e,".git")))return[];if(!ac(n))return[];let s=t.replace(/[\\.*+?^${}()|[\]/]/g,"\\$&"),o=Z(["log",`--grep=\\[${s}\\]`,"--name-only","--pretty=format:COMMIT|%h|%H|%s|%at","-n",String(n)],{cwd:e});return!o.success||!o.stdout.trim()?[]:lc(o.stdout)}function uc(e,t){if(!rt())return{success:!1,error:"Git not available"};if(!Nt(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!rc(t))return{success:!1,error:"Invalid commit hash"};let n=Z(["cat-file","-t",t],{cwd:e});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${t} not found`};let s=Z(["log","--format=%s","-1",t],{cwd:e}),o=s.success?s.stdout:t,i=Z(["checkout",t,"--","."],{cwd:e});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let r=`Rollback to: ${o}`.slice(0,72);return Z(["commit","-m",r],{cwd:e}),{success:!0}}function mc(e,t,n,s){if(!rt())return{success:!1,error:"Git not available"};if(!Nt(vt(e,".git")))return{success:!1,error:"Not a git repo"};if(!rc(n))return{success:!1,error:"Invalid commit hash"};let o=Z(["cat-file","-t",n],{cwd:e});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=Z(["log","--format=%s","-1",n],{cwd:e}),r=i.success?i.stdout:n,a=0;for(let d of s)Z(["checkout",n,"--",d],{cwd:e}).success&&a++;if(a===0)return{success:!1,error:"No files could be restored from that commit"};Z(["add","-A"],{cwd:e});let c=`${`[${t}] `}Rollback to: ${r}`.slice(0,72);return Z(["commit","-m",c],{cwd:e}),{success:!0}}var Eo,Pn=N(()=>{"use strict";y();Qt();Eo=null});import{readFileSync as Df,existsSync as gc,writeFileSync as jf,mkdirSync as Lf,rmSync as Jf}from"fs";import{join as Io}from"path";function an(e){let t=C();t&&(t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e.plan)}function at(){let e=C();if(!e)return;let t=ke();if(!t){if(e.modules.length===0)return;let n={modules:e.modules,moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,template:e.template,messages:e.messages,plan:e.brandAssets?.plan};t=Rt("landing_page",`${e.themeName} Landing Page`),e.activeTemplateId=t.id,e.modules=n.modules,e.moduleOrder=n.moduleOrder,e.sharedCss=n.sharedCss,e.sharedJs=n.sharedJs,e.template=n.template,e.messages=n.messages,e.brandAssets&&(e.brandAssets.plan=n.plan)}t.modules=e.modules,t.moduleOrder=e.moduleOrder,t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs,t.template=e.template,t.messages=e.messages,t.plan=e.brandAssets?.plan}function lt(e,t,n){let s=C();if(!s)return;let o={role:e,content:t,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),at(),Hf()}function fc(e){let t=C();t&&(t.assets||(t.assets=[]),t.assets.push(e),t.updatedAt=Date.now(),L())}function hc(e){let t=C();if(!t)return;if(e.calls===0)return t.costTotal;let n=t.costTotal??{costUsd:0,totalTokens:0,generations:0,costComplete:!0},s={costUsd:n.costUsd+e.costUsd,totalTokens:n.totalTokens+e.totalTokens,generations:n.generations+1,costComplete:n.costComplete&&e.costComplete};return t.costTotal=s,t.updatedAt=Date.now(),s}function pc(e){return e.toLowerCase().replace(/[\s\-_]+/g,"")}function Bf(e,t){let n=pc(e),s=pc(t);if(n===s)return!0;if(n.length<4||s.length<4)return!1;let o=n.length<=s.length?n:s,i=n.length<=s.length?s:n;return i.includes(o)?o.length/i.length>=.8:!1}function He(e){let t=C();if(t){if(e.sharedCss!==void 0&&(t.sharedCss=e.sharedCss),e.sharedJs!==void 0&&(t.sharedJs=e.sharedJs),e.template!==void 0&&(t.template=e.template),e.modules)for(let n of e.modules){let s=n.moduleName.toLowerCase(),o=t.modules.findIndex(i=>i.moduleName.toLowerCase()===s);if(o>=0)t.modules[o]=n;else{let i=t.modules.find(r=>Bf(r.moduleName,n.moduleName));i&&M.warn("session-state",`Module "${n.moduleName}" looks like a renamed variant of existing "${i.moduleName}" \u2014 adding as a new module. This usually indicates the Module Planner re-named an existing module. Check the prompt's "preserve existing names" rule.`),t.modules.push(n),t.moduleOrder.some(r=>r.toLowerCase()===s)||t.moduleOrder.push(n.moduleName)}}t.updatedAt=Date.now(),at()}}function Wt(e){let t=C();t&&(t.moduleOrder=e,t.updatedAt=Date.now(),at())}function yc(e){let t=C();if(t){t.modules=t.modules.filter(n=>n.moduleName!==e),t.moduleOrder=t.moduleOrder.filter(n=>n!==e);for(let n of t.templates)n.modules=n.modules.filter(s=>s.moduleName!==e),n.moduleOrder=n.moduleOrder.filter(s=>s!==e);if(t.themePath){let n=Io(t.themePath,"modules",`${e}.module`);gc(n)&&Jf(n,{recursive:!0,force:!0})}t.updatedAt=Date.now(),at()}}function bc(e){let t=C();t&&(t.moduleOrder=t.moduleOrder.filter(n=>n!==e),t.updatedAt=Date.now(),at())}function Sc(e,t,n){let s=C();if(!s)return;let o=s.modules.find(i=>i.moduleName===e);if(o)try{let i=JSON.parse(o.fieldsJson);wc(i,t,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),at()}catch{}}function ve(){let e=C();if(!e)return[];let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function Hf(){let e=C();if(e)try{let t=Io(e.themePath,".vibespot");Lf(t,{recursive:!0});let n={sessionId:e.id,themeName:e.themeName,messages:e.messages,updatedAt:Date.now()};jf(Io(t,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function vc(e){let t=Io(e,".vibespot","chat.json");if(!gc(t))return[];try{let n=JSON.parse(Df(t,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function xc(e){let t=C();if(t){for(let n of t.templates)n.sharedCss=e.sharedCss,n.sharedJs=e.sharedJs;t.sharedCss=e.sharedCss,t.sharedJs=e.sharedJs;for(let n of e.pages){let s=e.pageLabels.get(n.pageId),o=s?.label||n.pageId,i=s?.pageType||"website_page",r=t.templates.find(a=>a.id===n.templateId);r||(r=Rt(i,o),r.id=n.templateId,r.templateFile=`templates/${n.templateId}.html`),r.modules=n.modules,r.moduleOrder=n.moduleOrder,r.sharedCss=e.sharedCss,r.sharedJs=e.sharedJs}e.pages.length>0&&fs(e.pages[0].templateId),t.updatedAt=Date.now()}}function wc(e,t,n){let s=t.split("."),o=s[0],i=e.find(r=>r.name===o);i&&(s.length===1?i.default=n:i.children&&wc(i.children,s.slice(1).join("."),n))}var gs=N(()=>{"use strict";y();hs();Kt();le()});import{existsSync as Po,rmSync as No}from"fs";import{join as Nn}from"path";function Ro(e){if(e.templates&&e.templates.length>0)return;if(!e.modules||e.modules.length===0){e.templates=[],e.activeTemplateId="";return}let t=`lp-${e.themeName}`,n={id:t,label:`${e.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${e.themeName}.html`,modules:[...e.modules],moduleOrder:[...e.moduleOrder],sharedCss:e.sharedCss||"",sharedJs:e.sharedJs||"",template:e.template||"",messages:[...e.messages]};e.templates=[n],e.activeTemplateId=t}function ke(){let e=C();return!e||!e.activeTemplateId||!e.templates?.length?null:e.templates.find(t=>t.id===e.activeTemplateId)||null}function fs(e){let t=C();if(!t)return!1;let n=t.templates.find(s=>s.id===e);return n?(t.activeTemplateId=e,an(n),t.updatedAt=Date.now(),!0):!1}function Rt(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=t.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=n==="email",a=`${i?"email":e==="blog_post"?"bp":e==="website_page"?"wp":e==="module_only"?"mo":"lp"}-${o}`,l={id:a,label:t,pageType:e,contentMode:n,templateFile:i?"templates/email.html":e==="module_only"?"":`templates/${a}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return s.templates.push(l),s.activeTemplateId=a,an(l),s.updatedAt=Date.now(),l}function Cc(e,t){let n=C();if(!n)return null;let s=n.templates.find(c=>c.id===e);if(!s)return null;let o=t||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),a=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:a,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${a}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[],plan:s.plan};return n.templates.push(l),n.activeTemplateId=a,an(l),n.updatedAt=Date.now(),l}function kc(e){let t=C();if(!t||!Array.isArray(e)||e.length===0)return!1;let n=new Map(t.templates.map(i=>[i.id,i])),s=new Set,o=[];for(let i of e){let r=n.get(i);!r||s.has(i)||(o.push(r),s.add(i))}for(let i of t.templates)s.has(i.id)||o.push(i);return o.length!==t.templates.length?!1:(t.templates=o,t.updatedAt=Date.now(),!0)}function Tc(e,t){let n=C();if(!n)return!1;let s=n.templates.find(o=>o.id===e);return s?(s.label=t,n.updatedAt=Date.now(),!0):!1}function Ac(e,t=!1){let n=C();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===e);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Nn(n.themePath,"templates"),r=`${o.id}.html`,a=Nn(i,r);if(Po(a)&&No(a,{force:!0}),o.pageType==="blog_post"){let l=Nn(i,`${o.id}-listing.html`);Po(l)&&No(l,{force:!0})}}if(t&&o.modules.length>0){let i=new Set;for(let a of n.templates)for(let l of a.modules)i.add(l.moduleName);for(let a of n.modules)i.add(a.moduleName);let r=o.modules.map(a=>a.moduleName).filter(a=>!i.has(a));if(n.themePath&&r.length>0){let a=Nn(n.themePath,"modules");for(let l of r){let c=Nn(a,`${l}.module`);Po(c)&&No(c,{recursive:!0,force:!0})}}}if(n.activeTemplateId===e&&(n.templates.length>0?fs(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[],n.brandAssets&&delete n.brandAssets.plan)),o.plan&&n.themePath&&!n.templates.some(r=>!!r.plan)){let r=Nn(n.themePath,".vibespot","plan.md");Po(r)&&No(r,{force:!0})}return n.updatedAt=Date.now(),!0}function Ot(){let e=C();if(!e)return[];let t=new Map;for(let n of e.templates)for(let s of n.modules){let o=t.get(s.moduleName);o?o.usedIn.push(n.label):t.set(s.moduleName,{module:s,usedIn:[n.label]})}for(let n of e.modules)t.has(n.moduleName)||t.set(n.moduleName,{module:n,usedIn:[]});return Array.from(t.values())}var Kt=N(()=>{"use strict";y();hs();gs()});import{readFileSync as xt,readdirSync as dr,existsSync as Ie,writeFileSync as ys,mkdirSync as Oo,rmSync as rr,renameSync as ar,cpSync as Uf}from"fs";import{join as pe,dirname as _c}from"path";import{homedir as Gf}from"os";function Fo(){if(Rn)return Rn;try{return Ie(lr)?(Rn=JSON.parse(xt(lr,"utf-8")),Rn):cr()}catch{return cr()}}function Do(e){Rn=e;try{Oo(de,{recursive:!0}),ys(lr,JSON.stringify(e),"utf-8")}catch{}}function cr(){if(!Ie(de))return[];let e=[];for(let t of dr(de).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(xt(pe(de,t),"utf-8")),s=n.templates||[];e.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length,pageCount:s.filter(o=>o.contentMode!=="email").length,emailCount:s.filter(o=>o.contentMode==="email").length,hasBrandAssets:!!(n.brandAssets&&(n.brandAssets.styleguide||n.brandAssets.brandvoice||n.brandAssets.brandKit)),isImported:!!n.isImported})}catch{}return Rn=e,Do(e),e}function $c(e){let t=Fo(),n=e.templates||[],s={id:e.id,themeName:e.themeName,updatedAt:e.updatedAt,moduleCount:n.reduce((i,r)=>i+(r.modules?.length||0),0),templateCount:n.length,pageCount:n.filter(i=>i.contentMode!=="email").length,emailCount:n.filter(i=>i.contentMode==="email").length,hasBrandAssets:!!(e.brandAssets&&(e.brandAssets.styleguide||e.brandAssets.brandvoice||e.brandAssets.brandKit)),isImported:!!e.isImported},o=t.findIndex(i=>i.id===e.id);o>=0?t[o]=s:t.push(s),Do(t)}function Wf(e){let t=Fo().filter(n=>n.id!==e);Do(t)}function Kf(e){let t=Fo().filter(n=>n.themeName!==e);Do(t)}function C(){return Ue}function Ec(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function On(e,t,n={}){let s={id:Ec(),themePath:e,themeName:t,isImported:!!n.isImported,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return Ue=s,Mo(e),s}function L(){if(!Ue)return;Oo(de,{recursive:!0});let e=pe(de,`${Ue.id}.json`);ys(e,JSON.stringify(Ue,null,2),"utf-8"),$c(Ue)}function jo(e){let t=pe(de,e+".json");if(!Ie(t))return null;try{let n=JSON.parse(xt(t,"utf-8"));if(n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Ro(n),n.brandAssets?.plan&&n.templates?.length>0){let s=n.templates.find(o=>o.id===n.activeTemplateId)||n.templates[0];s.plan||(s.plan=n.brandAssets.plan)}return Ue=n,n}catch{return null}}function Fn(){return Ie(de)?Fo():[]}function Mc(e,t=!1){let n=pe(de,e+".json"),s="";if(t)try{let o=JSON.parse(xt(n,"utf-8"));s=o.themeName||"",o.themePath&&Ie(o.themePath)&&rr(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(xt(n,"utf-8")).themeName||""}catch{}try{Ie(n)&&rr(n)}catch{}if(s&&Ie(de)){for(let o of dr(de).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(xt(pe(de,o),"utf-8")).themeName===s&&rr(pe(de,o))}catch{}Kf(s)}else Wf(e);Ue?.id===e&&(Ue=null)}function Ic(e,t){let n=pe(de,e+".json");if(!Ie(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(xt(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===t)return{ok:!0};let i=s.themePath,r=pe(_c(i),t);if(Ie(i)){if(Ie(r))return{ok:!1,error:"A project with that name already exists"};try{ar(i,r)}catch(m){return{ok:!1,error:`Failed to rename folder: ${m instanceof Error?m.message:String(m)}`}}let a=pe(r,"css",`${o}-theme.css`),l=pe(r,"css",`${t}-theme.css`);if(Ie(a))try{ar(a,l)}catch{}let c=pe(r,"js",`${o}-animations.js`),d=pe(r,"js",`${t}-animations.js`);if(Ie(c))try{ar(c,d)}catch{}let u=pe(r,"theme.json");if(Ie(u))try{let m=JSON.parse(xt(u,"utf-8"));m.label=t,m.name=t,ys(u,JSON.stringify(m,null,2),"utf-8")}catch{}}if(Ie(de))for(let a of dr(de).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(xt(pe(de,a),"utf-8"));l.themeName===o&&(l.themeName=t,l.themePath=r,l.updatedAt=Date.now(),ys(pe(de,a),JSON.stringify(l,null,2),"utf-8"))}catch{}return Ue&&Ue.themeName===o&&(Ue.themeName=t,Ue.themePath=r,Ue.updatedAt=Date.now()),cr(),{ok:!0}}function Pc(e){let t=pe(de,e+".json");if(!Ie(t))return{ok:!1,error:"Session not found"};let n;try{n=JSON.parse(xt(t,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let s=n.themeName.replace(/-copy(-\d+)?$/,""),o=_c(n.themePath),i=`${s}-copy`,r=1;for(;Ie(pe(o,i));)r++,i=`${s}-copy-${r}`;let a=pe(o,i);if(Ie(n.themePath))try{Uf(n.themePath,a,{recursive:!0})}catch(d){return{ok:!1,error:`Failed to copy files: ${d instanceof Error?d.message:String(d)}`}}else Oo(a,{recursive:!0});let l=Ec(),c={...JSON.parse(JSON.stringify(n)),id:l,themeName:i,themePath:a,createdAt:Date.now(),updatedAt:Date.now(),messages:[]};return Oo(de,{recursive:!0}),ys(pe(de,`${l}.json`),JSON.stringify(c,null,2),"utf-8"),$c(c),{ok:!0,newName:i,newSessionId:l}}var de,lr,Rn,Ue,hs=N(()=>{"use strict";y();Pn();Kt();de=pe(Gf(),".vibespot","sessions"),lr=pe(de,"_index.json"),Rn=null;Ue=null});import{readFileSync as Vf,readdirSync as Oc,statSync as ur}from"fs";import{createHash as zf}from"crypto";import{join as be,relative as Yf}from"path";function Bo(e){let t=[];if(!x(e))return vh(e,[{severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}]);let n=Dn(e),s=hh(e),o=bh(e),i=Sh(e),r=eh(e);Object.keys(n.cssVariables).length===0&&t.push({severity:"info",rule:"design.cssVariables.empty",message:"No :root CSS custom properties found in theme CSS.",fix:"Run with --apply-tokens to seed a :root block from inferred palette/typography."}),n.palette.length===0&&t.push({severity:"info",rule:"design.palette.empty",message:"Could not infer a colour palette from the theme CSS."}),s.orphanModules.length>0&&t.push({severity:"warning",rule:"modules.orphan",message:`${s.orphanModules.length} module(s) are not referenced by any template: ${s.orphanModules.join(", ")}`,fix:"Either reference these modules from a template or remove them."}),s.templates.length===0&&s.modules.length>0&&t.push({severity:"warning",rule:"templates.missing",message:"Theme has modules but no page templates wiring them together.",fix:"Add a templates/<name>.html that includes the modules via dnd_module."});for(let l of o)t.push({severity:"info",rule:"field.unsupported-pattern",file:`modules/${l.module}.module/fields.json`,message:`${l.module}.${l.field}: ${l.reason}`,fix:"vibeSpot will preserve this field as-is. Edit it in HubSpot if changes are needed."});for(let l of i)t.push({severity:"warning",rule:"roundtrip.preserve-pattern",file:l.file,message:`${l.pattern}: ${l.detail}`,fix:"vibeSpot avoids modifying this. Don't ask the AI to refactor it."});r.hasSnapshot&&r.filesChanged>0&&t.push({severity:"info",rule:"roundtrip.snapshot.diff",message:`${r.filesChanged} file(s) differ from the imported theme snapshot.`,fix:"Review report.roundTripDiff before re-uploading if you need to preserve imported files exactly."});let a=i.filter(l=>l.pattern==="hubl.macro").length;return{themePath:e,designTokens:n,graph:s,fieldFlags:o,roundTripRisks:i,roundTripDiff:r,findings:t,summary:{moduleCount:s.modules.length,templateCount:s.templates.length,orphanCount:s.orphanModules.length,paletteSize:n.palette.length,cssVarCount:Object.keys(n.cssVariables).length,customMacroCount:a,roundTripChangedCount:r.filesChanged}}}function bs(e){let t=[];for(let[n,s]of Object.entries(e.cssVariables))t.push(` ${n}: ${s};`);return Object.keys(e.cssVariables).length===0&&(e.palette.slice(0,8).forEach((n,s)=>{let o=s===0?"primary":s===1?"secondary":`accent-${s-1}`;t.push(` --color-${o}: ${n.value};`)}),e.fontFamilies[0]&&t.push(` --font-family-base: ${e.fontFamilies[0]};`),e.fontFamilies[1]&&t.push(` --font-family-heading: ${e.fontFamilies[1]};`)),t.length===0?"":`:root {
|
|
187
187
|
${t.join(`
|
|
188
188
|
`)}
|
|
189
189
|
}
|
|
190
|
-
`}function
|
|
191
|
-
`),s}function Rc(e){let t=hs(e);return x(t)?null:ur(e)}function zf(e){let t=hs(e);if(!x(t))return null;try{let n=JSON.parse(P(t));return yh(n)?n:null}catch{return null}}function Yf(e){let t=hs(e),n=zf(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=Fc(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:Lo(d.text),afterLines:Lo(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:Lo(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:Lo(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 Fn(e){let t=dh(e),n={},s=new Map,o=new Map,i=new Set,r=new Set,a=new Set,l=new Set,c=new Set;for(let u of t){let m;try{m=P(u)}catch{continue}let g,h=new RegExp(oh.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(ih.source,"g"),S;for(;(S=b.exec(f))!==null;){let v=S[1].trim(),w=S[2].trim();n[v]||(n[v]=w);let M=w.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if(M){let j=Ic(M[0]);o.set(j,v)}}}for(let f of[qf,Xf,Zf]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let v=Ic(S[0]);v&&s.set(v,(s.get(v)??0)+1)}}jo(m,Qf,i,ah),jo(m,eh,r,f=>f.trim()),rh(m,a),jo(m,nh,l,f=>f.trim()),jo(m,sh,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!ch(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 jo(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 rh(e,t){let n=new RegExp(th.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 ah(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function Ic(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 ch(e){return lh.has(e)}function dh(e){let t=[],n=be(e,"css");if(x(n))for(let o of Gt(n))o.endsWith(".css")&&t.push(be(n,o));let s=be(e,"modules");if(x(s))for(let o of Gt(s)){if(!o.endsWith(".module"))continue;let i=be(s,o,"module.css");x(i)&&t.push(i)}return t}function uh(e){let t=be(e,"modules"),n=be(e,"templates"),s=new Set,o=new Map;if(x(t))for(let c of Gt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,x(be(t,c,"module.js")))}let i=[],r=new Map;if(x(n))for(let c of Gt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=be(n,c),u;try{u=dr(d)}catch{continue}if(!u.isFile())continue;let m;try{m=P(d)}catch{continue}let g=mr(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:bh(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 mr(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 ph(e){let t=[],n=be(e,"modules");if(!x(n))return t;for(let s of Gt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=be(n,s,"fields.json");if(!x(i))continue;let r;try{r=JSON.parse(P(i))}catch{continue}Array.isArray(r)&&Oc(r,o,t,0)}return t}function Oc(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&&!mh.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)&&Oc(i.children,t,n,s+1)}}function gh(e){let t=[],n=be(e,"modules");if(x(n))for(let i of Gt(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=be(n,i,"module.html");x(a)&&Pc(a,e,r,t);let l=be(n,i,"module.js");if(x(l))try{P(l).trim().length>0&&t.push({file:pr(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=be(e,"templates");if(x(s))for(let i of Gt(s)){if(!i.endsWith(".html"))continue;let r=be(s,i);if(!x(r))continue;let a;try{a=dr(r)}catch{continue}a.isFile()&&Pc(r,e,i,t)}let o=be(e,"import_modules.json");return x(o)&&t.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),t}function Pc(e,t,n,s){let o;try{o=P(e)}catch{return}let i=pr(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 fh(e,t){let n={hasSnapshot:!1,snapshotPath:hs(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 Fc(e){let t=[];function n(s){for(let o of Gt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=be(s,o),r;try{r=dr(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=pr(e,i),l=Hf(i),c={path:a,sha256:Uf("sha256").update(l).digest("hex"),size:l.length};hh(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function hh(e){let t=e.lastIndexOf(".");return t<0?!1:Kf.has(e.slice(t).toLowerCase())}function yh(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 Lo(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Gt(e){try{return Nc(e)}catch{return[]}}function pr(e,t){return Gf(e,t).split("\\").join("/")}function bh(e){return[...new Set(e)]}var Wf,Kf,qf,Xf,Zf,Qf,eh,th,nh,sh,oh,ih,lh,mh,Ho=N(()=>{"use strict";y();oe();Wf=".vibespot/import-snapshot.json",Kf=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);qf=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,Xf=/\brgba?\([^)]+\)/g,Zf=/\bhsla?\([^)]+\)/g,Qf=/font-family\s*:\s*([^;}\n]+)/g,eh=/font-size\s*:\s*([^;}\n]+)/g,th=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,nh=/border-radius\s*:\s*([^;}\n]+)/g,sh=/box-shadow\s*:\s*([^;}\n]+)/g,oh=/:root\s*\{([\s\S]*?)\}/g,ih=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;lh=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);mh=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 gr,readdirSync as bs,existsSync as xe,writeFileSync as Ye,mkdirSync as ys,rmSync as Dc}from"fs";import{join as U}from"path";function we(e){try{return gr(e,"utf-8")}catch{return""}}function Lc(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 Sh(e,t){let n=we(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o=/templateType:\s*email\b/i.test(n),i="landing_page",r;o?(i="module_only",r="email"):s.startsWith("bp-")?i="blog_post":s.startsWith("wp-")?i="website_page":s.startsWith("mo-")&&(i="module_only");let a=s,l=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);l&&(a=l[1].trim());let c=mr(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function vh(e,t,n,s,o){if(!xe(e))return[];let i=[],r=bs(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=U(e,a),c=Sh(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 Uo(e){let t=C();if(!t)return;let n=bc(e);n.length>0&&t.messages.length===0&&(t.messages=n),Eo(e),Rc(e);let s=U(e,"modules");if(!xe(s))return;let o=bs(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let v=U(s,S.name),w=S.name.replace(/\.module$/,""),M={moduleName:w,fieldsJson:we(U(v,"fields.json")),metaJson:we(U(v,"meta.json")),moduleHtml:we(U(v,"module.html")),moduleCss:we(U(v,"module.css")),moduleJs:we(U(v,"module.js"))||void 0};M.fieldsJson&&M.moduleHtml&&(t.modules.push(M),t.moduleOrder.push(w))}let i=U(e,"css"),r=U(e,"js"),a="",l="";if(xe(i)){let S=bs(i).filter(v=>v.endsWith("-theme.css"));S.length>0&&(a=we(U(i,S[0])),t.sharedCss=a)}if(xe(r)){let S=bs(r).filter(v=>v.endsWith("-animations.js"));S.length>0&&(l=we(U(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=Fn(e),v=fs(S);v&&(t.sharedCss=v,a=v)}let c=U(e,".vibespot","styleguide.md"),d=U(e,".vibespot","brandvoice.md"),u=U(e,".vibespot","theme-context.md"),m=U(e,".vibespot","plan.md"),g=U(e,".vibespot","brand-kit.json");if((xe(c)||xe(d)||xe(u)||xe(m)||xe(g))&&(t.brandAssets||(t.brandAssets={}),xe(c)&&(t.brandAssets.styleguide=we(c)),xe(d)&&(t.brandAssets.brandvoice=we(d)),xe(u)&&(t.brandAssets.themeContext=we(u)),xe(m)&&(t.brandAssets.plan=we(m)),xe(g)))try{t.brandAssets.brandKit=JSON.parse(we(g))}catch{}let h=U(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=vh(h,f,a,l,t.messages);if(b.length>0){t.templates=b,t.activeTemplateId=b[0].id,t.brandAssets?.plan&&!b[0].plan&&(b[0].plan=t.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let v=new Set(t.moduleOrder),w=S.filter(M=>v.has(M));for(let M of t.moduleOrder)w.includes(M)||w.push(M);t.moduleOrder=w}on(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),No(t)}function Te(){let e=C();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=U(t,"modules");ys(s,{recursive:!0});for(let l of n.values())ys(U(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=U(s,`${l.moduleName}.module`);Ye(U(c,"fields.json"),l.fieldsJson,"utf-8"),Ye(U(c,"meta.json"),l.metaJson,"utf-8"),Ye(U(c,"module.html"),l.moduleHtml,"utf-8"),Ye(U(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ye(U(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=U(t,"css");ys(l,{recursive:!0}),Ye(U(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=U(t,"js");ys(l,{recursive:!0}),Ye(U(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=U(t,"templates");ys(o,{recursive:!0});let i=U(o,"home.html");(e.templates.length>0||e.modules.length>0)&&xe(i)&&Dc(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=kh(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ye(U(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||Ch(l),d=jc(c,l.label,l.pageType),u=`${l.id}.html`;Ye(U(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(Th(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||Ah(),c=jc(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ye(U(o,d),c,"utf-8"),a.add(d)}try{for(let l of bs(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&Dc(U(o,l),{force:!0})}catch{}xh(),wh()}function Jc(){let e=C();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",Uo(e.themePath),e.updatedAt=Date.now(),at())}function Bc(){let e=C();if(!e)return;let t=ke();if(!t)return;let n=e.themePath,s=U(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=U(s,`${o}.module`);if(!xe(i))continue;let r={moduleName:o,fieldsJson:we(U(i,"fields.json")),metaJson:we(U(i,"meta.json")),moduleHtml:we(U(i,"module.html")),moduleCss:we(U(i,"module.css")),moduleJs:we(U(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=U(n,t.templateFile);xe(o)&&(t.template=we(o))}on(t),e.updatedAt=Date.now()}function xh(){let e=C();if(!e)return;let t=U(e.themePath,"templates","layouts","base.html");if(xe(t))try{let n=gr(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+`
|
|
190
|
+
`}function Ho(e,t){let n=be(e,"css");if(x(n))try{for(let r of Oc(n))if(r.endsWith("-theme.css"))return null}catch{}let s=Dn(e),o=bs(s);if(!o)return null;let i=be(n,`${t}-theme.css`);return B(i,o),i}function Ss(e){return be(e,qf)}function Zf(e,t=new Date().toISOString()){return{version:1,createdAt:t,files:jc(e)}}function mr(e,t){let n=Zf(e,t),s=Ss(e);return B(s,JSON.stringify(n,null,2)+`
|
|
191
|
+
`),s}function Fc(e){let t=Ss(e);return x(t)?null:mr(e)}function Qf(e){let t=Ss(e);if(!x(t))return null;try{let n=JSON.parse(P(t));return wh(n)?n:null}catch{return null}}function eh(e){let t=Ss(e),n=Qf(e);if(!n)return{hasSnapshot:!1,snapshotPath:t,filesChanged:0,added:0,modified:0,deleted:0,files:[]};let s=new Map(n.files.map(d=>[d.path,d])),o=jc(e),i=new Map(o.map(d=>[d.path,d])),r=[];for(let d of n.files){let u=i.get(d.path);u?u.sha256!==d.sha256&&r.push({file:d.path,status:"modified",beforeSha256:d.sha256,afterSha256:u.sha256,beforeSize:d.size,afterSize:u.size,beforeLines:Jo(d.text),afterLines:Jo(u.text)}):r.push({file:d.path,status:"deleted",beforeSha256:d.sha256,beforeSize:d.size,beforeLines:Jo(d.text)})}for(let d of o)s.has(d.path)||r.push({file:d.path,status:"added",afterSha256:d.sha256,afterSize:d.size,afterLines:Jo(d.text)});r.sort((d,u)=>d.file.localeCompare(u.file));let a=r.filter(d=>d.status==="added").length,l=r.filter(d=>d.status==="modified").length,c=r.filter(d=>d.status==="deleted").length;return{hasSnapshot:!0,snapshotPath:t,filesChanged:r.length,added:a,modified:l,deleted:c,files:r}}function Dn(e){let t=fh(e),n={},s=new Map,o=new Map,i=new Set,r=new Set,a=new Set,l=new Set,c=new Set;for(let u of t){let m;try{m=P(u)}catch{continue}let g,h=new RegExp(ch.source,"g");for(;(g=h.exec(m))!==null;){let f=g[1],b=new RegExp(dh.source,"g"),S;for(;(S=b.exec(f))!==null;){let v=S[1].trim(),w=S[2].trim();n[v]||(n[v]=w);let $=w.match(/#[0-9a-fA-F]{3,8}\b|rgba?\([^)]+\)|hsla?\([^)]+\)/);if($){let j=Nc($[0]);o.set(j,v)}}}for(let f of[th,nh,sh]){let b=new RegExp(f.source,"g"),S;for(;(S=b.exec(m))!==null;){let v=Nc(S[0]);v&&s.set(v,(s.get(v)??0)+1)}}Lo(m,oh,i,mh),Lo(m,ih,r,f=>f.trim()),uh(m,a),Lo(m,ah,l,f=>f.trim()),Lo(m,lh,c,f=>f.trim())}let d=[...s.entries()].filter(([u])=>!gh(u)).sort((u,m)=>m[1]-u[1]).slice(0,12).map(([u,m])=>({value:u,count:m,varName:o.get(u)}));return{cssVariables:n,palette:d,fontFamilies:[...i].slice(0,8),fontSizes:[...r].slice(0,16),spacing:[...a].slice(0,16),radii:[...l].slice(0,8),shadows:[...c].slice(0,8)}}function Lo(e,t,n,s){let o=new RegExp(t.source,"g"),i;for(;(i=o.exec(e))!==null;){let r=s(i[1]);r&&!r.startsWith("var(")&&n.add(r)}}function uh(e,t){let n=new RegExp(rh.source,"g"),s;for(;(s=n.exec(e))!==null;){let o=s[1].trim();if(!o.startsWith("var("))for(let i of o.split(/\s+/))/^-?\d+(\.\d+)?(rem|em|px|%)$/.test(i)&&t.add(i)}}function mh(e){return e.split(",")[0].trim().replace(/^["']|["']$/g,"")}function Nc(e){let t=e.trim().toLowerCase();if(t.startsWith("#")){if(/^#[0-9a-f]{3}$/.test(t)){let[,n,s,o]=t.match(/^#([0-9a-f])([0-9a-f])([0-9a-f])$/);return`#${n}${n}${s}${s}${o}${o}`}return t}return t.replace(/\s+/g,"")}function gh(e){return ph.has(e)}function fh(e){let t=[],n=be(e,"css");if(x(n))for(let o of Vt(n))o.endsWith(".css")&&t.push(be(n,o));let s=be(e,"modules");if(x(s))for(let o of Vt(s)){if(!o.endsWith(".module"))continue;let i=be(s,o,"module.css");x(i)&&t.push(i)}return t}function hh(e){let t=be(e,"modules"),n=be(e,"templates"),s=new Set,o=new Map;if(x(t))for(let c of Vt(t)){if(!c.endsWith(".module"))continue;let d=c.replace(/\.module$/,"");s.add(d),o.set(d,x(be(t,c,"module.js")))}let i=[],r=new Map;if(x(n))for(let c of Vt(n)){if(!c.endsWith(".html")||c==="home.html")continue;let d=be(n,c),u;try{u=ur(d)}catch{continue}if(!u.isFile())continue;let m;try{m=P(d)}catch{continue}let g=pr(m);for(let f of g){let b=r.get(f)??new Set;b.add(c),r.set(f,b)}let h=c.replace(/\.html$/,"");i.push({id:h,file:`templates/${c}`,modules:Ch(g)})}let a=[...s].sort().map(c=>({name:c,templates:[...r.get(c)??[]].sort(),hasJs:o.get(c)??!1})),l=a.filter(c=>c.templates.length===0).map(c=>c.name);return{templates:i,modules:a,orphanModules:l}}function pr(e){let t=[],n=/{%\s*dnd_module\b[\s\S]*?%}/g,s;for(;(s=n.exec(e))!==null;){let o=s[0].match(/\bpath\s*=\s*["']([^"']+)["']/);if(!o)continue;let i=o[1].match(/(?:^|\/)modules\/(.+)$/);if(!i)continue;let r=i[1].replace(/\.module$/,"");r&&t.push(r)}return t}function bh(e){let t=[],n=be(e,"modules");if(!x(n))return t;for(let s of Vt(n)){if(!s.endsWith(".module"))continue;let o=s.replace(/\.module$/,""),i=be(n,s,"fields.json");if(!x(i))continue;let r;try{r=JSON.parse(P(i))}catch{continue}Array.isArray(r)&&Dc(r,o,t,0)}return t}function Dc(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)",a=typeof i.type=="string"?i.type:"";if(a==="group"&&s>=1&&n.push({module:t,field:r,reason:"deeply nested group (>1 level)"}),(a==="group"||a==="module")&&i.occurrence){let l=i.occurrence;l.max!==void 0&&l.max!==1&&n.push({module:t,field:r,reason:"repeater (occurrence) field"})}(a==="hubdb_table"||a==="hubdbtable")&&n.push({module:t,field:r,reason:"HubDB-backed field"}),(a==="crm_object"||a==="crm_object_property")&&n.push({module:t,field:r,reason:"CRM object field"}),a==="embed"&&typeof i.embed=="object"&&n.push({module:t,field:r,reason:"rich embed field"}),a&&!yh.has(a)&&a!=="module"&&n.push({module:t,field:r,reason:`field type "${a}" not in vibeSpot's generation set`}),i.visibility&&typeof i.visibility=="object"&&n.push({module:t,field:r,reason:"conditional visibility rule"}),Array.isArray(i.children)&&Dc(i.children,t,n,s+1)}}function Sh(e){let t=[],n=be(e,"modules");if(x(n))for(let i of Vt(n)){if(!i.endsWith(".module"))continue;let r=i.replace(/\.module$/,""),a=be(n,i,"module.html");x(a)&&Rc(a,e,r,t);let l=be(n,i,"module.js");if(x(l))try{P(l).trim().length>0&&t.push({file:gr(e,l),pattern:"module.js.custom",detail:`${r}: module ships custom JS \u2014 preserve verbatim`})}catch{}}let s=be(e,"templates");if(x(s))for(let i of Vt(s)){if(!i.endsWith(".html"))continue;let r=be(s,i);if(!x(r))continue;let a;try{a=ur(r)}catch{continue}a.isFile()&&Rc(r,e,i,t)}let o=be(e,"import_modules.json");return x(o)&&t.push({file:"import_modules.json",pattern:"theme.import_modules",detail:"Theme declares import_modules.json \u2014 preserve to avoid breaking HubSpot pre-install"}),t}function Rc(e,t,n,s){let o;try{o=P(e)}catch{return}let i=gr(t,e);/{%\s*macro\s+\w+/.test(o)&&s.push({file:i,pattern:"hubl.macro",detail:`${n}: contains custom HubL {% macro %}`}),/{%\s*raw\s*%}/.test(o)&&s.push({file:i,pattern:"hubl.raw",detail:`${n}: contains {% raw %} block`});let r=/{%\s*include\s+["']([^"']+)["']/g,a;for(;(a=r.exec(o))!==null;){let l=a[1];!l.startsWith("../modules/")&&!l.startsWith("./modules/")&&!l.includes("/layouts/")&&s.push({file:i,pattern:"hubl.include",detail:`${n}: includes partial "${l}" outside modules/`})}}function vh(e,t){let n={hasSnapshot:!1,snapshotPath:Ss(e),filesChanged:0,added:0,modified:0,deleted:0,files:[]};return{themePath:e,designTokens:{cssVariables:{},palette:[],fontFamilies:[],fontSizes:[],spacing:[],radii:[],shadows:[]},graph:{templates:[],modules:[],orphanModules:[]},fieldFlags:[],roundTripRisks:[],roundTripDiff:n,findings:t,summary:{moduleCount:0,templateCount:0,orphanCount:0,paletteSize:0,cssVarCount:0,customMacroCount:0,roundTripChangedCount:0}}}function jc(e){let t=[];function n(s){for(let o of Vt(s)){if(o===".git"||o===".vibespot"||o==="node_modules")continue;let i=be(s,o),r;try{r=ur(i)}catch{continue}if(r.isDirectory()){n(i);continue}if(!r.isFile())continue;let a=gr(e,i),l=Vf(i),c={path:a,sha256:zf("sha256").update(l).digest("hex"),size:l.length};xh(a)&&(c.text=l.toString("utf8")),t.push(c)}}return n(e),t.sort((s,o)=>s.path.localeCompare(o.path))}function xh(e){let t=e.lastIndexOf(".");return t<0?!1:Xf.has(e.slice(t).toLowerCase())}function wh(e){if(typeof e!="object"||e===null)return!1;let t=e;return t.version!==1||typeof t.createdAt!="string"||!Array.isArray(t.files)?!1:t.files.every(n=>{if(typeof n!="object"||n===null)return!1;let s=n;return typeof s.path=="string"&&typeof s.sha256=="string"&&typeof s.size=="number"&&(s.text===void 0||typeof s.text=="string")})}function Jo(e){if(e!==void 0)return e.length===0?0:e.split(/\r\n|\r|\n/).length}function Vt(e){try{return Oc(e)}catch{return[]}}function gr(e,t){return Yf(e,t).split("\\").join("/")}function Ch(e){return[...new Set(e)]}var qf,Xf,th,nh,sh,oh,ih,rh,ah,lh,ch,dh,ph,yh,Uo=N(()=>{"use strict";y();oe();qf=".vibespot/import-snapshot.json",Xf=new Set([".css",".html",".htm",".js",".json",".md",".txt",".svg",".yml",".yaml"]);th=/#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})\b/g,nh=/\brgba?\([^)]+\)/g,sh=/\bhsla?\([^)]+\)/g,oh=/font-family\s*:\s*([^;}\n]+)/g,ih=/font-size\s*:\s*([^;}\n]+)/g,rh=/(?:padding|margin|gap)(?:-(?:top|right|bottom|left))?\s*:\s*([^;}\n]+)/g,ah=/border-radius\s*:\s*([^;}\n]+)/g,lh=/box-shadow\s*:\s*([^;}\n]+)/g,ch=/:root\s*\{([\s\S]*?)\}/g,dh=/(--[\w-]+)\s*:\s*([^;}\n]+)/g;ph=new Set(["#000000","#ffffff","transparent","currentcolor","inherit","initial"]);yh=new Set(["text","richtext","image","url","boolean","choice","number","color","icon","link","menu","video","form","cta","blog","tag","page","email","logo","embed","alignment","border","spacing","font","background","gradient","textalignment","group"])});import{readFileSync as fr,readdirSync as xs,existsSync as xe,writeFileSync as Ye,mkdirSync as vs,rmSync as Lc}from"fs";import{join as U}from"path";function we(e){try{return fr(e,"utf-8")}catch{return""}}function Bc(e){let t=[];for(let n of e.moduleOrder){let s=e.modules.find(o=>o.moduleName===n);s&&t.push(s)}for(let n of e.modules)e.moduleOrder.includes(n.moduleName)||t.push(n);return t}function kh(e,t){let n=we(e);if(!n||t==="home.html"||t.endsWith("-listing.html"))return null;let s=t.replace(/\.html$/,""),o=/templateType:\s*email\b/i.test(n),i="landing_page",r;o?(i="module_only",r="email"):s.startsWith("bp-")?i="blog_post":s.startsWith("wp-")?i="website_page":s.startsWith("mo-")&&(i="module_only");let a=s,l=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);l&&(a=l[1].trim());let c=pr(n);return{id:s,label:a,pageType:i,contentMode:r,moduleNames:c,templateContent:n,filename:t}}function Th(e,t,n,s,o){if(!xe(e))return[];let i=[],r=xs(e).filter(a=>a.endsWith(".html")&&a!=="home.html");for(let a of r){let l=U(e,a),c=kh(l,a);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let m of c.moduleNames){let g=t.get(m);g&&(d.push(g),u.push(m))}i.push({id:c.id,label:c.label,pageType:c.pageType,contentMode:c.contentMode,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:c.contentMode==="email"?"":n,sharedJs:c.contentMode==="email"?"":s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function Go(e){let t=C();if(!t)return;let n=vc(e);n.length>0&&t.messages.length===0&&(t.messages=n),Mo(e),Fc(e);let s=U(e,"modules");if(!xe(s))return;let o=xs(s,{withFileTypes:!0});for(let S of o){if(!S.isDirectory()||!S.name.endsWith(".module"))continue;let v=U(s,S.name),w=S.name.replace(/\.module$/,""),$={moduleName:w,fieldsJson:we(U(v,"fields.json")),metaJson:we(U(v,"meta.json")),moduleHtml:we(U(v,"module.html")),moduleCss:we(U(v,"module.css")),moduleJs:we(U(v,"module.js"))||void 0};$.fieldsJson&&$.moduleHtml&&(t.modules.push($),t.moduleOrder.push(w))}let i=U(e,"css"),r=U(e,"js"),a="",l="";if(xe(i)){let S=xs(i).filter(v=>v.endsWith("-theme.css"));S.length>0&&(a=we(U(i,S[0])),t.sharedCss=a)}if(xe(r)){let S=xs(r).filter(v=>v.endsWith("-animations.js"));S.length>0&&(l=we(U(r,S[0])),t.sharedJs=l)}if(!a&&t.modules.length>0){let S=Dn(e),v=bs(S);v&&(t.sharedCss=v,a=v)}let c=U(e,".vibespot","styleguide.md"),d=U(e,".vibespot","brandvoice.md"),u=U(e,".vibespot","theme-context.md"),m=U(e,".vibespot","plan.md"),g=U(e,".vibespot","brand-kit.json");if((xe(c)||xe(d)||xe(u)||xe(m)||xe(g))&&(t.brandAssets||(t.brandAssets={}),xe(c)&&(t.brandAssets.styleguide=we(c)),xe(d)&&(t.brandAssets.brandvoice=we(d)),xe(u)&&(t.brandAssets.themeContext=we(u)),xe(m)&&(t.brandAssets.plan=we(m)),xe(g)))try{t.brandAssets.brandKit=JSON.parse(we(g))}catch{}let h=U(e,"templates"),f=new Map(t.modules.map(S=>[S.moduleName,S])),b=Th(h,f,a,l,t.messages);if(b.length>0){t.templates=b,t.activeTemplateId=b[0].id,t.brandAssets?.plan&&!b[0].plan&&(b[0].plan=t.brandAssets.plan);let S=b[0].moduleOrder;if(S.length>0){let v=new Set(t.moduleOrder),w=S.filter($=>v.has($));for(let $ of t.moduleOrder)w.includes($)||w.push($);t.moduleOrder=w}an(b[0])}else t.templates||(t.templates=[]),t.activeTemplateId||(t.activeTemplateId=""),Ro(t)}function Te(){let e=C();if(!e)return;let t=e.themePath,n=new Map;if(e.templates.length>0)for(let l of e.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of e.modules)n.set(l.moduleName,l);let s=U(t,"modules");vs(s,{recursive:!0});for(let l of n.values())vs(U(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=U(s,`${l.moduleName}.module`);Ye(U(c,"fields.json"),l.fieldsJson,"utf-8"),Ye(U(c,"meta.json"),l.metaJson,"utf-8"),Ye(U(c,"module.html"),l.moduleHtml,"utf-8"),Ye(U(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&Ye(U(c,"module.js"),l.moduleJs,"utf-8")}if(e.sharedCss){let l=U(t,"css");vs(l,{recursive:!0}),Ye(U(l,`${e.themeName}-theme.css`),e.sharedCss,"utf-8")}if(e.sharedJs){let l=U(t,"js");vs(l,{recursive:!0}),Ye(U(l,`${e.themeName}-animations.js`),e.sharedJs,"utf-8")}let o=U(t,"templates");vs(o,{recursive:!0});let i=U(o,"home.html");(e.templates.length>0||e.modules.length>0)&&xe(i)&&Lc(i,{force:!0});let a=new Set;if(e.templates.length>0)for(let l of e.templates){if(l.contentMode==="email"){if(l.modules.length===0)continue;let m=Eh(l),g=l.templateFile?l.templateFile.replace("templates/",""):"email.html";Ye(U(o,g),m,"utf-8"),a.add(g);continue}if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||$h(l),d=Jc(c,l.label,l.pageType),u=`${l.id}.html`;Ye(U(o,u),d,"utf-8"),a.add(u),l.pageType==="blog_post"&&(Mh(o,l),a.add(`${l.id}-listing.html`))}else if(e.modules.length>0){let l=e.template||Ih(),c=Jc(l,`${e.themeName} Landing Page`),d=`lp-${e.themeName}.html`;Ye(U(o,d),c,"utf-8"),a.add(d)}try{for(let l of xs(o))l.startsWith("lp-")&&l.endsWith(".html")&&!a.has(l)&&Lc(U(o,l),{force:!0})}catch{}Ah(),_h()}function Hc(){let e=C();e&&(e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",Go(e.themePath),e.updatedAt=Date.now(),at())}function Uc(){let e=C();if(!e)return;let t=ke();if(!t)return;let n=e.themePath,s=U(n,"modules");t.modules=[];for(let o of t.moduleOrder){let i=U(s,`${o}.module`);if(!xe(i))continue;let r={moduleName:o,fieldsJson:we(U(i,"fields.json")),metaJson:we(U(i,"meta.json")),moduleHtml:we(U(i,"module.html")),moduleCss:we(U(i,"module.css")),moduleJs:we(U(i,"module.js"))||void 0};r.fieldsJson&&r.moduleHtml&&t.modules.push(r)}if(t.templateFile){let o=U(n,t.templateFile);xe(o)&&(t.template=we(o))}an(t),e.updatedAt=Date.now()}function Ah(){let e=C();if(!e)return;let t=U(e.themePath,"templates","layouts","base.html");if(xe(t))try{let n=fr(t,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
|
|
192
192
|
{% if template_js %}
|
|
193
193
|
{{ require_js(get_asset_url(template_js)) }}
|
|
194
194
|
{% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
|
|
195
195
|
{{ require_js(get_asset_url(template_js)) }}
|
|
196
196
|
{% endif %}
|
|
197
|
-
{{ standard_footer_includes }}`),Ye(t,n,"utf-8")}catch{}}function
|
|
197
|
+
{{ standard_footer_includes }}`),Ye(t,n,"utf-8")}catch{}}function _h(){let e=C();if(!e)return;let t=U(e.themePath,"theme.json");if(xe(t))try{let n=JSON.parse(fr(t,"utf-8"));n.label=e.themeName,n.name=e.themeName,Ye(t,JSON.stringify(n,null,2),"utf-8")}catch{}}function Jc(e,t,n="landing_page"){return e.includes("templateType")?e:`<!--
|
|
198
198
|
templateType: ${n==="blog_post"?"blog_post":"page"}
|
|
199
199
|
isAvailableForNewContent: true
|
|
200
200
|
label: "${t}"
|
|
201
201
|
-->
|
|
202
|
-
`+e}function
|
|
202
|
+
`+e}function $h(e){if(e.modules.length===0)return"";let n=C().themeName,o=Bc(e).map(r=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
|
|
203
203
|
{% dnd_module path="../modules/${r.moduleName}.module" %}
|
|
204
204
|
{% end_dnd_module %}
|
|
205
205
|
{% end_dnd_section %}`).join(`
|
|
@@ -230,7 +230,7 @@ ${o}
|
|
|
230
230
|
|
|
231
231
|
{% block footer %}
|
|
232
232
|
{% endblock footer %}
|
|
233
|
-
`}function
|
|
233
|
+
`}function Eh(e){let n=Bc(e).map(s=>` {% dnd_section %}
|
|
234
234
|
{% dnd_module path="../modules/${s.moduleName}.module" %}
|
|
235
235
|
{% end_dnd_module %}
|
|
236
236
|
{% end_dnd_section %}`).join(`
|
|
@@ -277,7 +277,7 @@ ${n}
|
|
|
277
277
|
{{ standard_footer_includes }}
|
|
278
278
|
</body>
|
|
279
279
|
</html>
|
|
280
|
-
`}function
|
|
280
|
+
`}function Mh(e,t){let n=`<!--
|
|
281
281
|
templateType: blog_listing
|
|
282
282
|
isAvailableForNewContent: true
|
|
283
283
|
label: "${t.label} - Listing"
|
|
@@ -302,7 +302,7 @@ ${n}
|
|
|
302
302
|
{% endif %}
|
|
303
303
|
</div>
|
|
304
304
|
{% endblock body %}
|
|
305
|
-
`;Ye(U(e,`${t.id}-listing.html`),n,"utf-8")}function
|
|
305
|
+
`;Ye(U(e,`${t.id}-listing.html`),n,"utf-8")}function Ih(){let e=C();if(!e||e.modules.length===0)return"";let t=e.themeName,s=ve().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
|
|
306
306
|
{% dnd_module path="../modules/${o.moduleName}.module" %}
|
|
307
307
|
{% end_dnd_module %}
|
|
308
308
|
{% end_dnd_section %}`).join(`
|
|
@@ -333,7 +333,7 @@ ${s}
|
|
|
333
333
|
|
|
334
334
|
{% block footer %}
|
|
335
335
|
{% endblock footer %}
|
|
336
|
-
`}var
|
|
336
|
+
`}var hr=N(()=>{"use strict";y();hs();gs();Kt();Pn();Uo()});var Gc=N(()=>{"use strict";y();oc();hs();gs();hr();Kt()});var Ce=N(()=>{"use strict";y();Gc()});function ln(e){let t={};for(let n of e)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?t[n.name]=n.default:n.type==="group"&&n.children?t[n.name]=ln(n.children):t[n.name]=n.default??"";return t}function Ln(e,t){let n=e;return n=Jh(n),n=zc(n,t),n=Yc(n,t),n=qc(n,t),n=Hh(n),n}function Sr(e){let t=[e.sharedCss||"",...e.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
|
|
337
337
|
`),n=[e.sharedJs||"",...e.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
|
|
338
338
|
`),s=e.renderedModules.join(`
|
|
339
339
|
`);return`<!DOCTYPE html>
|
|
@@ -380,11 +380,11 @@ document.querySelectorAll('img').forEach(function(img){
|
|
|
380
380
|
});
|
|
381
381
|
</script>
|
|
382
382
|
</body>
|
|
383
|
-
</html>`}function
|
|
383
|
+
</html>`}function Jh(e){return e=e.replace(Ph,""),e=e.replace(Nh,""),e=e.replace(Rh,""),Wc.lastIndex=0,e=e.replace(Wc,(t,n)=>`/theme-assets/${n}`),Kc.lastIndex=0,e=e.replace(Kc,""),e=e.replace(Oh,""),e=e.replace(Fh,""),e=e.replace(Dh,""),e=e.replace(jh,""),e=e.replace(Lh,""),e}function zc(e,t){let n=e,s=0;for(;s<30;){s++;let o=Bh(n);if(!o)break;let{varName:i,iterExpr:r,body:a,start:l,end:c}=o,d=Uh(r,t),u="";Array.isArray(d)&&(u=d.map((m,g)=>{let h={...t,[i]:m,loop:{index:g+1,index0:g,first:g===0,last:g===d.length-1,length:d.length}},f=zc(a,h);return f=Yc(f,h),f=qc(f,h),f}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function Bh(e){let t=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=t.exec(e);if(!s)return null;let o=s[1],i=s[2],r=s.index+s[0].length;n.lastIndex=r;let a=1,l;for(;(l=n.exec(e))!==null;)if(l[1].startsWith("for"))a++;else if(a--,a===0){let c=e.slice(r,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function Yc(e,t){let n=e,s=0;for(;yr.test(n)&&s<50;)s++,n=n.replace(yr,(o,i,r)=>{let a=r.split(/\{%[-\s]*else\s*-?%\}/),l=a[0],c=a[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if(jn(i,t))return d[0];for(let u=1;u<d.length;u+=2){let m=d[u],g=d[u+1]||"";if(jn(m,t))return g}return c}return jn(i,t)?l:c}),yr.lastIndex=0;return n}function qc(e,t){return e.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),r=i[0].trim(),a=Gh(t,r);for(let c=1;c<i.length;c++)a=Zc(a,i[c].trim());if(a==null)return"";if(typeof a=="object")return JSON.stringify(a);let l=String(a);return l=l.replace(/\\n/g," ").replace(/\n/g," "),l})}function Hh(e){return e=e.replace(/\{%.*?%\}/gs,""),e=e.replace(/\{\{.*?\}\}/gs,""),e}function Uh(e,t){let n=e.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=Vc(n[1],t),i=Vc(n[2],t),r=[];for(let a=o;a<i;a++)r.push(a);return r}let s=e.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=zt(t,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return zt(t,e)}function Vc(e,t){let s=e.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=zt(t,o);for(let r=1;r<s.length;r++)i=Zc(i,s[r].trim());return Number(i)||0}function zt(e,t){let n=t.split("."),s=e;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function Gh(e,t){let n=t.match(/^(.+?)\s*([*/])\s*([\d.]+)$/);if(n){let s=zt(e,n[1].trim());if(s==null||s==="")return"";let o=Number(s);if(Number.isNaN(o))return"";let i=Number(n[3]);return n[2]==="/"?i===0?"":o/i:o*i}return zt(e,t)}function jn(e,t){let n=e.trim();if(n.startsWith("not "))return!jn(n.slice(4),t);if(n.includes(" and "))return n.split(" and ").every(i=>jn(i,t));if(n.includes(" or "))return n.split(" or ").some(i=>jn(i,t));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=zt(t,s[1].trim()),r=s[2],a=s[3].trim();switch(typeof a=="string"&&a.startsWith('"')&&a.endsWith('"')||typeof a=="string"&&a.startsWith("'")&&a.endsWith("'")?a=a.slice(1,-1):isNaN(Number(a))?a=zt(t,a):a=Number(a),r){case"==":return i==a;case"!=":return i!=a;case">":return Number(i)>Number(a);case"<":return Number(i)<Number(a);case">=":return Number(i)>=Number(a);case"<=":return Number(i)<=Number(a)}}let o=zt(t,n);return Xc(o)}function Xc(e){return!(e==null||e===""||e===0||e===!1||Array.isArray(e)&&e.length===0)}function Zc(e,t){let n=e==null?"":String(e),s=t.match(/^(\w+)\((.*)\)$/),o=s?s[1]:t,i=s?s[2].replace(/^["']|["']$/g,""):void 0;switch(o){case"escape":case"e":return n.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");case"lower":return n.toLowerCase();case"upper":return n.toUpperCase();case"capitalize":return n.charAt(0).toUpperCase()+n.slice(1);case"trim":return n.trim();case"truncate":if(i){let r=parseInt(i,10);return n.length>r?n.slice(0,r)+"...":n}return n;case"default":return Xc(e)?e:i??"";case"length":return Array.isArray(e)?e.length:n.length;case"join":return Array.isArray(e)?e.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));case"convert_rgb":{let r=br(e);return r?Kh(r):""}default:return e}}function br(e){if(e==null)return null;if(typeof e=="string"){let t=e.match(/#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})(?![0-9a-fA-F])/);return t?Wh(t[1]):null}if(typeof e=="object"){let t=e;if(typeof t.color=="string")return br(t.color);if(typeof t.hex=="string")return br(t.hex)}return null}function Wh(e){let t=e.toLowerCase();return t.length===3?t.split("").map(n=>n+n).join(""):t}function Kh(e){let t=parseInt(e.slice(0,2),16),n=parseInt(e.slice(2,4),16),s=parseInt(e.slice(4,6),16);return`${t}, ${n}, ${s}`}var Ph,Nh,Rh,Wc,Kc,Oh,Fh,Dh,jh,Lh,yr,vr=N(()=>{"use strict";y();Ph=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Nh=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,Rh=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,Wc=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,Kc=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,Oh=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Fh=/\{%[-\s]*module\b.*?%\}/gs,Dh=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,jh=/\{#.*?#\}/gs,Lh=/\{\{[-\s]*content\.\w+.*?\}\}/gs,yr=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Wo={};Ge(Wo,{buildModulePreviewHtml:()=>Cr,buildPreviewHtml:()=>wr});function Vh(e){if(Jn()==="email")return!0;for(let t of e)try{let n=JSON.parse(t.metaJson);if(Array.isArray(n.host_template_types)&&n.host_template_types.includes("EMAIL"))return!0}catch{}return!1}function zh(e){if(!e)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let t=(a,l)=>{for(let c of a){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=e.match(d);if(u)return u[1].trim()}return l},n=t(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=t(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=t(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=t(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),r=t(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:r}}function xr(e,t){if(!Array.isArray(t))return e;let n=new Map;for(let o of t)n.set(o.name,o.type);let s=e;return s=s.replace(/(<([a-zA-Z]\w*)(\s[^>]*)?>)\s*(\{\{\s*module\.(\w+)(?:\.\w+)*(?:\|[^}]*)?\s*\}\})\s*(<\/\2>)/g,(o,i,r,a,l,c,d)=>{if(i.includes("data-vs-field"))return o;let u=n.get(c)||"text";return`${i.replace(/>$/,` data-vs-field="${c}" data-vs-type="${u}">`)}${l}${d}`}),s=s.replace(/(<img\b)([^>]*?)\bsrc\s*=\s*["']\{\{\s*module\.(\w+)\.src\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-field")?o:o.replace("<img",`<img data-vs-field="${a}" data-vs-type="image"`)),s=s.replace(/(<a\b)([^>]*?)\bhref\s*=\s*["']\{\{\s*module\.(\w+)\.url\.href\s*\}\}["']([^>]*?>)/g,(o,i,r,a)=>o.includes("data-vs-link")?o:o.replace("<a",`<a data-vs-link="${a}"`)),s}function wr(){let e=C();if(!e)return Qc();let t=ve(),n=e.moduleOrder||[];if(t.length===0&&n.length===0)return Qc();if(Vh(t))return Yh(t,n);let s=[],o=[],i=[],r=new Set;for(let c of t){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d,u=[];try{let f=JSON.parse(c.fieldsJson);u=Array.isArray(f)?f:[],d={module:ln(u)}}catch{d={module:{}}}let m=xr(c.moduleHtml,u),g=Ln(m,d),h=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${h}" data-module="${c.moduleName}">${g}</div>`),r.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let a=zh(e.sharedCss);for(let c of n)if(!r.has(c)){let d=c.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module vibespot-module--pending" id="${d}" data-module="${c}">
|
|
384
384
|
<div class="vibespot-placeholder">
|
|
385
385
|
<div class="vibespot-placeholder__name">${c}</div>
|
|
386
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
|
|
387
|
+
</div>`)}let l=`body{background:${a.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${a.surface};border:1px dashed ${a.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${a.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return Sr({renderedModules:s,sharedCss:e.sharedCss,moduleCssArray:[l,...o],sharedJs:e.sharedJs,moduleJsArray:i})}function Qc(){return`<!DOCTYPE html>
|
|
388
388
|
<html lang="en">
|
|
389
389
|
<head>
|
|
390
390
|
<meta charset="utf-8">
|
|
@@ -435,7 +435,7 @@ document.querySelectorAll('img').forEach(function(img){
|
|
|
435
435
|
<div class="welcome__sub">Build Something Great</div>
|
|
436
436
|
</div>
|
|
437
437
|
</body>
|
|
438
|
-
</html>`}function
|
|
438
|
+
</html>`}function Cr(e){let t=C();if(!t)return"";let n;for(let a of t.templates)if(n=a.modules.find(l=>l.moduleName===e),n)break;if(n||(n=t.modules.find(a=>a.moduleName===e)),!n)return"";let s,o=[];try{let a=JSON.parse(n.fieldsJson);o=Array.isArray(a)?a:[],s={module:ln(o)}}catch{s={module:{}}}let i=xr(n.moduleHtml,o),r=Ln(i,s);return Sr({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${r}</div>`],sharedCss:t.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:t.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}function Yh(e,t){let n=[],s=new Set;for(let i of e){let r,a=[];try{let u=JSON.parse(i.fieldsJson);a=Array.isArray(u)?u:[],r={module:ln(a)}}catch{r={module:{}}}let l=xr(i.moduleHtml,a),c=Ln(l,r),d=i.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module" id="${d}" data-module="${i.moduleName}">${c}</div>`),s.add(i.moduleName)}for(let i of t)if(!s.has(i)){let r=i.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");n.push(`<div class="vibespot-module vibespot-module--pending" id="${r}" data-module="${i}">
|
|
439
439
|
<table role="presentation" cellpadding="0" cellspacing="0" border="0" width="100%" style="max-width:600px;margin:0 auto;">
|
|
440
440
|
<tr><td style="padding:40px 30px;text-align:center;background-color:#ffffff;border:1px dashed #ddd;">
|
|
441
441
|
<p style="font-family:Arial,Helvetica,sans-serif;font-size:14px;color:#999;">${i}</p>
|
|
@@ -485,7 +485,7 @@ document.addEventListener('click', function(e) {
|
|
|
485
485
|
});
|
|
486
486
|
</script>
|
|
487
487
|
</body>
|
|
488
|
-
</html>`}var
|
|
488
|
+
</html>`}var ws=N(()=>{"use strict";y();vr();Ce();Cs()});function ct(e){try{return JSON.parse(e)}catch{}let t=e,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(t)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let r=parseInt(i[1],10);if(r<=n)return null;n=r;let a=Math.max(0,r-5),c=t.slice(a,r+1).lastIndexOf('"');if(c===-1)return null;let d=a+c;if(d>0&&t[d-1]==="\\")return null;t=t.slice(0,d)+'\\"'+t.slice(d+1)}return null}function ks(e){let t=e.indexOf('"modules"');if(t===-1)return null;let n=e.indexOf("[",t);if(n===-1)return null;let s=-1,o=0,i=!1,r=!1;for(let d=n+1;d<e.length;d++){let u=e[d];if(r){r=!1;continue}if(u==="\\"){r=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=e.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return ct(c)}function kr(e){return{moduleName:String(e.moduleName||""),fieldsJson:typeof e.fieldsJson=="string"?e.fieldsJson:JSON.stringify(e.fieldsJson,null,2),metaJson:typeof e.metaJson=="string"?e.metaJson:JSON.stringify(e.metaJson,null,2),moduleHtml:String(e.moduleHtml||""),moduleCss:String(e.moduleCss||""),moduleJs:e.moduleJs?String(e.moduleJs):void 0}}function ed(e,t){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(e))!==null;)try{M.info("parse","Found vibespot-modules block",{length:s[1].length});let i=ct(s[1]);if(!i||typeof i!="object")throw M.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let r=i;r.modules&&Array.isArray(r.modules)&&(He({modules:r.modules.map(a=>kr(a)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(i){M.warn("parse","Failed to parse vibespot-modules block",{error:i instanceof Error?i.message:String(i)})}if(!n){let i=/```(?:json)?\s*\n([\s\S]*?)```/g;for(;(s=i.exec(e))!==null;)if(s[1].includes('"modules"'))try{let r=ct(s[1]);if(!r||typeof r!="object")throw new Error("Invalid JSON after repair");let a=r;a.modules&&Array.isArray(a.modules)&&(He({modules:a.modules.map(l=>kr(l)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(r){M.warn("parse","Failed to parse JSON module block",{error:r instanceof Error?r.message:String(r)})}}if(!n&&(e.match(/```/g)||[]).length%2!==0&&e.includes('"modules"')){M.info("parse","Detected truncated response (odd fence count), attempting salvage");let r=e.lastIndexOf("```"),a=e.slice(r+3);a=a.replace(/^[\w-]*\s*\n?/,"");let l=ks(a);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(M.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),He({modules:c.modules.map(d=>kr(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,t&&t("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){M.info("parse","No modules applied",{responseLength:e.length,hasVibespot:e.includes("vibespot-modules"),hasModules:e.includes('"modules"'),fenceCount:(e.match(/```/g)||[]).length});let i=e.includes("vibespot-modules")||e.includes('"modules"'),r=/\bmodule|modul/i.test(e)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(e)||/\|.*\|.*\|/m.test(e));if(i||r){let a=i?"Module changes could not be applied \u2014 the AI response contained invalid JSON. Try sending your request again.":"The AI described modules but did not include the required structured data. Try sending your request again.";M.warn("parse",a),t&&t(a)}}}var Ko=N(()=>{"use strict";y();Ce();le()});function Hn(){let e=C();return e?{pageType:ke()?.pageType,brandAssets:e.brandAssets}:{}}function nd(e,t,n=!1,s,o){let r=[{type:"text",text:Xh(t,n)}];if(n){let l=`## HubSpot CMS Rules
|
|
489
489
|
${Je()}
|
|
490
490
|
|
|
491
491
|
## Conversion Guide Reference
|
|
@@ -512,22 +512,22 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
|
|
|
512
512
|
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
513
|
|
|
514
514
|
## Design Guide
|
|
515
|
-
${
|
|
515
|
+
${cs()}
|
|
516
516
|
|
|
517
517
|
## Content & Copywriting Guide
|
|
518
|
-
${
|
|
518
|
+
${Vi()}
|
|
519
519
|
|
|
520
520
|
## HubSpot CMS Rules
|
|
521
521
|
${Je()}
|
|
522
522
|
|
|
523
523
|
## Conversion Guide Reference
|
|
524
|
-
${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=
|
|
524
|
+
${e}`;r.push({type:"text",text:l,cache_control:{type:"ephemeral"}})}let a=qh(s,o);return a&&r.push({type:"text",text:a}),r.push({type:"text",text:"## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory."}),r}function qh(e,t){let n=[];if(e){let s=Yi(e);s&&n.push(`## Page Type Context
|
|
525
525
|
${s}`)}if(t?.styleguide&&n.push(`## Brand Style Guide
|
|
526
526
|
${t.styleguide}`),t?.brandvoice&&n.push(`## Brand Voice
|
|
527
|
-
${t.brandvoice}`),t?.humanify!==!1){let s=
|
|
527
|
+
${t.brandvoice}`),t?.humanify!==!1){let s=zi();s&&n.push(`## Anti-AI Copy Rules (Humanify)
|
|
528
528
|
${s}`)}return n.join(`
|
|
529
529
|
|
|
530
|
-
`)}function
|
|
530
|
+
`)}function Xh(e,t){return`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
|
|
531
531
|
|
|
532
532
|
## Your Role
|
|
533
533
|
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,7 +606,7 @@ The current template's modules are listed in page order in the user message. Thi
|
|
|
606
606
|
- **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
607
|
- **Remove**: When the user asks to remove a section, omit it from the output.
|
|
608
608
|
- **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
|
|
609
|
+
- **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`:"")}function Ts(e,t,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
|
|
610
610
|
|
|
611
611
|
## Your Role
|
|
612
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.
|
|
@@ -685,7 +685,7 @@ The current template's modules are listed in page order in the user message. Thi
|
|
|
685
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
686
|
- **Remove**: When the user asks to remove a section, omit it from the output.
|
|
687
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?
|
|
688
|
+
- **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,r=s?Yi(s):"",a=r?`
|
|
689
689
|
|
|
690
690
|
## Page Type Context
|
|
691
691
|
${r}`:"",l="";if(o?.styleguide&&(l+=`
|
|
@@ -694,7 +694,7 @@ ${r}`:"",l="";if(o?.styleguide&&(l+=`
|
|
|
694
694
|
${o.styleguide}`),o?.brandvoice&&(l+=`
|
|
695
695
|
|
|
696
696
|
## Brand Voice
|
|
697
|
-
${o.brandvoice}`),o?.humanify!==!1){let d=
|
|
697
|
+
${o.brandvoice}`),o?.humanify!==!1){let d=zi();d&&(l+=`
|
|
698
698
|
|
|
699
699
|
## Anti-AI Copy Rules (Humanify)
|
|
700
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+`
|
|
@@ -728,17 +728,17 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
|
|
|
728
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.
|
|
729
729
|
|
|
730
730
|
## Design Guide
|
|
731
|
-
${
|
|
731
|
+
${cs()}
|
|
732
732
|
|
|
733
733
|
## Content & Copywriting Guide
|
|
734
|
-
${
|
|
734
|
+
${Vi()}
|
|
735
735
|
|
|
736
736
|
## HubSpot CMS Rules
|
|
737
737
|
${Je()}
|
|
738
738
|
|
|
739
739
|
## Conversion Guide Reference
|
|
740
|
-
${e}`+c}function
|
|
741
|
-
/* \u2026truncated ${e.length-t} chars to fit the context budget\u2026 */`}function
|
|
740
|
+
${e}`+c}function Bn(e,t){return e.length<=t?e:e.slice(0,t)+`
|
|
741
|
+
/* \u2026truncated ${e.length-t} chars to fit the context budget\u2026 */`}function As(){let e=C(),t=[],n=e.modules,s=n.length;if(s>0){t.push(`
|
|
742
742
|
|
|
743
743
|
## Page Narrative (module sequence)
|
|
744
744
|
`),t.push(`This template has ${s} module${s===1?"":"s"} in this order:
|
|
@@ -747,43 +747,43 @@ ${e}`+c}function Jn(e,t){return e.length<=t?e:e.slice(0,t)+`
|
|
|
747
747
|
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
748
|
`),t.push(`
|
|
749
749
|
## Current Module State
|
|
750
|
-
`);let a=0,l=!1,c=Math.max(2e3,Math.floor(
|
|
750
|
+
`);let a=0,l=!1,c=Math.max(2e3,Math.floor(td/Math.max(s,1)));for(let d=0;d<s;d++){let u=n[d];if(l){t.push(`
|
|
751
751
|
### ${d+1}/${s}: ${u.moduleName}.module \u2014 (source omitted to fit context budget; ask to edit it specifically to load its source)
|
|
752
752
|
`);continue}let m=`
|
|
753
753
|
### ${d+1}/${s}: ${u.moduleName}.module
|
|
754
754
|
**fields.json:**
|
|
755
755
|
\`\`\`json
|
|
756
|
-
${
|
|
756
|
+
${Bn(u.fieldsJson,c)}
|
|
757
757
|
\`\`\`
|
|
758
758
|
**module.html:**
|
|
759
759
|
\`\`\`html
|
|
760
|
-
${
|
|
760
|
+
${Bn(u.moduleHtml,c)}
|
|
761
761
|
\`\`\`
|
|
762
762
|
**module.css:**
|
|
763
763
|
\`\`\`css
|
|
764
|
-
${
|
|
764
|
+
${Bn(u.moduleCss,c)}
|
|
765
765
|
\`\`\`
|
|
766
766
|
`+(u.moduleJs?`**module.js:**
|
|
767
767
|
\`\`\`js
|
|
768
|
-
${
|
|
768
|
+
${Bn(u.moduleJs,c)}
|
|
769
769
|
\`\`\`
|
|
770
|
-
`:"");a+=m.length,t.push(m),a>
|
|
770
|
+
`:"");a+=m.length,t.push(m),a>td&&(l=!0)}e.sharedCss&&t.push(`
|
|
771
771
|
### Shared CSS
|
|
772
772
|
\`\`\`css
|
|
773
|
-
${
|
|
773
|
+
${Bn(e.sharedCss,c)}
|
|
774
774
|
\`\`\`
|
|
775
775
|
`),e.sharedJs&&t.push(`
|
|
776
776
|
### Shared JS
|
|
777
777
|
\`\`\`js
|
|
778
|
-
${
|
|
778
|
+
${Bn(e.sharedJs,c)}
|
|
779
779
|
\`\`\`
|
|
780
|
-
`)}let o=
|
|
780
|
+
`)}let o=Ot(),i=new Set(e.modules.map(a=>a.moduleName)),r=o.filter(a=>!i.has(a.module.moduleName));if(r.length>0){t.push(`
|
|
781
781
|
|
|
782
782
|
## Available modules in this theme (reusable)
|
|
783
783
|
`);for(let a of r)t.push(`- ${a.module.moduleName} (used in: ${a.usedIn.join(", ")})
|
|
784
784
|
`);t.push(`
|
|
785
785
|
The user can ask to reuse any of these modules by name.
|
|
786
|
-
`)}return t.join("")}function
|
|
786
|
+
`)}return t.join("")}function Tr(e,t){let n=C(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===e&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=As(),r="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(r=`
|
|
787
787
|
|
|
788
788
|
## Available Theme Assets
|
|
789
789
|
These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
|
|
@@ -797,50 +797,50 @@ ${i}`),r&&(a+=r),a+="\n\n---\nRemember: respond with a ```vibespot-modules JSON
|
|
|
797
797
|
[Attached document: ${d.originalName}]
|
|
798
798
|
${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(a+=`
|
|
799
799
|
|
|
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
|
|
800
|
+
[Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?t.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:a}),o.push({role:"user",content:d})}else o.push({role:"user",content:a});return o}var td,sd=N(()=>{"use strict";y();Ke();Ce();td=2e5});import{spawn as id}from"child_process";import{mkdtempSync as Zh}from"fs";import{tmpdir as od}from"os";import{join as Qh}from"path";async function rd(){return Ar||(Ar=(await import("@anthropic-ai/sdk")).default),Ar}function ad(e){if(!e?.length)return"";let t=[];for(let n of e)n.type==="image"&&n.usage==="asset"&&n.assetPath&&t.push(`
|
|
801
801
|
[Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&t.push(`
|
|
802
802
|
|
|
803
803
|
---
|
|
804
804
|
[Attached document: ${n.originalName}]
|
|
805
|
-
${n.extractedText}`);return t.join("")}async function
|
|
806
|
-
`);
|
|
805
|
+
${n.extractedText}`);return t.join("")}async function ld(e,t,n,s,o,i,r,a="anthropic-api"){for(let l=0;;l++){let c=new Date;try{let d="",u=0,m=i||(()=>{});m(je[0]);let g=setInterval(()=>{u++,m(je[Math.min(u,je.length-1)])},6e3),h=e.messages.stream({model:s,max_tokens:48e3,system:t,messages:n});try{for await(let b of h)if(b.type==="content_block_delta"&&b.delta.type==="text_delta"){let S=b.delta.text;d+=S,o(S)}}finally{clearInterval(g)}let f;try{f=et((await h.finalMessage()).usage)}catch{}St({engine:a,model:s,name:"vibe-chat",input:{system:t,messages:n},output:d,usage:f,startTime:c,endTime:new Date}),r&&r(d);return}catch(d){let u=d.status,m=d.error?.type;if(!(u===429||m==="rate_limit_error"||d instanceof Error&&d.message.includes("429"))||l>=_r.length)throw d;let h=_r[l];M.warn("ai-engine",`Rate limited (429), attempt ${l+1}/${_r.length} \u2014 waiting ${h}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${h}s...`),await new Promise(f=>setTimeout(f,h*1e3)),i&&i("Retrying...")}}}function cd(e,t,n){let s=ye(),i=C().modules.length>0,r=Tr(e,n),a=Hn(),l=nd(s,t,i,a.pageType,a.brandAssets);return{messages:r,systemBlocks:l,conversionGuide:s,editMode:i}}async function $r(e,t,n,s,o,i,r,a,l){let c=await rd(),d=new c({apiKey:t,...l?{baseURL:l}:{}}),{messages:u,systemBlocks:m}=cd(e,n,a);M.info("anthropic","API call",{model:s,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:u.length}),await ld(d,m,u,s,o,i,r)}async function dd(e,t,n,s,o,i,r){let a=await Di();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let l=await rd(),c=new l({authToken:a,defaultHeaders:Zn}),{messages:d,systemBlocks:u}=cd(e,t,r),m=[{type:"text",text:xn},...u];M.info("anthropic-oauth","API call",{model:n,systemBlockCount:m.length,cachedBlocks:m.filter(g=>g.cache_control).length,messageCount:d.length}),await ld(c,m,d,n,s,o,i,"claude-oauth")}async function Er(e,t,n,s,o,i,r,a,l){let c=ye(),d=C().modules.length>0,u=Tr(e,a),m=Hn(),g=u.map(T=>typeof T.content=="string"?T:{role:T.role,content:T.content.map(k=>k.type==="text"?{type:"text",text:k.text}:{type:"image_url",image_url:{url:`data:${k.source.media_type};base64,${k.source.data}`}})}),h=Ts(c,n,d,m.pageType,m.brandAssets),f=l||"https://api.openai.com/v1/chat/completions",b=!/\/mistral(\/|$|\?)/.test(f),S=new Date,v=await fetch(f,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,...b?{stream_options:{include_usage:!0}}:{},messages:[{role:"system",content:h},...g]})});if(!v.ok){let T=await v.text();throw new Error(`API error (${v.status}): ${T}`)}let w=0,$=i||(()=>{});$(je[0]);let j=setInterval(()=>{w++,$(je[Math.min(w,je.length-1)])},6e3),J="",K,H=v.body.getReader(),X=new TextDecoder,F="";try{for(;;){let{done:T,value:k}=await H.read();if(T)break;F+=X.decode(k,{stream:!0});let E=F.split(`
|
|
806
|
+
`);F=E.pop()||"";for(let O of E){if(!O.startsWith("data: "))continue;let re=O.slice(6).trim();if(re==="[DONE]")break;try{let _e=JSON.parse(re),z=_e.choices?.[0]?.delta?.content;z&&(J+=z,o(z)),_e.usage&&(K=_e.usage)}catch{}}}}finally{clearInterval(j)}St({engine:"openai-api",model:s,name:"vibe-chat",input:{system:h,messages:g},output:J,usage:En(K),startTime:S,endTime:new Date}),r&&r(J)}async function Mr(e,t,n,s,o,i,r,a,l){let c=ye(),d=C(),u=d.modules.length>0,m=As(),g=Hn(),h=[];for(let O of d.messages.slice(-20))h.push({role:O.role==="assistant"?"model":"user",parts:[{text:O.content}]});let f=m?`${e}
|
|
807
807
|
|
|
808
808
|
---
|
|
809
|
-
${m}`:e;if(r?.length)for(let
|
|
809
|
+
${m}`:e;if(r?.length)for(let O of r)O.type==="document"&&O.extractedText&&(f+=`
|
|
810
810
|
|
|
811
811
|
---
|
|
812
|
-
[Attached document: ${
|
|
813
|
-
${
|
|
812
|
+
[Attached document: ${O.originalName}]
|
|
813
|
+
${O.extractedText}`),O.type==="image"&&O.usage==="asset"&&O.assetPath&&(f+=`
|
|
814
814
|
|
|
815
|
-
[Uploaded image: ${
|
|
816
|
-
`)
|
|
817
|
-
`))>=0;){let j=d.slice(0
|
|
818
|
-
${l}`,J=
|
|
815
|
+
[Uploaded image: ${O.originalName} \u2192 available as get_asset_url("${O.assetPath}")]`);let b=[];if(r?.length)for(let O of r)O.type==="image"&&O.base64&&b.push({inlineData:{mimeType:O.mimeType,data:O.base64}});b.push({text:f}),h.push({role:"user",parts:b});let S=l||"gemini-2.5-flash",v=a||`https://generativelanguage.googleapis.com/v1beta/models/${S}:streamGenerateContent?alt=sse&key=${t}`,w=Ts(c,n,u,g.pageType,g.brandAssets),$=new Date,j=await fetch(v,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:w}]},contents:h,generationConfig:{maxOutputTokens:48e3}})});if(!j.ok){let O=await j.text();throw new Error(`Gemini API error (${j.status}): ${O}`)}let J=0,K=o||(()=>{});K(je[0]);let H=setInterval(()=>{J++,K(je[Math.min(J,je.length-1)])},6e3),X="",F,T=j.body.getReader(),k=new TextDecoder,E="";try{for(;;){let{done:O,value:re}=await T.read();if(O)break;E+=k.decode(re,{stream:!0});let _e=E.split(`
|
|
816
|
+
`);E=_e.pop()||"";for(let z of _e){if(!z.startsWith("data: "))continue;let ue=z.slice(6).trim();try{let ne=JSON.parse(ue),$e=ne.candidates?.[0]?.content?.parts?.[0]?.text;$e&&(X+=$e,s($e)),ne.usageMetadata&&(F=ne.usageMetadata)}catch{}}}}finally{clearInterval(H)}St({engine:"gemini-api",model:S,name:"vibe-chat",input:{system:w,contents:h},output:X,usage:Mn(F),startTime:$,endTime:new Date}),i&&i(X)}function ey(){if(_s)return _s;try{_s=Zh(Qh(od(),"vibespot-claude-"))}catch{_s=od()}return _s}function ty(e){return/prompt is too long|exceed\w*\s+(the\s+)?(maximum\s+)?context|too many (input )?tokens|200000|context window/i.test(e)?"This request exceeded the model's 200k-token context window. vibeSpot isolates the Claude Code CLI from your MCP servers and project memory, so this usually means the page state itself is too large. Try: removing or splitting very large modules, starting a fresh theme, or switching to the Anthropic API engine in AI Settings (isolated per-request, no ambient context).":e}function Pr(e,t,n={},s){return new Promise((o,i)=>{let r={...process.env};delete r.CLAUDECODE;let a=id("claude",e,{stdio:["pipe","pipe","pipe"],env:r,cwd:ey()}),l="",c="",d="",u=!1,m=null,g=w=>{u||(u=!0,w())},h=w=>{try{if(w.type==="assistant"&&w.message?.content){for(let $ of w.message.content)if($.type==="text"&&typeof $.text=="string"){let j=$.text;l+=j,n.onChunk&&n.onChunk(j)}else if($.type==="tool_use"){let j=$;j.name&&n.onToolUse&&n.onToolUse(j.name,j.input)}}w.type==="result"&&(m=w,!l&&typeof w.result=="string"&&(l=w.result,n.onChunk&&n.onChunk(w.result))),n.onEvent&&n.onEvent(w)}catch{}};a.stdout.on("data",w=>{d+=w.toString();let $;for(;($=d.indexOf(`
|
|
817
|
+
`))>=0;){let j=d.slice(0,$).trim();if(d=d.slice($+1),!!j)try{h(JSON.parse(j))}catch{}}}),a.stderr.on("data",w=>{c+=w.toString()}),a.on("error",w=>g(()=>i(new Error(`claude failed to start: ${w.message}`)))),a.on("close",w=>{if(d.trim()){try{h(JSON.parse(d.trim()))}catch{}d=""}g(()=>{if(w!==0||m&&m.is_error){let j=`${c}
|
|
818
|
+
${l}`,J=ty(j);i(J!==j?new Error(J):new Error(`claude exited with code ${w}.
|
|
819
819
|
`+(c?`Stderr: ${c.slice(0,500)}
|
|
820
820
|
`:"")+(l?`Output: ${l.slice(0,500)}`:"No output")))}else o(l)})}),a.stdin.on("error",()=>{}),a.stdin.write(t)?a.stdin.end():a.stdin.once("drain",()=>a.stdin.end());let b=s||6e5,S=Math.round(b/6e4),v=setTimeout(()=>{a.kill(),g(()=>i(new Error(`claude (stream-json) timed out after ${S} minutes.
|
|
821
821
|
`+(c?`Stderr: ${c.slice(0,500)}
|
|
822
|
-
`:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(v))})}function
|
|
822
|
+
`:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},b);a.on("close",()=>clearTimeout(v))})}function Nr(e,t,n,s,o){return new Promise((i,r)=>{let a={...process.env};delete a.CLAUDECODE;let l=id(e,t,{stdio:["pipe","pipe","pipe"],env:a}),c="",d="",u=!1,m=S=>{u||(u=!0,S())};l.stdout.on("data",S=>{let v=S.toString();c+=v,s&&s(v)}),l.stderr.on("data",S=>{d+=S.toString()}),l.on("error",S=>m(()=>r(new Error(`${e} failed to start: ${S.message}`)))),l.on("close",S=>{m(()=>{S!==0?r(new Error(`${e} exited with code ${S}.
|
|
823
823
|
`+(d?`Stderr: ${d.slice(0,500)}
|
|
824
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.
|
|
825
825
|
`+(d?`Stderr: ${d.slice(0,500)}
|
|
826
|
-
`:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function
|
|
826
|
+
`:"")+`Partial output (${c.length} chars): ${c.slice(0,500)}`)))},h);l.on("close",()=>clearTimeout(b))})}async function ud(e,t,n,s,o,i){let r=ye(),a=R(),l=C().modules.length>0,c=Hn(),d=Ts(r,t,l,c.pageType,c.brandAssets);d+=`
|
|
827
827
|
|
|
828
828
|
## User Request
|
|
829
|
-
`+e,d+=
|
|
829
|
+
`+e,d+=As(),d+=ad(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print",...Ir];a.claudeCodeModel&&u.push("--model",a.claudeCodeModel),a.webSearch&&u.push("--allowedTools=WebSearch"),u.push("--output-format","stream-json","--include-partial-messages","--verbose");let m=0,g=s||(()=>{});g(je[0]);let h=setInterval(()=>{m++;let f=je[Math.min(m,je.length-1)];g(f)},6e3);try{let f=await Pr(u,d,{onChunk:b=>n(b),onToolUse:(b,S)=>{g(ny(b,S))}});o&&o(f)}finally{clearInterval(h)}}function ny(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function Rr(e,t,n,s,o,i,r){let a=ye(),l=C().modules.length>0,c=Hn(),d=Ts(a,n,l,c.pageType,c.brandAssets);d+=`
|
|
830
830
|
|
|
831
831
|
## User Request
|
|
832
|
-
`+t,d+=Cs(),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(je[0]);let f=setInterval(()=>{g++;let b=je[Math.min(g,je.length-1)];h(b)},6e3);try{let b=await Pr(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Tr,je,Ar,Mr,ks,Rr=N(()=>{"use strict";y();Ke();ee();_t();Ce();td();le();Be();tn();Tr=null;je=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],Ar=[10,20,40,60,120];Mr=["--strict-mcp-config"],ks=null});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function W(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function qe(e,t,n){W(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Xe=N(()=>{"use strict";y()});import{createWriteStream as Zh,mkdirSync as dd,existsSync as Or,readFileSync as Fr}from"fs";import{join as an,extname as Qh}from"path";import{randomUUID as ey}from"crypto";import ty from"busboy";function iy(e,t){if(md.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return oy[n]??t}function ry(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function ay(e,t){if(!Or(an(e,t)))return t;let n=Qh(t),s=t.slice(0,-n.length||void 0),o=1;for(;Or(an(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function ly(e){let t=(await import("pdf-parse")).default,n=Fr(e);return(await t(n)).text}async function cy(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function dy(e){return Fr(e,"utf-8")}function pd(e,t){let n=C();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],r=0,a=[],l=ty({headers:e.headers,limits:{fileSize:ny,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=iy(m,g);if(!md.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=ud.has(h),b=ry(m),S=ey(),v,w;f?(v=an(n.themePath,"assets"),dd(v,{recursive:!0}),w=ay(v,b)):(v=an(n.themePath,".vibespot","uploads"),dd(v,{recursive:!0}),w=`${S}-${b}`);let M=an(v,w),j=Zh(M),J=0,H=!1;d.on("data",K=>{J+=K.length}),d.on("limit",()=>{H=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(j),a.push(new Promise(K=>{j.on("finish",()=>{if(!H){let X={id:S,filename:w,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:J,addedAt:new Date().toISOString()};o.push(X),pc(X)}K()}),j.on("error",()=>{i.push(`Failed to write: ${m}`),K()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=an(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await ly(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await cy(d):c.extractedText=dy(d),E.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){E.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(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=>{E.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Ko(e){let t=C();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=an(t.themePath,"assets",s.filename);Or(i)&&(o.base64=Fr(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 ny,ud,sy,md,oy,Dr=N(()=>{"use strict";y();Xe();Ce();le();ny=10*1024*1024,ud=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),sy=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),md=new Set([...ud,...sy]),oy={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var vd={};Ge(vd,{LANGDOCK_BASE_URLS:()=>Ts,callAgent:()=>Pe,callAgentAPI:()=>Sd,isAgenticCapable:()=>_s,isCLIEngine:()=>Un,resolveThinkingBudget:()=>Hn});async function Vo(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>=jr.length)throw s;let a=jr[n];E.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${jr.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 As(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 yd(){return Lr||(Lr=(await import("@anthropic-ai/sdk")).default),Lr}async function gd(e,t,n,s,o,i){let r=await yd(),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 Vo(async()=>{let u=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,tools:[d],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),m=et(u.usage);for(let h of u.content)if(h.type==="tool_use")return{type:"structured",data:As(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 Vo(async()=>{let d="",u=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let g of u)g.type==="content_block_delta"&&g.delta.type==="text_delta"&&(d+=g.delta.text,n.onChunk&&n.onChunk(g.delta.text));let m;try{m=et((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:m}},n.onStatus)}async function uy(e,t,n){let s=await yd(),o=new s({authToken:e,defaultHeaders:Xn}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:Sn},...n.systemBlocks]:r=[{type:"text",text:Sn},{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 Vo(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),c=et(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:As(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 Vo(async()=>{let a="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let d of l)d.type==="content_block_delta"&&d.delta.type==="text_delta"&&(a+=d.delta.text,n.onChunk&&n.onChunk(d.delta.text));let c;try{c=et((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus)}function Jr(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"?Jr(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Jr(t.items)),t}async function fd(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:Jr(n.structuredOutput.schema)}});let a=await fetch(s||"https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(i)});if(!a.ok){let u=await a.text(),m=a.status;if(m===429){let g=new Error(`OpenAI rate limit: ${u}`);throw g.status=429,g}throw new Error(`OpenAI API error (${m}): ${u}`)}let l=await a.json(),c=l.choices?.[0]?.message?.content||"",d=_n(l.usage);if(n.structuredOutput)try{return{type:"structured",data:As(JSON.parse(c)),usage:d}}catch{return E.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 hd(e,t,n,s){let o=t||"gemini-2.5-flash",i=n.messages.map(m=>({role:m.role==="assistant"?"model":"user",parts:typeof m.content=="string"?[{text:m.content}]:m.content.map(g=>({text:g.text}))})),r={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:i,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`,l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok){let m=await l.text(),g=l.status;if(g===429){let h=new Error(`Gemini rate limit: ${m}`);throw h.status=429,h}throw new Error(`Gemini API error (${g}): ${m}`)}let c=await l.json(),d=c.candidates?.[0]?.content?.parts?.[0]?.text||"",u=$n(c.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:As(JSON.parse(d)),usage:u}}catch{return E.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 my(e,t,n){switch(e){case"claude-code":{let s=["--print",...Mr];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 py(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(`
|
|
832
|
+
`+t,d+=As(),d+=ad(r),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,m;e==="gemini"?(u="gemini",m=[]):(u="codex",m=["exec","--full-auto"]);let g=0,h=o||(()=>{});h(je[0]);let f=setInterval(()=>{g++;let b=je[Math.min(g,je.length-1)];h(b)},6e3);try{let b=await Nr(u,m,d,S=>{s(S)});i&&i(b)}finally{clearInterval(f)}}var Ar,je,_r,Ir,_s,Or=N(()=>{"use strict";y();Ke();ee();$t();Ce();sd();le();Be();on();Ar=null;je=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],_r=[10,20,40,60,120];Ir=["--strict-mcp-config"],_s=null});function p(e,t,n){e.writeHead(t,{"Content-Type":"application/json"}),e.end(JSON.stringify(n))}function W(e,t){let n=[];e.on("data",s=>n.push(s)),e.on("end",()=>t(Buffer.concat(n).toString("utf-8")))}function qe(e,t,n){W(e,s=>{try{n(JSON.parse(s||"{}"))}catch{p(t,400,{error:"Invalid JSON in request body"})}})}var Xe=N(()=>{"use strict";y()});import{createWriteStream as sy,mkdirSync as md,existsSync as Fr,readFileSync as Dr}from"fs";import{join as cn,extname as oy}from"path";import{randomUUID as iy}from"crypto";import ry from"busboy";function dy(e,t){if(gd.has(t))return t;let n=e.slice(e.lastIndexOf(".")).toLowerCase();return cy[n]??t}function uy(e){return e.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function my(e,t){if(!Fr(cn(e,t)))return t;let n=oy(t),s=t.slice(0,-n.length||void 0),o=1;for(;Fr(cn(e,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function py(e){let{PDFParse:t}=await import("pdf-parse"),n=Dr(e),s=new t({data:n});try{return(await s.getText()).text}finally{await s.destroy()}}async function gy(e){return(await(await import("mammoth")).extractRawText({path:e})).value}function fy(e){return Dr(e,"utf-8")}function fd(e,t){let n=C();if(!n){p(t,400,{error:"No active session"});return}if(!(e.headers["content-type"]||"").includes("multipart/form-data")){p(t,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],r=0,a=[],l=ry({headers:e.headers,limits:{fileSize:ay,files:10}});l.on("file",(c,d,u)=>{let{filename:m,mimeType:g}=u;r++;let h=dy(m,g);if(!gd.has(h)){i.push(`Unsupported file type: ${m} (${g})`),d.resume();return}let f=pd.has(h),b=uy(m),S=iy(),v,w;f?(v=cn(n.themePath,"assets"),md(v,{recursive:!0}),w=my(v,b)):(v=cn(n.themePath,".vibespot","uploads"),md(v,{recursive:!0}),w=`${S}-${b}`);let $=cn(v,w),j=sy($),J=0,K=!1;d.on("data",H=>{J+=H.length}),d.on("limit",()=>{K=!0,i.push(`File too large (>10MB): ${m}`)}),d.pipe(j),a.push(new Promise(H=>{j.on("finish",()=>{if(!K){let X={id:S,filename:w,originalName:m,type:f?"image":"document",usage:f?"asset":"context",mimeType:h,size:J,addedAt:new Date().toISOString()};o.push(X),fc(X)}H()}),j.on("error",()=>{i.push(`Failed to write: ${m}`),H()})}))}),l.on("finish",async()=>{await Promise.all(a);for(let c of o)if(c.type==="document"){let d=cn(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await py(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await gy(d):c.extractedText=fy(d),M.info("upload",`Extracted text from ${c.originalName} (${c.extractedText.length} chars)`)}catch(u){M.warn("upload",`Failed to extract text from ${c.originalName}: ${u}`),c.extractedText=`[Could not extract text from ${c.originalName}]`}}if(r===0){p(t,400,{error:"No files uploaded"});return}p(t,200,{files:o.map(c=>({id:c.id,filename:c.filename,originalName:c.originalName,type:c.type,usage:c.usage,size:c.size})),errors:i.length>0?i:void 0})}),l.on("error",c=>{M.error("upload",`Busboy error: ${c}`),p(t,500,{error:"Upload failed"})}),e.pipe(l)}function Vo(e){let t=C();return t?.assets?e.map(n=>{let s=t.assets.find(i=>i.id===n);if(!s)return null;let o={id:s.id,filename:s.filename,originalName:s.originalName,type:s.type,usage:s.usage,mimeType:s.mimeType};if(s.type==="image"){let i=cn(t.themePath,"assets",s.filename);Fr(i)&&(o.base64=Dr(i).toString("base64")),o.assetPath=`${t.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var ay,pd,ly,gd,cy,jr=N(()=>{"use strict";y();Xe();Ce();le();ay=10*1024*1024,pd=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),ly=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),gd=new Set([...pd,...ly]),cy={".md":"text/markdown",".txt":"text/plain",".markdown":"text/markdown"}});var wd={};Ge(wd,{LANGDOCK_BASE_URLS:()=>$s,callAgent:()=>Pe,callAgentAPI:()=>xd,isAgenticCapable:()=>Ms,isCLIEngine:()=>Gn,resolveThinkingBudget:()=>Un});async function zo(e,t){for(let n=0;;n++)try{return await e()}catch(s){let o=s.status,i=s.error?.type;if(!(o===429||i==="rate_limit_error"||s instanceof Error&&s.message.includes("429"))||n>=Lr.length)throw s;let a=Lr[n];M.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${Lr.length} \u2014 waiting ${a}s`),t&&t(`Rate limited \u2014 retrying in ${a}s...`),await new Promise(l=>setTimeout(l,a*1e3)),t&&t("Retrying...")}}function Es(e){if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e;for(let n of["fieldsJson","metaJson"])t[n]&&typeof t[n]=="object"&&(t[n]=JSON.stringify(t[n]))}return e}async function Sd(){return Jr||(Jr=(await import("@anthropic-ai/sdk")).default),Jr}async function hd(e,t,n,s,o,i){let r=await Sd(),a=new r({apiKey:e,...s?{defaultHeaders:s}:{},...i?{baseURL:i}:{}}),l=n.messages,c=n.systemPrompt;if(n.systemBlocks?c=o?[{type:"text",text:o},...n.systemBlocks]:n.systemBlocks:o&&(c=[{type:"text",text:o},{type:"text",text:n.systemPrompt}]),n.structuredOutput){let d={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return zo(async()=>{let u=await a.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,tools:[d],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),m=et(u.usage);for(let h of u.content)if(h.type==="tool_use")return{type:"structured",data:Es(h.input),usage:m};return{type:"text",text:u.content.filter(h=>h.type==="text").map(h=>h.text).join(""),usage:m}},n.onStatus)}return zo(async()=>{let d="",u=a.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:c,messages:l,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let g of u)g.type==="content_block_delta"&&g.delta.type==="text_delta"&&(d+=g.delta.text,n.onChunk&&n.onChunk(g.delta.text));let m;try{m=et((await u.finalMessage()).usage)}catch{}return{type:"text",text:d,usage:m}},n.onStatus)}async function hy(e,t,n){let s=await Sd(),o=new s({authToken:e,defaultHeaders:Zn}),i=n.messages,r;if(n.systemBlocks?r=[{type:"text",text:xn},...n.systemBlocks]:r=[{type:"text",text:xn},{type:"text",text:n.systemPrompt}],n.structuredOutput){let a={name:n.structuredOutput.name,description:`Return the result as structured JSON matching the ${n.structuredOutput.name} schema.`,input_schema:n.structuredOutput.schema,cache_control:{type:"ephemeral"}};return zo(async()=>{let l=await o.messages.create({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}}),c=et(l.usage);for(let u of l.content)if(u.type==="tool_use")return{type:"structured",data:Es(u.input),usage:c};return{type:"text",text:l.content.filter(u=>u.type==="text").map(u=>u.text).join(""),usage:c}},n.onStatus)}return zo(async()=>{let a="",l=o.messages.stream({model:t,max_tokens:n.maxTokens||16e3,system:r,messages:i,...n.enableWebSearch?{tools:[{type:"web_search_20250305",name:"web_search"}]}:{},...n.thinkingBudgetTokens?{thinking:{type:"enabled",budget_tokens:n.thinkingBudgetTokens}}:{}});for await(let d of l)d.type==="content_block_delta"&&d.delta.type==="text_delta"&&(a+=d.delta.text,n.onChunk&&n.onChunk(d.delta.text));let c;try{c=et((await l.finalMessage()).usage)}catch{}return{type:"text",text:a,usage:c}},n.onStatus)}function Br(e){let t={...e};if(t.type==="object"&&(t.additionalProperties=!1,t.properties&&typeof t.properties=="object")){let n={};for(let[s,o]of Object.entries(t.properties))n[s]=o&&typeof o=="object"?Br(o):o;t.properties=n}return t.items&&typeof t.items=="object"&&(t.items=Br(t.items)),t}async function yd(e,t,n,s){let o=[{role:"system",content:n.systemPrompt},...n.messages.map(u=>({role:u.role,content:typeof u.content=="string"?u.content:u.content.map(m=>({type:"text",text:m.text}))}))],i={model:t,max_completion_tokens:n.maxTokens||16e3,messages:o};n.structuredOutput&&(i.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!1,schema:Br(n.structuredOutput.schema)}});let a=await fetch(s||"https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify(i)});if(!a.ok){let u=await a.text(),m=a.status;if(m===429){let g=new Error(`OpenAI rate limit: ${u}`);throw g.status=429,g}throw new Error(`OpenAI API error (${m}): ${u}`)}let l=await a.json(),c=l.choices?.[0]?.message?.content||"",d=En(l.usage);if(n.structuredOutput)try{return{type:"structured",data:Es(JSON.parse(c)),usage:d}}catch{return M.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:c,usage:d}}return{type:"text",text:c,usage:d}}async function bd(e,t,n,s){let o=t||"gemini-2.5-flash",i=n.messages.map(m=>({role:m.role==="assistant"?"model":"user",parts:typeof m.content=="string"?[{text:m.content}]:m.content.map(g=>({text:g.text}))})),r={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:i,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=s||`https://generativelanguage.googleapis.com/v1beta/models/${o}:generateContent?key=${e}`,l=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)});if(!l.ok){let m=await l.text(),g=l.status;if(g===429){let h=new Error(`Gemini rate limit: ${m}`);throw h.status=429,h}throw new Error(`Gemini API error (${g}): ${m}`)}let c=await l.json(),d=c.candidates?.[0]?.content?.parts?.[0]?.text||"",u=Mn(c.usageMetadata);if(n.structuredOutput)try{return{type:"structured",data:Es(JSON.parse(d)),usage:u}}catch{return M.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:d,usage:u}}return{type:"text",text:d,usage:u}}function yy(e,t,n){switch(e){case"claude-code":{let s=["--print",...Ir];return t&&s.push("--model",t),n?.enableWebSearch&&s.push("--allowedTools=WebSearch"),{bin:"claude",args:s}}case"gemini-cli":{let s=[];return t&&s.push("-m",t),{bin:"gemini",args:s}}case"codex-cli":{let s=["exec","--full-auto"];return t&&s.push("-m",t),{bin:"codex",args:s}}default:throw new Error(`Not a CLI engine: ${e}`)}}function by(e){let t=[e.systemPrompt];for(let n of e.messages){let s=n.role==="user"?"User":"Assistant",o=typeof n.content=="string"?n.content:n.content.map(i=>i.text).join(`
|
|
833
833
|
`);t.push(`
|
|
834
834
|
|
|
835
835
|
## ${s}
|
|
836
|
-
${o}`)}if(e.structuredOutput){let n=
|
|
836
|
+
${o}`)}if(e.structuredOutput){let n=vd(e.structuredOutput.schema);t.push(`
|
|
837
837
|
|
|
838
838
|
## Output Format \u2014 CRITICAL
|
|
839
839
|
Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
|
|
840
840
|
|
|
841
841
|
The JSON must match this structure:
|
|
842
|
-
${n}`)}return t.join("")}function
|
|
843
|
-
`)}function
|
|
842
|
+
${n}`)}return t.join("")}function vd(e,t=0){let n=" ".repeat(t),s=e.properties,o=e.required||[];if(!s)return`${n}${JSON.stringify(e)}`;let i=["{"];for(let[r,a]of Object.entries(s)){let l=o.includes(r)?" (required)":"",c=a.type||"any",d=a.description?` \u2014 ${a.description}`:"",u=a.enum?` [${a.enum.join(", ")}]`:"";if(c==="array"&&a.items){let m=a.items.type||"object";i.push(`${n} "${r}": ${c}<${m}>${l}${d}${u}`)}else c==="object"&&a.properties?i.push(`${n} "${r}": ${vd(a,t+1)}${l}${d}`):i.push(`${n} "${r}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
|
|
843
|
+
`)}function Sy(e){let t=e.trim(),n=ct(t);if(n&&typeof n=="object")return n;let s=t.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let a=s[1].trim(),l=ct(a);if(l&&typeof l=="object")return l;let c=ks(a);if(c&&typeof c=="object")return c}let o=t.indexOf("{"),i=t.lastIndexOf("}");if(o!==-1&&i>o){let a=t.slice(o,i+1),l=ct(a);if(l&&typeof l=="object")return l;let c=ks(a);if(c&&typeof c=="object")return c}let r=ks(t);return r&&typeof r=="object"?r:null}async function vy(e,t,n){let{bin:s,args:o}=yy(e,t,n),i=by(n),r;if(e==="claude-code"){let l=[...o,"--output-format","stream-json","--include-partial-messages","--verbose"];r=await Pr(l,i,{onChunk:n.onChunk,onToolUse:(c,d)=>{if(!n.onStatus)return;let u=xy(c,d);n.onStatus(u)}})}else r=await Nr(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:r};let a=Sy(r);return a?{type:"structured",data:Es(a)}:(M.warn("agent-cli",`${e}: failed to parse structured output, returning text`,{outputPreview:r.slice(0,500),outputLength:r.length}),{type:"text",text:r})}function xy(e,t){let n=t||{};switch(e){case"WebSearch":case"web_search":return`Searching: "${String(n.query||"")}"`;case"WebFetch":return`Fetching: ${String(n.url||"")}`;case"Read":return`Reading ${String(n.file_path||n.path||"file")}`;case"Edit":case"Write":return`Editing ${String(n.file_path||n.path||"file")}`;case"Bash":return`Running: ${String(n.command||"").slice(0,60)}`;case"Grep":return`Searching for "${String(n.pattern||"")}"`;case"Glob":return`Globbing ${String(n.pattern||"")}`;default:return`Using ${e}`}}async function xd(e,t,n,s){M.info("agent-adapter",`${e} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length});let o=new Date,i=await(async()=>{switch(e){case"anthropic-api":return hd(t,n,s);case"claude-oauth":{let{getValidAccessToken:r}=await Promise.resolve().then(()=>($t(),ji)),a=await r();if(!a)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");return hy(a,n,s)}case"openai-api":return yd(t,n,s);case"gemini-api":return bd(t,n,s);case"langdock-api":{let r=R(),a=r.langdockProvider||"anthropic",l=r.langdockBaseUrl;switch(a){case"openai":case"mistral":{let c=l||$s[a];return yd(t,n,s,`${c}/v1/chat/completions`)}case"google":{let c=l||$s.google;return bd(t,n,s,`${c}/v1beta/models/${n}:generateContent`)}default:{let c=l||$s.anthropic;return hd(t,n,s,void 0,void 0,c)}}}default:throw new Error(`Unsupported API engine: ${e}`)}})();return Cy(e,n,s,i,o,new Date),i}function Cy(e,t,n,s,o,i){St({engine:e,model:t,name:n.structuredOutput?.name||"generation",input:{system:n.systemPrompt,messages:n.messages},output:s.type==="structured"?s.data:s.text,usage:s.usage,startTime:o,endTime:i,metadata:{structured:!!n.structuredOutput,systemPromptLength:n.systemPrompt.length,...n.prompt?.source?{promptSource:n.prompt.source}:{}},...n.prompt?{promptName:n.prompt.name,promptVersion:n.prompt.version}:{}})}async function Pe(e,t,n,s){return wy.has(e)?xd(e,t,n,s):(M.info("agent-adapter",`${e} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),vy(e,n,s))}function Un(e){if(e==="langdock-api"){if((R().langdockProvider||"anthropic")!=="anthropic")return 0}else if(e!=="anthropic-api"&&e!=="claude-oauth")return 0;let t=R();if(!t.extendedThinking)return 0;switch(t.extendedThinkingBudget){case"high":return 32e3;case"low":return 4e3;default:return 16e3}}function Ms(e){return e==="anthropic-api"||e==="claude-oauth"||e==="openai-api"||e==="gemini-api"||e==="langdock-api"||e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}function Gn(e){return e==="claude-code"||e==="gemini-cli"||e==="codex-cli"}var $s,Xk,Lr,Jr,wy,dt=N(()=>{"use strict";y();Or();Ko();ee();$t();le();on();Be();$s={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},Xk=$s.anthropic,Lr=[10,20,40,60,120];Jr=null;wy=new Set(["anthropic-api","claude-oauth","openai-api","gemini-api","langdock-api"])});var Hr,Cd=N(()=>{"use strict";y();Hr={"intent-analyzer":{version:2,placeholders:["themeName","contextData"],template:`You are the Intent Analyzer for vibeSpot, a HubSpot CMS builder that generates pages, email templates, and blog templates.
|
|
844
844
|
|
|
845
845
|
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
846
|
|
|
@@ -1176,7 +1176,7 @@ Every style/color field you reference in CSS must ship a complete default value.
|
|
|
1176
1176
|
- Include smooth scroll behavior in nav click handlers, and respect prefers-reduced-motion
|
|
1177
1177
|
|
|
1178
1178
|
## metaJson Template
|
|
1179
|
-
{ "host_template_types": ["PAGE"], "is_available_for_new_content": true }`}}});function
|
|
1179
|
+
{ "host_template_types": ["PAGE"], "is_available_for_new_content": true }`}}});function Ay(){if(kd!==void 0)return kd;if(Is!==void 0)return Is;try{let e=JSON.parse(P(bn(Ty)));Is=e&&typeof e=="object"&&e.prompts?e:null}catch{Is=null}return Is}function _y(e){let t=new Set;for(let n of e.matchAll(Td))t.add(n[1]);return[...t]}function Ad(e){let t=Hr[e],n=Ay()?.prompts?.[e];if(n&&n.version===t.version&&typeof n.template=="string"){let s=new Set(t.placeholders);if(_y(n.template).every(o=>s.has(o)))return{id:e,version:n.version,source:"langfuse-bundled",template:n.template}}return{id:e,version:t.version,source:"local-fallback",template:t.template}}function $y(e,t,n){let s=new Set(Hr[e].placeholders);return t.replace(Td,(o,i)=>s.has(i)?n[i]??"":o)}function wt(e){let t=Ad(e);return{name:`${ky}${e}`,version:t.version,source:t.source}}function Ft(e,t){return $y(e,Ad(e).template,t)}var ky,Ty,Td,Is,kd,Dt=N(()=>{"use strict";y();oe();Cd();ky="vibespot-stage-",Ty="prompts.bundle.json",Td=/\{\{\s*([a-zA-Z][\w]*)\s*\}\}/g});function _d(e,t,n,s,o){let i=t.length>0?`Current template modules (in page order):
|
|
1180
1180
|
${t.map((d,u)=>`${u+1}. ${d}`).join(`
|
|
1181
1181
|
`)}`:"No modules yet (new page).",r=n.length>0?`
|
|
1182
1182
|
|
|
@@ -1193,10 +1193,10 @@ All pages:
|
|
|
1193
1193
|
${o.pages.map(d=>`- ${d.label} (${d.id}, ${d.moduleCount} modules)`).join(`
|
|
1194
1194
|
`)}
|
|
1195
1195
|
|
|
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
|
|
1196
|
+
The user's message applies to the current page unless they reference another page by name or say "all pages" / "every page" / "the whole site".`:"",c=`${i}${r}${a}${l}`;return Ft("intent-analyzer",{themeName:e,contextData:c})}var $d,Ed=N(()=>{"use strict";y();Dt();$d={type:"object",properties:{intent:{type:"string",enum:["create","create_site","modify","add","remove","rearrange","style_change","question"]},contentType:{type:"string",enum:["page","email","blog"],description:'Content type: "page" (default), "email" for email templates, or "blog" for blog templates'},affectedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that need changes"},unchangedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that stay as-is"},newModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},position:{type:"number"}},required:["name","description","position"]},description:"New modules to create"},reuseModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},sourceTemplate:{type:"string"},position:{type:"number"}},required:["name","sourceTemplate","position"]},description:"Modules to copy from the library (immutable structure)"},guidesNeeded:{type:"array",items:{type:"string",enum:["design","content","conversion","hubspot_rules","humanify"]}},designSystemChanges:{type:"boolean",description:"True if shared CSS / design system needs regeneration"},answer:{type:"string",description:'For "question" intent only \u2014 the answer to return directly'},pages:{type:"array",items:{type:"object",properties:{id:{type:"string",description:"Kebab-case page ID (e.g. wp-home)"},label:{type:"string",description:"Human-readable page name"},pageType:{type:"string",enum:["landing_page","website_page","blog_post"]},purpose:{type:"string",description:"One-sentence page purpose"},slug:{type:"string",description:"URL path without leading /"}},required:["id","label","pageType","purpose","slug"]},description:'For "create_site" intent \u2014 list of pages to generate'},sharedModules:{type:"array",items:{type:"string"},description:'For "create_site" intent \u2014 module names shared across all pages (e.g. site-header, site-footer)'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function Md(e,t,n,s,o,i,r){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let a=t.modules.map(g=>g.moduleName),l=_d(t.themeName,a,r,t.brandAssets?.themeContext,t.sitePages?{activePageLabel:t.activePageLabel,pages:t.sitePages.map(g=>({id:g.id,label:g.label,moduleCount:g.moduleCount}))}:void 0),c=[],d=t.messages.slice(-6);for(let g of d)if(g.role==="user"||g.role==="assistant"){let h=g.role==="assistant"&&g.content.length>300?g.content.slice(0,300)+"...":g.content;c.push({role:g.role,content:h})}c.push({role:"user",content:e});let u=await te("intent-analyzer",()=>Pe(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:$d,name:"pipeline_plan"},maxTokens:2e3,prompt:wt("intent-analyzer")}));if(u.type!=="structured"){M.warn("intent-analyzer","Did not get structured output, falling back");let g=t.modules.length===0;return{intent:g?"create":"modify",affectedModules:g?[]:a,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:g}}let m=u.data;return m.affectedModules=m.affectedModules||[],m.unchangedModules=m.unchangedModules||[],m.newModules=m.newModules||[],m.guidesNeeded=m.guidesNeeded||[],t.contentMode==="email"?m.contentType="email":m.contentType=m.contentType==="email"?"email":"page",M.info("intent-analyzer","Plan",{intent:m.intent,affected:m.affectedModules.length,unchanged:m.unchangedModules.length,new:m.newModules.length,reuse:m.reuseModules?.length||0,designSystem:m.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:Ey(m)}),m}function Ey(e){let t=[`Intent: ${e.intent}`];return e.affectedModules.length>0&&t.push(`Modifying: ${e.affectedModules.join(", ")}`),e.unchangedModules.length>0&&t.push(`Unchanged: ${e.unchangedModules.join(", ")}`),e.newModules.length>0&&t.push(`New: ${e.newModules.map(n=>n.name).join(", ")}`),e.reuseModules?.length&&t.push(`Reuse: ${e.reuseModules.map(n=>`${n.name} from ${n.sourceTemplate}`).join(", ")}`),e.designSystemChanges&&t.push("Design system changes: yes"),t.join(" | ")}var Id=N(()=>{"use strict";y();dt();Ed();Dt();le();Be()});function Yo(e,t){let n=[];n.push(Ft("design-system",{themeName:e})),n.push(`
|
|
1197
1197
|
|
|
1198
1198
|
## Design Guide
|
|
1199
|
-
${
|
|
1199
|
+
${Fd()}`),t?.styleguide&&n.push(`
|
|
1200
1200
|
|
|
1201
1201
|
## Brand Style Guide
|
|
1202
1202
|
${t.styleguide}`),t?.themeContext&&n.push(`
|
|
@@ -1212,11 +1212,11 @@ ${o.join(`
|
|
|
1212
1212
|
## No Brand Provided \u2014 Follow the Generation Recipe
|
|
1213
1213
|
No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
|
|
1214
1214
|
|
|
1215
|
-
${
|
|
1215
|
+
${Od()}`),n.join("")}function Ur(e,t){let n=Yo(e),o=n.indexOf(`
|
|
1216
1216
|
|
|
1217
1217
|
## Design Guide
|
|
1218
1218
|
`);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Design Guide
|
|
1219
|
-
${
|
|
1219
|
+
${Fd()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
|
|
1220
1220
|
${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
|
|
1221
1221
|
${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
1222
|
The following brand identity values MUST be used. Do NOT substitute or override them:
|
|
@@ -1224,13 +1224,13 @@ ${d.join(`
|
|
|
1224
1224
|
`)}`)}return!c&&!t?.styleguide&&l.push(`## No Brand Provided \u2014 Follow the Generation Recipe
|
|
1225
1225
|
No brand colors, fonts, or styleguide have been set. You MUST follow these rules to create a unique design:
|
|
1226
1226
|
|
|
1227
|
-
${
|
|
1227
|
+
${Od()}`),l.length>0&&a.push({type:"text",text:l.join(`
|
|
1228
1228
|
|
|
1229
|
-
`)}),a}function
|
|
1230
|
-
`)}function
|
|
1229
|
+
`)}),a}function My(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
|
|
1230
|
+
`)}function Nd(e,t,n,s){let o=[],i=My(t);return o.push(Ft("module-planner",{themeName:e,cssSummary:i})),(!s||s.includes("content"))&&o.push(`
|
|
1231
1231
|
|
|
1232
1232
|
## Content & Copywriting Guide
|
|
1233
|
-
${
|
|
1233
|
+
${Iy()}`),n?.brandvoice&&o.push(`
|
|
1234
1234
|
|
|
1235
1235
|
## Brand Voice
|
|
1236
1236
|
${n.brandvoice}`),n?.themeContext&&o.push(`
|
|
@@ -1239,7 +1239,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
|
|
|
1239
1239
|
${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
|
|
1240
1240
|
|
|
1241
1241
|
## Anti-AI Copy Rules
|
|
1242
|
-
${
|
|
1242
|
+
${Py()}`),o.join("")}function Od(){let e=cs(),t=Pd(e,"## 4. Color System","## 5."),n=Pd(e,"### Recommended Font Pairings","### Typography Scale"),s=[];return s.push(`### Step 1: Derive the aesthetic from the content
|
|
1243
1243
|
Read the user's request carefully. What industry? What audience? What mood?
|
|
1244
1244
|
Map it to ONE of these aesthetic directions \u2014 then commit fully:
|
|
1245
1245
|
|
|
@@ -1295,7 +1295,7 @@ Before finalizing, ask yourself:
|
|
|
1295
1295
|
|
|
1296
1296
|
If any answer is "no," go bolder. The user wants personality, not safety.`),s.join(`
|
|
1297
1297
|
|
|
1298
|
-
`)}function
|
|
1298
|
+
`)}function Pd(e,t,n){let s=e.indexOf(t);if(s===-1)return"";let o=e.indexOf(n,s);return o===-1?e.slice(s):e.slice(s,o).trim()}function Fd(){return`### Design Philosophy
|
|
1299
1299
|
You are a senior UI designer. Every page must look professionally designed, not like AI output.
|
|
1300
1300
|
Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
|
|
1301
1301
|
|
|
@@ -1402,7 +1402,7 @@ Include these in shared CSS:
|
|
|
1402
1402
|
| All animations same speed | Stagger with increasing delays |
|
|
1403
1403
|
| Skip hover/focus states | Every interactive element needs feedback |
|
|
1404
1404
|
| Use \`<br>\` tags for spacing | Use proper margin/padding |
|
|
1405
|
-
| Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function
|
|
1405
|
+
| Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function Iy(){return`### Mandatory Page Sections (generate all)
|
|
1406
1406
|
1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
|
|
1407
1407
|
2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
|
|
1408
1408
|
3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
|
|
@@ -1490,7 +1490,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
|
|
|
1490
1490
|
- Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
|
|
1491
1491
|
- Keep paragraphs to 2-3 sentences max
|
|
1492
1492
|
- Aim for 6th-grade reading level
|
|
1493
|
-
- Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function
|
|
1493
|
+
- Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function Py(){return`### Banned Punctuation
|
|
1494
1494
|
- **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
|
|
1495
1495
|
- **Semicolons**: Feel academic, not conversational. Use periods instead.
|
|
1496
1496
|
- **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
|
|
@@ -1520,12 +1520,12 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
|
|
|
1520
1520
|
- Use plain short words: use > utilize, start > commence, help > facilitate
|
|
1521
1521
|
- Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
|
|
1522
1522
|
- 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
|
|
1523
|
+
- Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Gr,Rd,Dd=N(()=>{"use strict";y();Ke();Dt();Gr={type:"object",properties:{cssVariables:{type:"object",description:"CSS custom property name \u2192 value map. Every var() used in sharedCss must be defined here."},sharedCss:{type:"string",description:"Complete shared CSS file. MUST start with :root {} block defining all cssVariables, followed by reset, typography, layout, components, animations, and responsive styles."},sharedJs:{type:"string",description:"Optional shared JS for scroll animations (IntersectionObserver). Wrap in IIFE. Empty string if not needed."},aesthetic:{type:"string",description:"Brief description of the chosen aesthetic direction (e.g., 'dark luxury with warm gold accents')"}},required:["cssVariables","sharedCss","aesthetic"]};Rd={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module identifier. If this module already exists in the project, use the existing name verbatim. For new modules, use kebab-case (e.g., 'hero', 'pricing-cards')."},description:{type:"string",description:"What this module does"},contentBrief:{type:"string",description:"Specific content: headlines, body copy, stats, CTAs"},layoutNotes:{type:"string",description:"Visual layout approach referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Module names in page display order"},narrative:{type:"string",description:"Brief description of the page story/flow"}},required:["modules","moduleOrder","narrative"]}});function Wr(e){if(!e)return"";let t=[];return e.colors&&(e.colors.primary&&t.push(`- Primary color: ${e.colors.primary}`),e.colors.secondary&&t.push(`- Secondary color: ${e.colors.secondary}`),e.colors.accent&&t.push(`- Accent color: ${e.colors.accent}`)),e.fonts&&(e.fonts.heading&&t.push(`- Heading font: ${e.fonts.heading}`),e.fonts.body&&t.push(`- Body font: ${e.fonts.body}`)),e.logoUrl&&t.push(`- Logo URL: ${e.logoUrl}`),t.length===0?"":`
|
|
1524
1524
|
|
|
1525
1525
|
## Brand Kit \u2014 MANDATORY Design Constraints
|
|
1526
1526
|
The following brand identity values MUST be used. Do NOT substitute or override them:
|
|
1527
1527
|
${t.join(`
|
|
1528
|
-
`)}`}function
|
|
1528
|
+
`)}`}function qo(e,t){let n=[];n.push(`You are the Email Design Token Architect for vibeSpot, a HubSpot email template builder.
|
|
1529
1529
|
|
|
1530
1530
|
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
1531
|
|
|
@@ -1614,25 +1614,25 @@ Do NOT use: system-ui, -apple-system, Segoe UI, Inter, or any Google Fonts.
|
|
|
1614
1614
|
- No external font imports`),n.push(`
|
|
1615
1615
|
|
|
1616
1616
|
## Email Design Guide
|
|
1617
|
-
${
|
|
1617
|
+
${Ld()}`),t?.styleguide&&n.push(`
|
|
1618
1618
|
|
|
1619
1619
|
## Brand Style Guide
|
|
1620
1620
|
${t.styleguide}`),t?.themeContext&&n.push(`
|
|
1621
1621
|
|
|
1622
1622
|
## Product Context
|
|
1623
|
-
${t.themeContext}`);let s=
|
|
1623
|
+
${t.themeContext}`);let s=Wr(t?.brandKit);return s?n.push(s):t?.styleguide||n.push(`
|
|
1624
1624
|
|
|
1625
1625
|
## 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
|
|
1626
|
+
No brand colors or fonts have been set. Invent an original color palette that fits the email's topic and audience. Do NOT fall back to generic grays and blues. Choose web-safe font pairings (heading + body) that match the mood \u2014 vary between serif, sans-serif, and other stacks based on what fits.`),n.join("")}function Kr(e,t){let n=qo(e),o=n.indexOf(`
|
|
1627
1627
|
|
|
1628
1628
|
## Email Design Guide
|
|
1629
1629
|
`);if(o===-1)return[{type:"text",text:n}];let i=n.slice(0,o),r=`## Email Design Guide
|
|
1630
|
-
${
|
|
1630
|
+
${Ld()}`,a=[{type:"text",text:i},{type:"text",text:r,cache_control:{type:"ephemeral"}}],l=[];t?.styleguide&&l.push(`## Brand Style Guide
|
|
1631
1631
|
${t.styleguide}`),t?.themeContext&&l.push(`## Product Context
|
|
1632
|
-
${t.themeContext}`);let c=
|
|
1632
|
+
${t.themeContext}`);let c=Wr(t?.brandKit);return c?l.push(c):t?.styleguide||l.push(`## No Brand Provided \u2014 Be Creative
|
|
1633
1633
|
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
1634
|
|
|
1635
|
-
`)}),a}function
|
|
1635
|
+
`)}),a}function jd(e,t,n,s){let o=[],i=Object.entries(t).map(([a,l])=>` ${a}: ${l}`).join(`
|
|
1636
1636
|
`);o.push(`You are the Email Module Planner for vibeSpot, a HubSpot email template builder.
|
|
1637
1637
|
|
|
1638
1638
|
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.
|
|
@@ -1691,7 +1691,7 @@ List all module names in display order (top to bottom)
|
|
|
1691
1691
|
One sentence describing the email's purpose and flow`),(!s||s.includes("content"))&&o.push(`
|
|
1692
1692
|
|
|
1693
1693
|
## Email Content Guide
|
|
1694
|
-
${
|
|
1694
|
+
${Ny()}`),n?.brandvoice&&o.push(`
|
|
1695
1695
|
|
|
1696
1696
|
## Brand Voice
|
|
1697
1697
|
${n.brandvoice}`),n?.themeContext&&o.push(`
|
|
@@ -1700,7 +1700,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
|
|
|
1700
1700
|
${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
|
|
1701
1701
|
|
|
1702
1702
|
## Anti-AI Copy Rules
|
|
1703
|
-
${
|
|
1703
|
+
${Ry()}`);let r=Wr(n?.brandKit);return r&&o.push(r),o.join("")}function Ld(){return`### Email Design Philosophy
|
|
1704
1704
|
Design for the inbox, not the browser. Email templates must look clean and professional in Gmail, Outlook, Apple Mail, and Yahoo Mail simultaneously.
|
|
1705
1705
|
|
|
1706
1706
|
### Color Strategy
|
|
@@ -1733,7 +1733,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
|
|
|
1733
1733
|
- Hero images: 600px wide, 2:1 to 3:1 aspect ratio
|
|
1734
1734
|
- Always include alt text (images blocked by default in many clients)
|
|
1735
1735
|
- Use display:block to prevent gaps in Outlook
|
|
1736
|
-
- Product images: consistent sizing within a row`}function
|
|
1736
|
+
- Product images: consistent sizing within a row`}function Ny(){return`### Email Types and Structure
|
|
1737
1737
|
|
|
1738
1738
|
**Welcome / Onboarding Email**
|
|
1739
1739
|
- Warm greeting with first-name personalization
|
|
@@ -1779,7 +1779,7 @@ Design for the inbox, not the browser. Email templates must look clean and profe
|
|
|
1779
1779
|
- One idea per paragraph, 2-3 sentences max
|
|
1780
1780
|
- Use "you" more than "we"
|
|
1781
1781
|
- Specific > vague: "saves 3 hours/week" beats "saves time"
|
|
1782
|
-
- CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function
|
|
1782
|
+
- CTA copy = verb + benefit: "Start Your Trial", "See the Results"`}function Ry(){return`### Email-Specific Anti-AI Rules
|
|
1783
1783
|
- No em dashes (\u2014) in email copy. Period.
|
|
1784
1784
|
- No "I hope this email finds you well"
|
|
1785
1785
|
- No "In today's fast-paced world"
|
|
@@ -1788,61 +1788,61 @@ Design for the inbox, not the browser. Email templates must look clean and profe
|
|
|
1788
1788
|
- One exclamation mark per email maximum
|
|
1789
1789
|
- Avoid tricolon structures ("Fast, reliable, secure")
|
|
1790
1790
|
- 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
|
|
1791
|
+
- Every sentence must earn its place \u2014 if removing it doesn't hurt, remove it`}var Vr,Jd=N(()=>{"use strict";y();Vr={type:"object",properties:{cssVariables:{type:"object",description:"Token name \u2192 literal CSS value map. NOT CSS custom properties. These are reference values for inline styles (e.g., 'bg-color': '#f4f4f4', 'font-body': 'Arial, Helvetica, sans-serif')."},sharedCss:{type:"string",description:"MUST be empty string for email templates. Email uses inline styles only."},sharedJs:{type:"string",description:"MUST be empty string for email templates. No JavaScript in email."},aesthetic:{type:"string",description:"Brief description of the chosen email design direction."}},required:["cssVariables","sharedCss","aesthetic"]}});async function Bd(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?qo(n.themeName,n.brandAssets):Yo(n.themeName,n.brandAssets),d=l?a?Kr(n.themeName,n.brandAssets):Ur(n.themeName,n.brandAssets):void 0,u=`## User Request
|
|
1792
1792
|
${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
|
|
1793
1793
|
|
|
1794
1794
|
## Current Shared CSS (update this)
|
|
1795
1795
|
\`\`\`css
|
|
1796
1796
|
${n.sharedCss}
|
|
1797
|
-
\`\`\``);let m=
|
|
1797
|
+
\`\`\``);let m=Un(s),g=a?Vr:Gr,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:wt("design-system")}})),f;h.type!=="structured"?(M.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,M.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
|
|
1798
1798
|
${Object.entries(S).map(([j,J])=>` ${j.startsWith("--")?j:`--${j}`}: ${J};`).join(`
|
|
1799
1799
|
`)}
|
|
1800
1800
|
}
|
|
1801
1801
|
|
|
1802
1802
|
${b}`));let v=Object.keys(S||{}).length,w=a?[`Email design tokens: ${f.aesthetic||"created"} | ${v} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${v} variables, ${b.length} chars CSS`];return r({type:"agent_decision",step:"designing",decision:w.join(`
|
|
1803
|
-
`)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function
|
|
1803
|
+
`)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),{...f,sharedCss:b}}async function Hd(e,t,n,s,o,i,r){let a=t.contentType==="email";r({type:"agent_step",step:"designing",label:a?"Creating email design tokens...":"Creating design system..."});let l=s==="anthropic-api"||s==="claude-oauth",c=a?qo(n.themeName,n.brandAssets):Yo(n.themeName,n.brandAssets),d=l?a?Kr(n.themeName,n.brandAssets):Ur(n.themeName,n.brandAssets):void 0,u=`## User Request
|
|
1804
1804
|
${e}`;n.modules.length>0&&t.designSystemChanges&&(u+=`
|
|
1805
1805
|
|
|
1806
1806
|
## Current Shared CSS (update this)
|
|
1807
1807
|
\`\`\`css
|
|
1808
1808
|
${n.sharedCss}
|
|
1809
|
-
\`\`\``);let m=
|
|
1810
|
-
${Object.entries(S).map(([
|
|
1809
|
+
\`\`\``);let m=Un(s),g=a?Vr:Gr,h=await te("design-system",()=>Pe(s,o,i,{systemPrompt:c,systemBlocks:d,messages:[{role:"user",content:u}],structuredOutput:{schema:g,name:"design_system"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:wt("design-system")}})),f;h.type!=="structured"?(M.warn("page-architect","Design system: did not get structured output, using fallback"),f={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(f=h.data,M.info("page-architect","Design system created",{aesthetic:f.aesthetic,varCount:Object.keys(f.cssVariables||{}).length,cssLength:f.sharedCss?.length||0}));let b=a?"":f.sharedCss||"",S=f.cssVariables;!a&&S&&typeof S=="object"&&Object.keys(S).length>0&&(b.includes(":root")||(b=`:root {
|
|
1810
|
+
${Object.entries(S).map(([E,O])=>` ${E.startsWith("--")?E:`--${E}`}: ${O};`).join(`
|
|
1811
1811
|
`)}
|
|
1812
1812
|
}
|
|
1813
1813
|
|
|
1814
|
-
${b}`));let v=[],w=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi
|
|
1815
|
-
`)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let
|
|
1816
|
-
${e}`;if(t.newModules.length>0&&(
|
|
1814
|
+
${b}`));let v=[],w=/\b(Montserrat|Inter|Poppins|Raleway|Playfair|Lato|Roboto|Open\s?Sans|Nunito|Merriweather|Oswald|Source\s?Sans|Fira\s?Sans|Work\s?Sans|Manrope|Plus\s?Jakarta)\b/gi,$=[...new Set((e.match(w)||[]).map(k=>k.trim()))];if($.length>0){let k=$.filter(O=>b.toLowerCase().includes(O.toLowerCase())),E=$.filter(O=>!k.includes(O));E.length>0&&v.push(`Note: ${E.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let j=Object.keys(S||{}).length,J=a?[`Email design tokens: ${f.aesthetic||"created"} | ${j} tokens`]:[`Design system: ${f.aesthetic||"created"} | ${j} variables, ${b.length} chars CSS`,...v];r({type:"agent_decision",step:"designing",decision:J.join(`
|
|
1815
|
+
`)}),r({type:"design_system_ready",sharedCss:b,sharedJs:f.sharedJs||"",aesthetic:f.aesthetic||""}),r({type:"agent_step",step:"designing",label:"Planning modules..."});let K=a?jd(n.themeName,S||{},n.brandAssets,t.guidesNeeded):Nd(n.themeName,b,n.brandAssets,t.guidesNeeded),H=`## User Request
|
|
1816
|
+
${e}`;if(t.newModules.length>0&&(H+=`
|
|
1817
1817
|
|
|
1818
1818
|
## Planned Modules
|
|
1819
|
-
${t.newModules.map((
|
|
1820
|
-
`)}`),n.modules.length>0){let
|
|
1819
|
+
${t.newModules.map((k,E)=>`${E+1}. **${k.name}** \u2014 ${k.description}`).join(`
|
|
1820
|
+
`)}`),n.modules.length>0){let k=new Set(t.affectedModules),E=n.modules.filter(re=>k.has(re.moduleName)),O=n.modules.filter(re=>!k.has(re.moduleName));E.length>0&&(H+=`
|
|
1821
1821
|
|
|
1822
1822
|
## Existing Modules to Re-plan (PRESERVE THESE EXACT NAMES)
|
|
1823
1823
|
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
|
-
|
|
1825
|
-
`)),
|
|
1824
|
+
`+E.map(re=>`- \`${re.moduleName}\``).join(`
|
|
1825
|
+
`)),O.length>0&&(H+=`
|
|
1826
1826
|
|
|
1827
1827
|
## Existing Modules to Keep (do not re-plan)
|
|
1828
1828
|
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
|
-
`+
|
|
1830
|
-
`))}let X=await te("module-planner",()=>Pe(s,o,i,{systemPrompt:
|
|
1831
|
-
`)}function
|
|
1829
|
+
`+O.map(re=>`- \`${re.moduleName}\``).join(`
|
|
1830
|
+
`))}let X=await te("module-planner",()=>Pe(s,o,i,{systemPrompt:K,messages:[{role:"user",content:H}],structuredOutput:{schema:Rd,name:"module_plan"},maxTokens:8e3,...m>0?{thinkingBudgetTokens:m}:{},...a?{}:{prompt:wt("module-planner")}})),F,T={modules:t.newModules.map(k=>({name:k.name,description:k.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:t.newModules.map(k=>k.name),narrative:"Page generated from user request"};if(X.type!=="structured")M.warn("page-architect","Module planner: did not get structured output, using fallback"),F=T;else{let k=X.data;Array.isArray(k?.modules)&&k.modules.length>0?(F=k,F.moduleOrder=F.moduleOrder||F.modules.map(E=>E.name),F.narrative=F.narrative||"Page generated from user request"):(M.warn("page-architect","Module planner: structured output missing 'modules' array, using fallback",{keys:k?Object.keys(k):[]}),F=T),M.info("page-architect","Module plan",{moduleCount:F.modules.length})}return r({type:"agent_decision",step:"designing",decision:`Page: ${F.narrative} | ${F.modules.length} modules planned`}),{designSystem:{cssVariables:f.cssVariables||{},sharedCss:b,sharedJs:f.sharedJs},modules:F.modules,moduleOrder:F.moduleOrder,narrative:F.narrative}}var Ud=N(()=>{"use strict";y();dt();Dd();Jd();Dt();le();Be()});function Oy(e){let t=[...new Set([...e.matchAll(/\.([a-zA-Z][\w-]*)/g)].map(i=>`.${i[1]}`))],n=[...new Set([...e.matchAll(/(--[\w-]+)\s*:/g)].map(i=>i[1]))],s=[...new Set([...e.matchAll(/@media\s*\([^)]+\)/g)].map(i=>i[0]))],o=[];return n.length>0&&o.push(`CSS Variables: ${n.join(", ")}`),t.length>0&&o.push(`CSS Classes: ${t.join(", ")}`),s.length>0&&o.push(`Breakpoints: ${s.join(", ")}`),o.join(`
|
|
1831
|
+
`)}function Gd(e,t,n,s,o){let i=Oy(s),r=t.map(d=>`- **${d.label}** (${d.pageType}, slug: "${d.slug}"): ${d.purpose}`).join(`
|
|
1832
1832
|
`),a=n.map(d=>`- **${d}**`).join(`
|
|
1833
1833
|
`),l=[],c=t.map(d=>` - "${d.label}" \u2192 href="/${d.slug}"`).join(`
|
|
1834
|
-
`);return l.push(
|
|
1834
|
+
`);return l.push(Ft("site-module-planner",{themeName:e,siteMap:r,sharedList:a,cssSummary:i,navHrefs:c,sharedModuleNamesCsv:n.join(", ")})),o?.brandvoice&&l.push(`
|
|
1835
1835
|
|
|
1836
1836
|
## Brand Voice
|
|
1837
1837
|
${o.brandvoice}`),o?.themeContext&&l.push(`
|
|
1838
1838
|
|
|
1839
1839
|
## Product Context
|
|
1840
|
-
${o.themeContext}`),l.join("")}var
|
|
1840
|
+
${o.themeContext}`),l.join("")}var Wd,Kd=N(()=>{"use strict";y();Dt();Wd={type:"object",properties:{sharedModules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Shared module identifier (e.g., site-header, site-footer)"},description:{type:"string"},contentBrief:{type:"string",description:"Content for this shared module"},layoutNotes:{type:"string",description:"Layout referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]},description:"Modules shared across all pages (header, footer)"},pages:{type:"array",items:{type:"object",properties:{pageId:{type:"string",description:"Matches the page ID from the site map"},modules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},contentBrief:{type:"string"},layoutNotes:{type:"string"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Per-page module names in display order (excluding shared modules)"}},required:["pageId","modules","moduleOrder"]}},narrative:{type:"string",description:"Brief description of the overall site story and how pages connect"}},required:["sharedModules","pages","narrative"]}});async function zd(e,t,n,s,o,i,r,a){a({type:"agent_step",step:"planning_site",label:`Planning modules for ${t.pages?.length||0} pages...`});let l=t.pages||[],c=t.sharedModules||["site-header","site-footer"],d=Gd(n.themeName,l,c,s,n.brandAssets),u=`## User Request
|
|
1841
1841
|
${e}
|
|
1842
1842
|
|
|
1843
1843
|
## Site Map
|
|
1844
1844
|
${l.map(v=>`- ${v.label} (${v.slug}): ${v.purpose}`).join(`
|
|
1845
|
-
`)}`,m=
|
|
1845
|
+
`)}`,m=Un(o),g=await te("site-module-planner",()=>Pe(o,i,r,{systemPrompt:d,messages:[{role:"user",content:u}],structuredOutput:{schema:Wd,name:"site_module_plan"},maxTokens:16e3,...m>0?{thinkingBudgetTokens:m}:{},prompt:wt("site-module-planner")}));if(g.type!=="structured")return M.warn("site-planner","Did not get structured output, building fallback"),Vd(t,c,s);let h=g.data;if(!Array.isArray(h?.pages)||!Array.isArray(h?.sharedModules))return M.warn("site-planner","Structured output missing expected fields",{keys:h?Object.keys(h):[]}),Vd(t,c,s);let f=h.sharedModules.map(v=>({name:v.name,description:v.description,contentBrief:v.contentBrief,layoutNotes:v.layoutNotes})),b=h.pages.map(v=>({pageId:v.pageId,modules:(v.modules||[]).map(w=>({name:w.name,description:w.description,contentBrief:w.contentBrief,layoutNotes:w.layoutNotes})),moduleOrder:v.moduleOrder||[]})),S=f.length+b.reduce((v,w)=>v+w.modules.length,0);return M.info("site-planner","Site plan complete",{pages:b.length,sharedModules:f.length,totalModules:S}),a({type:"agent_decision",step:"planning_site",decision:`${b.length} pages planned, ${f.length} shared modules, ${S} total modules`}),a({type:"site_blueprint_ready",pages:b.map(v=>{let w=l.find($=>$.id===v.pageId);return{pageId:v.pageId,label:w?.label||v.pageId,moduleCount:v.modules.length}}),sharedModuleCount:f.length}),{designSystem:{cssVariables:{},sharedCss:s},pages:b,sharedModules:f,narrative:h.narrative||"Multi-page site generated from user request"}}function Vd(e,t,n){let s=e.pages||[];return{designSystem:{cssVariables:{},sharedCss:n},pages:s.map(o=>({pageId:o.id,modules:[{name:`${o.slug}-hero`,description:`Hero section for ${o.label}`,contentBrief:`Create a hero for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"},{name:`${o.slug}-content`,description:`Main content for ${o.label}`,contentBrief:`Create main content for the ${o.label} page: ${o.purpose}`,layoutNotes:"Use responsive layout matching the design system"}],moduleOrder:[`${o.slug}-hero`,`${o.slug}-content`]})),sharedModules:t.map(o=>({name:o,description:`Shared ${o} module`,contentBrief:`Generate ${o} for the site`,layoutNotes:"Use responsive layout matching the design system"})),narrative:"Multi-page site (fallback plan)"}}var Yd=N(()=>{"use strict";y();dt();Kd();Dt();le();Be()});function Xo(e){let t=0,n=[];return async function(o){t>=e&&await new Promise(i=>n.push(i)),t++;try{return await o()}finally{t--,n.length>0&&n.shift()()}}}var zr=N(()=>{"use strict";y()});function Ps(e,t,n,s){let o=[];return o.push(Ft("module-developer",{themeName:e})),t&&o.push(`
|
|
1846
1846
|
|
|
1847
1847
|
## Theme Shared CSS (use these custom properties)
|
|
1848
1848
|
\`\`\`css
|
|
@@ -1859,7 +1859,7 @@ ${ye()}`),s?.themeContext&&o.push(`
|
|
|
1859
1859
|
${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
|
|
1860
1860
|
|
|
1861
1861
|
## Anti-AI Copy Rules
|
|
1862
|
-
${
|
|
1862
|
+
${qd()}`),o.join("")}function Zo(e,t,n,s){let o=[],i=Ps(e,"",[],s?{...s,humanify:!1}:void 0);t&&(i+=`
|
|
1863
1863
|
|
|
1864
1864
|
## Theme Shared CSS (use these custom properties)
|
|
1865
1865
|
\`\`\`css
|
|
@@ -1870,9 +1870,9 @@ ${ye()}`),r.length>0&&o.push({type:"text",text:r.join(`
|
|
|
1870
1870
|
|
|
1871
1871
|
`),cache_control:{type:"ephemeral"}});let a=[];return s?.themeContext&&a.push(`## Product Context
|
|
1872
1872
|
${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&a.push(`## Anti-AI Copy Rules
|
|
1873
|
-
${
|
|
1873
|
+
${qd()}`),a.length>0&&o.push({type:"text",text:a.join(`
|
|
1874
1874
|
|
|
1875
|
-
`)}),o}function
|
|
1875
|
+
`)}),o}function qd(){return`### Banned Punctuation
|
|
1876
1876
|
- **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
|
|
1877
1877
|
- **Semicolons**: Use periods instead in marketing copy.
|
|
1878
1878
|
- **Exclamation marks**: One per page max. Zero ideal for B2B.
|
|
@@ -1911,7 +1911,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
|
|
|
1911
1911
|
- Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
|
|
1912
1912
|
- Full names, specific roles (not "John D., CEO")
|
|
1913
1913
|
- Never start with "This product is..." \u2014 start with the person's situation
|
|
1914
|
-
- Vary length and voice across testimonials`}function
|
|
1914
|
+
- Vary length and voice across testimonials`}function Xd(e,t,n){let s=[];return s.push(`## User Request
|
|
1915
1915
|
${e}`),s.push(`
|
|
1916
1916
|
|
|
1917
1917
|
## Module Specification
|
|
@@ -1938,7 +1938,7 @@ ${n.moduleCss}
|
|
|
1938
1938
|
**module.js:**
|
|
1939
1939
|
\`\`\`js
|
|
1940
1940
|
${n.moduleJs}
|
|
1941
|
-
\`\`\``)),s.join("")}var
|
|
1941
|
+
\`\`\``)),s.join("")}var Ns,Yr=N(()=>{"use strict";y();Ke();Dt();Ns={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});function qr(e,t){let n=[];if(n.push(`You are an Email Module Developer for vibeSpot, a HubSpot CMS builder.
|
|
1942
1942
|
|
|
1943
1943
|
Your job: generate ONE HubSpot CMS email module. You receive a module specification and must produce the complete module code optimized for email client rendering.
|
|
1944
1944
|
|
|
@@ -2096,17 +2096,17 @@ Modules that serve as email footers MUST include:
|
|
|
2096
2096
|
${t.themeContext}`),t?.humanify!==!1&&n.push(`
|
|
2097
2097
|
|
|
2098
2098
|
## Anti-AI Copy Rules
|
|
2099
|
-
${
|
|
2099
|
+
${Qd()}`),t?.brandKit){let s=[];t.brandKit.colors&&(t.brandKit.colors.primary&&s.push(`- Primary color: ${t.brandKit.colors.primary}`),t.brandKit.colors.secondary&&s.push(`- Secondary color: ${t.brandKit.colors.secondary}`),t.brandKit.colors.accent&&s.push(`- Accent color: ${t.brandKit.colors.accent}`)),t.brandKit.fonts&&(t.brandKit.fonts.heading&&s.push(`- Heading font: ${t.brandKit.fonts.heading}`),t.brandKit.fonts.body&&s.push(`- Body font: ${t.brandKit.fonts.body}`)),t.brandKit.logoUrl&&s.push(`- Logo URL: ${t.brandKit.logoUrl}`),s.length>0&&n.push(`
|
|
2100
2100
|
|
|
2101
2101
|
## Brand Kit \u2014 MANDATORY Design Constraints
|
|
2102
2102
|
The following brand identity values MUST be used. Do NOT substitute or override them:
|
|
2103
2103
|
${s.join(`
|
|
2104
|
-
`)}`)}return n.join("")}function
|
|
2104
|
+
`)}`)}return n.join("")}function Zd(e,t){let n=[],s=qr(e,{...t,humanify:!1});n.push({type:"text",text:s});let o;try{o=Sl()}catch{o=""}o&&n.push({type:"text",text:`## Email Template Rules Reference
|
|
2105
2105
|
${o}`,cache_control:{type:"ephemeral"}});let i=[];return t?.themeContext&&i.push(`## Product Context
|
|
2106
2106
|
${t.themeContext}`),t?.humanify!==!1&&i.push(`## Anti-AI Copy Rules
|
|
2107
|
-
${
|
|
2107
|
+
${Qd()}`),i.length>0&&n.push({type:"text",text:i.join(`
|
|
2108
2108
|
|
|
2109
|
-
`)}),n}function
|
|
2109
|
+
`)}),n}function Qd(){return`### Banned Punctuation
|
|
2110
2110
|
- **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
|
|
2111
2111
|
- **Semicolons**: Use periods instead.
|
|
2112
2112
|
- **Exclamation marks**: One per email max. Zero ideal for B2B.
|
|
@@ -2125,7 +2125,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
|
|
|
2125
2125
|
- Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
|
|
2126
2126
|
- Use plain words: use > utilize, start > commence, help > facilitate
|
|
2127
2127
|
- Front-load the benefit in the first 5 words
|
|
2128
|
-
- Email subject lines: specific, benefit-first, under 50 chars`}function
|
|
2128
|
+
- Email subject lines: specific, benefit-first, under 50 chars`}function eu(e,t,n){let s=[];return s.push(`## User Request
|
|
2129
2129
|
${e}`),s.push(`
|
|
2130
2130
|
|
|
2131
2131
|
## Email Module Specification
|
|
@@ -2145,7 +2145,7 @@ ${n.fieldsJson}
|
|
|
2145
2145
|
**module.html:**
|
|
2146
2146
|
\`\`\`html
|
|
2147
2147
|
${n.moduleHtml}
|
|
2148
|
-
\`\`\``),s.join("")}var
|
|
2148
|
+
\`\`\``),s.join("")}var tu,nu=N(()=>{"use strict";y();Ke();tu={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types: ["EMAIL"]'},moduleHtml:{type:"string",description:"Complete module.html with TABLE-BASED layout and ALL CSS inline. No <style> blocks."},moduleCss:{type:"string",description:"Must be empty string \u2014 all CSS is inline in moduleHtml for email"},moduleJs:{type:"string",description:"Must be empty string \u2014 no JavaScript in email"}},required:["moduleName","fieldsJson","metaJson","moduleHtml"]}});function Xr(e,t,n,s){let o=[];o.push(`You are a Blog Module Developer for vibeSpot, a HubSpot CMS builder.
|
|
2149
2149
|
|
|
2150
2150
|
Your job: generate ONE HubSpot CMS blog module. You receive a module specification and must produce the complete module code optimized for blog templates.
|
|
2151
2151
|
|
|
@@ -2330,22 +2330,22 @@ The blog post body module wraps \`{{ content.post_body }}\` with reading-optimiz
|
|
|
2330
2330
|
${s.themeContext}`),s?.humanify!==!1&&o.push(`
|
|
2331
2331
|
|
|
2332
2332
|
## Anti-AI Copy Rules
|
|
2333
|
-
${
|
|
2333
|
+
${ou()}`);let i=[];if(n?.includes("conversion"))try{let r=ye();r&&i.push(`## Conversion Guide
|
|
2334
2334
|
${r}`)}catch{}if(n?.includes("hubspot_rules"))try{let r=Je();r&&i.push(`## HubSpot Rules
|
|
2335
2335
|
${r}`)}catch{}return i.length>0&&o.push(`
|
|
2336
2336
|
|
|
2337
2337
|
${i.join(`
|
|
2338
2338
|
|
|
2339
|
-
`)}`),o.join("")}function
|
|
2339
|
+
`)}`),o.join("")}function su(e,t,n,s){let o=[],i=Xr(e,t,void 0,{...s,humanify:!1});o.push({type:"text",text:i});let r;try{r=vl()}catch{r=""}r&&o.push({type:"text",text:`## Blog Template Rules Reference
|
|
2340
2340
|
${r}`,cache_control:{type:"ephemeral"}});let a=[];if(n?.includes("conversion"))try{let c=ye();c&&a.push(`## Conversion Guide
|
|
2341
2341
|
${c}`)}catch{}if(n?.includes("hubspot_rules"))try{let c=Je();c&&a.push(`## HubSpot Rules
|
|
2342
2342
|
${c}`)}catch{}a.length>0&&o.push({type:"text",text:a.join(`
|
|
2343
2343
|
|
|
2344
2344
|
`),cache_control:{type:"ephemeral"}});let l=[];return s?.themeContext&&l.push(`## Product Context
|
|
2345
2345
|
${s.themeContext}`),s?.humanify!==!1&&l.push(`## Anti-AI Copy Rules
|
|
2346
|
-
${
|
|
2346
|
+
${ou()}`),l.length>0&&o.push({type:"text",text:l.join(`
|
|
2347
2347
|
|
|
2348
|
-
`)}),o}function
|
|
2348
|
+
`)}),o}function ou(){return`### Banned Punctuation
|
|
2349
2349
|
- **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses.
|
|
2350
2350
|
- **Semicolons**: Use periods instead.
|
|
2351
2351
|
- **Exclamation marks**: Maximum one per page. Zero ideal for B2B.
|
|
@@ -2364,7 +2364,7 @@ Never start with: "In today's", "In an era", "Whether you're", "Imagine a world"
|
|
|
2364
2364
|
- Be concrete: "42 minutes" not "fast", "\u20AC29/month" not "affordable"
|
|
2365
2365
|
- Use plain words: use > utilize, start > commence, help > facilitate
|
|
2366
2366
|
- Front-load the benefit in the first 5 words
|
|
2367
|
-
- Blog headlines: specific, benefit-first, no clickbait`}function
|
|
2367
|
+
- Blog headlines: specific, benefit-first, no clickbait`}function iu(e,t,n){let s=[];return s.push(`## User Request
|
|
2368
2368
|
${e}`),s.push(`
|
|
2369
2369
|
|
|
2370
2370
|
## Blog Module Specification
|
|
@@ -2389,17 +2389,17 @@ ${n.moduleHtml}
|
|
|
2389
2389
|
**module.css:**
|
|
2390
2390
|
\`\`\`css
|
|
2391
2391
|
${n.moduleCss}
|
|
2392
|
-
\`\`\``),s.join("")}var
|
|
2392
|
+
\`\`\``),s.join("")}var ru,au=N(()=>{"use strict";y();Ke();Ke();ru={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:'Complete meta.json content \u2014 must include host_template_types with "BLOG_POST" and/or "BLOG_LISTING"'},moduleHtml:{type:"string",description:"Complete module.html using HubSpot blog variables where appropriate"},moduleCss:{type:"string",description:"Complete module.css with reading-optimized styles"},moduleJs:{type:"string",description:"Optional module.js (vanilla JS in IIFE) or empty string"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function Rs(e,t,n,s,o,i,r,a,l,c,d,u){let m=u==="email",g=u==="blog",h=m?"email module":g?"blog module":"module";l({type:"agent_step",step:"developing",label:`Generating ${t.length} ${h}${t.length===1?"":"s"}...`});let f=o==="anthropic-api"||o==="claude-oauth",b=m?qr(s,d):g?Xr(s,n,c,d):Ps(s,n,c,d),S=f?m?Zd(s,d):g?su(s,n,c,d):Zo(s,n,c,d):void 0,v=Xo(a),w=t.length,$=m?tu:g?ru:Ns,j=m||g?void 0:wt("module-developer"),J=t.map((H,X)=>v(async()=>{l({type:"module_progress",module:H.name,status:"generating",current:X+1,total:w});let F="";for(let T=0;T<2;T++)try{T>0&&(M.warn("module-developer",`${H.name}: retrying after failure (attempt ${T+1})`),l({type:"module_progress",module:H.name,status:"retrying",current:X+1,total:w}));let k=await lu(e,H,b,o,i,r,0,S,m,$,g,j);return l({type:"module_progress",module:H.name,status:"complete",current:X+1,total:w,moduleFiles:k}),{moduleName:H.name,module:k}}catch(k){F=k instanceof Error?k.message:typeof k=="object"&&k!==null?JSON.stringify(k):String(k),M.error("module-developer",`Failed: ${H.name} (attempt ${T+1})`,{error:F})}return l({type:"module_progress",module:H.name,status:"failed",current:X+1,total:w}),{moduleName:H.name,error:F}}));return(await Promise.allSettled(J)).map(H=>H.status==="fulfilled"?H.value:{moduleName:"unknown",error:H.reason instanceof Error?H.reason.message:String(H.reason)})}async function lu(e,t,n,s,o,i,r=0,a,l=!1,c=Ns,d=!1,u){let m=l?eu(e,t,t.existingCode):d?iu(e,t,t.existingCode):Xd(e,t,t.existingCode),g=await Pe(s,o,i,{systemPrompt:n,systemBlocks:a,messages:[{role:"user",content:m}],structuredOutput:{schema:c,name:"module_output"},maxTokens:16e3,...u?{prompt:u}:{}});if(g.type!=="structured"){if(r<2)return M.warn("module-developer",`${t.name}: no structured output, retry ${r+1}`),lu(e,t,n,s,o,i,r+1,a,l,c,d,u);throw new Error(`Module "${t.name}" failed to produce structured output after ${r+1} attempts`)}let h=g.data,f=typeof h.fieldsJson=="string"?h.fieldsJson:JSON.stringify(h.fieldsJson,null,2),b=typeof h.metaJson=="string"?h.metaJson:JSON.stringify(h.metaJson,null,2);return{moduleName:t.name,fieldsJson:f,metaJson:b,moduleHtml:String(h.moduleHtml||""),moduleCss:l?"":String(h.moduleCss||""),moduleJs:l?void 0:h.moduleJs?String(h.moduleJs):void 0}}var cu=N(()=>{"use strict";y();dt();zr();Yr();nu();au();Dt();le()});function dn(e,t,n,s,o){let i=s==="email",r=s==="blog";return n({type:"agent_step",step:"quality_check",label:i?"Email quality check...":r?"Blog quality check...":"Quality check..."}),e.map(a=>{let l=[],c={...a};c.fieldsJson=du(c.fieldsJson,c.moduleName,"fieldsJson",l,i),c.metaJson=du(c.metaJson,c.moduleName,"metaJson",l,i,r);let d={};c.fieldsJson=Dy(c.fieldsJson,c.moduleName,l,d),c.moduleHtml=jy(c.moduleHtml,d),c.fieldsJson=Ly(c.fieldsJson,c.moduleName,l),i?c=qy(c,l):(c.moduleCss=Jy(c.moduleCss,c.moduleName,"moduleCss",l),c.moduleCss=Hy(c.moduleCss,c.moduleName,t,l),c.moduleHtml=Uy(c.moduleHtml,c.moduleName,t,l),r&&(c=Xy(c,l))),c.moduleHtml=Wy(c.moduleHtml,c.moduleName,l),i||Ky(c,l),c.metaJson=Vy(c.metaJson,c.moduleName,l,i,r),o&&Yy(c,o,l);let u=l.every(m=>m.autoFixed);return l.length>0&&M.info("validator",`${c.moduleName}: ${l.length} issues`,{autoFixed:l.filter(m=>m.autoFixed).length,unfixed:l.filter(m=>!m.autoFixed).length}),{module:c,issues:l,valid:u}})}function du(e,t,n,s,o=!1,i=!1){return!e||e.trim()===""?(s.push({module:t,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0}):e):ct(e)===null?(s.push({module:t,field:n,message:`Invalid JSON in ${n} \u2014 reset to empty`,autoFixed:!0}),n==="fieldsJson"?"[]":JSON.stringify({host_template_types:[o?"EMAIL":i?"BLOG_POST":"PAGE"],is_available_for_new_content:!0})):e}function Dy(e,t,n,s){let o=e;for(let[i,r]of Fy)new RegExp(`"name"\\s*:\\s*"${i}"`,"g").test(o)&&(n.push({module:t,field:"fieldsJson",message:`"${i}" is a reserved field name \u2192 renamed to "${r}"`,autoFixed:!0}),o=o.replace(new RegExp(`"name"\\s*:\\s*"${i}"`,"g"),`"name": "${r}"`),s[i]=r);return o}function jy(e,t){let n=e;for(let[s,o]of Object.entries(t))n=n.replace(new RegExp(`module\\.${s}\\b`,"g"),`module.${o}`);return n}function Ly(e,t,n){let s=e;return/"type"\s*:\s*"textarea"/g.test(s)&&(n.push({module:t,field:"fieldsJson",message:'"textarea" is deprecated \u2192 changed to "text"',autoFixed:!0}),s=s.replace(/"type"\s*:\s*"textarea"/g,'"type": "text"')),s}function Jy(e,t,n,s){if(!e)return e;let o=e,i=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return i.test(o)&&(s.push({module:t,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(i,"/* CDN import removed */")),o}function mu(e){return By.has(e)||e.startsWith("body-wrapper")||e.startsWith("dnd-")||e.startsWith("row-")||e.startsWith("hs-")||e.startsWith("hs_")}function Hy(e,t,n,s){if(!e)return e;let o=n+"-",i=/\.([a-zA-Z][\w-]*)/g,r=new Set,a;for(;(a=i.exec(e))!==null;){let c=a[1];!c.startsWith(o)&&!mu(c)&&r.add(c)}if(r.size<=3)return e;let l=e;for(let c of r){let d=new RegExp(`\\.${Gy(c)}(?=[\\s,{:+~>\\[\\]])`,"g");l=l.replace(d,`.${o}${c}`)}return l!==e&&s.push({module:t,field:"moduleCss",message:`${r.size} CSS classes auto-prefixed with "${o}"`,autoFixed:!0}),l}function Uy(e,t,n,s){if(!e)return e;let o=n+"-",i=/class="([^"]*)"/g,r=!1,a=e.replace(i,(l,c)=>{let d=/(\{%[-~]?[\s\S]*?[-~]?%\}|\{\{[\s\S]*?\}\})/g,u=c.split(d),m=!1,g=u.map((h,f)=>f%2===1?h:h.split(/(\s+)/).map(b=>/^\s*$/.test(b)?b:b&&!b.startsWith(o)&&!mu(b)&&/^[a-zA-Z][\w-]*$/.test(b)?(m=!0,o+b):b).join("")).join("");return m?(r=!0,`class="${g}"`):l});return r&&s.push({module:t,field:"moduleHtml",message:`HTML class references auto-prefixed with "${o}"`,autoFixed:!0}),a}function Gy(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Wy(e,t,n){if(!e)return e;let s=e,i=["if","elif","else","endif","for","endfor","set","do","block","endblock","macro","endmacro","call","endcall","filter","endfilter","raw","endraw","include","import","from","extends","print","unless","endunless","is","not","and","or","in"].join("|"),r=new RegExp(`\\b[a-zA-Z][\\w-]*-(${i})\\b(?!-)`,"g"),a=/(\{%[-~]?[\s\S]*?[-~]?%\})/g,l=!1;s=s.replace(a,h=>h.replace(r,(b,S)=>(l=!0,S))),l&&n.push({module:t,field:"moduleHtml",message:"Stripped CSS-class prefix from HubL keywords inside {% %} tags",autoFixed:!0});let c=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,d=[],u;for(;(u=c.exec(s))!==null;){let h=u[1],f=!h.startsWith("end"),b=f?h:h.replace("end","");d.push({tag:h,isOpen:f,baseTag:b,start:u.index,end:u.index+u[0].length})}let m=[],g=[];for(let h=0;h<d.length;h++)if(d[h].isOpen)m.push(h);else{let f=-1;for(let b=m.length-1;b>=0;b--)if(d[m[b]].baseTag===d[h].baseTag){f=b;break}f!==-1?m.splice(f,1):g.push(h)}if(g.length>0){for(let h=g.length-1;h>=0;h--){let f=d[g[h]];s=s.slice(0,f.start)+`<!-- removed orphan {% ${f.tag} %} -->`+s.slice(f.end)}n.push({module:t,field:"moduleHtml",message:`Removed ${g.length} orphan closing tag${g.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(m.length>0){let h=m.map(b=>d[b].baseTag),f=h.reverse().map(b=>`{% end${b} %}`).join(`
|
|
2393
2393
|
`);s=`${s}
|
|
2394
|
-
${f}`,n.push({module:t,field:"moduleHtml",message:`Added ${h.length} missing closing tag${h.length===1?"":"s"}: ${h.map(b=>`{% end${b} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:t,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function lu(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 By(e,t){let n=ct(e.fieldsJson),s=Array.isArray(n)?rn(n):{},o=e.moduleHtml||"";try{o=jn(e.moduleHtml||"",{module:s})}catch{}let i=[...lu(o),...lu(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 Hy(e,t,n,s=!1,o=!1){let i=ct(e);if(!i||typeof i!="object")return e;let r=i,a=!1;if(r.host_template_types){if(s)r.host_template_types.includes("EMAIL")||(r.host_template_types=["EMAIL"],a=!0,n.push({module:t,field:"metaJson",message:'Fixed host_template_types to ["EMAIL"] for email module',autoFixed:!0}));else if(o){let l=r.host_template_types;l.includes("BLOG_POST")||l.includes("BLOG_LISTING")||(r.host_template_types=["BLOG_POST"],a=!0,n.push({module:t,field:"metaJson",message:"Fixed host_template_types to include blog type for blog module",autoFixed:!0}))}}else{let l=s?"EMAIL":o?"BLOG_POST":"PAGE";r.host_template_types=[l],a=!0}return r.is_available_for_new_content===void 0&&(r.is_available_for_new_content=!0,a=!0),a?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(r,null,2)):e}function du(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 Gy(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(Uy))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 Wy(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 Ky(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 Iy,Fy,Uy,Xr=N(()=>{"use strict";y();Wo();le();Sr();Iy=[["name","item_name"],["label","section_label"],["body","body_text"]];Fy=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);Uy=/#[0-9a-fA-F]{6}\b/g});import{execSync as Vy}from"child_process";async function uu(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(Un(n)){let k={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(k)try{Vy(`command -v ${k}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${k}" to be installed and on your PATH.`)}}let d=await _d(e,t,n,s,o,r,a);if(d.intent==="question"&&d.answer){let O=Date.now()-l;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:O,answer:d.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:O}}}if(d.intent==="create_site"&&d.pages&&d.pages.length>0)return zy(e,d,t,n,s,o,i,r,l);let u=null,m=t.sharedCss,g=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Ld(e,d,t,n,s,o,r),d.contentType!=="email"&&(m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g),r({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let f=[];if(u)for(let O of u.modules)f.push({name:O.name,description:O.description,contentBrief:O.contentBrief,layoutNotes:O.layoutNotes});else{for(let O of d.newModules)f.push({name:O.name,description:O.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let O of d.affectedModules){let k=t.modules.find(T=>T.moduleName===O);k&&f.push({name:O,description:`Modify existing module: ${O}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:k})}}let b=[],S=[];if(f.length>0){let O=await te("module-development",()=>Ps(e,f,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:f.length}});for(let k of O)k.module?b.push(k.module):S.push(k.moduleName)}let v=null;if(b.length>0){v=ln(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit);let O=v.filter(T=>T.issues.some($=>$.field==="fieldsJson"&&$.message.includes("reset to empty"))).map(T=>T.module.moduleName);if(O.length>0){let T=O.map($=>f.find(F=>F.name===$)).filter($=>$!=null);if(T.length>0){E.info("pipeline",`Retrying ${T.length} module(s) with broken fieldsJson: ${T.map(F=>F.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${T.length} module(s) with invalid fields JSON...`});let $=await te("module-development-retry",()=>Ps(e,T,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:T.length}});for(let F of $)if(F.module){let re=b.findIndex(_e=>_e.moduleName===F.moduleName);re>=0&&(b[re]=F.module)}v=ln(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit)}}b=v.map(T=>T.module);let k=v.reduce((T,$)=>T+$.issues.length,0);if(k>0){let T=v.reduce((F,re)=>F+re.issues.filter(_e=>_e.autoFixed).length,0);E.info("pipeline",`Quality check: ${k} issues, ${T} auto-fixed`);let $=v.flatMap(F=>F.issues).map(F=>`${F.autoFixed?"\u2713":"\u26A0"} ${F.module}: ${F.message}`).join(`
|
|
2395
|
-
`);r({type:"agent_decision",step:"quality_check",decision:`${
|
|
2396
|
-
${
|
|
2397
|
-
`);for(let
|
|
2394
|
+
${f}`,n.push({module:t,field:"moduleHtml",message:`Added ${h.length} missing closing tag${h.length===1?"":"s"}: ${h.map(b=>`{% end${b} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:t,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function uu(e){if(!e)return[];let t=[],n=/\b(rgba?|hsla?)\(([^()]*)\)/gi,s;for(;(s=n.exec(e))!==null;){let o=s[2];(o.trim()===""||o.split(",").some(i=>i.trim()===""))&&t.push(s[0].trim())}return t}function Ky(e,t){let n=ct(e.fieldsJson),s=Array.isArray(n)?ln(n):{},o=e.moduleHtml||"";try{o=Ln(e.moduleHtml||"",{module:s})}catch{}let i=[...uu(o),...uu(e.moduleCss||"")];if(i.length===0)return;let r=i[0].length>60?i[0].slice(0,57)+"\u2026":i[0];t.push({module:e.moduleName,field:"moduleCss",message:`${i.length} invalid CSS color value${i.length===1?"":"s"} (e.g. \`${r}\`) \u2014 renders unstyled. A style field with no default is likely fed into rgba()/hsla().`,autoFixed:!1,code:"invalid-css"})}function Vy(e,t,n,s=!1,o=!1){let i=ct(e);if(!i||typeof i!="object")return e;let r=i,a=!1;if(r.host_template_types){if(s)r.host_template_types.includes("EMAIL")||(r.host_template_types=["EMAIL"],a=!0,n.push({module:t,field:"metaJson",message:'Fixed host_template_types to ["EMAIL"] for email module',autoFixed:!0}));else if(o){let l=r.host_template_types;l.includes("BLOG_POST")||l.includes("BLOG_LISTING")||(r.host_template_types=["BLOG_POST"],a=!0,n.push({module:t,field:"metaJson",message:"Fixed host_template_types to include blog type for blog module",autoFixed:!0}))}}else{let l=s?"EMAIL":o?"BLOG_POST":"PAGE";r.host_template_types=[l],a=!0}return r.is_available_for_new_content===void 0&&(r.is_available_for_new_content=!0,a=!0),a?(n.push({module:t,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(r,null,2)):e}function pu(e,t){let n=[],s=new Set(t.map(o=>`/${o}`));for(let o of e){if(!o.moduleName.includes("header")&&!o.moduleName.includes("nav")&&!o.moduleName.includes("footer"))continue;let i=/href=["'](\/?[a-z0-9][a-z0-9-]*(?:\/[a-z0-9-]*)*)["']/gi,r,a=[];for(;(r=i.exec(o.moduleHtml))!==null;){let l=r[1];l.startsWith("/")||(l="/"+l),!(l==="/"||l.startsWith("/http")||l.startsWith("/#"))&&a.push(l)}for(let l of a)s.has(l)||n.push({module:o.moduleName,message:`Nav link "${l}" does not match any page slug (valid: ${t.map(c=>"/"+c).join(", ")})`,autoFixed:!1})}return n}function Yy(e,t,n){let s=new Set;if(t.colors?.primary&&s.add(t.colors.primary.toLowerCase()),t.colors?.secondary&&s.add(t.colors.secondary.toLowerCase()),t.colors?.accent&&s.add(t.colors.accent.toLowerCase()),s.size===0&&!t.fonts?.heading&&!t.fonts?.body)return;let o=(e.moduleHtml||"")+(e.moduleCss||"");if(s.size>0){let i=new Set;for(let a of o.matchAll(zy))i.add(a[0].toLowerCase());let r=new Set(["#ffffff","#000000","#f4f4f4","#f5f5f5","#fafafa","#eeeeee","#e0e0e0","#dddddd","#cccccc","#999999","#666666","#333333","#1a1a1a","#111111","#222222","#444444","#555555","#777777","#888888","#aaaaaa","#bbbbbb"]);for(let a of i)if(!r.has(a)&&!s.has(a)){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand color ${a} (brand colors: ${[...s].join(", ")})`,autoFixed:!1});break}}if(t.fonts?.heading||t.fonts?.body){let i=[];t.fonts.heading&&i.push(t.fonts.heading.toLowerCase()),t.fonts.body&&i.push(t.fonts.body.toLowerCase());let r=/font-family:\s*([^;}"]+)/gi;for(let a of o.matchAll(r)){let l=a[1].toLowerCase().trim();if(!i.some(c=>l.includes(c))){n.push({module:e.moduleName,field:"moduleHtml",message:`Off-brand font "${a[1].trim()}" (brand fonts: ${i.join(", ")})`,autoFixed:!1});break}}}}function qy(e,t){let n={...e},s=n.moduleHtml;n.moduleCss&&n.moduleCss.trim()&&(t.push({module:e.moduleName,field:"moduleCss",message:"Cleared moduleCss \u2014 email modules must use inline styles only",autoFixed:!0}),n.moduleCss=""),n.moduleJs&&n.moduleJs.trim()&&(t.push({module:e.moduleName,field:"moduleJs",message:"Cleared moduleJs \u2014 email clients do not support JavaScript",autoFixed:!0}),n.moduleJs=void 0),/<style[\s>]/i.test(s)&&(s=s.replace(/<style[^>]*>[\s\S]*?<\/style>/gi,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed <style> blocks \u2014 email clients strip them",autoFixed:!0})),/display\s*:\s*flex/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:flex \u2014 not supported in email clients",autoFixed:!1}),/display\s*:\s*grid/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains display:grid \u2014 not supported in email clients",autoFixed:!1}),/var\s*\(/i.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains var() \u2014 CSS custom properties not supported in email",autoFixed:!1});let o=/\{[{%].*?(?:require_css|require_js|scope_css|get_asset_url)\s*\(.*?\}[}%]/g;o.test(s)&&(s=s.replace(o,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed banned HubL functions for email (require_css, require_js, scope_css, get_asset_url)",autoFixed:!0}));let i=/<link[^>]*href="https?:\/\/[^"]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^"]*"[^>]*\/?>/gi;return i.test(s)&&(s=s.replace(i,""),t.push({module:e.moduleName,field:"moduleHtml",message:"Removed CDN <link> tags \u2014 external resources not supported in email",autoFixed:!0})),n.moduleHtml=s,n}function Xy(e,t){let n={...e},s=n.moduleHtml;return/\{\{[\s]*content\.body[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.body[\s]*\}\}/g,"{{ content.post_body }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.body \u2192 content.post_body (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.title[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.title[\s]*\}\}/g,"{{ content.name }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.title \u2192 content.name (correct blog variable)",autoFixed:!0})),/\{\{[\s]*content\.author_name[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.author_name[\s]*\}\}/g,"{{ content.blog_post_author }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.author_name \u2192 content.blog_post_author",autoFixed:!0})),/\{\{[\s]*content\.date[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.date[\s]*\}\}/g,"{{ content.publish_date }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.date \u2192 content.publish_date",autoFixed:!0})),/\{\{[\s]*content\.image[\s]*\}\}/g.test(s)&&(s=s.replace(/\{\{[\s]*content\.image[\s]*\}\}/g,"{{ content.featured_image }}"),t.push({module:e.moduleName,field:"moduleHtml",message:"Fixed content.image \u2192 content.featured_image",autoFixed:!0})),/\{%.*dnd_area.*%\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"Contains dnd_area \u2014 blog templates typically use fixed module positions",autoFixed:!1}),/\{\{[\s]*content\.publish_date[\s]*\}\}/g.test(s)&&t.push({module:e.moduleName,field:"moduleHtml",message:"publish_date used without |datetimeformat filter \u2014 dates may render as raw timestamps",autoFixed:!1}),n.moduleHtml=s,n}var Fy,By,zy,Zr=N(()=>{"use strict";y();Ko();le();vr();Fy=[["name","item_name"],["label","section_label"],["body","body_text"]];By=new Set(["visible","active","scroll-animate","hidden","open","closed","fade-in","fade-out","is-active","is-open","is-visible"]);zy=/#[0-9a-fA-F]{6}\b/g});import{execSync as Zy}from"child_process";async function gu(e,t,n,s,o,i,r,a){let l=Date.now(),c=i;if(Gn(n)){let T={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(T)try{Zy(`command -v ${T}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${T}" to be installed and on your PATH.`)}}let d=await Md(e,t,n,s,o,r,a);if(d.intent==="question"&&d.answer){let F=Date.now()-l;return r({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:t.modules.length,durationMs:F,answer:d.answer}),{modules:[...t.modules],moduleOrder:t.moduleOrder,sharedCss:t.sharedCss,sharedJs:t.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:t.modules.length,modulesFailed:0,durationMs:F}}}if(d.intent==="create_site"&&d.pages&&d.pages.length>0)return Qy(e,d,t,n,s,o,i,r,l);let u=null,m=t.sharedCss,g=t.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Hd(e,d,t,n,s,o,r),d.contentType!=="email"&&(m=u.designSystem.sharedCss||m,g=u.designSystem.sharedJs||g),r({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:m,sharedJs:g}));let f=[];if(u)for(let F of u.modules)f.push({name:F.name,description:F.description,contentBrief:F.contentBrief,layoutNotes:F.layoutNotes});else{for(let F of d.newModules)f.push({name:F.name,description:F.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let F of d.affectedModules){let T=t.modules.find(k=>k.moduleName===F);T&&f.push({name:F,description:`Modify existing module: ${F}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:T})}}let b=[],S=[];if(f.length>0){let F=await te("module-development",()=>Rs(e,f,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:f.length}});for(let T of F)T.module?b.push(T.module):S.push(T.moduleName)}let v=null;if(b.length>0){v=dn(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit);let F=v.filter(k=>k.issues.some(E=>E.field==="fieldsJson"&&E.message.includes("reset to empty"))).map(k=>k.module.moduleName);if(F.length>0){let k=F.map(E=>f.find(O=>O.name===E)).filter(E=>E!=null);if(k.length>0){M.info("pipeline",`Retrying ${k.length} module(s) with broken fieldsJson: ${k.map(O=>O.name).join(", ")}`),r({type:"agent_decision",step:"quality_check",decision:`Regenerating ${k.length} module(s) with invalid fields JSON...`});let E=await te("module-development-retry",()=>Rs(e,k,m,t.themeName,n,s,o,c,r,d.guidesNeeded,t.brandAssets,d.contentType),{metadata:{moduleCount:k.length}});for(let O of E)if(O.module){let re=b.findIndex(_e=>_e.moduleName===O.moduleName);re>=0&&(b[re]=O.module)}v=dn(b,t.themeName,r,d.contentType,t.brandAssets?.brandKit)}}b=v.map(k=>k.module);let T=v.reduce((k,E)=>k+E.issues.length,0);if(T>0){let k=v.reduce((O,re)=>O+re.issues.filter(_e=>_e.autoFixed).length,0);M.info("pipeline",`Quality check: ${T} issues, ${k} auto-fixed`);let E=v.flatMap(O=>O.issues).map(O=>`${O.autoFixed?"\u2713":"\u26A0"} ${O.module}: ${O.message}`).join(`
|
|
2395
|
+
`);r({type:"agent_decision",step:"quality_check",decision:`${T} issues found, ${k} auto-fixed
|
|
2396
|
+
${E}`})}else r({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let w=tb(t,d,b,u,a),$=nb(t,d,u,w);if(u?.moduleOrder?.length){let F=new Set(u.moduleOrder),T=w.filter(k=>!F.has(k.moduleName)).map(k=>k.moduleName);T.length>0&&r({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${T.length} module${T.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${T.join(", ")}`})}let j=Date.now()-l,J=b.length,K=d.unchangedModules.length,H=v?v.flatMap(F=>F.issues):[],X=sb(d,J,K,S,j,u,H);return S.length>0?r({type:"pipeline_partial",succeeded:b.map(F=>F.moduleName),failed:S,durationMs:j}):r({type:"pipeline_complete",modulesGenerated:J,modulesUnchanged:K,durationMs:j,assistantMessage:X}),{modules:w,moduleOrder:$,sharedCss:m,sharedJs:g,assistantMessage:X,contentType:d.contentType,stats:{modulesGenerated:J,modulesUnchanged:K,modulesFailed:S.length,durationMs:j}}}async function Qy(e,t,n,s,o,i,r,a,l){let c=t.pages,d=t.sharedModules||["site-header","site-footer"],u=await Bd(e,t,n,s,o,i,a),m=u.sharedCss||n.sharedCss,g=u.sharedJs||n.sharedJs;a({type:"blueprint_ready",moduleOrder:d,sharedCss:m,sharedJs:g});let h=await zd(e,t,n,m,s,o,i,a);a({type:"agent_step",step:"developing",label:`Generating modules for ${c.length} pages...`});let f=[];for(let E of h.sharedModules)f.push({...E});for(let E of h.pages)for(let O of E.modules)f.push({name:O.name,description:O.description,contentBrief:O.contentBrief,layoutNotes:O.layoutNotes});let b=c.map(E=>`- "${E.label}" \u2192 /${E.slug}`).join(`
|
|
2397
|
+
`);for(let E of f)(E.name.includes("header")||E.name.includes("nav"))&&(E.layoutNotes+=`
|
|
2398
2398
|
|
|
2399
2399
|
## Site Navigation
|
|
2400
2400
|
This is a multi-page site. Include navigation links to all pages:
|
|
2401
2401
|
${b}
|
|
2402
|
-
Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await te("module-development",()=>
|
|
2402
|
+
Use relative href paths. Add CSS class "${n.themeName}-nav__link--active" on the current page's link.`);let S=await te("module-development",()=>Rs(e,f,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:f.length}}),v=[],w=[];for(let E of S)E.module?v.push(E.module):w.push(E.moduleName);let $=v,j=[];if(v.length>0){let E=dn(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit),O=E.filter(z=>z.issues.some(ue=>ue.field==="fieldsJson"&&ue.message.includes("reset to empty"))).map(z=>z.module.moduleName);if(O.length>0){let z=O.map(ue=>f.find(ne=>ne.name===ue)).filter(ue=>ue!=null);if(z.length>0){M.info("pipeline",`Retrying ${z.length} module(s) with broken fieldsJson`),a({type:"agent_decision",step:"quality_check",decision:`Regenerating ${z.length} module(s) with invalid fields JSON...`});let ue=await te("module-development-retry",()=>Rs(e,z,m,n.themeName,s,o,i,r,a,t.guidesNeeded,n.brandAssets,t.contentType),{metadata:{moduleCount:z.length}});for(let ne of ue)if(ne.module){let $e=v.findIndex(Ws=>Ws.moduleName===ne.moduleName);$e>=0&&(v[$e]=ne.module)}E=dn(v,n.themeName,a,t.contentType,n.brandAssets?.brandKit)}}$=E.map(z=>z.module),j=E.flatMap(z=>z.issues);let re=pu($,c.map(z=>z.slug));j.push(...re);let _e=j.length;if(_e>0){let z=j.filter(ue=>ue.autoFixed).length;a({type:"agent_decision",step:"quality_check",decision:`${_e} issues found, ${z} auto-fixed`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let J=new Map($.map(E=>[E.moduleName,E])),K=h.sharedModules.map(E=>J.get(E.name)).filter(E=>!!E),H=new Map(c.map(E=>[E.id,E])),X=h.pages.map(E=>{let O=E.modules.map(ne=>J.get(ne.name)).filter(ne=>!!ne),re=d.filter(ne=>ne.includes("header")||ne.includes("nav")),_e=d.filter(ne=>ne.includes("footer")),z=[...re,...E.moduleOrder,..._e],ue=H.get(E.pageId);return{pageId:E.pageId,templateId:E.pageId,label:ue?.label||E.pageId,pageType:ue?.pageType||"website_page",modules:[...K,...O],moduleOrder:z}}),F=Date.now()-l,T=eb(c,v.length,w,F,h.narrative,j);return w.length>0?a({type:"pipeline_partial",succeeded:v.map(E=>E.moduleName),failed:w,durationMs:F}):a({type:"pipeline_complete",modulesGenerated:v.length,modulesUnchanged:0,durationMs:F,assistantMessage:T}),{modules:$,moduleOrder:$.map(E=>E.moduleName),sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{modulesGenerated:v.length,modulesUnchanged:0,modulesFailed:w.length,durationMs:F},multiPage:{pages:X,sharedModules:K,sharedCss:m,sharedJs:g||"",assistantMessage:T,stats:{pagesGenerated:c.length,modulesGenerated:v.length,modulesFailed:w.length,durationMs:F}}}}function eb(e,t,n,s,o,i){let r=Math.round(s/1e3),a=[];a.push(`Created ${e.length}-page site with ${t} modules in ${r}s.`),a.push(`
|
|
2403
2403
|
|
|
2404
2404
|
**Pages:** ${e.map(d=>d.label).join(", ")}`),o&&a.push(`
|
|
2405
2405
|
|
|
@@ -2408,17 +2408,17 @@ ${o}`),n.length>0&&a.push(`
|
|
|
2408
2408
|
**Failed:** ${n.join(", ")}. You can retry these individually.`);let l=i.filter(d=>!d.autoFixed),c=i.filter(d=>d.autoFixed);if(c.length>0||l.length>0){let d=[];c.length>0&&d.push(`**Auto-fixed:** ${c.map(u=>`${u.module}: ${u.message}`).join(", ")}`),l.length>0&&d.push(`**Warnings:** ${l.map(u=>`${u.module}: ${u.message}`).join(", ")}`),a.push(`
|
|
2409
2409
|
|
|
2410
2410
|
${d.join(`
|
|
2411
|
-
`)}`)}return a.join("")}function
|
|
2411
|
+
`)}`)}return a.join("")}function tb(e,t,n,s,o){let i=[],r=new Set;for(let a of n)i.push(a),r.add(a.moduleName);for(let a of t.unchangedModules){if(r.has(a))continue;let l=e.modules.find(c=>c.moduleName===a);l&&(i.push(l),r.add(a))}if(t.reuseModules)for(let a of t.reuseModules){if(r.has(a.name))continue;let l=o.find(c=>c.name===a.name&&c.module);l&&l.module&&(i.push(l.module),r.add(a.name))}return i}function nb(e,t,n,s){if(n?.moduleOrder?.length){let a=[...n.moduleOrder],l=new Set(a);for(let c of s)if(!l.has(c.moduleName)){let d=a.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?a.splice(d,0,c.moduleName):a.push(c.moduleName),l.add(c.moduleName),M.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return a}if(t.intent==="create")return s.map(a=>a.moduleName);let o=[...e.moduleOrder],i=[...t.newModules.map(a=>({name:a.name,position:a.position})),...(t.reuseModules||[]).map(a=>({name:a.name,position:a.position}))].sort((a,l)=>a.position-l.position);for(let a of i){let l=Math.min(a.position,o.length);o.splice(l,0,a.name)}let r=new Set(s.map(a=>a.moduleName));return o.filter(a=>r.has(a))}function sb(e,t,n,s,o,i,r){let a=Math.round(o/1e3),l=[];if(e.intent==="create")l.push(`Created ${t} module${t===1?"":"s"} in ${a}s.`);else if(e.intent==="modify"||e.intent==="style_change")l.push(`Updated ${t} module${t===1?"":"s"} in ${a}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(e.intent==="add"){let u=e.newModules.map(m=>m.name).join(", ");l.push(`Added ${u} in ${a}s.`)}else e.intent==="remove"?l.push(`Removed modules in ${a}s.`):e.intent==="rearrange"&&l.push(`Rearranged modules in ${a}s.`);i?.narrative&&l.push(`
|
|
2412
2412
|
|
|
2413
2413
|
${i.narrative}`),s.length>0&&l.push(`
|
|
2414
2414
|
|
|
2415
2415
|
**Failed:** ${s.join(", ")}. You can retry these individually.`);let c=r.filter(u=>!u.autoFixed),d=r.filter(u=>u.autoFixed);if(d.length>0||c.length>0){let u=[];d.length>0&&u.push(`**Auto-fixed:** ${d.map(m=>`${m.module}: ${m.message}`).join(", ")}`),c.length>0&&u.push(`**Warnings:** ${c.map(m=>`${m.module}: ${m.message}`).join(", ")}`),l.push(`
|
|
2416
2416
|
|
|
2417
2417
|
${u.join(`
|
|
2418
|
-
`)}`)}return l.join("")}var
|
|
2418
|
+
`)}`)}return l.join("")}var fu=N(()=>{"use strict";y();dt();Id();Ud();Yd();cu();Zr();le();Be();dt()});var vu={};Ge(vu,{runFigmaConversion:()=>ob});import{basename as bu}from"path";async function ob(e,t,n,s,o,i,r,a,l){let c=Date.now();r({type:"agent_step",step:"designing",label:"Building design system from Figma tokens..."});let{sharedCss:d,sharedJs:u}=ib(e.designTokens,t);r({type:"design_system_ready",sharedCss:d,sharedJs:u,aesthetic:"Figma import"}),r({type:"agent_decision",step:"designing",decision:`Generated CSS variables and utility classes from ${e.designTokens.colors.length} colors, ${e.designTokens.typography.length} typography styles`});let{specs:m,moduleOrder:g}=ab(e.sections,e.assets,t);r({type:"blueprint_ready",moduleOrder:g,sharedCss:d,sharedJs:u}),r({type:"agent_decision",step:"designing",decision:`Mapped ${m.length} Figma sections to modules: ${g.join(", ")}`}),r({type:"agent_step",step:"developing",label:`Converting ${m.length} modules...`});let h=n==="anthropic-api"||n==="claude-oauth",f=Ps(t,d,["hubspot_rules","conversion"],a),b=h?Zo(t,d,["hubspot_rules","conversion"],a):void 0,S=Xo(i),v=m.length,$=(await te("module-development",()=>{let k=m.map((E,O)=>{let re=e.sections[O];return S(async()=>{r({type:"module_progress",module:E.name,status:"generating",current:O+1,total:v});let _e=db(re,E,e.assets,t,l!==!1),z="";for(let ue=0;ue<2;ue++)try{ue>0&&(M.warn("figma-pipeline",`${E.name}: retrying (attempt ${ue+1})`),r({type:"module_progress",module:E.name,status:"retrying",current:O+1,total:v}));let ne=await Pe(n,s,o,{systemPrompt:f,systemBlocks:b,messages:[{role:"user",content:_e}],structuredOutput:{schema:Ns,name:"module_output"},maxTokens:16e3});if(ne.type!=="structured")throw new Error("No structured output returned");let $e=ne.data,Ws={moduleName:E.name,fieldsJson:typeof $e.fieldsJson=="string"?$e.fieldsJson:JSON.stringify($e.fieldsJson,null,2),metaJson:typeof $e.metaJson=="string"?$e.metaJson:JSON.stringify($e.metaJson,null,2),moduleHtml:String($e.moduleHtml||""),moduleCss:String($e.moduleCss||""),moduleJs:$e.moduleJs?String($e.moduleJs):void 0};return r({type:"module_progress",module:E.name,status:"complete",current:O+1,total:v,moduleFiles:Ws}),{moduleName:E.name,module:Ws}}catch(ne){z=ne instanceof Error?ne.message:String(ne),M.error("figma-pipeline",`Failed: ${E.name} (attempt ${ue+1}): ${z}`)}return r({type:"module_progress",module:E.name,status:"failed",current:O+1,total:v}),{moduleName:E.name,error:z}})});return Promise.allSettled(k)},{metadata:{moduleCount:v}})).map(k=>k.status==="fulfilled"?k.value:{moduleName:"unknown",error:String(k.reason)}),j=$.filter(k=>k.module).map(k=>k.module),J=$.filter(k=>k.error).map(k=>k.moduleName),H=dn(j,t,r).map(k=>k.module),X=Date.now()-c,F=Math.round(X/1e3),T=`Imported ${H.length} modules from Figma design "${e.fileName}" in ${F}s.`;return J.length>0?r({type:"pipeline_partial",succeeded:H.map(k=>k.moduleName),failed:J,durationMs:X}):r({type:"pipeline_complete",modulesGenerated:H.length,modulesUnchanged:0,durationMs:X,assistantMessage:T}),{modules:H,moduleOrder:g,sharedCss:d,sharedJs:u,assistantMessage:T,stats:{modulesGenerated:H.length,modulesUnchanged:0,modulesFailed:J.length,durationMs:X}}}function Qo(e){let t=parseInt(e.slice(1,3),16)/255,n=parseInt(e.slice(3,5),16)/255,s=parseInt(e.slice(5,7),16)/255,o=Math.max(t,n,s),i=Math.min(t,n,s),r=(o+i)/2;if(o===i)return{h:0,s:0,l:r};let a=o-i,l=r>.5?a/(2-o-i):a/(o+i),c=0;return o===t?c=((n-s)/a+(n<s?6:0))/6:o===n?c=((s-t)/a+2)/6:c=((t-n)/a+4)/6,{h:c*360,s:l,l:r}}function ib(e,t){let n=[],s=t,o=[...e.colors].sort((T,k)=>k.occurrences-T.occurrences),i=o.filter(T=>T.usage==="background"||T.usage==="fill"),r=o.filter(T=>T.usage==="text"),a=i[0]||o[0],l=a?Qo(a.hex).l<.4:!1;a&&n.push(` --${s}-color-bg: ${a.hex}`);let c=r[0]||(l?o.find(T=>Qo(T.hex).l>.7):o.find(T=>Qo(T.hex).l<.3));c&&n.push(` --${s}-color-text: ${c.hex}`);let d=new Set([a?.hex,c?.hex].filter(Boolean)),u=o.filter(T=>!d.has(T.hex));if(u[0]&&(n.push(` --${s}-color-primary: ${u[0].hex}`),d.add(u[0].hex)),u[1]&&(n.push(` --${s}-color-accent: ${u[1].hex}`),d.add(u[1].hex)),u.filter(T=>!d.has(T.hex)).slice(0,6).forEach((T,k)=>n.push(` --${s}-color-${k+1}: ${T.hex}`)),a){let T=Qo(a.hex).l;n.push(` --${s}-color-surface: ${l?hu(a.hex,.05):yu(a.hex,.03)}`),n.push(` --${s}-color-border: ${l?hu(a.hex,.15):yu(a.hex,.12)}`)}let g=e.typography.filter(T=>T.role==="heading"||T.role==="subheading"),h=e.typography.filter(T=>T.role==="body"||T.role==="label"||T.role==="caption"),f=g[0]?.fontFamily||h[0]?.fontFamily||"system-ui",b=h[0]?.fontFamily||f;n.push(` --${s}-font-display: "${f}", system-ui, sans-serif`),n.push(` --${s}-font-body: "${b}", system-ui, sans-serif`);let S=g.sort((T,k)=>k.fontSize-T.fontSize);S[0]&&n.push(` --${s}-size-h1: ${S[0].fontSize}px`),S[1]&&n.push(` --${s}-size-h2: ${S[1].fontSize}px`),S[2]&&n.push(` --${s}-size-h3: ${S[2].fontSize}px`);let v=h.sort((T,k)=>k.occurrences-T.occurrences)[0];v&&n.push(` --${s}-size-body: ${v.fontSize}px`);let w=[...new Set(e.spacing.map(T=>T.value))].sort((T,k)=>T-k),$=["xs","sm","md","lg","xl","2xl","section"];w.slice(0,$.length).forEach((T,k)=>{n.push(` --${s}-space-${$[k]}: ${T}px`)});let j=e.effects.filter(T=>T.type==="shadow"),J=e.effects.filter(T=>T.type==="radius");j[0]&&n.push(` --${s}-shadow: ${j[0].cssValue}`),J.sort((T,k)=>parseFloat(T.cssValue)-parseFloat(k.cssValue)),J[0]&&n.push(` --${s}-radius: ${J[0].cssValue}`),J[1]&&n.push(` --${s}-radius-lg: ${J[1].cssValue}`);let K=`:root {
|
|
2419
2419
|
${n.join(`;
|
|
2420
2420
|
`)};
|
|
2421
|
-
}`,
|
|
2421
|
+
}`,H=`
|
|
2422
2422
|
/* Reset */
|
|
2423
2423
|
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
2424
2424
|
|
|
@@ -2502,8 +2502,8 @@ body {
|
|
|
2502
2502
|
h1 { font-size: 2rem; }
|
|
2503
2503
|
h2 { font-size: 1.5rem; }
|
|
2504
2504
|
h3 { font-size: 1.25rem; }
|
|
2505
|
-
}`;return{sharedCss:
|
|
2506
|
-
`+
|
|
2505
|
+
}`;return{sharedCss:K+`
|
|
2506
|
+
`+H,sharedJs:`(function() {
|
|
2507
2507
|
var observer = new IntersectionObserver(function(entries) {
|
|
2508
2508
|
entries.forEach(function(entry) {
|
|
2509
2509
|
if (entry.isIntersecting) {
|
|
@@ -2513,11 +2513,11 @@ body {
|
|
|
2513
2513
|
});
|
|
2514
2514
|
}, { threshold: 0.1 });
|
|
2515
2515
|
document.querySelectorAll('[data-animate]').forEach(function(el) { observer.observe(el); });
|
|
2516
|
-
})();`}}function
|
|
2517
|
-
`)}function
|
|
2516
|
+
})();`}}function hu(e,t){return Su(e,t)}function yu(e,t){return Su(e,-t)}function Su(e,t){let n=parseInt(e.slice(1,3),16),s=parseInt(e.slice(3,5),16),o=parseInt(e.slice(5,7),16);return n=Math.min(255,Math.max(0,Math.round(n+255*t))),s=Math.min(255,Math.max(0,Math.round(s+255*t))),o=Math.min(255,Math.max(0,Math.round(o+255*t))),`#${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}${o.toString(16).padStart(2,"0")}`}function rb(e){return e.replace(/([a-z])([A-Z])/g,"$1-$2").replace(/[^a-zA-Z0-9]+/g,"-").replace(/(^-|-$)/g,"").toLowerCase()}function ab(e,t,n){let s=new Set,o=[];for(let i of e){let r=rb(i.name);if(s.has(r)){let d=2;for(;s.has(`${r}-${d}`);)d++;r=`${r}-${d}`}s.add(r);let a=lb(i.textContent),l=cb(i,t,n),c=`Figma section "${i.name}" \u2014 ${i.width}x${i.height}px, ${i.textContent.length} text elements, ${i.children.length} children`;o.push({name:r,description:c,contentBrief:a,layoutNotes:l})}return{specs:o,moduleOrder:o.map(i=>i.name)}}function lb(e){let t={};for(let o of e){let i=o.role;t[i]||(t[i]=[]),t[i].push(o.text)}let n=[],s=["headline","subheadline","body","cta","label","caption"];for(let o of s)if(t[o])for(let i of t[o])n.push(`**${o}** (use as field default): "${i}"`);return n.join(`
|
|
2517
|
+
`)}function cb(e,t,n){let s=[];if(s.push(`Dimensions: ${e.width}x${e.height}px`),e.backgroundColor&&s.push(`Background: ${e.backgroundColor}`),e.layoutMode&&s.push(`Layout: ${e.layoutMode}`),e.itemSpacing&&s.push(`Gap: ${e.itemSpacing}px`),(e.paddingTop||e.paddingRight||e.paddingBottom||e.paddingLeft)&&s.push(`Padding: ${e.paddingTop||0}px ${e.paddingRight||0}px ${e.paddingBottom||0}px ${e.paddingLeft||0}px`),e.children.length>0){s.push(`
|
|
2518
2518
|
Children (${e.children.length}):`);for(let o of e.children){let i=` - ${o.type} "${o.name}" (${o.width}x${o.height})`;o.layoutMode&&(i+=` [${o.layoutMode}]`),o.childCount>0&&(i+=` [${o.childCount} children]`),o.characters&&(i+=` text: "${o.characters.slice(0,60)}"`),s.push(i)}}if(t.length>0){s.push(`
|
|
2519
|
-
Available image assets:`);for(let o of t){let i=
|
|
2520
|
-
`)}function
|
|
2519
|
+
Available image assets:`);for(let o of t){let i=bu(o.localPath);s.push(` - get_asset_url("${n}/assets/${i}") \u2014 ${o.name}`)}}return s.join(`
|
|
2520
|
+
`)}function db(e,t,n,s,o){let i=[];if(i.push(`## Figma Design Translation
|
|
2521
2521
|
|
|
2522
2522
|
TRANSLATE this Figma section into a HubSpot CMS module. This is a CONVERSION, not creation.
|
|
2523
2523
|
- Use the EXACT text content from the design as field default values
|
|
@@ -2542,12 +2542,12 @@ The Figma design shows the DESKTOP layout. You MUST add responsive CSS:
|
|
|
2542
2542
|
### Text Content \u2014 USE THESE AS FIELD DEFAULTS`);for(let r of e.textContent)i.push(`- **${r.role}** (${r.fontSize}px, weight ${r.fontWeight}): "${r.text}"`)}if(e.children.length>0){i.push(`
|
|
2543
2543
|
### Structure (${e.children.length} children)`);for(let r of e.children){let a=`- ${r.type} "${r.name}" (${r.width}x${r.height})`;r.layoutMode&&(a+=` layout: ${r.layoutMode}`),r.childCount>0&&(a+=`, ${r.childCount} children`),r.characters&&(a+=`
|
|
2544
2544
|
text: "${r.characters.slice(0,100)}"`),i.push(a)}}if(n.length>0)if(o){i.push(`
|
|
2545
|
-
### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let r of n){let a=
|
|
2545
|
+
### Available Image Assets \u2014 USE get_asset_url()`),i.push("Images are uploaded as theme assets. Reference them with get_asset_url():");for(let r of n){let a=bu(r.localPath);i.push(`- \`get_asset_url("${s}/assets/${a}")\` \u2014 ${r.name}`)}}else{i.push(`
|
|
2546
2546
|
### Images \u2014 USE IMAGE FIELDS WITH PLACEHOLDERS`),i.push('Do NOT use get_asset_url(). Instead, create "image" type fields in fields.json for each image.'),i.push('Set a descriptive default.src (e.g. "https://placehold.co/600x400?text=Hero+Image") and default.alt text.'),i.push("In the module HTML, use: {{ module.field_name.src }} and {{ module.field_name.alt }}"),i.push("This gives content editors full control to replace images in HubSpot.");for(let r of n)i.push(`- "${r.name}" \u2014 create an image field for this`)}return i.push(`
|
|
2547
2547
|
## Module Specification
|
|
2548
2548
|
- **Name**: ${t.name}
|
|
2549
2549
|
- **Description**: ${t.description}`),i.join(`
|
|
2550
|
-
`)}var
|
|
2550
|
+
`)}var xu=N(()=>{"use strict";y();dt();zr();Yr();Zr();le();Be()});var wu={};Ge(wu,{buildPlanModePrompt:()=>ub});function ub(e,t,n,s,o){let i=mb(o,!!t?.plan),r=[];return r.push(`You are vibeSpot's plan-mode assistant for the theme "${e}".
|
|
2551
2551
|
|
|
2552
2552
|
Plan mode is a DELIBERATION PHASE. Your job is to help the user articulate what they want to build BEFORE any code is generated. You do NOT write modules, HTML, or CSS in this mode. You ask questions, surface gaps, and maintain a living plan document.
|
|
2553
2553
|
|
|
@@ -2616,15 +2616,15 @@ Drive toward filling these gaps in priority order:
|
|
|
2616
2616
|
The theme already has a styleguide. Reference its colors, typography, and tokens in the plan rather than asking about them again.
|
|
2617
2617
|
|
|
2618
2618
|
\`\`\`
|
|
2619
|
-
${
|
|
2619
|
+
${Qr(t.styleguide,1500)}
|
|
2620
2620
|
\`\`\``),t?.brandvoice&&r.push(`## Available brand voice
|
|
2621
2621
|
|
|
2622
2622
|
\`\`\`
|
|
2623
|
-
${
|
|
2623
|
+
${Qr(t.brandvoice,1e3)}
|
|
2624
2624
|
\`\`\``),t?.themeContext&&r.push(`## Theme context
|
|
2625
2625
|
|
|
2626
2626
|
\`\`\`
|
|
2627
|
-
${
|
|
2627
|
+
${Qr(t.themeContext,1e3)}
|
|
2628
2628
|
\`\`\``),n.length>0&&r.push(`## Existing modules in this theme
|
|
2629
2629
|
|
|
2630
2630
|
These already exist on the page \u2014 you can keep, modify, or remove them in the plan, or reference them as reusable:
|
|
@@ -2645,13 +2645,13 @@ ${t.plan}
|
|
|
2645
2645
|
|
|
2646
2646
|
${i}`),r.join(`
|
|
2647
2647
|
|
|
2648
|
-
`)}function
|
|
2648
|
+
`)}function mb(e,t){return e===0&&!t?"**Phase 1: UNDERSTAND.** This is the user's first message in plan mode. Acknowledge what they said, then ask 2\u20133 high-leverage questions to surface gaps. The plan block should be a skeleton with TBDs and an **Open questions** section. Do NOT propose specific sections or content yet \u2014 you don't know enough.":e===0&&t?`**Phase 1-T: TEMPLATED START.** The user picked a plan-mode template, so a structured plan already exists. Your job on this turn is to:
|
|
2649
2649
|
- Briefly acknowledge the template and that you'll work from this structure (1\u20132 sentences in chat).
|
|
2650
2650
|
- Pick 2\u20133 of the highest-leverage items from the plan's **Open questions** section and ask the user about them. Prefer questions about: product/page name + one-line pitch, primary CTA, and target audience. Save tone/visual questions for later turns.
|
|
2651
2651
|
- Do NOT propose new sections or rewrite the existing structure on this turn \u2014 the user explicitly chose this scaffold. Keep the plan block VERBATIM (same headings, same sections, same open-questions list) and only re-emit it.
|
|
2652
2652
|
- If the user's first message already supplies content (e.g. "It's for Acme, a fintech startup, primary CTA is book a demo"), thread that into the plan's TBDs and check those items off the **Open questions** list before asking your follow-ups.
|
|
2653
|
-
- Use \`vibespot-choices\` chips when one of your questions is multiple-choice (e.g. "Primary CTA?", "Cuisine?").`:e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function
|
|
2654
|
-
... [truncated]`}var
|
|
2653
|
+
- Use \`vibespot-choices\` chips when one of your questions is multiple-choice (e.g. "Primary CTA?", "Cuisine?").`:e<=2&&!t?"**Phase 2: RESEARCH & DRAFT.** Take what the user has shared and produce a real first draft of the plan: goal, audience, primary CTA, and a proposed module list with brief descriptions. Reference existing modules/styleguide where applicable. Ask 1\u20132 narrow follow-ups to fill remaining gaps. Don't be exhaustive \u2014 a directionally-correct draft is better than asking 10 more questions.":`**Phase 3: REFINE.** A plan exists. Update it based on the user's latest message \u2014 change only what they're asking to change, preserve the rest. Confirm what you've updated in your conversational reply ("I changed the hero CTA to 'Get started free' and added a logos bar before the features section."). Ask narrow clarifying questions only when the user's edit creates a new ambiguity.`}function Qr(e,t){return e.length<=t?e:e.slice(0,t)+`
|
|
2654
|
+
... [truncated]`}var Cu=N(()=>{"use strict";y()});var aa={};Ge(aa,{applyPipelineResult:()=>un,handleAgenticGenerate:()=>ei,handleFigmaImport:()=>Fs,handleGenerate:()=>pb,handleGenerateStream:()=>Os,handlePlanModeStream:()=>oa,isGenerating:()=>Yt,isPlanModeActive:()=>ia,resolveAgenticEngine:()=>Wn,setParseWarningCallback:()=>na,shouldUseAgenticMode:()=>ra});import{execSync as ea}from"child_process";function na(e){ta=e}function Yt(){return jt!==null}function Ct(e){if(jt){let t=C();if(!t||t.id!==jt){M.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}lt("assistant",e),ed(e,ta||void 0),L()}async function Os(e,t,n,s){let o=C();if(!o)throw new Error("No active session");jt=o.id;let r=s?.length?Vo(s):void 0;try{let a=R(),l=a.aiEngine||sa();switch(l){case"anthropic-api":case"api":{let c=Fe("anthropic-api",a);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await $r(e,c,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,Ct,r);break}case"claude-oauth":{await dd(e,o.themeName,a.anthropicApiModel||"claude-sonnet-4-6",t,n,Ct,r);break}case"openai-api":{let c=Fe("openai-api",a);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await Er(e,c,o.themeName,a.openaiApiModel||"gpt-4o",t,n,Ct,r);break}case"gemini-api":{let c=Fe("gemini-api",a);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await Mr(e,c,o.themeName,t,n,Ct,r);break}case"claude-code":await ud(e,o.themeName,t,n,Ct,r);break;case"gemini-cli":await Rr("gemini",e,o.themeName,t,n,Ct,r);break;case"codex-cli":await Rr("codex",e,o.themeName,t,n,Ct,r);break;case"langdock-api":{let c=Fe("langdock-api",a);if(!c)throw new Error("Langdock API key not configured. Open Settings to add one.");let d=a.langdockProvider||"anthropic",u={anthropic:"https://api.langdock.com/anthropic",openai:"https://api.langdock.com/openai",google:"https://api.langdock.com/google",mistral:"https://api.langdock.com/mistral"},m=a.langdockBaseUrl||u[d],g=a.langdockApiModel;switch(d){case"openai":case"mistral":await Er(e,c,o.themeName,g||"gpt-4.1",t,n,Ct,r,`${m}/v1/chat/completions`);break;case"google":await Mr(e,c,o.themeName,t,n,Ct,r,`${m}/v1beta/models/${g||"gemini-2.5-flash"}:streamGenerateContent?alt=sse`,g);break;default:await $r(e,c,o.themeName,g||"claude-sonnet-4-6",t,n,Ct,r,m);break}break}default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{jt=null,ta=null}}function sa(){let e=R();if(Ze())return"claude-oauth";if(e.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(e.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(e.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return ea("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return ea("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return ea("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function pb(e){let t="";return await Os(e,n=>{t+=n}),t}function ku(){let e=C(),t=ke(),n=t?[...t.modules]:[...e.modules],s=t?[...t.moduleOrder]:[...e.moduleOrder],o={modules:n,moduleOrder:s,sharedCss:t?.sharedCss||e.sharedCss,sharedJs:t?.sharedJs||e.sharedJs,messages:[...e.messages],themeName:e.themeName,themePath:e.themePath,contentMode:t?.contentMode,brandAssets:e.brandAssets?{...e.brandAssets}:void 0};return e.templates.length>1&&(o.activePageLabel=t?.label,o.sitePages=e.templates.map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))),o}function Wn(e){let t=e.aiEngine||sa();if(!Ms(t))throw new Error("Agentic pipeline is not available for this engine.");if(Gn(t)){let o="";return t==="claude-code"&&(o=e.claudeCodeModel||""),{engine:t,apiKey:"",model:o}}let n;if(t==="claude-oauth"){if(!Ze())throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");n="oauth"}else n=Fe(t,e);if(!n)throw new Error(`API key not configured for ${t}. Open Settings to add one.`);let s;switch(t){case"anthropic-api":case"claude-oauth":s=e.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=e.openaiApiModel||"gpt-5.5";break;case"gemini-api":s=e.geminiApiModel||"gemini-2.5-pro";break;case"langdock-api":{let o={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-flash",mistral:"mistral-large-latest"};s=e.langdockApiModel||o[e.langdockProvider||"anthropic"];break}case"claude-code":s=e.claudeCodeModel||"";break;case"codex-cli":s=e.codexCliModel||"";break;case"gemini-cli":s=e.geminiCliModel||"";break;default:s=""}return{engine:t,apiKey:n,model:s}}function Tu(e){let t=e.multiPage;return{modules:e.modules.map(n=>n.moduleName),moduleCount:e.modules.length,moduleOrder:e.moduleOrder,stats:e.stats,...t?{pages:t.pages.map(n=>n.pageId)}:{},assistantMessage:e.assistantMessage}}async function ei(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=s.id;jt=o;try{let i=R(),{engine:r,apiKey:a,model:l}=Wn(i),c=i.agenticConcurrency||20,d=ku(),u=d.brandAssets?.plan,m=e;u&&u.trim()&&(m=`## Approved plan
|
|
2655
2655
|
|
|
2656
2656
|
Build the page according to this plan exactly. The user reviewed and approved it; do not deviate from its goal, audience, sections, or content unless the user message below explicitly requests changes.
|
|
2657
2657
|
|
|
@@ -2661,39 +2661,39 @@ ${u}
|
|
|
2661
2661
|
|
|
2662
2662
|
## User message
|
|
2663
2663
|
|
|
2664
|
-
${e}`);let g=n?.length?
|
|
2664
|
+
${e}`);let g=n?.length?Vo(n):void 0;if(g?.length)for(let $ of g)$.type==="document"&&$.extractedText&&(m+=`
|
|
2665
2665
|
|
|
2666
2666
|
---
|
|
2667
|
-
[Attached document: ${
|
|
2668
|
-
${
|
|
2667
|
+
[Attached document: ${$.originalName}]
|
|
2668
|
+
${$.extractedText}`),$.type==="image"&&$.usage==="asset"&&$.assetPath&&(m+=`
|
|
2669
2669
|
|
|
2670
|
-
[Uploaded image: ${
|
|
2670
|
+
[Uploaded image: ${$.originalName} \u2192 available as get_asset_url("${$.assetPath}")]`);let h=Ot(),f=new Set(d.modules.map($=>$.moduleName)),b=h.filter($=>!f.has($.module.moduleName)).map($=>({name:$.module.moduleName,usedIn:$.usedIn})),{result:S,cost:v}=await er(()=>tt({name:"agent_pipeline",sessionId:d.themeName,input:e,metadata:{engine:r,model:l,concurrency:c},tags:["vibespot","agentic-pipeline"]},async()=>{let $=await gu(m,d,r,a,l,c,t,b);return nr(Tu($)),$}));S.cost=v;let w=C();if(!w||w.id!==o)throw M.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return S}finally{jt=null}}async function Fs(e,t,n,s){let o=C();if(!o)throw new Error("No active session");let i=o.id;jt=i;try{let{runFigmaConversion:r}=await Promise.resolve().then(()=>(xu(),vu)),a=R(),{engine:l,apiKey:c,model:d}=Wn(a),u=a.agenticConcurrency||20,m=ku(),{result:g,cost:h}=await er(()=>tt({name:"figma_import",sessionId:t,input:{fileName:e.fileName,sections:e.sections.length},metadata:{engine:l,model:d,concurrency:u},tags:["vibespot","figma-import"]},async()=>{let b=await r(e,t,l,c,d,u,n,m.brandAssets,s?.useAssets);return nr(Tu(b)),b}));g.cost=h;let f=C();if(!f||f.id!==i)throw M.warn("ai-handler","Session changed during Figma import \u2014 discarding output"),new Error("Session changed during generation");return g}finally{jt=null}}function un(e,t){let n=e.multiPage;if(n&&n.pages.length>0){let s=new Map;for(let o of n.pages)s.set(o.pageId,{label:o.label||o.pageId,pageType:o.pageType||"website_page"});xc({pages:n.pages,sharedModules:n.sharedModules,sharedCss:n.sharedCss,sharedJs:n.sharedJs,pageLabels:s})}else if(He({modules:e.modules,sharedCss:e.sharedCss,sharedJs:e.sharedJs}),Wt(e.moduleOrder),e.contentType==="email"){let o=ke();o&&!o.contentMode&&(o.contentMode="email")}t?.cost&&hc(t.cost),lt("assistant",e.assistantMessage,t),L()}async function oa(e,t,n){let s=C();if(!s)throw new Error("No active session");let o=R(),{engine:i,apiKey:r,model:a}=Wn(o),[{buildPlanModePrompt:l},{callAgent:c}]=await Promise.all([Promise.resolve().then(()=>(Cu(),wu)),Promise.resolve().then(()=>(dt(),wd))]),d=s.messages.filter(w=>w.role==="assistant").length,u=s.modules.map(w=>w.moduleName),m=Ot(),g=new Set(u),h=m.filter(w=>!g.has(w.module.moduleName)).map(w=>({name:w.module.moduleName,usedIn:w.usedIn})),f=l(s.themeName,s.brandAssets,u,h,d),b=n?.length?Vo(n):void 0,S=e;if(b?.length)for(let w of b)w.type==="document"&&w.extractedText&&(S+=`
|
|
2671
2671
|
|
|
2672
2672
|
---
|
|
2673
2673
|
[Attached document: ${w.originalName}]
|
|
2674
|
-
${w.extractedText}`);let v=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return v.type==="text"?v.text:JSON.stringify(v.data)}function
|
|
2675
|
-
`}}function
|
|
2674
|
+
${w.extractedText}`);let v=await c(i,r,a,{systemPrompt:f,messages:[{role:"user",content:S}],maxTokens:8e3,onChunk:t,enableWebSearch:!!o.webSearch});return v.type==="text"?v.text:JSON.stringify(v.data)}function ia(){return!!R().planMode}function ra(){let e=R(),t=e.aiEngine||sa();return Ms(t)?e.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:e.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var ta,jt,Kn=N(()=>{"use strict";y();ee();Ce();Ko();le();tr();Or();$t();jr();fu();Be();ta=null;jt=null});import{readFileSync as gb,readdirSync as fb,existsSync as hb}from"fs";import{dirname as yb,join as ti}from"path";import{fileURLToPath as bb}from"url";function vb(e){let t=e.match(Sb);if(!t)return null;let[,n,s]=t,o={};for(let i of n.split(/\r?\n/)){let r=i.indexOf(":");if(r===-1)continue;let a=i.slice(0,r).trim(),l=i.slice(r+1).trim();(l.startsWith('"')&&l.endsWith('"')||l.startsWith("'")&&l.endsWith("'"))&&(l=l.slice(1,-1)),a&&(o[a]=l)}return{fields:o,body:s.trimStart()}}function xb(e){let t=vb(e);if(!t)return null;let{fields:n,body:s}=t,o=n.id,i=n.label,r=n.description??"";if(!o||!i)return null;let a=n.order?Number(n.order):NaN,l=n.contentType==="email"?"email":void 0;return{id:o,label:i,description:r,icon:n.icon||void 0,order:Number.isFinite(a)?a:9999,contentType:l,body:s.trimEnd()+`
|
|
2675
|
+
`}}function wb(){let e=[ti(Au,"../../assets/plan-templates"),ti(Au,"../assets/plan-templates"),ti(process.cwd(),"assets/plan-templates")];for(let t of e)if(hb(t))return t;return null}function _u(){if(qt)return qt;let e=wb();if(!e)return qt=[],qt;let t=[],n=[];try{n=fb(e)}catch{return qt=[],qt}for(let s of n)if(s.endsWith(".md"))try{let o=gb(ti(e,s),"utf-8"),i=xb(o);i&&t.push(i)}catch{}return t.sort((s,o)=>s.order!==o.order?s.order-o.order:s.label.localeCompare(o.label)),qt=t,qt}function $u(e){return _u().find(t=>t.id===e)??null}function Eu(){return _u().map(({id:e,label:t,description:n,icon:s,order:o,contentType:i})=>({id:e,label:t,description:n,icon:s,order:o,contentType:i}))}var Au,Sb,qt,Mu=N(()=>{"use strict";y();Au=yb(bb(import.meta.url)),Sb=/^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;qt=null});import{existsSync as Iu,mkdirSync as Cb,writeFileSync as kb,rmSync as Tb}from"fs";import{join as Pu}from"path";function Nu(e){return Pu(e,".vibespot",Ab)}function ni(e){let t=C();if(!t)return null;t.brandAssets||(t.brandAssets={}),t.brandAssets.plan=e;let n=ke();n&&(n.plan=e);try{let s=Pu(t.themePath,".vibespot");Iu(s)||Cb(s,{recursive:!0}),kb(Nu(t.themePath),e,"utf-8")}catch(s){M.warn("plan",`Failed to write plan.md: ${s instanceof Error?s.message:String(s)}`)}return L(),e}function la(){let e=C();if(!e)return;e.brandAssets&&delete e.brandAssets.plan;let t=ke();t&&delete t.plan;try{let n=Nu(e.themePath);Iu(n)&&Tb(n)}catch(n){M.warn("plan",`Failed to remove plan.md: ${n instanceof Error?n.message:String(n)}`)}L()}function Ru(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.markdown=="string"?n.markdown:"";if(!o.trim()){p(t,400,{error:"Plan content cannot be empty"});return}ni(o),p(t,200,{ok:!0,plan:o})})}function Ou(e,t){qe(e,t,()=>{la(),Y({planMode:!1}),p(t,200,{ok:!0})})}function Fu(e,t){p(t,200,{templates:Eu()})}function Du(e,t){qe(e,t,n=>{if(!C()){p(t,400,{error:"No active session"});return}let o=typeof n.templateId=="string"?n.templateId.trim():"";if(!o){p(t,400,{error:"templateId is required"});return}let i=$u(o);if(!i){p(t,404,{error:`Unknown plan template: ${o}`});return}ni(i.body),Y({planMode:!0}),p(t,200,{ok:!0,templateId:i.id,label:i.label,plan:i.body})})}var Ab,ju=N(()=>{"use strict";y();Xe();Ce();Kt();ee();le();Mu();Ab="plan.md"});function Lu(e){let t,n,s;for(ca.lastIndex=0;(s=ca.exec(e))!==null;)t=s[1].trim();let o;for(da.lastIndex=0;(o=da.exec(e))!==null;)try{let r=JSON.parse(o[1].trim());r&&typeof r.question=="string"&&Array.isArray(r.options)&&r.options.every(a=>typeof a=="string")&&r.options.length>0&&(n={question:r.question,options:r.options})}catch{}return{cleanedContent:e.replace(ca,"").replace(da,"").replace(/\n{3,}/g,`
|
|
2676
2676
|
|
|
2677
|
-
`).trim(),plan:t,choices:n}}var
|
|
2677
|
+
`).trim(),plan:t,choices:n}}var ca,da,Ju=N(()=>{"use strict";y();ca=/```vibespot-plan\s*\n([\s\S]*?)```/g,da=/```vibespot-choices\s*\n([\s\S]*?)```/g});import{spawn as ua}from"child_process";function Bu(e,t,n){e.stdout?.on("data",o=>{t.output+=o.toString()}),e.stderr?.on("data",o=>{t.output+=o.toString()}),e.on("close",o=>{t.status=o===0?"completed":"failed",t.exitCode=o,t.completedAt=Date.now()}),e.on("error",o=>{t.status="failed",t.output+=`
|
|
2678
2678
|
Process error: ${o.message}`,t.completedAt=Date.now()}),setTimeout(()=>{t.status==="running"&&(e.kill(),t.status="failed",t.output+=`
|
|
2679
|
-
Process timed out`,t.completedAt=Date.now())},n||3e5)}function
|
|
2679
|
+
Process timed out`,t.completedAt=Date.now())},n||3e5)}function Ds(e,t,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${e} ${t.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};Xt.set(o,i);let r=ua(e,t,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&r.stdin&&(r.stdin.write(s.stdin),r.stdin.end()),Bu(r,i,s?.timeout),o}function mn(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};Xt.set(s,o);let i=e.split(" "),r=ua(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Bu(r,o,n?.timeout),s}function si(e){return Xt.get(e)}function _b(){let e=Date.now()-18e5;for(let[t,n]of Xt)n.completedAt&&n.completedAt<e&&Xt.delete(t)}function oi(e,t,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:e,description:t,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};Xt.set(s,o);let i=e.split(" "),r=ua(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),a=c=>{for(let d of o.listeners)try{d(c)}catch{}};r.stdout?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.stderr?.on("data",c=>{let d=c.toString();o.output+=d,a(d)}),r.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),r.on("error",c=>{o.status="failed",o.output+=`
|
|
2680
2680
|
Process error: ${c.message}`,o.completedAt=Date.now(),o.listeners.clear()});let l=n?.timeout||3e5;return setTimeout(()=>{o.status==="running"&&(r.kill(),o.status="failed",o.output+=`
|
|
2681
|
-
Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function
|
|
2681
|
+
Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Hu(e,t){let n=Xt.get(e);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{t(s.output)}catch{}s.listeners.add(t)}function Uu(e,t){let n=Xt.get(e);!n||!("listeners"in n)||n.listeners.delete(t)}var Xt,ii=N(()=>{"use strict";y();Xt=new Map;setInterval(_b,600*1e3)});import{readFileSync as $b,readdirSync as Eb,existsSync as Mb}from"fs";import{dirname as Ib,join as ri}from"path";import{fileURLToPath as Pb}from"url";function Nb(){let e=[ri(Gu,"../../starters"),ri(Gu,"../starters"),ri(process.cwd(),"starters")];for(let t of e)if(Mb(t))return t;return null}function Wu(){if(Vn!==null)return Vn;let e=Nb();if(!e)return Vn=[],Vn;let t=[];for(let n of Eb(e).filter(s=>s.endsWith(".json")).sort())try{let s=JSON.parse($b(ri(e,n),"utf-8"));t.push({id:s.id,name:s.name,description:s.description,category:s.category||"General",contentType:s.contentType==="email"?"email":void 0,modules:s.modules||[],moduleOrder:s.moduleOrder||[],sharedCss:s.sharedCss||"",sharedJs:s.sharedJs||""})}catch{}return Vn=t,Vn}function Ku(){return Wu().map(e=>({id:e.id,name:e.name,description:e.description,category:e.category,contentType:e.contentType,moduleCount:e.modules.length}))}function ma(e){return Wu().find(t=>t.id===e)||null}var Gu,Vn,Vu=N(()=>{"use strict";y();Gu=Ib(Pb(import.meta.url)),Vn=null});var Ls={};Ge(Ls,{collectThemeFiles:()=>Yu,extractDesignContext:()=>jb});import{existsSync as ai,readdirSync as li,readFileSync as Rb}from"fs";import{join as kt}from"path";import{spawn as Ob}from"child_process";async function zu(){return pa||(pa=(await import("@anthropic-ai/sdk")).default),pa}function js(e){try{return Rb(e,"utf-8")}catch{return""}}function Yu(e){let t=[],n=0;function s(a,l){if(!l.trim())return!0;let c=`
|
|
2682
2682
|
### ${a}
|
|
2683
2683
|
\`\`\`
|
|
2684
2684
|
${l}
|
|
2685
2685
|
\`\`\`
|
|
2686
|
-
`;return n+c.length>
|
|
2687
|
-
${n}`;t?.({status:"Analyzing design patterns..."});let i=R(),r=i.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(r){case"anthropic-api":case"api":{let u=Fe("anthropic-api");if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");let m=await
|
|
2686
|
+
`;return n+c.length>Fb?!1:(t.push(c),n+=c.length,!0)}let o=js(kt(e,"theme.json"));o&&s("theme.json",o);let i=kt(e,"css");if(ai(i)){for(let a of li(i).filter(l=>l.endsWith(".css")))if(!s(`css/${a}`,js(kt(i,a))))break}let r=kt(e,"modules");if(ai(r))for(let a of li(r).filter(l=>l.endsWith(".module"))){let l=kt(r,a),c=js(kt(l,"module.css"));if(c&&!s(`modules/${a}/module.css`,c))break}if(ai(r))for(let a of li(r).filter(l=>l.endsWith(".module"))){let l=kt(r,a),c=js(kt(l,"module.html"));if(c&&!s(`modules/${a}/module.html`,c))break}if(ai(r))for(let a of li(r).filter(l=>l.endsWith(".module"))){let l=kt(r,a),c=js(kt(l,"fields.json"));if(c&&!s(`modules/${a}/fields.json`,c))break}return t.join("")}function Db(){if(!ci)try{ci=P(bn("extraction-prompt.md"))}catch{ci=""}return ci}function ga(e,t,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let r=Ob(e,t,{stdio:["pipe","pipe","pipe"],env:i,shell:!0}),a="",l="";r.stdout.on("data",c=>{a+=c.toString()}),r.stderr.on("data",c=>{l+=c.toString()}),r.on("error",c=>o(new Error(`${e} failed to start: ${c.message}`))),r.on("close",c=>{c===0||a.trim()?s(a.trim()):o(new Error(`${e} exited with code ${c}: ${l.trim()}`))}),r.stdin.write(n),r.stdin.end()})}async function jb(e,t){t?.({status:"Collecting theme files..."});let n=Yu(e);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=Db();if(!s)throw new Error("Extraction prompt not found (assets/extraction-prompt.md).");let o=`Analyze this HubSpot CMS theme and extract the design system:
|
|
2687
|
+
${n}`;t?.({status:"Analyzing design patterns..."});let i=R(),r=i.aiEngine||"anthropic-api",a="",l=new Date,c,d="";switch(r){case"anthropic-api":case"api":{let u=Fe("anthropic-api");if(!u)throw new Error("Anthropic API key not configured. Open Settings to add one.");let m=await zu(),g=new m({apiKey:u});d=i.anthropicApiModel||"claude-sonnet-4-6";let h=await g.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=h.content.map(f=>f.type==="text"?f.text:"").join(""),c=et(h.usage);break}case"claude-oauth":{let{getValidAccessToken:u,OAUTH_EXTRA_HEADERS:m,OAUTH_SYSTEM_PREFIX:g}=await Promise.resolve().then(()=>($t(),ji)),h=await u();if(!h)throw new Error("Claude OAuth session expired. Please re-authenticate in Settings.");let f=await zu(),b=new f({authToken:h,defaultHeaders:m});d=i.anthropicApiModel||"claude-sonnet-4-6";let S=await b.messages.create({model:d,max_tokens:8e3,system:[{type:"text",text:g},{type:"text",text:s,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:o}]});a=S.content.map(v=>v.type==="text"?v.text:"").join(""),c=et(S.usage);break}case"openai-api":{let u=Fe("openai-api");if(!u)throw new Error("OpenAI API key not configured. Open Settings to add one.");d=i.openaiApiModel||"gpt-4o";let m=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${u}`},body:JSON.stringify({model:d,max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!m.ok)throw new Error(`OpenAI API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.choices?.[0]?.message?.content||"",c=En(g.usage);break}case"gemini-api":{let u=Fe("gemini-api");if(!u)throw new Error("Gemini API key not configured. Open Settings to add one.");d=i.geminiApiModel||"gemini-2.5-flash";let m=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${d}:generateContent?key=${u}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!m.ok)throw new Error(`Gemini API error: ${m.status} ${await m.text()}`);let g=await m.json();a=g.candidates?.[0]?.content?.parts?.map(h=>h.text).join("")||"",c=Mn(g.usageMetadata);break}case"claude-code":{let u=`${s}
|
|
2688
2688
|
|
|
2689
2689
|
## User Request
|
|
2690
|
-
${o}`,m=["--print"];i.claudeCodeModel&&m.push("--model",i.claudeCodeModel),a=await
|
|
2690
|
+
${o}`,m=["--print"];i.claudeCodeModel&&m.push("--model",i.claudeCodeModel),a=await ga("claude",m,u);break}case"gemini-cli":{let u=`${s}
|
|
2691
2691
|
|
|
2692
2692
|
## User Request
|
|
2693
|
-
${o}`;a=await
|
|
2693
|
+
${o}`;a=await ga("gemini",[],u);break}case"codex-cli":{let u=`${s}
|
|
2694
2694
|
|
|
2695
2695
|
## User Request
|
|
2696
|
-
${o}`;a=await
|
|
2696
|
+
${o}`;a=await ga("codex",[],u);break}default:throw new Error(`Unknown AI engine: ${r}. Open Settings to configure one.`)}if(!a.trim())throw new Error("AI returned empty response.");return d&&St({engine:r,model:d,name:"styleguide-extraction",input:{system:s,messages:[{role:"user",content:o}]},output:a,usage:c,startTime:l,endTime:new Date}),t?.({status:"Design extraction complete."}),a}var pa,Fb,ci,Js=N(()=>{"use strict";y();oe();ee();Be();on();pa=null;Fb=8e4;ci=""});var fa={};Ge(fa,{extractBrandvoice:()=>Lb});async function Lb(e,t,n,s){if(!e||e.length<50)return null;let o=`You are a brand strategist. Analyze the rendered landing page HTML below and extract a concise brand voice guide. The HTML contains the actual text content with all template variables resolved to their default values.
|
|
2697
2697
|
|
|
2698
2698
|
Return a markdown document with these sections (skip any section where the content provides no signal):
|
|
2699
2699
|
|
|
@@ -2713,7 +2713,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
|
|
|
2713
2713
|
## Dos and Don'ts
|
|
2714
2714
|
3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
|
|
2715
2715
|
|
|
2716
|
-
Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Pe(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),r=i.type==="text"?i.text:JSON.stringify(i.data);return!r||r.trim().length<20?null:(
|
|
2716
|
+
Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Pe(t,n,s,{systemPrompt:o,messages:[{role:"user",content:e}],maxTokens:1e3}),r=i.type==="text"?i.text:JSON.stringify(i.data);return!r||r.trim().length<20?null:(M.info("brandvoice-extractor",`Extracted brand voice (${r.length} chars)`),r.trim())}catch(i){let r=i instanceof Error?i.message:String(i);return M.warn("brandvoice-extractor",`Brand voice extraction failed: ${r}`),null}}var ha=N(()=>{"use strict";y();dt();le()});var di={};Ge(di,{extractThemeContext:()=>Jb});async function Jb(e,t,n,s,o){if(!e||e.length<50)return null;let r=`You are a content analyst. Extract a concise product/company brief from the rendered landing page HTML below. The HTML contains the actual text content (headings, paragraphs, button labels, image alt text, etc.) with all template variables resolved to their default values.
|
|
2717
2717
|
|
|
2718
2718
|
Return a markdown document with these sections (skip any section where the content provides no information):
|
|
2719
2719
|
|
|
@@ -2735,11 +2735,11 @@ Specific terms, product names, or branded language used consistently.
|
|
|
2735
2735
|
Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${t?`
|
|
2736
2736
|
|
|
2737
2737
|
Existing product context (update if the new content adds info, keep what's still accurate):
|
|
2738
|
-
${t}`:""}`;try{let a=await Pe(n,s,o,{systemPrompt:r,messages:[{role:"user",content:e}],maxTokens:1e3}),l=a.type==="text"?a.text:JSON.stringify(a.data);return!l||l.trim().length<20?null:(E.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return E.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var di=N(()=>{"use strict";y();dt();le()});import{join as Ku}from"path";function Fb(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function Db(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=Ku(e.themePath,".vibespot");Re(o),B(Ku(o,s),n)}async function Vu(e,t){let n=Fb(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:tt({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>jb(e,t,n,s))}async function jb(e,t,n,s){let o=Lb(t)?t:{...await Jb(e),...t??{}};n.includes("styleguide")&&await ha(e,"styleguide",s,()=>te("extract-styleguide",()=>o.extractStyleguide(e)));let i=n.filter(a=>a==="brandvoice"||a==="themeContext");if(i.length===0)return s;let r="";try{r=o.buildPreviewHtml()}catch(a){let l=a instanceof Error?a.message:String(a);for(let c of i)s.skipped.push(c),s.errors.push({asset:c,message:`Could not render preview HTML: ${l}`});return s}if(!r||r.length<50){for(let a of i)s.skipped.push(a);return s}return n.includes("brandvoice")&&await ha(e,"brandvoice",s,()=>te("extract-brandvoice",()=>o.extractBrandvoice(e,r))),n.includes("themeContext")&&await ha(e,"themeContext",s,()=>te("extract-theme-context",()=>o.extractThemeContext(e,r))),s}async function ha(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}Db(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}),E.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function Lb(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function Jb(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(js(),Ds)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(Ss(),Go)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Wn(),ra)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(fa(),ga)),{extractThemeContext:i}=await Promise.resolve().then(()=>(di(),ci)),r=R();return{extractStyleguide:()=>t(e.themePath),buildPreviewHtml:n,extractBrandvoice:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return o(l,c,d,u)},extractThemeContext:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return i(l,a.brandAssets?.themeContext,c,d,u)}}}var zu=N(()=>{"use strict";y();oe();ee();le();Be()});import{existsSync as Vn,readdirSync as Yu,rmSync as Bb,writeFileSync as un,mkdirSync as ui}from"fs";import{join as Ne,basename as Hb}from"path";import{homedir as Ub}from"os";import{execFileSync as Xu}from"child_process";function pi(){if(mi&&Date.now()-mi.ts<Gb)return mi.data;let e=[];if(Vn(ut))try{for(let t of Yu(ut,{withFileTypes:!0}))if(t.isDirectory()){let n=Ne(ut,t.name,"theme.json");if(Vn(n)){let s=0,o=Ne(ut,t.name,"modules");if(Vn(o))try{s=Yu(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return mi={data:e,ts:Date.now()},e}function Qu(e){let t=C(),n=so(),s=!1;try{Xu("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Zu}),s=!0}catch{}let o=On().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:Ln()})}function em(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s,starterId:o,assetType:i}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let r=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!r){p(t,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Ne(ut,r);if(Re(ut),Vn(a)&&Bb(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!ua(o)){p(t,400,{error:`Starter template "${o}" not found`});return}os(a,r),Rn(a,r),o&&typeof o=="string"?(Wb(a,r,o),Te()):i==="email"&&(Pt("module_only","Email","email"),An(a,r)),L(),p(t,200,{ok:!0,themeName:r,themePath:a,starterId:o||void 0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Wb(e,t,n){let s=ua(n);if(!s)return;let o=C();if(!o)return;let i=s.contentType==="email",r=s.modules.map(u=>({...u})),a=[...s.moduleOrder],l=i?`email-${t}`:`lp-${t}`,c={id:l,label:`${s.name}`,pageType:i?"module_only":"landing_page",contentMode:i?"email":void 0,templateFile:i?"templates/email.html":`templates/${l}.html`,modules:r,moduleOrder:a,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};i&&An(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Ne(e,"modules");ui(d,{recursive:!0});for(let u of s.modules){let m=Ne(d,`${u.moduleName}.module`);ui(m,{recursive:!0}),un(Ne(m,"fields.json"),u.fieldsJson,"utf-8"),un(Ne(m,"meta.json"),u.metaJson,"utf-8"),un(Ne(m,"module.html"),u.moduleHtml,"utf-8"),un(Ne(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&un(Ne(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Ne(e,"css");ui(u,{recursive:!0}),un(Ne(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Ne(e,"js");ui(u,{recursive:!0}),un(Ne(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function tm(e){p(e,200,{starters:Hu()})}function nm(e,t){W(e,n=>{try{if(Kt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Le(),r=R(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Ne(ut,a);Re(ut),r.hubspotUploadMode==="cli"||!i?(async()=>{Xu("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Zu});let c=await qu(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)})}):rs(i,o,l).then(async()=>{let c=await qu(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 qu(e,t){Rn(e,t,{isImported:!0}),Uo(e),L();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await Vu(n),L()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function sm(e,t){W(e,n=>{try{if(Kt()){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(Vn(o)||(o=Ne(ut,s)),!Vn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Hb(o);Rn(o,i),Uo(o),L(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:C()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function om(e,t){W(e,n=>{try{if(Kt()){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=Do(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 im(e,t){W(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}Y({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function rm(e){let t=Le();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await ll(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 ro(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 Zu,ut,mi,Gb,gi=N(()=>{"use strict";y();Xe();ee();is();uo();en();Ce();Ut();Wn();Qt();ee();oe();Uu();vs();zu();Zu=process.platform==="win32"?{shell:!0}:{},ut=Ne(Ub(),"vibespot-themes"),mi=null,Gb=5e3});import{existsSync as Kb,readFileSync as Vb,appendFileSync as zb}from"fs";import{join as am}from"path";import{homedir as lm}from"os";function Xb(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 ba(e,t={},n=pm){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function Zb(e){let t=await ba("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 Qb(e){let t=await ba("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function dm(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:Xb(n)}))}async function eS(e){let t=await ba(`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 tS(e=!1){if(!e&&Date.now()-zn.ts<Yb&&Object.keys(zn.data).length>0)return zn.data;let t=R(),n={...ya},s=[],o=Fe("anthropic-api",t);o&&s.push(Zb(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c)}).catch(()=>{}));let i=Fe("openai-api",t);i&&s.push(Qb(i).then(c=>{if(!c.length)return;let d=dm(c,mm);d.length&&(n["openai-api"]=d);let u=dm(c,qb);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let r=Fe("gemini-api",t);r&&s.push(eS(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,pm+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=cm[l]||cm.anthropic,a&&(zn.data=n,zn.ts=Date.now()),n}function gm(e){let t=tl(),n=R(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,codexCliModel:n.codexCliModel||null,geminiCliModel:n.geminiCliModel||null,geminiApiModel:n.geminiApiModel||null,langdockApiModel:n.langdockApiModel||null,langdockBaseUrl:n.langdockBaseUrl||null,langdockProvider:n.langdockProvider||"anthropic",hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(o=>({portalId:o.portalId,portalName:o.portalName,dataCenter:o.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null,langfuseEnabled:n.langfuseEnabled,langfuseBaseUrl:n.langfuseBaseUrl||null};p(e,200,{version:yn(),environment:t,config:s,models:ya,sessionCount:On().length,localThemeCount:pi().length})}function fm(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");tS(n).then(s=>p(t,200,{models:s})).catch(()=>p(t,200,{models:ya}))}function hm(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=um[o];if(!i&&Date.now()-r.ts<nS&&Object.keys(r.data).length>0){p(t,200,{...r.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=nl();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:sl()};else{let l=so();a={tools:l.tools,availableEngines:l.availableEngines}}um[o]={data:a,ts:Date.now()},p(t,200,{...a,group:o,cached:!1})}function ym(e,t){W(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli","langdock-api"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let r={aiEngine:s};if(o)switch(s){case"claude-code":r.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":r.anthropicApiModel=o;break;case"openai-api":r.openaiApiModel=o;break;case"codex-cli":r.codexCliModel=o;break;case"gemini-cli":r.geminiCliModel=o;break;case"gemini-api":r.geminiApiModel=o;break;case"langdock-api":r.langdockApiModel=o;break}Y(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function bm(e,t){W(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"langdock":l.langdockApiKey="";break;case"figma":l.figmaToken="";break;case"langfuse-public":l.langfusePublicKey="";break;case"langfuse-secret":l.langfuseSecretKey="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"langdock":i.langdockApiKey=o;break;case"figma":i.figmaToken=o;break;case"langfuse-public":i.langfusePublicKey=o;break;case"langfuse-secret":i.langfuseSecretKey=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(i);let r=null;if(!R().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(Y({aiEngine:c}),r=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Sm(e,t){W(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let r=dn(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 vm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}"),o=R(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){io(s.personalAccessKey).then(r=>{qn(s.personalAccessKey,r.portalId,r.portalName,r.dataCenter),p(t,200,{ok:!0,portalName:r.portalName,portalId:r.portalId,dataCenter:r.dataCenter})}).catch(r=>{p(t,400,{error:r instanceof Error?r.message:String(r)})});return}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=Os("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:a});return}if(i==="api"){let r=o.hubspotAccounts||[];if(r.length>0&&!s.force){let a=r.find(l=>l.portalId===o.activeHubSpotAccount)||r[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ht();if(a.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function xm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}");if(!eo().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=to();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=Os("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=dn("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 wm(e,t){W(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((R().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Pi(s),p(t,200,{ok:!0});return}if(s){Ni(s),p(t,200,{ok:!0});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=Os("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=Os("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 Cm(e){let t=dn("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function km(e,t){W(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=dn("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=dn("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,Y({openaiApiKey:i}),process.platform!=="win32"){let r=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(r){let a=`export OPENAI_API_KEY="${r}"`,l=process.env.SHELL?.includes("zsh")?am(lm(),".zshrc"):am(lm(),".bashrc");try{(Kb(l)?Vb(l,"utf-8"):"").includes("OPENAI_API_KEY")||zb(l,`
|
|
2738
|
+
${t}`:""}`;try{let a=await Pe(n,s,o,{systemPrompt:r,messages:[{role:"user",content:e}],maxTokens:1e3}),l=a.type==="text"?a.text:JSON.stringify(a.data);return!l||l.trim().length<20?null:(M.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(a){let l=a instanceof Error?a.message:String(a);return M.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var ui=N(()=>{"use strict";y();dt();le()});import{join as qu}from"path";function Bb(e){let t=[];return e.brandAssets?.styleguide||t.push("styleguide"),e.brandAssets?.brandvoice||t.push("brandvoice"),e.brandAssets?.themeContext||t.push("themeContext"),t}function Hb(e,t,n){e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=qu(e.themePath,".vibespot");Re(o),B(qu(o,s),n)}async function Xu(e,t){let n=Bb(e),s={attempted:[],extracted:[],skipped:[],errors:[]};return n.length===0?s:tt({name:"brand_enrichment",sessionId:e.themeName,metadata:{missing:n},tags:["vibespot","brand-enrichment"]},()=>Ub(e,t,n,s))}async function Ub(e,t,n,s){let o=Gb(t)?t:{...await Wb(e),...t??{}};n.includes("styleguide")&&await ya(e,"styleguide",s,()=>te("extract-styleguide",()=>o.extractStyleguide(e)));let i=n.filter(a=>a==="brandvoice"||a==="themeContext");if(i.length===0)return s;let r="";try{r=o.buildPreviewHtml()}catch(a){let l=a instanceof Error?a.message:String(a);for(let c of i)s.skipped.push(c),s.errors.push({asset:c,message:`Could not render preview HTML: ${l}`});return s}if(!r||r.length<50){for(let a of i)s.skipped.push(a);return s}return n.includes("brandvoice")&&await ya(e,"brandvoice",s,()=>te("extract-brandvoice",()=>o.extractBrandvoice(e,r))),n.includes("themeContext")&&await ya(e,"themeContext",s,()=>te("extract-theme-context",()=>o.extractThemeContext(e,r))),s}async function ya(e,t,n,s){n.attempted.push(t);try{let o=await s();if(!o){n.skipped.push(t);return}Hb(e,t,o),n.extracted.push(t)}catch(o){let i=o instanceof Error?o.message:String(o);n.skipped.push(t),n.errors.push({asset:t,message:i}),M.warn("brand-enrichment",`${t} enrichment skipped: ${i}`)}}function Gb(e){return!!e?.extractStyleguide&&!!e.extractBrandvoice&&!!e.extractThemeContext&&!!e.buildPreviewHtml}async function Wb(e){let{extractDesignContext:t}=await Promise.resolve().then(()=>(Js(),Ls)),{buildPreviewHtml:n}=await Promise.resolve().then(()=>(ws(),Wo)),{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Kn(),aa)),{extractBrandvoice:o}=await Promise.resolve().then(()=>(ha(),fa)),{extractThemeContext:i}=await Promise.resolve().then(()=>(ui(),di)),r=R();return{extractStyleguide:()=>t(e.themePath),buildPreviewHtml:n,extractBrandvoice:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return o(l,c,d,u)},extractThemeContext:async(a,l)=>{let{engine:c,apiKey:d,model:u}=s(r);return i(l,a.brandAssets?.themeContext,c,d,u)}}}var Zu=N(()=>{"use strict";y();oe();ee();le();Be()});import{existsSync as zn,readdirSync as Qu,rmSync as Kb,writeFileSync as pn,mkdirSync as mi}from"fs";import{join as Ne,basename as Vb}from"path";import{homedir as zb}from"os";import{execFileSync as tm}from"child_process";function gi(){if(pi&&Date.now()-pi.ts<Yb)return pi.data;let e=[];if(zn(ut))try{for(let t of Qu(ut,{withFileTypes:!0}))if(t.isDirectory()){let n=Ne(ut,t.name,"theme.json");if(zn(n)){let s=0,o=Ne(ut,t.name,"modules");if(zn(o))try{s=Qu(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}e.push({name:t.name,moduleCount:s})}}}catch{}return pi={data:e,ts:Date.now()},e}function sm(e){let t=C(),n=io(),s=!1;try{tm("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...nm}),s=!0}catch{}let o=Fn().sort((r,a)=>a.updatedAt-r.updatedAt),i=gi();p(e,200,{hasActiveSession:!!t,activeSession:t?{id:t.id,themeName:t.themeName,moduleCount:t.modules.length,isImported:!!t.isImported}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i,contentMode:Jn()})}function om(e,t){W(e,n=>{try{if(Yt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s,starterId:o,assetType:i}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let r=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"");if(!r){p(t,400,{error:"Theme name must contain at least one alphanumeric character"});return}let a=Ne(ut,r);if(Re(ut),zn(a)&&Kb(a,{recursive:!0,force:!0}),o&&typeof o=="string"&&!ma(o)){p(t,400,{error:`Starter template "${o}" not found`});return}is(a,r),On(a,r),o&&typeof o=="string"?(qb(a,r,o),Te()):i==="email"&&(Rt("module_only","Email","email"),$n(a,r)),L(),p(t,200,{ok:!0,themeName:r,themePath:a,starterId:o||void 0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function qb(e,t,n){let s=ma(n);if(!s)return;let o=C();if(!o)return;let i=s.contentType==="email",r=s.modules.map(u=>({...u})),a=[...s.moduleOrder],l=i?`email-${t}`:`lp-${t}`,c={id:l,label:`${s.name}`,pageType:i?"module_only":"landing_page",contentMode:i?"email":void 0,templateFile:i?"templates/email.html":`templates/${l}.html`,modules:r,moduleOrder:a,sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:"",messages:[]};i&&$n(e,t),o.templates=[c],o.activeTemplateId=l,o.modules=r,o.moduleOrder=a,o.sharedCss=s.sharedCss,o.sharedJs=s.sharedJs;let d=Ne(e,"modules");mi(d,{recursive:!0});for(let u of s.modules){let m=Ne(d,`${u.moduleName}.module`);mi(m,{recursive:!0}),pn(Ne(m,"fields.json"),u.fieldsJson,"utf-8"),pn(Ne(m,"meta.json"),u.metaJson,"utf-8"),pn(Ne(m,"module.html"),u.moduleHtml,"utf-8"),pn(Ne(m,"module.css"),u.moduleCss,"utf-8"),u.moduleJs&&pn(Ne(m,"module.js"),u.moduleJs,"utf-8")}if(s.sharedCss){let u=Ne(e,"css");mi(u,{recursive:!0}),pn(Ne(u,`${t}-theme.css`),s.sharedCss,"utf-8")}if(s.sharedJs){let u=Ne(e,"js");mi(u,{recursive:!0}),pn(Ne(u,`${t}-animations.js`),s.sharedJs,"utf-8")}}function im(e){p(e,200,{starters:Ku()})}function rm(e,t){W(e,n=>{try{if(Yt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){p(t,400,{error:"Theme name is required"});return}let i=Le(),r=R(),a=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=Ne(ut,a);Re(ut),r.hubspotUploadMode==="cli"||!i?(async()=>{tm("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...nm});let c=await em(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})})().catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})}):as(i,o,l).then(async()=>{let c=await em(l,a);p(t,200,{ok:!0,themeName:a,themePath:l,moduleCount:c.moduleCount,brandEnrichment:c.brandEnrichment})}).catch(c=>{p(t,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}async function em(e,t){On(e,t,{isImported:!0}),Go(e),L();let n=C(),s={attempted:[],extracted:[],skipped:[],errors:[]};return n&&(s=await Xu(n),L()),{moduleCount:n?.modules.length||0,brandEnrichment:s}}function am(e,t){W(e,n=>{try{if(Yt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme path is required"});return}let o=s;if(zn(o)||(o=Ne(ut,s)),!zn(o)){p(t,400,{error:`Theme folder not found: ${s}`});return}let i=Vb(o);On(o,i),Go(o),L(),p(t,200,{ok:!0,themeName:i,themePath:o,moduleCount:C()?.modules.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function lm(e,t){W(e,n=>{try{if(Yt()){p(t,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Session ID is required"});return}let o=jo(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function cm(e,t){W(e,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"API key is required"});return}Y({anthropicApiKey:s}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function dm(e){let t=Le();if(!t){p(e,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await cl(t);if(n.length===0){p(e,200,{themes:[]});return}let s=[],o=n.map(async a=>{let l=a.path||a.name;try{let c=await lo(t,`${l}/theme.json`);c&&!c.folder&&s.push({name:a.name,path:l})}catch{}});await Promise.all(o),s.sort((a,l)=>a.name.localeCompare(l.name));let i=gi(),r=new Set(i.map(a=>a.name));p(e,200,{themes:s.map(a=>({...a,existsLocally:r.has(a.name)}))})})().catch(n=>{p(e,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}var nm,ut,pi,Yb,fi=N(()=>{"use strict";y();Xe();ee();rs();po();sn();Ce();Kt();Kn();nn();ee();oe();Vu();Cs();Zu();nm=process.platform==="win32"?{shell:!0}:{},ut=Ne(zb(),"vibespot-themes"),pi=null,Yb=5e3});import{existsSync as Xb,readFileSync as Zb,appendFileSync as Qb}from"fs";import{join as um}from"path";import{homedir as mm}from"os";function nS(e){let t=e.match(/^gpt-(\d+(?:\.\d+)?)(?:-(.+))?$/);if(t){let n=t[1],s=t[2];if(!s)return`GPT-${n}`;let o=s.replace(/-/g," ").replace(/\b\w/g,i=>i.toUpperCase());return`GPT-${n} ${o}`}return e.startsWith("codex-")?`Codex ${e.slice(6).replace(/-/g," ").replace(/\b\w/g,s=>s.toUpperCase())}`:/^o\d/.test(e)?e.replace(/-/g," "):e}async function Sa(e,t={},n=ym){let s=new AbortController,o=setTimeout(()=>s.abort(),n);try{return await fetch(e,{...t,signal:s.signal})}finally{clearTimeout(o)}}async function sS(e){let t=await Sa("https://api.anthropic.com/v1/models",{headers:{"x-api-key":e,"anthropic-version":"2023-06-01"}});return t.ok?(await t.json()).data.filter(s=>!s.id.startsWith("claude-3-")&&!s.id.startsWith("claude-2")).map(s=>({id:s.id,label:s.display_name})):[]}async function oS(e){let t=await Sa("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${e}`}});return t.ok?(await t.json()).data.map(s=>s.id):[]}function gm(e,t){return e.filter(n=>t.test(n)).sort((n,s)=>n.localeCompare(s)).map(n=>({id:n,label:nS(n)}))}async function iS(e){let t=await Sa(`https://generativelanguage.googleapis.com/v1beta/models?key=${e}`);return t.ok?(await t.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function rS(e=!1){if(!e&&Date.now()-Yn.ts<eS&&Object.keys(Yn.data).length>0)return Yn.data;let t=R(),n={...ba},s=[],o=Fe("anthropic-api",t);o&&s.push(sS(o).then(c=>{c.length&&(n["anthropic-api"]=c,n["claude-oauth"]=c,n["claude-code"]=c)}).catch(()=>{}));let i=Fe("openai-api",t);i&&s.push(oS(i).then(c=>{if(!c.length)return;let d=gm(c,hm);d.length&&(n["openai-api"]=d);let u=gm(c,tS);u.length&&(n["codex-cli"]=u)}).catch(()=>{}));let r=Fe("gemini-api",t);r&&s.push(iS(r).then(c=>{c.length&&(n["gemini-api"]=c,n["gemini-cli"]=c)}).catch(()=>{}));let a=!1;await Promise.race([Promise.all(s).then(()=>{a=!0}),new Promise(c=>setTimeout(c,ym+500))]);let l=t.langdockProvider||"anthropic";return n["langdock-api"]=pm[l]||pm.anthropic,a&&(Yn.data=n,Yn.ts=Date.now()),n}function bm(e){let t=nl(),n=R(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,codexCliModel:n.codexCliModel||null,geminiCliModel:n.geminiCliModel||null,geminiApiModel:n.geminiApiModel||null,langdockApiModel:n.langdockApiModel||null,langdockBaseUrl:n.langdockBaseUrl||null,langdockProvider:n.langdockProvider||"anthropic",hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(o=>({portalId:o.portalId,portalName:o.portalName,dataCenter:o.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency,planMode:n.planMode||!1,extendedThinking:n.extendedThinking||!1,extendedThinkingBudget:n.extendedThinkingBudget||"medium",webSearch:n.webSearch||!1,figmaToken:n.figmaToken?"\u2022\u2022\u2022\u2022"+n.figmaToken.slice(-4):null,langfuseEnabled:n.langfuseEnabled,langfuseBaseUrl:n.langfuseBaseUrl||null};p(e,200,{version:Sn(),environment:t,config:s,models:ba,sessionCount:Fn().length,localThemeCount:gi().length})}function Sm(e,t){let n=/[?&]refresh=1\b/.test(e.url||"");rS(n).then(s=>p(t,200,{models:s})).catch(()=>p(t,200,{models:ba}))}function vm(e,t){let n=new URL(e.url||"/","http://localhost"),s=n.searchParams.get("group")||"all",o=s==="ai"||s==="platform"?s:"all",i=n.searchParams.get("refresh")==="1",r=fm[o];if(!i&&Date.now()-r.ts<aS&&Object.keys(r.data).length>0){p(t,200,{...r.data,group:o,cached:!0});return}let a;if(o==="ai"){let l=sl();a={tools:{claudeCode:l.claudeCode,geminiCli:l.geminiCli,codexCli:l.codexCli,claudeOAuth:l.claudeOAuth},availableEngines:l.availableEngines}}else if(o==="platform")a={tools:ol()};else{let l=io();a={tools:l.tools,availableEngines:l.availableEngines}}fm[o]={data:a,ts:Date.now()},p(t,200,{...a,group:o,cached:!1})}function xm(e,t){W(e,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","claude-oauth","openai-api","gemini-cli","gemini-api","codex-cli","langdock-api"].includes(s)){p(t,400,{error:`Invalid engine: ${s}`});return}let r={aiEngine:s};if(o)switch(s){case"claude-code":r.claudeCodeModel=o;break;case"anthropic-api":case"claude-oauth":r.anthropicApiModel=o;break;case"openai-api":r.openaiApiModel=o;break;case"codex-cli":r.codexCliModel=o;break;case"gemini-cli":r.geminiCliModel=o;break;case"gemini-api":r.geminiApiModel=o;break;case"langdock-api":r.langdockApiModel=o;break}Y(r),p(t,200,{ok:!0,engine:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function wm(e,t){W(e,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;case"langdock":l.langdockApiKey="";break;case"figma":l.figmaToken="";break;case"langfuse-public":l.langfusePublicKey="";break;case"langfuse-secret":l.langfuseSecretKey="";break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(l),p(t,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;case"langdock":i.langdockApiKey=o;break;case"figma":i.figmaToken=o;break;case"langfuse-public":i.langfusePublicKey=o;break;case"langfuse-secret":i.langfuseSecretKey=o;break;default:p(t,400,{error:`Unknown provider: ${s}`});return}Y(i);let r=null;if(!R().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api",langdock:"langdock-api"}[s];c&&(Y({aiEngine:c}),r=c)}p(t,200,{ok:!0,provider:s,autoSelectedEngine:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Cm(e,t){W(e,n=>{try{let{tool:s}=JSON.parse(n),o={hubspot:{cmd:"npm install -g @hubspot/cli",desc:"Installing HubSpot CLI"},claude:{cmd:"npm install -g @anthropic-ai/claude-code",desc:"Installing Claude Code"},gemini:{cmd:"npm install -g @google/gemini-cli",desc:"Installing Gemini CLI"},codex:{cmd:process.platform==="darwin"?"brew install --cask codex":"npm install -g @openai/codex",desc:"Installing OpenAI Codex"},gh:{cmd:process.platform==="darwin"?"brew install gh":"npm install -g @cli/gh",desc:"Installing GitHub CLI"}},i=o[s];if(!i){p(t,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let r=mn(i.cmd,i.desc,{timeout:12e4});p(t,200,{ok:!0,jobId:r})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function km(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}"),o=R(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){ao(s.personalAccessKey).then(r=>{Xn(s.personalAccessKey,r.portalId,r.portalName,r.dataCenter),p(t,200,{ok:!0,portalName:r.portalName,portalId:r.portalId,dataCenter:r.dataCenter})}).catch(r=>{p(t,400,{error:r instanceof Error?r.message:String(r)})});return}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=Ds("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});p(t,200,{ok:!0,jobId:a});return}if(i==="api"){let r=o.hubspotAccounts||[];if(r.length>0&&!s.force){let a=r.find(l=>l.portalId===o.activeHubSpotAccount)||r[0];p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let a=ht();if(a.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,portalName:a.portalName,portalId:a.portalId});return}}p(t,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Tm(e,t){W(e,n=>{try{let s=JSON.parse(n||"{}");if(!no().found){p(t,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=so();if(i.authenticated&&!s.force){p(t,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let a=Ds("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});p(t,200,{ok:!0,jobId:a});return}let r=mn("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});p(t,200,{ok:!0,jobId:r,browserAuthRequired:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Am(e,t){W(e,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((R().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){Ni(s),p(t,200,{ok:!0});return}if(s){Ri(s),p(t,200,{ok:!0});return}}else{if(!ft().found){p(t,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){p(t,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=Ds("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}if(l){let c=Ds("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});p(t,200,{ok:!0,jobId:c});return}}p(t,400,{error:"portalId required"})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function _m(e){let t=mn("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});p(e,200,{ok:!0,jobId:t})}function $m(e,t){W(e,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=mn("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=mn("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,Y({openaiApiKey:i}),process.platform!=="win32"){let r=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(r){let a=`export OPENAI_API_KEY="${r}"`,l=process.env.SHELL?.includes("zsh")?um(mm(),".zshrc"):um(mm(),".bashrc");try{(Xb(l)?Zb(l,"utf-8"):"").includes("OPENAI_API_KEY")||Qb(l,`
|
|
2739
2739
|
# Added by vibeSpot
|
|
2740
2740
|
${a}
|
|
2741
|
-
`)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=dn("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 Tm(e,t){W(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}Y({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Am(e,t){W(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(t,400,{error:"toolId (string) and enabled (boolean) required"});return}Ri(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 _m(e,t){W(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider","langfuseEnabled","langfuseBaseUrl"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langfuseEnabled!==void 0&&typeof s.langfuseEnabled!="boolean"){p(t,400,{error:"langfuseEnabled must be a boolean"});return}if(s.langfuseBaseUrl!==void 0&&typeof s.langfuseBaseUrl!="string"){p(t,400,{error:"langfuseBaseUrl must be a string"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){p(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(i.langdockProvider){let r={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};i.langdockApiModel=r[i.langdockProvider]||"",zn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}Y(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function $m(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=ni(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 zn,Yb,ya,cm,mm,qb,pm,nS,um,Em=N(()=>{"use strict";y();Xe();ee();Ce();gi();Qt();en();oe();oi();zn={data:{},ts:0},Yb=600*1e3,ya={"claude-code":[{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-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-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"}]},cm={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{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"}]},mm=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,qb=mm;pm=2500;nS=60*1e3,um={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}}});function Mm(e,t){W(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"access_token is required"});return}Oi(s.trim(),(o||"").trim());let i=R();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&Y({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Im(e,t){let n=Ze(),s=Xt();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Pm(e,t){try{qs(),R().aiEngine==="claude-oauth"&&Y({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var Nm=N(()=>{"use strict";y();Xe();ee();_t()});import{existsSync as sS,rmSync as oS}from"fs";import{join as iS}from"path";function Rm(e,t,n){if(e==="GET"){let s=C(),o=On().sort((i,r)=>r.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName,isImported:!!s.isImported}:null,sessions:o});return}if(e==="DELETE"){W(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);$c(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 Om(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=Do(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 Fm(e,t){W(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}if(/[\/\\]|\.\./.test(s)||s==="."||!s.replace(/[^a-z0-9]/gi,"")){p(t,400,{error:"Invalid theme name"});return}let o=iS(ut,s);if(!sS(o)){p(t,404,{error:"Theme not found on disk"});return}oS(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Dm(e,t){W(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){p(t,400,{error:"Invalid name"});return}let r=Ec(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 jm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=Mc(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 Lm=N(()=>{"use strict";y();Xe();Ce();gi()});import{existsSync as fi,readFileSync as rS,readdirSync as aS,rmSync as Gm}from"fs";import{join as Oe,basename as lS,relative as cS,sep as dS}from"path";import uS from"jszip";function Wm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=Nt();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 Km(e,t=[]){for(let n of aS(e,{withFileTypes:!0}))if(n.isDirectory()){if(mS.has(n.name))continue;Km(Oe(e,n.name),t)}else n.isFile()&&t.push(Oe(e,n.name));return t}async function Vm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!fi(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=lS(n);try{let i=new uS;for(let a of Km(n)){let l=Oe(o,cS(n,a)).split(dS).join("/");i.file(l,rS(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){E.error("download-zip","Failed to create zip archive",i),p(e,500,{error:"Failed to create zip archive"})}}function zm(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.contentMode==="email"?"email":o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){W(t,o=>{try{let{pageType:i,label:r}=JSON.parse(o);if(!i||!r){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only","email"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=i==="email",d=Pt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&An(s.themePath,s.themeName),L(),p(n,200,{ok:!0,template:{id:d.id,label:d.label,pageType:d.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!kc(i,!!r)){p(n,404,{error:"Template not found"});return}L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function Ym(e,t){W(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!ms(s)){p(t,404,{error:"Template not found"});return}L();let i=C();p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function qm(e,t){W(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"templateId and newLabel are required"});return}if(!Cc(s,o.trim())){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Xm(e,t){W(e,n=>{try{let{templateIds:s}=JSON.parse(n);if(!Array.isArray(s)||s.some(i=>typeof i!="string")){p(t,400,{error:"templateIds must be an array of strings"});return}if(!wc(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}L(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Zm(e,t){W(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=xc(s,o);if(!i){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Qm(e){let t=Nt();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function ep(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}W(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=Nt().find(d=>d.module.moduleName===i);if(!a){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...a.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function tp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){W(t,o=>{try{let{type:i,content:r}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=r==="on",s.updatedAt=Date.now(),L(),p(n,200,{ok:!0});return}if(!r){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let a=i,l=a==="themeContext"?"theme-context.md":`${a}.md`;s.brandAssets[a]=r,s.updatedAt=Date.now();let c=Oe(s.themePath,".vibespot");Re(c),B(Oe(c,l),r);let d=null;a==="styleguide"&&(d=Sa(s,r)),L(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let r=i;s.brandAssets&&delete s.brandAssets[r],s.updatedAt=Date.now();let a=r==="themeContext"?"theme-context.md":`${r}.md`,l=Oe(s.themePath,".vibespot",a);fi(l)&&Gm(l),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function sp(e,t){p(t,200,np)}function gS(e){let t=[],n=[],s=e.split(`
|
|
2742
|
-
`),o=!1,i=!1;for(let r of s){let a=r.trim();if(/^##\s+color/i.test(a)){o=!0,i=!1;continue}if(/^##\s+typography/i.test(a)){i=!0,o=!1;continue}if(/^##\s+/.test(a)&&!(/color/i.test(a)||/typography/i.test(a))){o=!1,i=!1;continue}if(o){let l=a.match(pS);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Jm.exec(a);if(Jm.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 Sa(e,t){let{colors:n,fonts:s}=gS(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=np.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=r(s[0])),s[1]?o.fonts.body=r(s[1]):s[0]&&(o.fonts.body=r(s[0]))}e.brandAssets.brandKit=o;let i=Oe(e.themePath,".vibespot");return Re(i),B(Oe(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function op(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){W(t,o=>{try{let i=JSON.parse(o);s.brandAssets||(s.brandAssets={});let r={};if(i.colors&&typeof i.colors=="object"){let l={};for(let c of["primary","secondary","accent"])typeof i.colors[c]=="string"&&fS.test(i.colors[c])&&(l[c]=i.colors[c]);Object.keys(l).length>0&&(r.colors=l)}if(i.fonts&&typeof i.fonts=="object"){let l={};for(let c of["heading","body"])typeof i.fonts[c]=="string"&&i.fonts[c].trim()&&(l[c]=i.fonts[c].trim());Object.keys(l).length>0&&(r.fonts=l)}typeof i.logoUrl=="string"&&i.logoUrl.trim()&&(r.logoUrl=i.logoUrl.trim()),s.brandAssets.brandKit=r,s.updatedAt=Date.now();let a=Oe(s.themePath,".vibespot");Re(a),B(Oe(a,"brand-kit.json"),JSON.stringify(r,null,2)),L(),p(n,200,{ok:!0,brandKit:r})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Oe(s.themePath,".vibespot","brand-kit.json");fi(o)&&Gm(o),L(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Bm(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Oe(e.themePath,".vibespot");Re(o),B(Oe(o,s),n)}function Hm(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function Um(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(js(),Ds));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Wn(),ra)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),Ya)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Ss(),Go)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(fa(),ga));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(di(),ci));return u(d,e.brandAssets?.themeContext,r,a,l)}function ip(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",r=o.sourcePath;if(i==="all"){let c=["styleguide","brandvoice","themeContext"],d=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>te(Hm(g),()=>Um(n,g,r))))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Bm(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=Sa(n,u.styleguide)),L(),p(t,200,{ok:!0,type:"all",extracted:u,brandKit:m});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let a=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:i},tags:["vibespot","brand-extract"]},()=>te(Hm(i),()=>Um(n,i,r)));if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Bm(n,i,a);let l=null;i==="styleguide"&&(l=Sa(n,a)),L(),p(t,200,{ok:!0,type:i,content:a,brandKit:l})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function rp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:r}=JSON.parse(s),a;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Le();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),f=Oe(h(),"vibespot-themes",".references",g);Re(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(uo(),hl));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(!fi(r)){p(t,400,{error:`Path not found: ${r}`});return}a=r}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(js(),Ds)),c=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Oe(n.themePath,".vibespot");Re(d),B(Oe(d,"styleguide.md"),c),L(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var mS,np,pS,Jm,fS,ap=N(()=>{"use strict";y();Xe();le();Be();ee();is();Ce();oe();mS=new Set([".git",".vibespot","node_modules"]);np=[{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"}];pS=/#[0-9a-fA-F]{6}\b/g,Jm=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;fS=/^#[0-9a-fA-F]{6}$/});import{join as hS}from"path";function lp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function cp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=ve();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){qe(t,n,o=>{o.deleteEntirely?fc(o.moduleName):hc(o.moduleName),L(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function dp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=ke();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:r,content:a}=o;if(!i||!r){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(r){case"html":l.moduleHtml=a;break;case"css":l.moduleCss=a;break;case"js":l.moduleJs=a||void 0;break;case"fields":try{JSON.parse(a)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:p(t,400,{error:`Invalid fileType: ${r}`});return}n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function up(e,t){qe(e,t,n=>{Array.isArray(n.order)?(Ht(n.order),L(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function mp(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}try{Te();let n=To(t.themePath),s=si(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:hS(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function pp(e,t){W(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);yc(s,o,i),L(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function gp(e,t){W(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=pl(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
|
|
2741
|
+
`)}catch{}}}p(t,200,{ok:!0,message:"API key saved"})}else{let i=mn("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});p(t,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:p(t,400,{error:`Unknown CLI: ${s}`})}}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Em(e,t){W(e,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){p(t,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}Y({hubspotUploadMode:s}),p(t,200,{ok:!0,mode:s})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Mm(e,t){W(e,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){p(t,400,{error:"toolId (string) and enabled (boolean) required"});return}Oi(s,o),p(t,200,{ok:!0,toolId:s,enabled:o})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Im(e,t){W(e,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency","planMode","extendedThinking","extendedThinkingBudget","webSearch","langdockProvider","langfuseEnabled","langfuseBaseUrl"];if(s.extendedThinkingBudget!==void 0&&!["low","medium","high"].includes(s.extendedThinkingBudget)){p(t,400,{error:"extendedThinkingBudget must be 'low' | 'medium' | 'high'"});return}if(s.langfuseEnabled!==void 0&&typeof s.langfuseEnabled!="boolean"){p(t,400,{error:"langfuseEnabled must be a boolean"});return}if(s.langfuseBaseUrl!==void 0&&typeof s.langfuseBaseUrl!="string"){p(t,400,{error:"langfuseBaseUrl must be a string"});return}if(s.langdockProvider!==void 0&&!["anthropic","openai","google","mistral"].includes(s.langdockProvider)){p(t,400,{error:"langdockProvider must be 'anthropic' | 'openai' | 'google' | 'mistral'"});return}let i={};for(let r of o)r in s&&(i[r]=s[r]);if(i.langdockProvider){let r={anthropic:"claude-sonnet-4-6",openai:"gpt-4.1",google:"gemini-2.5-pro",mistral:"mistral-large-latest"};i.langdockApiModel=r[i.langdockProvider]||"",Yn.ts=0}if(Object.keys(i).length===0){p(t,400,{error:"No valid settings fields provided"});return}Y(i),p(t,200,{ok:!0,updated:Object.keys(i)})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Pm(e,t){let n=e.replace("/api/settings/job/","");if(!n){p(t,400,{error:"Job ID required"});return}let s=si(n);if(!s){p(t,404,{error:"Job not found"});return}p(t,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}var Yn,eS,ba,pm,hm,tS,ym,aS,fm,Nm=N(()=>{"use strict";y();Xe();ee();Ce();fi();nn();sn();oe();ii();Yn={data:{},ts:0},eS=600*1e3,ba={"claude-code":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5",label:"Claude Haiku 4.5"}],"codex-cli":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"},{id:"gpt-5.2-codex",label:"GPT-5.2 Codex"},{id:"gpt-5.1-codex-max",label:"GPT-5.1 Codex Max"},{id:"gpt-5.1-codex-mini",label:"GPT-5.1 Codex Mini"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"codex-mini-latest",label:"Codex Mini (latest)"}],"anthropic-api":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"claude-oauth":[{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],"openai-api":[{id:"gpt-5.5",label:"GPT-5.5 (default)"},{id:"gpt-5.5-pro",label:"GPT-5.5 Pro"},{id:"gpt-5.4-mini",label:"GPT-5.4 Mini"},{id:"gpt-5.4-nano",label:"GPT-5.4 Nano"},{id:"gpt-5.3-codex",label:"GPT-5.3 Codex"}],"gemini-api":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],"gemini-cli":[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}]},pm={anthropic:[{id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6 (default)"},{id:"claude-opus-4-8",label:"Claude Opus 4.8"},{id:"claude-opus-4-7",label:"Claude Opus 4.7"},{id:"claude-opus-4-6",label:"Claude Opus 4.6"},{id:"claude-sonnet-4-5",label:"Claude Sonnet 4.5"},{id:"claude-haiku-4-5-20251001",label:"Claude Haiku 4.5"}],openai:[{id:"gpt-4.1",label:"GPT-4.1 (default)"},{id:"gpt-4.1-mini",label:"GPT-4.1 Mini"},{id:"gpt-4.1-nano",label:"GPT-4.1 Nano"},{id:"gpt-4o",label:"GPT-4o"},{id:"o3-mini",label:"o3 Mini"}],google:[{id:"gemini-2.5-pro",label:"Gemini 2.5 Pro (default)"},{id:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{id:"gemini-2.0-flash",label:"Gemini 2.0 Flash"}],mistral:[{id:"mistral-large-latest",label:"Mistral Large (default)"},{id:"mistral-medium-latest",label:"Mistral Medium"},{id:"mistral-small-latest",label:"Mistral Small"},{id:"codestral-latest",label:"Codestral"},{id:"pixtral-large-latest",label:"Pixtral Large"}]},hm=/^(gpt-[45](\.\d+)?(-[a-z0-9-]+)?|o[1-4](-(mini|pro|nano)(-high)?)?|codex(-[a-z0-9-]+)?)$/,tS=hm;ym=2500;aS=60*1e3,fm={ai:{data:{},ts:0},platform:{data:{},ts:0},all:{data:{},ts:0}}});function Rm(e,t){W(e,n=>{try{let{access_token:s,refresh_token:o}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"access_token is required"});return}Fi(s.trim(),(o||"").trim());let i=R();(!i.aiEngine||i.aiEngine!=="claude-oauth")&&Y({aiEngine:"claude-oauth"}),p(t,200,{ok:!0})}catch(s){p(t,400,{error:s instanceof Error?s.message:String(s)})}})}function Om(e,t){let n=Ze(),s=en();p(t,200,{authenticated:n,expiresAt:s?.expiresAt||null})}function Fm(e,t){try{Zs(),R().aiEngine==="claude-oauth"&&Y({aiEngine:void 0}),p(t,200,{ok:!0})}catch(n){p(t,500,{error:n instanceof Error?n.message:String(n)})}}var Dm=N(()=>{"use strict";y();Xe();ee();$t()});import{existsSync as lS,rmSync as cS}from"fs";import{join as dS}from"path";function jm(e,t,n){if(e==="GET"){let s=C(),o=Fn().sort((i,r)=>r.updatedAt-i.updatedAt);p(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName,isImported:!!s.isImported}:null,sessions:o});return}if(e==="DELETE"){W(t,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Mc(o,i),p(n,200,{ok:!0})}catch(o){p(n,500,{error:o instanceof Error?o.message:String(o)})}});return}p(n,405,{error:"Method not allowed"})}function Lm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n),o=jo(s);if(!o){p(t,404,{error:"Session not found"});return}p(t,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Jm(e,t){W(e,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"Theme name is required"});return}if(/[\/\\]|\.\./.test(s)||s==="."||!s.replace(/[^a-z0-9]/gi,"")){p(t,400,{error:"Invalid theme name"});return}let o=dS(ut,s);if(!lS(o)){p(t,404,{error:"Theme not found on disk"});return}cS(o,{recursive:!0,force:!0}),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Bm(e,t){W(e,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){p(t,400,{error:"Invalid name"});return}let r=Ic(s,i);r.ok?p(t,200,{ok:!0,newName:i}):p(t,400,{error:r.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Hm(e,t){W(e,n=>{try{let{sessionId:s}=JSON.parse(n);if(!s){p(t,400,{error:"sessionId is required"});return}let o=Pc(s);o.ok?p(t,200,{ok:!0,newName:o.newName,newSessionId:o.newSessionId}):p(t,400,{error:o.error})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var Um=N(()=>{"use strict";y();Xe();Ce();fi()});import{existsSync as hi,readFileSync as uS,readdirSync as mS,rmSync as zm}from"fs";import{join as Oe,basename as pS,relative as gS,sep as fS}from"path";import hS from"jszip";function Ym(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=Ot();p(e,200,{themeName:t.themeName,themePath:t.themePath,templates:t.templates.map(s=>({id:s.id,label:s.label,pageType:s.contentMode==="email"?"email":s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:t.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!t.brandAssets?.styleguide,hasBrandvoice:!!t.brandAssets?.brandvoice,hasThemeContext:!!t.brandAssets?.themeContext,humanify:t.brandAssets?.humanify!==!1,hasBrandKit:!!t.brandAssets?.brandKit&&Object.keys(t.brandAssets.brandKit).length>0,brandKit:t.brandAssets?.brandKit||null}})}function qm(e,t=[]){for(let n of mS(e,{withFileTypes:!0}))if(n.isDirectory()){if(yS.has(n.name))continue;qm(Oe(e,n.name),t)}else n.isFile()&&t.push(Oe(e,n.name));return t}async function Xm(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}let n=t.themePath;if(!hi(n)){p(e,404,{error:"Theme directory not found"});return}let s=t.themeName||"theme",o=pS(n);try{let i=new hS;for(let a of qm(n)){let l=Oe(o,gS(n,a)).split(fS).join("/");i.file(l,uS(a))}let r=await i.generateAsync({type:"nodebuffer",compression:"DEFLATE",compressionOptions:{level:6}});e.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${s}.zip"`,"Content-Length":r.length}),e.end(r)}catch(i){M.error("download-zip","Failed to create zip archive",i),p(e,500,{error:"Failed to create zip archive"})}}function Zm(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.contentMode==="email"?"email":o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(e==="POST"){W(t,o=>{try{let{pageType:i,label:r}=JSON.parse(o);if(!i||!r){p(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only","email"].includes(i)){p(n,400,{error:`Invalid pageType: ${i}`});return}let l=i==="email",d=Rt(l?"module_only":i,r,l?"email":void 0);l&&s.themePath&&$n(s.themePath,s.themeName),L(),p(n,200,{ok:!0,template:{id:d.id,label:d.label,pageType:d.pageType}})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{templateId:i,deleteModules:r}=JSON.parse(o);if(!i){p(n,400,{error:"templateId is required"});return}if(!Ac(i,!!r)){p(n,404,{error:"Template not found"});return}L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function Qm(e,t){W(e,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}if(!fs(s)){p(t,404,{error:"Template not found"});return}L();let i=C();p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName),messageCount:i?.messages.length||0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function ep(e,t){W(e,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){p(t,400,{error:"templateId and newLabel are required"});return}if(!Tc(s,o.trim())){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,newLabel:o.trim()})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function tp(e,t){W(e,n=>{try{let{templateIds:s}=JSON.parse(n);if(!Array.isArray(s)||s.some(i=>typeof i!="string")){p(t,400,{error:"templateIds must be an array of strings"});return}if(!kc(s)){p(t,400,{error:"Reorder rejected (length mismatch or no session)"});return}L(),p(t,200,{ok:!0})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function np(e,t){W(e,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){p(t,400,{error:"templateId is required"});return}let i=Cc(s,o);if(!i){p(t,404,{error:"Template not found"});return}L(),p(t,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function sp(e){let t=Ot();p(e,200,{modules:t.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function op(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}W(t,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){p(n,400,{error:"moduleName is required"});return}let a=Ot().find(d=>d.module.moduleName===i);if(!a){p(n,404,{error:`Module "${i}" not found in library`});return}let l={...a.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}})}function ip(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(e==="POST"){W(t,o=>{try{let{type:i,content:r}=JSON.parse(o);if(!i){p(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=r==="on",s.updatedAt=Date.now(),L(),p(n,200,{ok:!0});return}if(!r){p(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let a=i,l=a==="themeContext"?"theme-context.md":`${a}.md`;s.brandAssets[a]=r,s.updatedAt=Date.now();let c=Oe(s.themePath,".vibespot");Re(c),B(Oe(c,l),r);let d=null;a==="styleguide"&&(d=va(s,r)),L(),p(n,200,{ok:!0,brandKit:d})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){W(t,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(n,400,{error:`Invalid type: ${i}`});return}let r=i;s.brandAssets&&delete s.brandAssets[r],s.updatedAt=Date.now();let a=r==="themeContext"?"theme-context.md":`${r}.md`,l=Oe(s.themePath,".vibespot",a);hi(l)&&zm(l),L(),p(n,200,{ok:!0})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}p(n,405,{error:"Method not allowed"})}function ap(e,t){p(t,200,rp)}function SS(e){let t=[],n=[],s=e.split(`
|
|
2742
|
+
`),o=!1,i=!1;for(let r of s){let a=r.trim();if(/^##\s+color/i.test(a)){o=!0,i=!1;continue}if(/^##\s+typography/i.test(a)){i=!0,o=!1;continue}if(/^##\s+/.test(a)&&!(/color/i.test(a)||/typography/i.test(a))){o=!1,i=!1;continue}if(o){let l=a.match(bS);if(l)for(let c of l)t.includes(c.toLowerCase())||t.push(c.toLowerCase())}if(i){let l=Gm.exec(a);if(Gm.lastIndex=0,l){let c=l[1].trim().replace(/['"`]/g,"").split(",")[0].trim();c&&!n.includes(c)&&n.push(c)}if(/\bheading|body|display|monospace\b/i.test(a)&&!l){let c=a.split(":").slice(1).join(":").trim();if(c){let d=c.replace(/['"`*]/g,"").split(",")[0].trim().split("(")[0].trim();d&&d.length<60&&!/^\d/.test(d)&&!n.includes(d)&&n.push(d)}}}}return{colors:t.slice(0,6),fonts:n.slice(0,4)}}function va(e,t){let{colors:n,fonts:s}=SS(t);if(n.length===0&&s.length===0)return null;e.brandAssets||(e.brandAssets={});let o=e.brandAssets.brandKit||{};if(n.length>0&&(o.colors||(o.colors={}),n[0]&&(o.colors.primary=n[0]),n[1]&&(o.colors.secondary=n[1]),n[2]&&(o.colors.accent=n[2])),s.length>0){o.fonts||(o.fonts={});let r=a=>{let l=a.toLowerCase(),c=rp.find(d=>d.name.toLowerCase()===l);return c?c.stack:a};s[0]&&(o.fonts.heading=r(s[0])),s[1]?o.fonts.body=r(s[1]):s[0]&&(o.fonts.body=r(s[0]))}e.brandAssets.brandKit=o;let i=Oe(e.themePath,".vibespot");return Re(i),B(Oe(i,"brand-kit.json"),JSON.stringify(o,null,2)),o}function lp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){p(n,200,s.brandAssets?.brandKit||{});return}if(e==="POST"){W(t,o=>{try{let i=JSON.parse(o);s.brandAssets||(s.brandAssets={});let r={};if(i.colors&&typeof i.colors=="object"){let l={};for(let c of["primary","secondary","accent"])typeof i.colors[c]=="string"&&vS.test(i.colors[c])&&(l[c]=i.colors[c]);Object.keys(l).length>0&&(r.colors=l)}if(i.fonts&&typeof i.fonts=="object"){let l={};for(let c of["heading","body"])typeof i.fonts[c]=="string"&&i.fonts[c].trim()&&(l[c]=i.fonts[c].trim());Object.keys(l).length>0&&(r.fonts=l)}typeof i.logoUrl=="string"&&i.logoUrl.trim()&&(r.logoUrl=i.logoUrl.trim()),s.brandAssets.brandKit=r,s.updatedAt=Date.now();let a=Oe(s.themePath,".vibespot");Re(a),B(Oe(a,"brand-kit.json"),JSON.stringify(r,null,2)),L(),p(n,200,{ok:!0,brandKit:r})}catch(i){p(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(e==="DELETE"){s.brandAssets&&delete s.brandAssets.brandKit,s.updatedAt=Date.now();let o=Oe(s.themePath,".vibespot","brand-kit.json");hi(o)&&zm(o),L(),p(n,200,{ok:!0});return}p(n,405,{error:"Method not allowed"})}function Wm(e,t,n){if(!e)return;e.brandAssets||(e.brandAssets={}),e.brandAssets[t]=n,e.updatedAt=Date.now();let s=t==="themeContext"?"theme-context.md":`${t}.md`,o=Oe(e.themePath,".vibespot");Re(o),B(Oe(o,s),n)}function Km(e){return e==="themeContext"?"extract-theme-context":`extract-${e}`}async function Vm(e,t,n){if(t==="styleguide"){let{extractDesignContext:m}=await Promise.resolve().then(()=>(Js(),Ls));return m(n||e.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(Kn(),aa)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),qa)),i=o(),{engine:r,apiKey:a,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ws(),Wo)),d=c();if(!d||d.length<50)return null;if(t==="brandvoice"){let{extractBrandvoice:m}=await Promise.resolve().then(()=>(ha(),fa));return m(d,r,a,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(ui(),di));return u(d,e.brandAssets?.themeContext,r,a,l)}function cp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",r=o.sourcePath;if(i==="all"){let c=["styleguide","brandvoice","themeContext"],d=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"all"},tags:["vibespot","brand-extract"]},()=>Promise.allSettled(c.map(g=>te(Km(g),()=>Vm(n,g,r))))),u={};for(let g=0;g<c.length;g++){let h=d[g],f=h.status==="fulfilled"?h.value:null;f&&Wm(n,c[g],f),u[c[g]]=f}let m=null;u.styleguide&&(m=va(n,u.styleguide)),L(),p(t,200,{ok:!0,type:"all",extracted:u,brandKit:m});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){p(t,400,{error:`Invalid type: ${i}`});return}let a=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:i},tags:["vibespot","brand-extract"]},()=>te(Km(i),()=>Vm(n,i,r)));if(!a){p(t,200,{ok:!1,type:i,error:"No content to extract from"});return}Wm(n,i,a);let l=null;i==="styleguide"&&(l=va(n,a)),L(),p(t,200,{ok:!0,type:i,content:a,brandKit:l})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}function dp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{(async()=>{try{let{source:o,themeName:i,localPath:r}=JSON.parse(s),a;if(o==="hubspot"){if(!i){p(t,400,{error:"themeName is required for HubSpot import"});return}let u=Le();if(!u){p(t,400,{error:"No HubSpot account connected"});return}let m=i.replace(/^\/+|\/+$/g,"");if(!m){p(t,400,{error:"Invalid theme name"});return}let g=m.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),f=Oe(h(),"vibespot-themes",".references",g);Re(f);let{fetchTheme:b}=await Promise.resolve().then(()=>(po(),yl));await b(u,m,f),a=f}else if(o==="local"){if(!r){p(t,400,{error:"localPath is required for local import"});return}if(!hi(r)){p(t,400,{error:`Path not found: ${r}`});return}a=r}else{p(t,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(Js(),Ls)),c=await tt({name:"brand_extract",sessionId:n.themeName,metadata:{type:"styleguide",source:o},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>l(a)));n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Oe(n.themePath,".vibespot");Re(d),B(Oe(d,"styleguide.md"),c),L(),p(t,200,{ok:!0,styleguide:c,source:a})}catch(o){p(t,500,{error:o instanceof Error?o.message:String(o)})}})()})}var yS,rp,bS,Gm,vS,up=N(()=>{"use strict";y();Xe();le();Be();ee();rs();Ce();oe();yS=new Set([".git",".vibespot","node_modules"]);rp=[{name:"System Default",stack:"system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",category:"system"},{name:"Inter",stack:"Inter, system-ui, sans-serif",category:"sans-serif"},{name:"DM Sans",stack:"'DM Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Open Sans",stack:"'Open Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Roboto",stack:"Roboto, system-ui, sans-serif",category:"sans-serif"},{name:"Lato",stack:"Lato, system-ui, sans-serif",category:"sans-serif"},{name:"Montserrat",stack:"Montserrat, system-ui, sans-serif",category:"sans-serif"},{name:"Poppins",stack:"Poppins, system-ui, sans-serif",category:"sans-serif"},{name:"Nunito",stack:"Nunito, system-ui, sans-serif",category:"sans-serif"},{name:"Raleway",stack:"Raleway, system-ui, sans-serif",category:"sans-serif"},{name:"Work Sans",stack:"'Work Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Source Sans 3",stack:"'Source Sans 3', system-ui, sans-serif",category:"sans-serif"},{name:"Manrope",stack:"Manrope, system-ui, sans-serif",category:"sans-serif"},{name:"Plus Jakarta Sans",stack:"'Plus Jakarta Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Outfit",stack:"Outfit, system-ui, sans-serif",category:"sans-serif"},{name:"Space Grotesk",stack:"'Space Grotesk', system-ui, sans-serif",category:"sans-serif"},{name:"Albert Sans",stack:"'Albert Sans', system-ui, sans-serif",category:"sans-serif"},{name:"Figtree",stack:"Figtree, system-ui, sans-serif",category:"sans-serif"},{name:"Helvetica",stack:"Helvetica, Arial, sans-serif",category:"sans-serif"},{name:"Arial",stack:"Arial, Helvetica, sans-serif",category:"sans-serif"},{name:"Verdana",stack:"Verdana, Geneva, sans-serif",category:"sans-serif"},{name:"Georgia",stack:"Georgia, 'Times New Roman', serif",category:"serif"},{name:"Playfair Display",stack:"'Playfair Display', Georgia, serif",category:"serif"},{name:"Merriweather",stack:"Merriweather, Georgia, serif",category:"serif"},{name:"Lora",stack:"Lora, Georgia, serif",category:"serif"},{name:"PT Serif",stack:"'PT Serif', Georgia, serif",category:"serif"},{name:"Libre Baskerville",stack:"'Libre Baskerville', Georgia, serif",category:"serif"},{name:"Source Serif 4",stack:"'Source Serif 4', Georgia, serif",category:"serif"},{name:"Cormorant Garamond",stack:"'Cormorant Garamond', Garamond, serif",category:"serif"},{name:"Times New Roman",stack:"'Times New Roman', Times, serif",category:"serif"},{name:"Sora",stack:"Sora, system-ui, sans-serif",category:"display"},{name:"Clash Display",stack:"'Clash Display', system-ui, sans-serif",category:"display"},{name:"Cabinet Grotesk",stack:"'Cabinet Grotesk', system-ui, sans-serif",category:"display"},{name:"Satoshi",stack:"Satoshi, system-ui, sans-serif",category:"display"},{name:"General Sans",stack:"'General Sans', system-ui, sans-serif",category:"display"},{name:"JetBrains Mono",stack:"'JetBrains Mono', 'Fira Code', monospace",category:"monospace"},{name:"Fira Code",stack:"'Fira Code', 'Courier New', monospace",category:"monospace"},{name:"Source Code Pro",stack:"'Source Code Pro', monospace",category:"monospace"},{name:"Courier New",stack:"'Courier New', Courier, monospace",category:"monospace"}];bS=/#[0-9a-fA-F]{6}\b/g,Gm=/font[- ]?famil(?:y|ies)\s*[:=]\s*([^\n]+)/gi;vS=/^#[0-9a-fA-F]{6}$/});import{join as xS}from"path";function mp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}p(t,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function pp(e,t,n){let s=C();if(!s){p(n,404,{error:"No active session"});return}if(e==="GET"){let o=ve();p(n,200,{modules:o.map(i=>({moduleName:i.moduleName,fieldsJson:i.fieldsJson,moduleHtml:i.moduleHtml,moduleCss:i.moduleCss,moduleJs:i.moduleJs||null})),sharedCss:s.sharedCss,sharedJs:s.sharedJs});return}if(e==="DELETE"){qe(t,n,o=>{o.deleteEntirely?yc(o.moduleName):bc(o.moduleName),L(),p(n,200,{ok:!0})});return}p(n,405,{error:"Method not allowed"})}function gp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}W(e,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{p(t,400,{error:"Invalid shared type"});return}let c=ke();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0});return}let{moduleName:i,fileType:r,content:a}=o;if(!i||!r){p(t,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){p(t,404,{error:`Module "${i}" not found`});return}switch(r){case"html":l.moduleHtml=a;break;case"css":l.moduleCss=a;break;case"js":l.moduleJs=a||void 0;break;case"fields":try{JSON.parse(a)}catch{p(t,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=a;break;default:p(t,400,{error:`Invalid fileType: ${r}`});return}n.updatedAt=Date.now(),at(),L(),Te(),p(t,200,{ok:!0})}catch(o){p(t,400,{error:String(o)})}})}function fp(e,t){qe(e,t,n=>{Array.isArray(n.order)?(Wt(n.order),L(),p(t,200,{ok:!0})):p(t,400,{error:"order must be an array"})})}async function hp(e){let t=C();if(!t){p(e,404,{error:"No active session"});return}try{Te();let n=Ao(t.themePath),s=oi(`hs cms upload "${t.themePath}" "${t.themeName}"`,"Uploading to HubSpot",{cwd:xS(t.themePath,".."),timeout:18e4});p(e,200,{ok:!0,jobId:s,fixes:n})}catch(n){p(e,500,{error:String(n)})}}function yp(e,t){W(e,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Sc(s,o,i),L(),p(t,200,{ok:!0})}catch(s){p(t,400,{error:String(s)})}})}function bp(e,t){W(e,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){p(t,400,{error:"url is required"});return}let o=gl(s),i=o.components.map(a=>`- ${a.name}: ${a.description}`).join(`
|
|
2743
2743
|
`),r={sourceDir:o.sourceDir,componentCount:o.components.length,components:o.components.map(a=>({name:a.name,description:a.description})),hasTailwind:o.hasTailwind,cssVarCount:o.cssVarCount,fonts:o.fonts,interactions:o.interactions,conversionPrompt:`Import and convert the React landing page from ${s} to native HubSpot modules.
|
|
2744
2744
|
|
|
2745
2745
|
Source analysis found ${o.components.length} components:
|
|
@@ -2749,19 +2749,19 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
|
|
|
2749
2749
|
Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
|
|
2750
2750
|
Interactions: ${o.interactions.join(", ")}
|
|
2751
2751
|
|
|
2752
|
-
Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};p(t,200,r)}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function fp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}if(!rt()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?lc(n.themePath,o,50):ac(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function hp(e,t){W(e,n=>{try{let s=C();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(lt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let r=s.templates.find(c=>c.id===i);if(!r){p(t,404,{error:"Template not found"});return}let a=r.moduleOrder.map(c=>`modules/${c}.module`);r.templateFile&&a.push(r.templateFile);let l=dc(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}Bc()}else{let r=cc(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}Jc()}L(),p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var yp=N(()=>{"use strict";y();Xe();Ce();Ao();oi();co();In()});import{writeFileSync as yS,mkdirSync as Sp}from"fs";import{join as hi}from"path";import{randomUUID as bS}from"crypto";function vp(e){let t=e.match(SS);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 bi(e,t){let n=await fetch(`${vS}${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 xa(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=bp.length)throw s;let r=bp[n];E.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 mn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)mn(s,t,n+1)}function xp(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=xp(n,t);if(s)return s}return null}function xS(e,t){if(t){let s=xp(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 yi(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 wS(e){let t=new Map;for(let n of e)mn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=yi(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=yi(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 CS(e){let t=new Map;for(let n of e)mn(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 kS(e){let t=[],n=new Set;for(let s of e)mn(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 TS(e){let t=[],n=new Set;for(let s of e)mn(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 AS(e,t){let n=[];return mn(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 _S(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 $S(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return yi(t.color)}if(e.backgroundColor)return yi(e.backgroundColor)}function ES(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:AS(t,t.name),children:(t.children||[]).slice(0,20).map(_S),backgroundColor:$S(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 MS(e){let t=[];for(let n of e)mn(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 wp(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());yS(t,s)}async function IS(e,t,n,s,o){if(t.length===0)return new Map;Sp(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await xa(()=>bi(`/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=hi(s,`frame-${u}.png`);try{await wp(d,m),l.set(c,m),E.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){E.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function PS(e,t,n,s,o){if(t.length===0)return[];Sp(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 xa(()=>bi(`/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()}-${bS().slice(0,6)}.png`,f=hi(s,h);try{await wp(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),E.info("figma",`Downloaded asset: ${h}`)}catch(b){E.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function Cp(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 xa(()=>bi(i,n),o);E.info("figma",`Fetched file: ${r.name}`);let a=xS(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.");E.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:wS(a),typography:CS(a),spacing:kS(a),effects:TS(a)};E.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=ES(a),d=hi(s,".vibespot","figma-frames"),u=await IS(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=MS(a),h=hi(s,"assets"),f=await PS(e,g,n,h,o);return E.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 kp(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 Tp(e){return await bi("/v1/me",e)}var SS,vS,bp,va,Ap=N(()=>{"use strict";y();le();SS=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;vS="https://api.figma.com",bp=[10,20,40,60,120];va=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var Pp={};Ge(Pp,{getCachedExtraction:()=>Ip,handleFigmaExtractRoute:()=>Ca,handleFigmaGenerateRoute:()=>ka,handleFigmaTestTokenRoute:()=>wa});import{randomUUID as _p}from"crypto";import{existsSync as $p,mkdirSync as Ep,writeFileSync as NS,copyFileSync as RS}from"fs";import{join as Si,basename as OS}from"path";function Mp(){let e=Date.now();for(let[t,n]of Ls)n.expires<e&&Ls.delete(t)}function Ip(e){Mp();let t=Ls.get(e);return t?(Ls.delete(e),t.extraction):null}function wa(e,t){qe(e,t,async n=>{let s=n.token||R().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Tp(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);E.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function Ca(e,t){qe(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||R().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=vp(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=C()?.themePath||`/tmp/vibespot-figma-${_p().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)}
|
|
2752
|
+
Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};p(t,200,r)}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}function Sp(e,t){let n=C();if(!n){p(t,404,{error:"No active session"});return}if(!rt()){p(t,200,{available:!1,commits:[]});return}let o=new URL(e.url||"/","http://localhost").searchParams.get("templateId"),i=o?dc(n.themePath,o,50):cc(n.themePath,50);p(t,200,{available:!0,commits:i,filtered:!!o})}function vp(e,t){W(e,n=>{try{let s=C();if(!s){p(t,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){p(t,400,{error:"Commit hash is required"});return}if(lt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let r=s.templates.find(c=>c.id===i);if(!r){p(t,404,{error:"Template not found"});return}let a=r.moduleOrder.map(c=>`modules/${c}.module`);r.templateFile&&a.push(r.templateFile);let l=mc(s.themePath,i,o,a);if(!l.success){p(t,500,{error:l.error||"Rollback failed"});return}Uc()}else{let r=uc(s.themePath,o);if(!r.success){p(t,500,{error:r.error||"Rollback failed"});return}Hc()}L(),p(t,200,{ok:!0,modules:ve().map(r=>r.moduleName)})}catch(s){p(t,500,{error:s instanceof Error?s.message:String(s)})}})}var xp=N(()=>{"use strict";y();Xe();Ce();_o();ii();mo();Pn()});import{writeFileSync as wS,mkdirSync as Cp}from"fs";import{join as yi}from"path";import{randomUUID as CS}from"crypto";function kp(e){let t=e.match(kS);if(!t)return null;let n=t[1],s=t[2]?decodeURIComponent(t[2].replace(/-/g," ")):void 0,o;try{let r=new URL(e).searchParams.get("node-id");r&&(o=r.replace(/-/g,":"))}catch{}return{fileKey:n,nodeId:o,fileName:s}}async function Si(e,t){let n=await fetch(`${TS}${e}`,{headers:{"X-Figma-Token":t}});if(!n.ok){let s=await n.text().catch(()=>""),o=new Error(`Figma API ${n.status}: ${s.slice(0,200)}`);throw o.status=n.status,o}return n.json()}async function wa(e,t){for(let n=0;;n++)try{return await e()}catch(s){if(!(s.status===429)||n>=wp.length)throw s;let r=wp[n];M.warn("figma",`Rate limited (429), attempt ${n+1} \u2014 waiting ${r}s`),t&&t(`Figma rate limited \u2014 retrying in ${r}s...`),await new Promise(a=>setTimeout(a,r*1e3))}}function gn(e,t,n=0){if(t(e,n),e.children)for(let s of e.children)gn(s,t,n+1)}function Tp(e,t){if(e.id===t)return e;if(e.children)for(let n of e.children){let s=Tp(n,t);if(s)return s}return null}function AS(e,t){if(t){let s=Tp(e,t);if(!s)return[];if(s.type==="FRAME"||s.type==="COMPONENT"||s.type==="COMPONENT_SET"){let o=(s.children||[]).filter(i=>xa.has(i.type));return o.length>0?o:[s]}return s.children?s.children.filter(o=>xa.has(o.type)):[]}let n=e.children?.[0];return n?.children?n.children.filter(s=>xa.has(s.type)):[]}function bi(e){let t=Math.round(e.r*255),n=Math.round(e.g*255),s=Math.round(e.b*255);return`#${t.toString(16).padStart(2,"0")}${n.toString(16).padStart(2,"0")}${s.toString(16).padStart(2,"0")}`}function _S(e){let t=new Map;for(let n of e)gn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="SOLID"&&o.color){let i=bi(o.color),r=t.get(i),a=s.type==="TEXT",l=a?"text":"fill";r?(r.occurrences++,a&&r.usage!=="text"&&(r.usage="text")):t.set(i,{hex:i,opacity:o.opacity??o.color.a,occurrences:1,usage:l})}}if(s.strokes){for(let o of s.strokes)if(o.type==="SOLID"&&o.color){let i=bi(o.color),r=t.get(i);r?r.occurrences++:t.set(i,{hex:i,opacity:1,occurrences:1,usage:"border"})}}});return[...t.values()].sort((n,s)=>s.occurrences-n.occurrences)}function $S(e){let t=new Map;for(let n of e)gn(n,s=>{if(s.type!=="TEXT"||!s.style)return;let o=s.style,i=o.fontSize||16,r=o.fontWeight||400,a=o.lineHeightPx?Math.round(o.lineHeightPx/i*100)/100:1.5,l=o.letterSpacing||0,c=o.fontFamily||"sans-serif",d="body";i>=32?d="heading":i>=20?d="subheading":i<=12?d="caption":r>=600&&i<=14&&(d="label");let u=`${c}-${i}-${r}`,m=t.get(u);m?m.occurrences++:t.set(u,{fontFamily:c,fontSize:i,fontWeight:r,lineHeight:a,letterSpacing:l,role:d,occurrences:1})});return[...t.values()].sort((n,s)=>s.fontSize-n.fontSize)}function ES(e){let t=[],n=new Set;for(let s of e)gn(s,o=>{if(!o.layoutMode||o.layoutMode==="NONE")return;if(o.itemSpacing&&o.itemSpacing>0){let c=`gap-${o.itemSpacing}-${o.name}`;n.has(c)||(n.add(c),t.push({context:`${o.name} gap`,value:o.itemSpacing,type:"gap"}))}let i=o.paddingTop||0,r=o.paddingRight||0,a=o.paddingBottom||0,l=o.paddingLeft||0;if(i>0||r>0||a>0||l>0){let c=`pad-${i}-${r}-${a}-${l}-${o.name}`;if(!n.has(c)){n.add(c);let d=i===a&&l===r&&i===l?i:Math.max(i,r,a,l);t.push({context:`${o.name} padding`,value:d,type:"padding"})}}});return t}function MS(e){let t=[],n=new Set;for(let s of e)gn(s,o=>{if(o.effects){for(let i of o.effects)if(i.type==="DROP_SHADOW"&&i.color&&i.offset){let{r,g:a,b:l,a:c}=i.color,d=`${i.offset.x}px ${i.offset.y}px ${i.radius||0}px rgba(${Math.round(r*255)},${Math.round(a*255)},${Math.round(l*255)},${Math.round(c*100)/100})`;n.has(d)||(n.add(d),t.push({type:"shadow",cssValue:d,context:o.name}))}}if(o.cornerRadius&&o.cornerRadius>0){let i=`${o.cornerRadius}px`;n.has(`radius-${i}`)||(n.add(`radius-${i}`),t.push({type:"radius",cssValue:i,context:o.name}))}});return t}function IS(e,t){let n=[];return gn(e,s=>{if(s.type!=="TEXT"||!s.characters?.trim())return;let o=s.style?.fontSize||16,i=s.style?.fontWeight||400,r="body";o>=32?r="headline":o>=20?r="subheadline":o<=12?r="caption":i>=600&&o<=16&&(r="label"),i>=600&&s.characters.length<40&&o>=14&&o<32&&(r="cta"),n.push({text:s.characters,fontSize:o,fontWeight:i,role:r,sectionName:t})}),n}function PS(e){let t=e.absoluteBoundingBox;return{name:e.name,type:e.type,nodeId:e.id,width:t?.width||0,height:t?.height||0,layoutMode:e.layoutMode==="NONE"?void 0:e.layoutMode,childCount:e.children?.length||0,characters:e.type==="TEXT"?e.characters:void 0}}function NS(e){if(e.fills){for(let t of e.fills)if(t.type==="SOLID"&&t.color)return bi(t.color)}if(e.backgroundColor)return bi(e.backgroundColor)}function RS(e){return e.map(t=>{let n=t.absoluteBoundingBox;return{name:t.name,nodeId:t.id,width:n?.width||0,height:n?.height||0,textContent:IS(t,t.name),children:(t.children||[]).slice(0,20).map(PS),backgroundColor:NS(t),layoutMode:t.layoutMode==="NONE"?void 0:t.layoutMode,itemSpacing:t.itemSpacing,paddingTop:t.paddingTop,paddingRight:t.paddingRight,paddingBottom:t.paddingBottom,paddingLeft:t.paddingLeft}})}function OS(e){let t=[];for(let n of e)gn(n,s=>{if(s.fills){for(let o of s.fills)if(o.type==="IMAGE"&&o.imageRef){t.push({nodeId:s.id,name:s.name||"image"});break}}});return t}async function Ap(e,t){let n=await fetch(e);if(!n.ok)throw new Error(`Failed to download image: ${n.status}`);let s=Buffer.from(await n.arrayBuffer());wS(t,s)}async function FS(e,t,n,s,o){if(t.length===0)return new Map;Cp(s,{recursive:!0});let r=t.map(c=>c.id).join(",");o&&o("Exporting frame screenshots...");let a=await wa(()=>Si(`/v1/images/${e}?ids=${r}&format=png&scale=2`,n),o),l=new Map;for(let[c,d]of Object.entries(a.images)){if(!d)continue;let u=c.replace(/:/g,"-"),m=yi(s,`frame-${u}.png`);try{await Ap(d,m),l.set(c,m),M.info("figma",`Downloaded frame screenshot: ${m}`)}catch(g){M.warn("figma",`Failed to download frame ${c}: ${g}`)}}return l}async function DS(e,t,n,s,o){if(t.length===0)return[];Cp(s,{recursive:!0});let i=50,r=[];for(let a=0;a<t.length;a+=i){let l=t.slice(a,a+i),c=l.map(u=>u.nodeId).join(",");o&&o(`Exporting images (${a+1}-${Math.min(a+i,t.length)} of ${t.length})...`);let d=await wa(()=>Si(`/v1/images/${e}?ids=${c}&format=png&scale=2`,n),o);for(let u of l){let m=d.images[u.nodeId];if(!m)continue;let h=`${u.name.replace(/[^a-zA-Z0-9-_]/g,"-").toLowerCase()}-${CS().slice(0,6)}.png`,f=yi(s,h);try{await Ap(m,f),r.push({name:u.name,localPath:f,nodeId:u.nodeId,format:"png"}),M.info("figma",`Downloaded asset: ${h}`)}catch(b){M.warn("figma",`Failed to download image ${u.name}: ${b}`)}}}return r}async function _p(e,t,n,s,o){o&&o("Fetching Figma file...");let i=t?`/v1/files/${e}?ids=${t}&geometry=paths`:`/v1/files/${e}?geometry=paths`,r=await wa(()=>Si(i,n),o);M.info("figma",`Fetched file: ${r.name}`);let a=AS(r.document,t);if(a.length===0)throw new Error("No frames found in the Figma file. The file may be empty or structured differently.");M.info("figma",`Found ${a.length} top-level frames`),o&&o(`Found ${a.length} sections. Extracting design tokens...`);let l={colors:_S(a),typography:$S(a),spacing:ES(a),effects:MS(a)};M.info("figma","Design tokens extracted",{colors:l.colors.length,typography:l.typography.length,spacing:l.spacing.length,effects:l.effects.length}),o&&o("Mapping page structure...");let c=RS(a),d=yi(s,".vibespot","figma-frames"),u=await FS(e,a,n,d,o),m=c.map(b=>({...b,frameImagePath:u.get(b.nodeId)||""}));o&&o("Extracting image assets...");let g=OS(a),h=yi(s,"assets"),f=await DS(e,g,n,h,o);return M.info("figma",`Extraction complete: ${m.length} sections, ${f.length} assets`),{fileName:r.name,fileUrl:`https://www.figma.com/design/${e}`,designTokens:l,sections:m,assets:f}}function $p(e){let t=e.fileName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"").slice(0,30);return{fileName:e.fileName,fileUrl:e.fileUrl,sectionNames:e.sections.map(n=>n.name),sectionCount:e.sections.length,colorPalette:e.designTokens.colors.slice(0,10).map(n=>n.hex),fontFamilies:[...new Set(e.designTokens.typography.map(n=>n.fontFamily))],textBlockCount:e.sections.reduce((n,s)=>n+s.textContent.length,0),assetCount:e.assets.length,suggestedThemeName:t}}async function Ep(e){return await Si("/v1/me",e)}var kS,TS,wp,xa,Mp=N(()=>{"use strict";y();le();kS=/figma\.com\/(?:design|file|proto)\/([a-zA-Z0-9]+)(?:\/([^?]*))?/;TS="https://api.figma.com",wp=[10,20,40,60,120];xa=new Set(["FRAME","COMPONENT","COMPONENT_SET","SECTION"])});var Fp={};Ge(Fp,{getCachedExtraction:()=>Op,handleFigmaExtractRoute:()=>ka,handleFigmaGenerateRoute:()=>Ta,handleFigmaTestTokenRoute:()=>Ca});import{randomUUID as Ip}from"crypto";import{existsSync as Pp,mkdirSync as Np,writeFileSync as jS,copyFileSync as LS}from"fs";import{join as vi,basename as JS}from"path";function Rp(){let e=Date.now();for(let[t,n]of Bs)n.expires<e&&Bs.delete(t)}function Op(e){Rp();let t=Bs.get(e);return t?(Bs.delete(e),t.extraction):null}function Ca(e,t){qe(e,t,async n=>{let s=n.token||R().figmaToken;if(!s){p(t,400,{ok:!1,error:"No Figma token provided"});return}try{let o=await Ep(s);p(t,200,{ok:!0,user:o})}catch(o){let i=o instanceof Error?o.message:String(o);M.warn("figma",`Token test failed: ${i}`),p(t,200,{ok:!1,error:"Invalid or expired Figma token"})}})}function ka(e,t){qe(e,t,async n=>{let s=n.url;if(!s){p(t,400,{error:"Missing 'url' field"});return}let o=n.token||R().figmaToken;if(!o){p(t,400,{error:"No Figma token configured. Add one in Settings."});return}let i=kp(s);if(!i){p(t,400,{error:"Not a valid Figma URL. Expected: figma.com/design/<key>/..."});return}let a=C()?.themePath||`/tmp/vibespot-figma-${Ip().slice(0,8)}`;t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
|
|
2753
2753
|
|
|
2754
|
-
`)};try{let c=await
|
|
2755
|
-
`)}function
|
|
2754
|
+
`)};try{let c=await _p(i.fileKey,i.nodeId,o,a,m=>l({type:"progress",message:m})),d=Ip();Rp(),Bs.set(d,{extraction:c,expires:Date.now()+BS});let u=$p(c);l({type:"complete",ok:!0,extractionId:d,summary:u})}catch(c){let d=c instanceof Error?c.message:String(c);M.error("figma",`Extraction failed: ${d}`);let u=d;d.includes("403")?u="Cannot access this file. Check sharing permissions and your token.":d.includes("404")?u="Figma file not found. Check the URL.":d.includes("429")&&(u="Figma rate limited. Try again in a minute."),l({type:"complete",ok:!1,error:u})}t.end()})}function HS(e){let{designTokens:t,fileName:n}=e,s=[`# Styleguide \u2014 ${n}`,""];if(t.colors.length>0){s.push("## Colors","");let o=[...t.colors].sort((a,l)=>l.occurrences-a.occurrences),i=o[0],r=o[1];i&&s.push(`- **Primary:** \`${i.hex}\` (${i.variableName||"dominant color"})`),r&&s.push(`- **Secondary:** \`${r.hex}\` (${r.variableName||"accent color"})`),s.push(""),s.push("### Full palette","");for(let a of o.slice(0,15)){let l=a.variableName?`${a.variableName}`:`${a.occurrences}\xD7 used`;s.push(`- \`${a.hex}\` \u2014 ${l}`)}s.push("")}if(t.typography.length>0){s.push("## Typography","");let o=[...new Set(t.typography.map(r=>r.fontFamily))];s.push(`**Font families:** ${o.join(", ")}`,""),s.push("| Role | Family | Size | Weight |"),s.push("|------|--------|------|--------|");let i=new Set;for(let r of t.typography){let a=`${r.role}-${r.fontSize}-${r.fontWeight}`;i.has(a)||(i.add(a),s.push(`| ${r.role} | ${r.fontFamily} | ${r.fontSize}px | ${r.fontWeight} |`))}s.push("")}if(t.spacing.length>0){s.push("## Spacing","");let o=[...new Set(t.spacing.map(i=>i.value))].sort((i,r)=>i-r);s.push(`**Scale:** ${o.join("px, ")}px`,"");for(let i of t.spacing)s.push(`- **${i.type}** (${i.context}): ${i.value}px`);s.push("")}if(t.effects.length>0){s.push("## Effects","");for(let o of t.effects)o.type==="shadow"?s.push(`- **Box shadow** (${o.context}): \`${o.cssValue}\``):o.type==="radius"?s.push(`- **Border radius** (${o.context}): ${o.cssValue}`):o.type==="blur"&&s.push(`- **Blur** (${o.context}): ${o.cssValue}`);s.push("")}return s.join(`
|
|
2755
|
+
`)}function Ta(e,t){qe(e,t,async n=>{let s=n.extractionId,o=n.themeName,i=n.useAssets!==!1;if(!s||!o){p(t,400,{error:"Missing extractionId or themeName"});return}let r=Op(s);if(!r){p(t,400,{error:"Extraction expired or not found. Please re-extract."});return}let a=C();if(!a){p(t,400,{error:"No active session. Create a theme first."});return}t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});let l=c=>{t.write(`data: ${JSON.stringify(c)}
|
|
2756
2756
|
|
|
2757
|
-
`)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=
|
|
2758
|
-
`)}function
|
|
2759
|
-
`),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=q(r,"fields.json");if(x(c))try{let d=JSON.parse(P(c));if(Array.isArray(d)){let u=
|
|
2760
|
-
`),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=qS(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function qS(e){let t=[],n=/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,s=/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,o=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*><\/script>/gi,i=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*\/>/gi;function r(c){let d;try{d=P(c)}catch{return}let u=d.replace(n,"");u!==d&&(B(c,u),t.push(mt(e,c)))}function a(c){let d;try{d=P(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(B(c,u),t.push(mt(e,c)))}vi(q(e,"css"),".css").forEach(r);let l=q(e,"modules");if(x(l))for(let c of Bs(l)){if(!c.endsWith(".module"))continue;let d=q(l,c),u=q(d,"module.css"),m=q(d,"module.html");x(u)&&r(u),x(m)&&a(m)}return t}function Op(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!kt(s,"label")&&kt(s,"name")&&(s.label=Dp(String(s.name)),t++),Array.isArray(s.children)&&(t+=Op(s.children))}return t}function _a(e){if(!x(e))return null;try{let t=JSON.parse(P(e));return t&&typeof t=="object"?t:null}catch{return null}}function kt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Fp(e,t){let n=t.replace(/^\.?\//,"");return q(e,n)}function mt(e,t){return LS(e,t).split("\\").join("/")}function Bs(e){try{return $a(e)}catch{return[]}}function vi(e,t){if(!x(e))return[];try{let n=[];for(let s of $a(e)){let o=q(e,s);jS(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Dp(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var Yt,JS,BS,Ft,Ea=N(()=>{"use strict";y();oe();Yt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],JS=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],BS=["enable_domain_stylesheets","is_available_for_new_content"],Ft="marketplace.json"});function Ma(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Te()}catch{}return t.themePath}function jp(e,t){let n=Ma(t);if(!n)return;let s=Js(n);p(t,200,{report:s,categories:Yt})}function Lp(e,t){let n=Ma(t);if(!n)return;let s=wi(n),o=Js(n);p(t,200,{fix:s,report:o})}function Jp(e,t,n){let s=Ma(n);if(s){if(e==="GET"){p(n,200,{metadata:Yn(s),categories:Yt});return}if(e==="POST"){qe(t,n,o=>{let i={category:typeof o.category=="string"?o.category:void 0,description:typeof o.description=="string"?o.description:void 0,features:Array.isArray(o.features)?o.features.filter(r=>typeof r=="string"&&r.trim().length>0):void 0,supportUrl:typeof o.supportUrl=="string"?o.supportUrl:void 0,documentationUrl:typeof o.documentationUrl=="string"?o.documentationUrl:void 0,pricingTier:o.pricingTier==="free"||o.pricingTier==="paid"?o.pricingTier:void 0,tags:Array.isArray(o.tags)?o.tags.filter(r=>typeof r=="string"):void 0};xi(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Bp=N(()=>{"use strict";y();Xe();Ce();Ea()});function XS(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Te()}catch{}return t.themePath}function Hp(e,t){let n=XS(t);if(!n)return;let s=Jo(n);p(t,200,{report:s})}function Up(e,t){let n=C();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=Fn(n.themePath),o=fs(s);if(!o){p(t,200,{applied:!1,reason:"No tokens to apply."});return}if(!n.sharedCss||n.sharedCss.trim().length===0){n.sharedCss=o,n.updatedAt=Date.now(),L(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=Bo(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 Gp=N(()=>{"use strict";y();Xe();Ce();Ho()});import{createServer as ZS}from"http";import{readFileSync as Na,existsSync as Hs}from"fs";import{join as jt,extname as Kp}from"path";import{WebSocketServer as QS,WebSocket as ev}from"ws";function Ae(e){ki&&ki.readyState===ev.OPEN&&ki.send(JSON.stringify(e))}function Ci(e){Ti.push(e),Ae(e)}function Dt(){Ti=[]}function Ia(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;Ci(o)}else Ci(n);if(n.type==="agent_step")e.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=e[e.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Ht(n.moduleOrder),Ci({type:"modules_updated",modules:ve().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(He({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),Ci({type:"modules_updated",modules:ve().map(s=>s.moduleName)}),t.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&t.push({name:n.module,status:"failed"})}}function Pa(e){let t=e.cost;if(!t||t.calls===0)return;let n=C();Ae({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}function Ln(){return zp}function Ai(e){let{port:t,uiDir:n}=e;zp=e.contentMode||"page";let s=ZS((i,r)=>tv(i,r,n)),o=new QS({server:s});return o.on("connection",i=>sv(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 tv(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/")){nv(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=xr();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=wr(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){ov(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";Wp(i,jt(n,"docs"),e,t);return}Wp(s.pathname,n,e,t)}function nv(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":lp(e,s);break;case"/api/modules":cp(e,n,s);break;case"/api/modules/reorder":up(n,s);break;case"/api/modules/code":dp(n,s);break;case"/api/upload":mp(s);break;case"/api/upload-files":e==="POST"?pd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":pp(n,s);break;case"/api/import":gp(n,s);break;case"/api/setup":Qu(s);break;case"/api/setup/create":em(n,s);break;case"/api/setup/fetch":nm(n,s);break;case"/api/setup/open":sm(n,s);break;case"/api/setup/resume":om(n,s);break;case"/api/setup/apikey":im(n,s);break;case"/api/setup/remote-themes":e==="GET"?rm(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?tm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?gm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/models":e==="GET"?fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/tools":e==="GET"?hm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?ym(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?bm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Sm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?vm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?xm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?wm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?Cm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?km(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Am(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Mm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Im(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Pm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?_m(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Ga()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":Rm(e,n,s);break;case"/api/themes/switch":e==="POST"?Om(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Dm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?jm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?fp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Wm(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":zm(e,n,s);break;case"/api/templates/activate":e==="POST"?Ym(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?qm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?Zm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?Xm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?Qm(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":tp(e,n,s);break;case"/api/brand-kit":op(e,n,s);break;case"/api/fonts":e==="GET"?sp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?ip(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?rp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Vm(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?wa(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?Ca(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?ka(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Mu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Iu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Pu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?Nu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?jp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?Lp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Jp(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Up(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?$m(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?ep(t,n,s):p(s,404,{error:"Not found"})}}function sv(e){e.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{e.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;let i=Array.isArray(s.fileIds)?s.fileIds:void 0;if(oa()){lt("user",o),L();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await sa(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=Ou(l||a);c.plan&&(ti(c.plan),e.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&e.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),lt("assistant",c.cleanedContent),L(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(a){e.send(JSON.stringify({type:"error",message:a instanceof Error?a.message:String(a)}))}break}lt("user",o),L();let r=ia();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Dt();let l=[],c=[],d=await Qo(o,Ia(l,c),i);cn(d,{steps:l,modules:c,stats:d.stats,cost:d.cost}),Pa(d)}else ta(l=>{Ae({type:"parse_warning",message:l})}),await Ns(o,l=>{Ae({type:"stream",content:l})},l=>{Ae({type:"stream_status",content:l})},i);let a=C();if(a){Te();let l=ke(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${a.themeName}-theme.css`),l.sharedJs&&d.push(`js/${a.themeName}-animations.js`),c=or(a.themePath,l.id,o,d)}else c=sn(a.themePath,o);c&&Ae({type:"version_created",hash:c})}Ae({type:"generation_complete"});{let l=C();Ae({type:"modules_updated",modules:ve().map(c=>c.moduleName),templateId:l?.activeTemplateId||null,templates:(l?.templates||[]).map(c=>({id:c.id,label:c.label,pageType:c.pageType,moduleCount:c.modules.length}))})}Dt();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Ae({type:"suggest_brand_extraction"})}}catch(a){Dt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:r}=await Promise.resolve().then(()=>(Ta(),Pp)),a=r(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=C();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:h}=await import("fs"),{createThemeScaffold:f}=await Promise.resolve().then(()=>(is(),gl)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!h(b)){let{mkdirSync:v}=await import("fs");v(b,{recursive:!0})}h(S)||f(S,i),Rn(S,i),L()}Ae({type:"figma_import_started",fileName:a.fileName}),Dt();let c=[],d=[],u=await Rs(a,i,Ia(c,d));cn(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),Pa(u),Te(),sn(C().themePath,`Figma import: ${a.fileName}`),Ae({type:"generation_complete"});{let m=C();Ae({type:"modules_updated",modules:ve().map(g=>g.moduleName),templateId:m?.activeTemplateId||null,templates:(m?.templates||[]).map(g=>({id:g.id,label:g.label,pageType:g.pageType,moduleCount:g.modules.length}))})}Dt()}catch(l){Dt(),Ae({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=R(),{engine:r,apiKey:a,model:l}=Gn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Ss(),Go)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(di(),ci)),m=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>te("extract-theme-context",()=>u(d,o.brandAssets?.themeContext,r,a,l))),{mkdirSync:g,writeFileSync:h}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let f=jt(o.themePath,".vibespot");Hs(f)||g(f,{recursive:!0}),h(jt(f,"theme-context.md"),m),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(js(),Ds)),b=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>f(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=jt(o.themePath,".vibespot");Hs(S)||g(S,{recursive:!0}),h(jt(S,"styleguide.md"),b),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Te();let i=To(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(R().hubspotUploadMode||"api")==="api"){let l=Le();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await _o(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
|
|
2757
|
+
`)};try{l({type:"progress",message:"Generating styleguide from design tokens..."});let c=HS(r),d=vi(a.themePath,".vibespot");if(Pp(d)||Np(d,{recursive:!0}),jS(vi(d,"styleguide.md"),c),a.brandAssets||(a.brandAssets={}),a.brandAssets.styleguide=c,L(),l({type:"progress",message:"Styleguide saved."}),a.templates.length===0)Rt("landing_page","Landing Page");else{a.modules=[],a.moduleOrder=[],a.sharedCss="",a.sharedJs="";let f=a.templates.find(b=>b.id===a.activeTemplateId);f&&(f.modules=[],f.moduleOrder=[],f.sharedCss="",f.sharedJs="")}if(L(),i&&r.assets.length>0){let f=vi(a.themePath,"assets");Np(f,{recursive:!0});let b=0;for(let S of r.assets)if(Pp(S.localPath)){let v=vi(f,JS(S.localPath));try{LS(S.localPath,v),S.localPath=v,b++}catch{}}b>0&&l({type:"progress",message:`Copied ${b} image assets to theme.`})}l({type:"progress",message:"Starting AI conversion..."});let u=[],m=[],g=await Fs(r,o,f=>{if(f.type==="agent_step")u.push({step:f.step,label:f.label}),l({type:"progress",message:`${f.label}...`});else if(f.type==="agent_decision"){let b=u[u.length-1];b&&(b.decisions||(b.decisions=[]),b.decisions.push(f.decision)),l({type:"progress",message:` ${f.decision}`})}else f.type==="design_system_ready"?He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}):f.type==="blueprint_ready"?(He({sharedCss:f.sharedCss,sharedJs:f.sharedJs}),Wt(f.moduleOrder),l({type:"progress",message:`Planned ${f.moduleOrder.length} modules`})):f.type==="module_progress"&&(f.status==="generating"?l({type:"progress",message:`Generating module: ${f.module}`}):f.status==="complete"&&f.moduleFiles?(He({modules:[{moduleName:f.module,fieldsJson:f.moduleFiles.fieldsJson,metaJson:f.moduleFiles.metaJson,moduleHtml:f.moduleFiles.moduleHtml,moduleCss:f.moduleFiles.moduleCss,moduleJs:f.moduleFiles.moduleJs}]}),m.push({name:f.module,status:"complete"}),l({type:"progress",message:`Module complete: ${f.module}`})):f.status==="failed"&&(m.push({name:f.module,status:"failed"}),l({type:"progress",message:`Module failed: ${f.module}`})))},{useAssets:i});un(g,{steps:u,modules:m,stats:g.stats}),Te(),rn(a.themePath,`Figma import: ${r.fileName}`);let h=ve().map(f=>f.moduleName);l({type:"progress",message:`Conversion complete \u2014 ${h.length} modules generated`}),l({type:"complete",ok:!0,modules:h})}catch(c){let d=c instanceof Error?c.message:String(c);M.error("figma",`Generate failed: ${d}`),l({type:"complete",ok:!1,error:d})}t.end()})}var Bs,BS,Aa=N(()=>{"use strict";y();Xe();ee();le();Mp();Ce();gs();hr();Pn();Kn();Kt();Bs=new Map,BS=1800*1e3});import{readdirSync as Ea,statSync as US}from"fs";import{join as q,relative as GS}from"path";function qn(e){let t=q(e,Lt);if(!x(t))return null;try{return JSON.parse(P(t))}catch{return null}}function wi(e,t){let n=q(e,Lt);B(n,JSON.stringify(t,null,2)+`
|
|
2758
|
+
`)}function Hs(e){let t=[];if(!x(e))return t.push({severity:"error",rule:"theme.path.missing",message:`Theme directory not found: ${e}`}),_a(e,t,null);let n=$a(q(e,"theme.json"));if(!n)return t.push({severity:"error",rule:"theme.json.missing",file:"theme.json",message:"theme.json is missing or invalid JSON",fix:"Recreate the theme so theme.json is generated, or restore it from version control."}),_a(e,t,qn(e));VS(e,n,t),zS(e,n,t),YS(e,t),XS(e,t),ZS(e,t),QS(e,t);let s=qn(e);return ev(s,t),_a(e,t,s)}function _a(e,t,n){let s=t.filter(r=>r.severity==="error").length,o=t.filter(r=>r.severity==="warning").length,i=t.filter(r=>r.severity==="info").length;return{themePath:e,passed:s===0,errorCount:s,warningCount:o,infoCount:i,findings:t,metadata:n}}function VS(e,t,n){let s={documentation_url:'Add a "documentation_url" entry pointing to public docs for the theme.',license:'Add a "license" entry \u2014 an SPDX identifier or URL (e.g. "MIT").',example_url:'Add an "example_url" entry pointing to a public live preview of the theme.'};for(let r of WS)Tt(t,r)||n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json is missing required field "${r}"`,fix:s[r]??`Add a "${r}" entry to theme.json.`});for(let r of KS)(!(r in t)||typeof t[r]!="boolean")&&n.push({severity:"error",rule:`theme.json.${r}.missing`,file:"theme.json",message:`theme.json must declare boolean "${r}"`,fix:`Add "${r}": true (or false) to theme.json.`});let o=t.author;!o||typeof o!="object"?n.push({severity:"error",rule:"theme.json.author.missing",file:"theme.json",message:'theme.json is missing required "author" block',fix:'Add { "author": { "name": "...", "email": "...", "url": "..." } } to theme.json.'}):(Tt(o,"name")||n.push({severity:"error",rule:"theme.json.author.name.missing",file:"theme.json",message:"theme.json author.name is missing",fix:"Provide a publisher name in theme.json author.name."}),Tt(o,"email")||n.push({severity:"error",rule:"theme.json.author.email.missing",file:"theme.json",message:"theme.json author.email is missing",fix:"Provide a contact email in theme.json author.email."}),Tt(o,"url")||n.push({severity:"error",rule:"theme.json.author.url.missing",file:"theme.json",message:"theme.json author.url is missing",fix:"Add a public URL for the publisher (homepage or support page)."}));let i=t.preview_path;if(typeof i=="string"&&i.length>0){let r=Jp(e,i);x(r)||n.push({severity:"error",rule:"theme.json.preview_path.invalid",file:"theme.json",message:`preview_path "${i}" does not point to an existing file`,fix:"Update preview_path to a real template, e.g. ./templates/home.html."})}}function zS(e,t,n){let s=t.screenshot_path;if(typeof s!="string"||s.length===0)return;let o=Jp(e,s);if(!x(o)){n.push({severity:"error",rule:"theme.json.screenshot.missing",file:"theme.json",message:`Screenshot not found at ${s}`,fix:"Place a 1500\xD71000 PNG at the screenshot_path declared in theme.json."});return}/\.(png|jpg|jpeg)$/i.test(s)||n.push({severity:"warning",rule:"theme.json.screenshot.format",file:s,message:"Screenshot should be a PNG or JPG",fix:"Re-export the screenshot as PNG (1500\xD71000) or JPG."})}function YS(e,t){let n=q(e,"modules");if(!x(n)){t.push({severity:"warning",rule:"modules.empty",message:"Theme has no modules/ directory",fix:"Generate at least one module before submitting to Marketplace."});return}let s=0,o=[];try{o=Ea(n)}catch{return}for(let i of o){if(!i.endsWith(".module"))continue;s++;let r=q(n,i);qS(e,r,i,t)}s===0&&t.push({severity:"warning",rule:"modules.empty",message:"Theme has no .module directories",fix:"Generate at least one module before submitting to Marketplace."})}function qS(e,t,n,s){let o=$a(q(t,"meta.json")),i=mt(e,q(t,"meta.json"));o?(Tt(o,"label")||s.push({severity:"error",rule:"module.meta.label.missing",file:i,message:`${n}: meta.json is missing "label"`,fix:`Add a "label" entry to the module's meta.json.`,autoFixable:!0}),o.is_available_for_new_content===!1&&s.push({severity:"info",rule:"module.meta.unavailable",file:i,message:`${n}: is_available_for_new_content=false (won\u2019t be selectable in HubSpot UI)`})):s.push({severity:"error",rule:"module.meta.missing",file:i,message:`${n}: meta.json is missing or invalid`,fix:"Recreate the module so meta.json is generated."});let r=q(t,"fields.json"),a=mt(e,r);if(!x(r))s.push({severity:"warning",rule:"module.fields.missing",file:a,message:`${n}: fields.json is missing`,fix:"Add a fields.json (an empty array [] is acceptable for static modules)."});else{let c=$a(r);Array.isArray(c)?jp(c,n,a,s):s.push({severity:"warning",rule:"module.fields.invalid",file:a,message:`${n}: fields.json is not a JSON array`})}let l=q(t,"module.html");x(l)||s.push({severity:"error",rule:"module.html.missing",file:mt(e,l),message:`${n}: module.html is missing`,fix:"Recreate the module so module.html is generated."})}function jp(e,t,n,s){for(let o of e){if(typeof o!="object"||o===null)continue;let i=o,r=typeof i.name=="string"?i.name:"(unnamed)";Tt(i,"label")||s.push({severity:"error",rule:"module.field.label.missing",file:n,message:`${t}.${r}: field is missing "label"`,fix:`Add a human-readable "label" to the "${r}" field in fields.json.`,autoFixable:!0}),!Tt(i,"help_text")&&i.type!=="group"&&s.push({severity:"info",rule:"module.field.help_text.missing",file:n,message:`${t}.${r}: consider adding "help_text"`,fix:`Add a short "help_text" describing what "${r}" controls.`}),Array.isArray(i.children)&&jp(i.children,t,n,s)}}function XS(e,t){let n=[],s=q(e,"css");xi(s,".css").forEach(i=>{Dp(i,n,e)});let o=q(e,"modules");if(x(o))for(let i of Us(o)){if(!i.endsWith(".module"))continue;let r=q(o,i);["module.css","module.html"].forEach(a=>{let l=q(r,a);x(l)&&Dp(l,n,e)})}for(let i of n)t.push({severity:"error",rule:"asset.cdn-import",file:i.file,message:`External CDN reference found: ${i.match}`,fix:"Remove external @import / <link> URLs and bundle the asset locally.",autoFixable:!0})}function Dp(e,t,n){let s;try{s=P(e)}catch{return}let o=s.match(/@import\s+url\(['"]?https?:\/\/[^)\s'"]+['"]?\)/i);o&&t.push({file:mt(n,e),match:o[0]});let i=s.match(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/i);i&&t.push({file:mt(n,e),match:i[0]});let r=s.match(/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*>/i);r&&t.push({file:mt(n,e),match:r[0]})}function ZS(e,t){let n=[{rule:"asset.hardcoded.hubfs",re:/https?:\/\/[\w.-]*hubfs[\w.-]*\/(\d+)\//i,message:"Hardcoded portal-specific HubFS URL detected"},{rule:"asset.hardcoded.usercontent",re:/hubspotusercontent[-\w]*\.net\/(\w+\/)?(\d+)\//i,message:"Hardcoded portal-specific HubSpot user-content URL detected"},{rule:"asset.hardcoded.preview",re:/\d+\.hs-sites\.com|hubspotpagebuilder\.com\/\d+/i,message:"Hardcoded portal preview URL detected"}],s=[],o=q(e,"css");xi(o,".css").forEach(a=>s.push(a));let i=q(e,"js");xi(i,".js").forEach(a=>s.push(a));let r=q(e,"modules");if(x(r))for(let a of Us(r))a.endsWith(".module")&&["module.html","module.css","module.js"].forEach(l=>{let c=q(r,a,l);x(c)&&s.push(c)});for(let a of s){let l;try{l=P(a)}catch{continue}for(let c of n){let d=l.match(c.re);d&&t.push({severity:"error",rule:c.rule,file:mt(e,a),message:`${c.message}: ${d[0]}`,fix:"Replace portal-specific URLs with theme-relative paths or HubSpot tokens like get_asset_url."})}}}function QS(e,t){let n=q(e,"modules");if(x(n))for(let s of Us(n)){if(!s.endsWith(".module"))continue;let o=q(n,s,"module.html");if(!x(o))continue;let i;try{i=P(o)}catch{continue}let r=/<img\b([^>]*)>/gi,a;for(;a=r.exec(i);){let c=a[1];/\balt\s*=/.test(c)||t.push({severity:"warning",rule:"a11y.img.alt-missing",file:mt(e,o),message:`${s}: <img> without alt attribute`,fix:'Add an alt attribute (alt="" is fine for purely decorative images).'})}/<(section|article|header|footer|main|nav|aside|h[1-6])\b/i.test(i)||t.push({severity:"info",rule:"a11y.semantics.missing",file:mt(e,o),message:`${s}: module.html has no semantic landmarks (section/article/header/etc.)`,fix:"Wrap the module's main content in a <section> with a heading."})}}function ev(e,t){if(!e){t.push({severity:"warning",rule:"marketplace.json.missing",file:Lt,message:"marketplace.json sidecar not found",fix:"Run `vibespot marketplace edit` (CLI) or open the Marketplace panel in the editor to fill in listing details."});return}e.category?Zt.includes(e.category)||t.push({severity:"warning",rule:"marketplace.json.category.unknown",file:Lt,message:`marketplace.json category "${e.category}" is not a recognized HubSpot Marketplace category`,fix:`Use one of: ${Zt.join(", ")}.`}):t.push({severity:"warning",rule:"marketplace.json.category.missing",file:Lt,message:"marketplace.json has no category",fix:`Pick one of: ${Zt.join(", ")}.`}),(!e.description||e.description.trim().length<40)&&t.push({severity:"warning",rule:"marketplace.json.description.short",file:Lt,message:"marketplace.json description is missing or short (<40 chars)",fix:"Provide a 1\u20132 sentence description of the theme for the Marketplace listing."}),e.supportUrl||t.push({severity:"warning",rule:"marketplace.json.supportUrl.missing",file:Lt,message:"marketplace.json has no supportUrl",fix:"Add a public support URL where buyers can reach the publisher."});let n=e.features?.length??0;n<2?t.push({severity:"warning",rule:"marketplace.json.features.too_few",file:Lt,message:`marketplace.json needs at least 2 features (has ${n})`,fix:"Add 2\u20135 short bullet points highlighting what the theme does well."}):n>5&&t.push({severity:"warning",rule:"marketplace.json.features.too_many",file:Lt,message:`marketplace.json has ${n} features but HubSpot allows at most 5`,fix:"Trim the features list to 5 or fewer entries."})}function Ci(e){let t=[],n=[],s=q(e,"modules");if(x(s))for(let i of Us(s)){if(!i.endsWith(".module"))continue;let r=q(s,i),a=i.replace(/\.module$/,""),l=q(r,"meta.json");if(x(l))try{let d=JSON.parse(P(l));Tt(d,"label")||(d.label=Bp(a),B(l,JSON.stringify(d,null,2)+`
|
|
2759
|
+
`),t.push(`${i}: filled meta.label = "${d.label}"`))}catch{n.push(`${i}: meta.json could not be parsed`)}let c=q(r,"fields.json");if(x(c))try{let d=JSON.parse(P(c));if(Array.isArray(d)){let u=Lp(d);u>0&&(B(c,JSON.stringify(d,null,2)+`
|
|
2760
|
+
`),t.push(`${i}: filled ${u} missing field label(s)`))}}catch{n.push(`${i}: fields.json could not be parsed`)}}let o=tv(e);for(let i of o)t.push(`${i}: stripped external CDN reference(s)`);return{applied:t,skipped:n}}function tv(e){let t=[],n=/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,s=/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,o=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*><\/script>/gi,i=/<script[^>]+src=['"]https?:\/\/[^'"]+['"][^>]*\/>/gi;function r(c){let d;try{d=P(c)}catch{return}let u=d.replace(n,"");u!==d&&(B(c,u),t.push(mt(e,c)))}function a(c){let d;try{d=P(c)}catch{return}let u=d.replace(s,"");u=u.replace(o,""),u=u.replace(i,""),u=u.replace(n,""),u!==d&&(B(c,u),t.push(mt(e,c)))}xi(q(e,"css"),".css").forEach(r);let l=q(e,"modules");if(x(l))for(let c of Us(l)){if(!c.endsWith(".module"))continue;let d=q(l,c),u=q(d,"module.css"),m=q(d,"module.html");x(u)&&r(u),x(m)&&a(m)}return t}function Lp(e){let t=0;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;!Tt(s,"label")&&Tt(s,"name")&&(s.label=Bp(String(s.name)),t++),Array.isArray(s.children)&&(t+=Lp(s.children))}return t}function $a(e){if(!x(e))return null;try{let t=JSON.parse(P(e));return t&&typeof t=="object"?t:null}catch{return null}}function Tt(e,t){let n=e[t];return typeof n=="string"?n.trim().length>0:Array.isArray(n)?n.length>0:n!=null&&n!==""}function Jp(e,t){let n=t.replace(/^\.?\//,"");return q(e,n)}function mt(e,t){return GS(e,t).split("\\").join("/")}function Us(e){try{return Ea(e)}catch{return[]}}function xi(e,t){if(!x(e))return[];try{let n=[];for(let s of Ea(e)){let o=q(e,s);US(o).isFile()&&s.endsWith(t)&&n.push(o)}return n}catch{return[]}}function Bp(e){return e.replace(/[-_]+/g," ").split(" ").filter(Boolean).map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}var Zt,WS,KS,Lt,Ma=N(()=>{"use strict";y();oe();Zt=["Business Services","Education","Events","Health & Wellness","Hospitality","Marketing & SEO","Non-profit","Portfolio","Real Estate","Restaurant & Food","Retail & E-commerce","SaaS & Technology","Travel","Other"],WS=["label","preview_path","screenshot_path","version","documentation_url","license","example_url"],KS=["enable_domain_stylesheets","is_available_for_new_content"],Lt="marketplace.json"});function Ia(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or create a theme first."}),null;try{Te()}catch{}return t.themePath}function Hp(e,t){let n=Ia(t);if(!n)return;let s=Hs(n);p(t,200,{report:s,categories:Zt})}function Up(e,t){let n=Ia(t);if(!n)return;let s=Ci(n),o=Hs(n);p(t,200,{fix:s,report:o})}function Gp(e,t,n){let s=Ia(n);if(s){if(e==="GET"){p(n,200,{metadata:qn(s),categories:Zt});return}if(e==="POST"){qe(t,n,o=>{let i={category:typeof o.category=="string"?o.category:void 0,description:typeof o.description=="string"?o.description:void 0,features:Array.isArray(o.features)?o.features.filter(r=>typeof r=="string"&&r.trim().length>0):void 0,supportUrl:typeof o.supportUrl=="string"?o.supportUrl:void 0,documentationUrl:typeof o.documentationUrl=="string"?o.documentationUrl:void 0,pricingTier:o.pricingTier==="free"||o.pricingTier==="paid"?o.pricingTier:void 0,tags:Array.isArray(o.tags)?o.tags.filter(r=>typeof r=="string"):void 0};wi(s,i),p(n,200,{ok:!0,metadata:i})});return}p(n,405,{error:"Method not allowed"})}}var Wp=N(()=>{"use strict";y();Xe();Ce();Ma()});function nv(e){let t=C();if(!t)return p(e,400,{error:"No active theme. Open or fetch a theme first."}),null;try{Te()}catch{}return t.themePath}function Kp(e,t){let n=nv(t);if(!n)return;let s=Bo(n);p(t,200,{report:s})}function Vp(e,t){let n=C();if(!n){p(t,400,{error:"No active theme. Open or fetch a theme first."});return}let s=Dn(n.themePath),o=bs(s);if(!o){p(t,200,{applied:!1,reason:"No tokens to apply."});return}if(!n.sharedCss||n.sharedCss.trim().length===0){n.sharedCss=o,n.updatedAt=Date.now(),L(),p(t,200,{applied:!0,written:"session.sharedCss",rootBlock:o});return}let i=Ho(n.themePath,n.themeName);i?p(t,200,{applied:!0,written:i,rootBlock:o}):p(t,200,{applied:!1,reason:"Theme already has shared CSS."})}var zp=N(()=>{"use strict";y();Xe();Ce();Uo()});import{createServer as sv}from"http";import{readFileSync as Ra,existsSync as Gs}from"fs";import{join as Bt,extname as qp}from"path";import{WebSocketServer as ov,WebSocket as iv}from"ws";function Ae(e){Ti&&Ti.readyState===iv.OPEN&&Ti.send(JSON.stringify(e))}function ki(e){Ai.push(e),Ae(e)}function Jt(){Ai=[]}function Pa(e,t){return n=>{if(n.type==="module_progress"&&n.moduleFiles){let{moduleFiles:s,...o}=n;ki(o)}else ki(n);if(n.type==="agent_step")e.push({step:n.step,label:n.label});else if(n.type==="agent_decision"){let s=e[e.length-1];s&&(s.decisions||(s.decisions=[]),s.decisions.push(n.decision))}else n.type==="design_system_ready"?He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}):n.type==="blueprint_ready"?(He({sharedCss:n.sharedCss,sharedJs:n.sharedJs}),Wt(n.moduleOrder),ki({type:"modules_updated",modules:ve().map(s=>s.moduleName)})):n.type==="module_progress"&&n.status==="complete"&&n.moduleFiles?(He({modules:[{moduleName:n.module,fieldsJson:n.moduleFiles.fieldsJson,metaJson:n.moduleFiles.metaJson,moduleHtml:n.moduleFiles.moduleHtml,moduleCss:n.moduleFiles.moduleCss,moduleJs:n.moduleFiles.moduleJs}]}),ki({type:"modules_updated",modules:ve().map(s=>s.moduleName)}),t.push({name:n.module,status:"complete"})):n.type==="module_progress"&&n.status==="failed"&&t.push({name:n.module,status:"failed"})}}function Na(e){let t=e.cost;if(!t||t.calls===0)return;let n=C();Ae({type:"generation_cost",cost:t,projectTotal:n?.costTotal})}function Jn(){return Zp}function _i(e){let{port:t,uiDir:n}=e;Zp=e.contentMode||"page";let s=sv((i,r)=>rv(i,r,n)),o=new ov({server:s});return o.on("connection",i=>lv(i)),new Promise((i,r)=>{s.on("error",a=>{a.code==="EADDRINUSE"?s.listen(t+1,"0.0.0.0",()=>{i({port:t+1,close:()=>{s.close(),o.close()}})}):r(a)}),s.listen(t,"0.0.0.0",()=>{i({port:t,close:()=>{s.close(),o.close()}})})})}function rv(e,t,n){let s=new URL(e.url||"/",`http://${e.headers.host}`),o=e.method||"GET";if(t.setHeader("X-Content-Type-Options","nosniff"),t.setHeader("X-Frame-Options","DENY"),t.setHeader("X-XSS-Protection","1; mode=block"),t.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname==="/healthz"){t.writeHead(200,{"Content-Type":"application/json; charset=utf-8"}),t.end(JSON.stringify({status:"ok"}));return}if(s.pathname.startsWith("/api/")){av(o,s.pathname,e,t);return}if(s.pathname==="/preview"){let i=wr();t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",r=Cr(i);t.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),t.end(r||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){cv(s.pathname.slice(14),t);return}if(s.pathname==="/docs"){t.writeHead(301,{Location:"/docs/"}),t.end();return}if(s.pathname.startsWith("/docs/")){let i=s.pathname.slice(5)||"/index.html";Yp(i,Bt(n,"docs"),e,t);return}Yp(s.pathname,n,e,t)}function av(e,t,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1|100\.\d+\.\d+\.\d+|192\.168\.\d+\.\d+|10\.\d+\.\d+\.\d+)(:\d+)?$/.test(o)&&s.setHeader("Access-Control-Allow-Origin",o),s.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type"),e==="OPTIONS"){s.writeHead(204),s.end();return}switch(t){case"/api/session":mp(e,s);break;case"/api/modules":pp(e,n,s);break;case"/api/modules/reorder":fp(n,s);break;case"/api/modules/code":gp(n,s);break;case"/api/upload":hp(s);break;case"/api/upload-files":e==="POST"?fd(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/field":yp(n,s);break;case"/api/import":bp(n,s);break;case"/api/setup":sm(s);break;case"/api/setup/create":om(n,s);break;case"/api/setup/fetch":rm(n,s);break;case"/api/setup/open":am(n,s);break;case"/api/setup/resume":lm(n,s);break;case"/api/setup/apikey":cm(n,s);break;case"/api/setup/remote-themes":e==="GET"?dm(s):p(s,405,{error:"Method not allowed"});break;case"/api/starters":e==="GET"?im(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/status":e==="GET"?bm(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/models":e==="GET"?Sm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/tools":e==="GET"?vm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":e==="POST"?xm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":e==="POST"?wm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/install":e==="POST"?Cm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":e==="POST"?km(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":e==="POST"?Tm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":e==="POST"?Am(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":e==="POST"?_m(s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":e==="POST"?$m(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":e==="POST"?Em(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":e==="POST"?Mm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/save":e==="POST"?Rm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/status":e==="GET"?Om(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings/claude-oauth/logout":e==="POST"?Fm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/settings":e==="POST"?Im(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/changelog":e==="GET"?p(s,200,{changelog:Wa()}):p(s,405,{error:"Method not allowed"});break;case"/api/themes":jm(e,n,s);break;case"/api/themes/switch":e==="POST"?Lm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":e==="POST"?Jm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":e==="POST"?Bm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/themes/duplicate":e==="POST"?Hm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/history":e==="GET"?Sp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/rollback":e==="POST"?vp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/dashboard":e==="GET"?Ym(s):p(s,405,{error:"Method not allowed"});break;case"/api/templates":Zm(e,n,s);break;case"/api/templates/activate":e==="POST"?Qm(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":e==="POST"?ep(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":e==="POST"?np(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/templates/reorder":e==="POST"?tp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/module-library":e==="GET"?sp(s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":ip(e,n,s);break;case"/api/brand-kit":lp(e,n,s);break;case"/api/fonts":e==="GET"?ap(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/extract":e==="POST"?cp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":e==="POST"?dp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/download-zip":e==="GET"?Xm(s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/test-token":e==="POST"?Ca(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/extract":e==="POST"?ka(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/figma/generate":e==="POST"?Ta(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/edit":e==="POST"?Ru(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/discard":e==="POST"?Ou(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/templates":e==="GET"?Fu(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/plan/template":e==="POST"?Du(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/check":e==="GET"?Hp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/fix":e==="POST"?Up(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/marketplace/listing":Gp(e,n,s);break;case"/api/inverse/analyze":e==="GET"?Kp(n,s):p(s,405,{error:"Method not allowed"});break;case"/api/inverse/apply-tokens":e==="POST"?Vp(n,s):p(s,405,{error:"Method not allowed"});break;default:t.startsWith("/api/settings/job/")&&e==="GET"?Pm(t,s):t.match(/^\/api\/templates\/[^/]+\/add-module$/)&&e==="POST"?op(t,n,s):p(s,404,{error:"Not found"})}}function lv(e){e.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{e.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;let i=Array.isArray(s.fileIds)?s.fileIds:void 0;if(ia()){lt("user",o),L();try{e.send(JSON.stringify({type:"stream_status",content:"Planning..."}));let a="",l=await oa(o,d=>{a+=d,e.send(JSON.stringify({type:"stream",content:d}))},i),c=Lu(l||a);c.plan&&(ni(c.plan),e.send(JSON.stringify({type:"plan_updated",plan:c.plan}))),c.choices&&e.send(JSON.stringify({type:"plan_choices",question:c.choices.question,options:c.choices.options})),lt("assistant",c.cleanedContent),L(),e.send(JSON.stringify({type:"plan_complete",cleanedContent:c.cleanedContent})),e.send(JSON.stringify({type:"generation_complete"}))}catch(a){e.send(JSON.stringify({type:"error",message:a instanceof Error?a.message:String(a)}))}break}lt("user",o),L();let r=ra();r.needsPrompt&&e.send(JSON.stringify({type:"agentic_prompt"}));try{if(r.useAgentic){Jt();let l=[],c=[],d=await ei(o,Pa(l,c),i);un(d,{steps:l,modules:c,stats:d.stats,cost:d.cost}),Na(d)}else na(l=>{Ae({type:"parse_warning",message:l})}),await Os(o,l=>{Ae({type:"stream",content:l})},l=>{Ae({type:"stream_status",content:l})},i);let a=C();if(a){Te();let l=ke(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${a.themeName}-theme.css`),l.sharedJs&&d.push(`js/${a.themeName}-animations.js`),c=ir(a.themePath,l.id,o,d)}else c=rn(a.themePath,o);c&&Ae({type:"version_created",hash:c})}Ae({type:"generation_complete"});{let l=C();Ae({type:"modules_updated",modules:ve().map(c=>c.moduleName),templateId:l?.activeTemplateId||null,templates:(l?.templates||[]).map(c=>({id:c.id,label:c.label,pageType:c.pageType,moduleCount:c.modules.length}))})}Jt();{let l=C();l&&r.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&Ae({type:"suggest_brand_extraction"})}}catch(a){Jt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"figma_import":{let o=String(s.extractionId||""),i=String(s.themeName||"");if(!o||!i){e.send(JSON.stringify({type:"error",message:"Missing extractionId or themeName"}));break}let{getCachedExtraction:r}=await Promise.resolve().then(()=>(Aa(),Fp)),a=r(o);if(!a){e.send(JSON.stringify({type:"error",message:"Extraction expired or not found. Please re-extract."}));break}try{let l=C();if(!l||l.themeName!==i){let{join:m}=await import("path"),{homedir:g}=await import("os"),{existsSync:h}=await import("fs"),{createThemeScaffold:f}=await Promise.resolve().then(()=>(rs(),fl)),b=m(g(),"vibespot-themes"),S=m(b,i);if(!h(b)){let{mkdirSync:v}=await import("fs");v(b,{recursive:!0})}h(S)||f(S,i),On(S,i),L()}Ae({type:"figma_import_started",fileName:a.fileName}),Jt();let c=[],d=[],u=await Fs(a,i,Pa(c,d));un(u,{steps:c,modules:d,stats:u.stats,cost:u.cost}),Na(u),Te(),rn(C().themePath,`Figma import: ${a.fileName}`),Ae({type:"generation_complete"});{let m=C();Ae({type:"modules_updated",modules:ve().map(g=>g.moduleName),templateId:m?.activeTemplateId||null,templates:(m?.templates||[]).map(g=>({id:g.id,label:g.label,pageType:g.pageType,moduleCount:g.modules.length}))})}Jt()}catch(l){Jt(),Ae({type:"error",message:l instanceof Error?l.message:String(l)})}break}case"extract_brand_assets":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=R(),{engine:r,apiKey:a,model:l}=Wn(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(ws(),Wo)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(ui(),di)),m=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"themeContext"},tags:["vibespot","brand-extract"]},()=>te("extract-theme-context",()=>u(d,o.brandAssets?.themeContext,r,a,l))),{mkdirSync:g,writeFileSync:h}=await import("fs");if(m){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=m,o.updatedAt=Date.now();let f=Bt(o.themePath,".vibespot");Gs(f)||g(f,{recursive:!0}),h(Bt(f,"theme-context.md"),m),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:f}=await Promise.resolve().then(()=>(Js(),Ls)),b=await tt({name:"brand_extract",sessionId:o.themeName,metadata:{type:"styleguide"},tags:["vibespot","brand-extract"]},()=>te("extract-styleguide",()=>f(o.themePath)));if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let S=Bt(o.themePath,".vibespot");Gs(S)||g(S,{recursive:!0}),h(Bt(S,"styleguide.md"),b),L(),e.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}e.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){e.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}try{Te();let i=Ao(o.themePath);if(i.length>0&&e.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(R().hubspotUploadMode||"api")==="api"){let l=Le();if(!l){e.send(JSON.stringify({type:"upload_failed",output:"No HubSpot account configured. Open Settings \u2192 HubSpot to add one.",errors:[{file:"",message:"No HubSpot account configured",fixable:!1}]}));break}e.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await $o(l,o.themePath,o.themeName,{onFileStart:d=>{e.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
|
|
2761
2761
|
`}))},onFileComplete:d=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
|
|
2762
2762
|
`}))},onFileError:(d,u)=>{e.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
|
|
2763
|
-
`}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=
|
|
2764
|
-
`),errors:d}))}}else{let l=
|
|
2763
|
+
`}))},onProgress:(d,u)=>{e.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Ht();e.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName,contentMode:Jn()}))}else{let d=ko(c.errors);e.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
|
|
2764
|
+
`),errors:d}))}}else{let l=oi(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:Bt(o.themePath,".."),timeout:18e4});e.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{e.send(JSON.stringify({type:"upload_output",chunk:u}))};Hu(l,c);let d=setInterval(()=>{let u=si(l);if(!(!u||u.status==="running"))if(clearInterval(d),Uu(l,c),u.status==="completed"){let m=ht(),g=m.portalId?ts(m.portalId):"na1";e.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:m.portalId||"",dataCenter:g,themeName:o.themeName,contentMode:Jn()}))}else{let m=To(u.output);e.send(JSON.stringify({type:"upload_failed",output:u.output,errors:m,exitCode:u.exitCode}))}},500)}}catch(i){e.send(JSON.stringify({type:"error",message:i instanceof Error?i.message:String(i)}))}break}case"upload_fix_with_ai":{let o=String(s.errorContext||"");if(!o.trim()){e.send(JSON.stringify({type:"error",message:"No error context provided"}));break}let i=`The HubSpot upload ("hs cms upload") failed. Below is the upload log output containing the errors.
|
|
2765
2765
|
|
|
2766
2766
|
IMPORTANT: Be verbose in your response. For each error:
|
|
2767
2767
|
1. State exactly which file has the problem and what the error is
|
|
@@ -2774,9 +2774,9 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
|
|
|
2774
2774
|
After fixing all errors, summarize the changes you made.
|
|
2775
2775
|
|
|
2776
2776
|
Upload log:
|
|
2777
|
-
${o}`;lt("user",i),L(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await
|
|
2777
|
+
${o}`;lt("user",i),L(),e.send(JSON.stringify({type:"upload_fix_started"}));try{await Os(i,a=>{e.send(JSON.stringify({type:"stream",content:a})),e.send(JSON.stringify({type:"upload_fix_stream",content:a}))});let r=C();if(r){Te();let a=rn(r.themePath,"AI fix: upload errors");a&&e.send(JSON.stringify({type:"version_created",hash:a}))}e.send(JSON.stringify({type:"upload_fix_complete"}));{let a=C();e.send(JSON.stringify({type:"modules_updated",modules:ve().map(l=>l.moduleName),templateId:a?.activeTemplateId||null,templates:(a?.templates||[]).map(l=>({id:l.id,label:l.label,pageType:l.pageType,moduleCount:l.modules.length}))}))}}catch(r){e.send(JSON.stringify({type:"upload_failed",output:r instanceof Error?r.message:String(r),errors:[{file:"AI fix",message:r instanceof Error?r.message:String(r),fixable:!1}]}))}break}case"ping":e.send(JSON.stringify({type:"pong"}));break;case"plan_approve":{let o=C();if(!o){e.send(JSON.stringify({type:"error",message:"No active session"}));break}let i=o.brandAssets?.plan;if(!i||!i.trim()){e.send(JSON.stringify({type:"error",message:"No plan to approve. Send a chat message first."}));break}Y({planMode:!1});let r="Implement the approved plan.";lt("user",r),L();try{Jt();let a=[],l=[],c=await ei(r,Pa(a,l));un(c,{steps:a,modules:l,stats:c.stats,cost:c.cost}),Na(c);let d=C();if(d){Te();let u=ke(),m=null;if(u){let g=u.moduleOrder.map(h=>`modules/${h}.module`);u.templateFile&&g.push(u.templateFile),u.sharedCss&&g.push(`css/${d.themeName}-theme.css`),u.sharedJs&&g.push(`js/${d.themeName}-animations.js`),m=ir(d.themePath,u.id,"Approved plan: implementation",g)}else m=rn(d.themePath,"Approved plan: implementation");m&&Ae({type:"version_created",hash:m})}Ae({type:"generation_complete"});{let u=C();Ae({type:"modules_updated",modules:ve().map(m=>m.moduleName),templateId:u?.activeTemplateId||null,templates:(u?.templates||[]).map(m=>({id:m.id,label:m.label,pageType:m.pageType,moduleCount:m.modules.length}))})}Jt()}catch(a){Jt(),Ae({type:"error",message:a instanceof Error?a.message:String(a)})}break}case"plan_discard":{la(),Y({planMode:!1}),e.send(JSON.stringify({type:"plan_discarded"}));break}default:e.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}}),Ti=e;let t=C();if(t){let n=R(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Yt(),i=ke();if(e.send(JSON.stringify({type:"init",sessionId:t.id,themeName:t.themeName,modules:ve().map(r=>r.moduleName),messageCount:t.messages.length,messages:t.messages,gitAvailable:rt(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",updatedAt:t.updatedAt,templateId:i?.id||null,pageType:i?.pageType||null,templates:(t.templates||[]).map(r=>({id:r.id,label:r.label,pageType:r.pageType,moduleCount:r.modules.length})),planMode:!!n.planMode,plan:t.brandAssets?.plan||"",isGenerating:o,costTotal:t.costTotal||null})),o&&Ai.length>0)for(let r of Ai)e.send(JSON.stringify(r))}else e.send(JSON.stringify({type:"needs_setup"}))}function cv(e,t){let n=C();if(!n){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("No session");return}let s=Bt(n.themePath,"assets",e);if(!Gs(s)){t.writeHead(404,{"Content-Type":"text/plain"}),t.end("Asset not found");return}let o=qp(s),i=Xp[o]||"application/octet-stream",r=Ra(s);t.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),t.end(r)}function Yp(e,t,n,s){let i=Bt(t,e==="/"?"/index.html":e);if(!Gs(i)){let c=Bt(t,"index.html");if(Gs(c)){let d=Ra(c);s.writeHead(200,{"Content-Type":"text/html","Cache-Control":"no-cache"}),s.end(d)}else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not found");return}let r=qp(i),a=Xp[r]||"application/octet-stream",l=r===".html";try{let c=Ra(i);s.writeHead(200,{"Content-Type":a,"Cache-Control":"no-store"}),s.end(c)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}var Xp,Ti,Ai,Zp,Cs=N(()=>{"use strict";y();Ce();Pn();ws();Kn();ju();Ju();ee();nn();_o();ii();sr();Xe();oe();Be();fi();Nm();Dm();Um();up();xp();jr();Aa();Wp();zp();Xp={".html":"text/html",".css":"text/css",".js":"application/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".ico":"image/x-icon",".woff2":"font/woff2"},Ti=null,Ai=[];Zp="page"});y();y();import{Command as wv}from"commander";y();y();gt();oe();function Ee(){let e=I.vibes,t=I.accent,n=I.muted,s=[`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${t(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${e(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${e(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${t("\u2580\u2580\u2580\u2580 \u2588\u2588 \u2580\u2580\u2580\u2580 \u2588\u2588 ")}`];console.log();for(let o of s)console.log(` ${o}`);console.log(),console.log(` ${n("AI-powered HubSpot Landing Pages")} ${I.dim(`v${Sn()}`)}`),console.log()}y();nn();$t();Qt();ee();sn();Qe();gt();async function co(){await ge("Checking your environment");let e=Qn();e.found||(V("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),oo(e.version)||(V(`Node.js ${e.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),G(`Node.js v${e.version}`);let t=es();t.found||(V("Git not found. Install it from https://git-scm.com"),process.exit(1)),G(`Git ${t.version}`);let n=R(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let b=Le(),S=Ht();if(b)o=S?.portalId||"",i=S?.portalName||"",G(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{se("No HubSpot account connected"),await yt(`You need a Personal Access Key to deploy themes.
|
|
2778
2778
|
Create one at: https://app.hubspot.com/l/personal-access-key
|
|
2779
|
-
Make sure the Content scope is enabled.`,"HubSpot connection required");let v=await Se({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate
|
|
2779
|
+
Make sure the Content scope is enabled.`,"HubSpot connection required");let v=await Se({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:$=>$.trim()?void 0:"Key is required"}),w=await De();w.start("Validating key...");try{let $=await ao(v);Xn(v,$.portalId,$.portalName,$.dataCenter),b=v,o=$.portalId,i=$.portalName,w.stop(`Connected to ${$.portalName} (${$.portalId})`)}catch($){w.stop("Validation failed"),V(`Invalid key: ${$ instanceof Error?$.message:String($)}`),process.exit(1)}}}else{let b=ft();if(b.found)G(`HubSpot CLI v${b.version}`);else{se("HubSpot CLI not found"),await Me({message:"Install HubSpot CLI globally?"})||(V("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let w=await De();w.start("Installing HubSpot CLI..."),ie("npm install -g @hubspot/cli").success||(w.stop("Failed"),V("Try: npm install -g @hubspot/cli"),process.exit(1)),b=ft(),w.stop(`HubSpot CLI v${b.version} installed`)}let S=ht();if(S.authenticated)G(`HubSpot portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`);else{se("HubSpot not authenticated"),await Me({message:"Run `hs init` now?"})||(V("Run `hs init` manually."),process.exit(1));let w=await De();w.start("Waiting for HubSpot authentication..."),Va("hs init")||(w.stop("Authentication failed"),process.exit(1)),S=ht(),w.stop(`Connected to portal${S.portalName?`: ${S.portalName}`:""} (ID: ${S.portalId})`)}o=S.portalId,i=S.portalName}let r=kn(),a=Tn(),l=An(),c=el(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex","langdock-api":"Langdock (EU)"},u=Ze(),m,g=n.aiEngine,h=[];if(r.found&&h.push({value:"claude-code",label:"Claude Code",hint:g==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),u&&h.push({value:"claude-oauth",label:"Claude (OAuth)",hint:g==="claude-oauth"?"last used":"uses your Claude Pro/Max subscription via OAuth"}),a.found&&h.push({value:"gemini-cli",label:"Gemini CLI",hint:g==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&h.push({value:"codex-cli",label:"OpenAI Codex",hint:g==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&h.push({value:"api",label:"Anthropic API",hint:g==="api"?"last used":"uses your API key"}),g&&h.sort((b,S)=>b.value===g?-1:S.value===g?1:0),h.length===1)m=h[0].value,G(`AI engine: ${d[m]} (auto-detected)`);else if(h.length>1)m=await Mt({message:"Choose your AI engine:",options:h});else if(await yt(`You need an AI coding assistant to power the conversion.
|
|
2780
2780
|
|
|
2781
2781
|
${I.bold("Option 1:")} Install Claude Code ${I.muted("(recommended)")}
|
|
2782
2782
|
https://claude.ai/code
|
|
@@ -2789,7 +2789,7 @@ ${I.bold("Option 3:")} Install OpenAI Codex
|
|
|
2789
2789
|
|
|
2790
2790
|
${I.bold("Option 4:")} Set an Anthropic API key
|
|
2791
2791
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
2792
|
-
(get one at https://console.anthropic.com)`,"AI engine required"),m=await
|
|
2792
|
+
(get one at https://console.anthropic.com)`,"AI engine required"),m=await Mt({message:"Which will you set up?",options:[{value:"claude-code",label:"Claude Code",hint:"I'll install it now"},{value:"gemini-cli",label:"Gemini CLI",hint:"I'll install it now"},{value:"codex-cli",label:"OpenAI Codex",hint:"I'll install it now"},{value:"api",label:"Anthropic API",hint:"I'll enter my key"}]}),m==="api"){let b=await Se({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:S=>S.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=b,Y({anthropicApiKey:b})}let f;return m==="claude-code"&&(f=await Mt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),Y({aiEngine:m}),await fe("Environment ready!"),{aiEngine:m,model:f,portalId:o,portalName:i}}mo();y();Qt();oe();Qe();gt();ee();rs();po();import{join as ls}from"path";async function go(){await ge("HubSpot Theme Setup");let e=await Mt({message:"Do you have an existing HubSpot theme?",options:[{value:"fetch",label:"Fetch my existing theme from HubSpot",hint:"downloads your current theme"},{value:"create",label:"Start fresh (HubSpot Boilerplate)",hint:"creates a new starter theme"}]}),t,n,s=ls(process.cwd(),"workspace");if(Re(s),e==="fetch"){t=await Se({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=ls(s,t);let l=await De();l.start("Fetching theme from HubSpot...");let c=R(),d=Le();if(c.hubspotUploadMode==="cli"||!d)ie(`hs cms fetch "${t}" "${n}"`).success||(l.stop("Fetch failed"),V(`Could not fetch theme "${t}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await as(d,t,n)}catch(u){l.stop("Fetch failed"),V(`Could not fetch theme "${t}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${I.dim(n)}`)}else{t=await Se({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=ls(s,t);let l=await De();l.start("Creating theme...");try{is(n,t)}catch(c){l.stop("Creation failed"),V(`Could not create theme "${t}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${I.dim(n)}`)}await ge("Checking theme compatibility");let o=ls(n,"templates/layouts/base.html");x(o)||(V(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),G("base.html found");let i=P(o),r=!1;if(i.includes("template_css"))G("template_css support");else{se("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
|
|
2793
2793
|
`,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
|
|
2794
2794
|
`,l);i=i.slice(0,c)+`
|
|
2795
2795
|
{% if template_css %}
|
|
@@ -2802,17 +2802,17 @@ ${I.bold("Option 4:")} Set an Anthropic API key
|
|
|
2802
2802
|
{% endif %}`,m=i.indexOf("}}",l)+2+i.slice(i.indexOf("}}",l)+2).indexOf(`
|
|
2803
2803
|
`)+1;i=i.slice(0,i.indexOf(`
|
|
2804
2804
|
`,i.indexOf("}}",l)+2))+u+i.slice(i.indexOf(`
|
|
2805
|
-
`,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await De();l.start("Patching base.html..."),B(o,i),l.stop("base.html patched with template_css/template_js support")}let a=
|
|
2805
|
+
`,i.indexOf("}}",l)+2)),r=!0}}if(r){let l=await De();l.start("Patching base.html..."),B(o,i),l.stop("base.html patched with template_css/template_js support")}let a=ls(n,".hsignore");if(x(a)){let l=P(a);l.includes("docs/")||(B(a,l+`
|
|
2806
2806
|
docs/
|
|
2807
2807
|
`),G("Added docs/ to .hsignore"))}else B(a,`docs/
|
|
2808
2808
|
*.md
|
|
2809
2809
|
node_modules/
|
|
2810
2810
|
.git
|
|
2811
|
-
`),G("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}y();import{join as nt}from"path";import{readdirSync as
|
|
2811
|
+
`),G("Created .hsignore");return await fe("Theme ready!"),{themePath:n,themeName:t}}y();import{join as nt}from"path";import{readdirSync as ps,rmSync as Ol}from"fs";y();Ke();oe();import{spawn as Bg}from"child_process";import{join as Q,basename as Hg}from"path";import{readdirSync as bt,statSync as Al,writeFileSync as Ug}from"fs";var Gg=new Set(["about.html","blog-index.html","blog-post.html","contact.html","home.html","hubdb.html","landing-page.html","pricing.html","qa-test.html","base.html"]),fo=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(t){this.model=t}async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let r=this.countSourceComponents(n),a=this.listModules(s),l=this.listDir(Q(s,"css")),c=this.listDir(Q(s,"js")),d=this.listDir(Q(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${r} source components found)...`);let m="",g="",h=setInterval(()=>{this.reportProgress(s,a,l,c,d,o)},3e3);try{await new Promise((v,w)=>{let $={...process.env};delete $.CLAUDECODE;let j=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&j.push("--model",this.model);let J=Bg("claude",j,{cwd:s,stdio:["pipe","pipe","pipe"],env:$,shell:!0});J.stdout.on("data",K=>{m+=K.toString()}),J.stderr.on("data",K=>{g+=K.toString()}),J.on("error",K=>w(new Error(`Claude Code failed to start: ${K.message}`))),J.on("close",K=>{K!==0?w(new Error(`Claude Code exited with code ${K}.
|
|
2812
2812
|
`+(g?`Stderr: ${g.slice(0,500)}
|
|
2813
2813
|
`:"")+(m?`Output: ${m.slice(0,500)}`:"No output"))):v()}),J.stdin.on("error",()=>{}),J.stdin.write(u),J.stdin.end(),setTimeout(()=>{J.kill(),w(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let f=Q(s,"..","vibespot-conversion.log");try{let w=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
|
|
2814
2814
|
... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",m||"(empty)","","=== CLAUDE CODE STDERR ===",g||"(empty)",""].join(`
|
|
2815
|
-
`);
|
|
2815
|
+
`);Ug(f,w,"utf-8"),o("status",`Log written to ${Hg(f)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(v=>!a.has(v.moduleName+".module")).length===0){let v=m.slice(0,1500)||"(no output)",w=g.slice(0,500);throw new Error(`Claude Code did not create any new module files.
|
|
2816
2816
|
|
|
2817
2817
|
This usually means the model described the conversion instead of using Write tool to create files.
|
|
2818
2818
|
|
|
@@ -2874,13 +2874,13 @@ HUBSPOT CMS RULES:
|
|
|
2874
2874
|
${Je()}
|
|
2875
2875
|
|
|
2876
2876
|
CONVERSION GUIDE:
|
|
2877
|
-
${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Q(t,"css");if(x(s)){for(let a of bt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Q(s,a));break}}let o=Q(t,"js");if(x(o)){for(let a of bt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Q(o,a));break}}let i=Q(t,"templates");if(x(i)){for(let a of bt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=P(Q(i,a));break}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!
|
|
2877
|
+
${s}`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Q(t,"css");if(x(s)){for(let a of bt(s))if(a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Q(s,a));break}}let o=Q(t,"js");if(x(o)){for(let a of bt(o))if(a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Q(o,a));break}}let i=Q(t,"templates");if(x(i)){for(let a of bt(i))if(a.startsWith("lp-")&&a.endsWith(".html")){n.template=P(Q(i,a));break}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!Gg.has(a)&&!a.startsWith("system")){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let a of bt(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Q(i,a));if(l.includes("dnd_area")){n.template=l;break}}}}let r=Q(t,"modules");if(x(r))for(let a of bt(r)){if(!a.endsWith(".module"))continue;let l=Q(r,a);if(!Al(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Q(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Q(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Q(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Q(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Q(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(t){let n=Q(t,"modules");return x(n)?new Set(bt(n).filter(s=>s.endsWith(".module"))):new Set}listDir(t){return x(t)?new Set(bt(t)):new Set}detectExpectedModules(t,n){let s=Q(t,"templates");if(!x(s))return 0;for(let o of bt(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=P(Q(s,o));if(i.includes("dnd_area")){let r=i.match(/dnd_module/g);return r?r.length:0}}catch{}return 0}countSourceComponents(t){let n=Q(t,"src");return x(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(t){let n=0;for(let s of bt(t)){let o=Q(t,s);try{Al(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};y();Ke();oe();Be();on();import uf from"@anthropic-ai/sdk";import{join as ce,basename as mf}from"path";import{readdirSync as Rl}from"fs";var bo=class{client;model="claude-sonnet-4-6";constructor(t){this.client=new uf({apiKey:t||process.env.ANTHROPIC_API_KEY})}async convert(t){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=t,r=xl(o),a=mf(n)||"page",l=a.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);i("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(r,Cl(c,d,l)),m=ce(s,"css",`${l}-theme.css`);B(m,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let g=this.findAndReadHooks(n),h=this.findInteractiveComponents(n),f=await this.complete(r,kl(g,h,l)),b=ce(s,"js",`${l}-animations.js`);B(b,f),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let S=this.findComponents(n),v=[];for(let J=0;J<S.length;J++){let K=S[J],H=K.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${H}.module (${J+1}/${S.length})...`);let X=P(K.path),F=await this.complete(r,wl(X,H,`See css/${l}-theme.css`));try{let T=JSON.parse(F),k={moduleName:H,fieldsJson:typeof T.fieldsJson=="string"?T.fieldsJson:JSON.stringify(T.fieldsJson,null,2),metaJson:typeof T.metaJson=="string"?T.metaJson:JSON.stringify(T.metaJson,null,2),moduleHtml:T.moduleHtml||"",moduleCss:T.moduleCss||"",moduleJs:T.moduleJs||void 0},E=ce(s,"modules",`${H}.module`);Re(E),B(ce(E,"fields.json"),k.fieldsJson),B(ce(E,"meta.json"),k.metaJson),B(ce(E,"module.html"),k.moduleHtml),B(ce(E,"module.css"),k.moduleCss),k.moduleJs&&B(ce(E,"module.js"),k.moduleJs),v.push(k),i("module-done",`${H}.module (${this.countFiles(k)} files)`)}catch{i("module-error",`Failed to parse ${H} \u2014 skipping`)}}i("template","Creating page template...");let w=v.map(J=>J.moduleName),$=await this.complete(r,Tl(w,a,l)),j=ce(s,"templates",`lp-${l}.html`);return B(j,$),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:f,template:$,modules:v}}async complete(t,n){let s=new Date,o=await this.client.messages.create({model:this.model,max_tokens:8192,system:[{type:"text",text:t,cache_control:{type:"ephemeral"}}],messages:[{role:"user",content:n}]}),r=o.content.find(a=>a.type==="text")?.text||"";return St({engine:"anthropic-api",model:this.model,name:"react-conversion",input:{system:t,messages:[{role:"user",content:n}]},output:r,usage:et(o.usage),startTime:s,endTime:new Date}),r}findAndReadCSS(t){let n=[ce(t,"src/index.css"),ce(t,"src/globals.css"),ce(t,"src/app/globals.css"),ce(t,"app/globals.css")];for(let s of n)if(x(s))return P(s);return""}findAndReadTailwind(t){let n=[ce(t,"tailwind.config.ts"),ce(t,"tailwind.config.js"),ce(t,"tailwind.config.mjs")];for(let s of n)if(x(s))return P(s);return""}findAndReadHooks(t){let n=ce(t,"src/hooks");if(!x(n))return"";try{return Rl(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
|
|
2878
2878
|
${P(ce(n,s))}`).join(`
|
|
2879
2879
|
|
|
2880
2880
|
`)}catch{return""}}findInteractiveComponents(t){let n=this.findComponents(t),s=[];for(let o of n){let i=P(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
|
|
2881
2881
|
${i}`)}return s.join(`
|
|
2882
2882
|
|
|
2883
|
-
`)}findComponents(t){let n=[ce(t,"src/components/landing"),ce(t,"src/components/sections"),ce(t,"src/components")];for(let s of n)if(x(s))try{return
|
|
2883
|
+
`)}findComponents(t){let n=[ce(t,"src/components/landing"),ce(t,"src/components/sections"),ce(t,"src/components")];for(let s of n)if(x(s))try{return Rl(s).filter(o=>(o.endsWith(".tsx")||o.endsWith(".jsx"))&&!o.startsWith("ui")&&o!=="index.tsx"&&o!=="index.jsx").map(o=>({name:o.replace(/\.(tsx|jsx)$/,""),path:ce(s,o)}))}catch{continue}return[]}countFiles(t){let n=3;return t.moduleCss&&n++,t.moduleJs&&n++,n}};y();Ke();oe();import{spawn as pf}from"child_process";import{join as Ve}from"path";import{readdirSync as So,statSync as gf}from"fs";var vo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((a,l)=>{let c=pf("gemini",["-p",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Gemini CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Gemini CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Gemini CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
|
|
2884
2884
|
|
|
2885
2885
|
INSTRUCTIONS:
|
|
2886
2886
|
1. Analyze all .tsx/.jsx components in the React source
|
|
@@ -2895,7 +2895,7 @@ CONVERSION GUIDE:
|
|
|
2895
2895
|
${s}
|
|
2896
2896
|
|
|
2897
2897
|
Do NOT run hs upload \u2014 I will handle that separately.
|
|
2898
|
-
Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ve(t,"css");if(x(s)){for(let a of
|
|
2898
|
+
Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=Ve(t,"css");if(x(s)){for(let a of So(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(Ve(s,a));break}}let o=Ve(t,"js");if(x(o)){for(let a of So(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(Ve(o,a));break}}let i=Ve(t,"templates");if(x(i)){for(let a of So(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(Ve(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=Ve(t,"modules");if(x(r))for(let a of So(r)){if(!a.endsWith(".module"))continue;let l=Ve(r,a);if(!gf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=Ve(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=Ve(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=Ve(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=Ve(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=Ve(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};y();Ke();oe();import{spawn as ff}from"child_process";import{join as ze}from"path";import{readdirSync as xo,statSync as hf}from"fs";var wo=class{async convert(t){let{sourceDir:n,themePath:s,onProgress:o}=t,i=t.conversionGuide||ye(),r=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((a,l)=>{let c=ff("codex",["exec","--full-auto",r],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",m=>{d+=m.toString()}),c.stderr.on("data",m=>{u+=m.toString()}),c.on("error",m=>l(new Error(`Codex CLI failed: ${m.message}`))),c.on("close",m=>{m!==0&&u&&!d?l(new Error(`Codex CLI failed: ${u}`)):a()}),setTimeout(()=>{c.kill(),l(new Error("Codex CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(t,n,s){return`Read the conversion guide below, then convert the React landing page at ${t} into native HubSpot CMS modules for the theme at ${n}.
|
|
2899
2899
|
|
|
2900
2900
|
INSTRUCTIONS:
|
|
2901
2901
|
1. Analyze all .tsx/.jsx components in the React source
|
|
@@ -2910,15 +2910,15 @@ CONVERSION GUIDE:
|
|
|
2910
2910
|
${s}
|
|
2911
2911
|
|
|
2912
2912
|
Do NOT run hs upload \u2014 I will handle that separately.
|
|
2913
|
-
Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ze(t,"css");if(x(s)){for(let a of
|
|
2914
|
-
HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=
|
|
2913
|
+
Create all files directly in the theme directory.`}scanGeneratedFiles(t){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=ze(t,"css");if(x(s)){for(let a of xo(s))if((a.includes("theme")||a.includes("page"))&&a.endsWith(".css")&&a!=="theme-overrides.css"&&a!=="main.css"&&a!=="style.css"){n.sharedCss=P(ze(s,a));break}}let o=ze(t,"js");if(x(o)){for(let a of xo(o))if((a.includes("animation")||a.includes("page"))&&a.endsWith(".js")&&a!=="main.js"){n.sharedJs=P(ze(o,a));break}}let i=ze(t,"templates");if(x(i)){for(let a of xo(i))if(a.endsWith(".html")&&!a.startsWith("system")&&a!=="base.html"){let l=P(ze(i,a));if(l.includes("dnd_area")){n.template=l;break}}}let r=ze(t,"modules");if(x(r))for(let a of xo(r)){if(!a.endsWith(".module"))continue;let l=ze(r,a);if(!hf(l).isDirectory())continue;let c={moduleName:a.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=ze(l,"fields.json");x(d)&&(c.fieldsJson=P(d));let u=ze(l,"meta.json");x(u)&&(c.metaJson=P(u));let m=ze(l,"module.html");x(m)&&(c.moduleHtml=P(m));let g=ze(l,"module.css");x(g)&&(c.moduleCss=P(g));let h=ze(l,"module.js");x(h)&&(c.moduleJs=P(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ke();oe();Qe();function yf(e,t){switch(e){case"claude-code":return new fo(t);case"gemini-cli":return new vo;case"codex-cli":return new wo;case"api":case"anthropic-api":case"claude-oauth":return new bo;default:throw new Error(`The wizard does not support the "${e}" engine. Use claude-code, gemini-cli, codex-cli, or the Anthropic API.`)}}async function Co(e){await ge("Converting React to HubSpot Modules"),await yt(`AI will now analyze your React code and create
|
|
2914
|
+
HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let t=yf(e.aiEngine,e.model),n=ye(),s=await De();s.start("Starting AI conversion...");let o=Date.now(),i=await t.convert({sourceDir:e.sourceDir,themePath:e.themePath,conversionGuide:n,onProgress:(h,f)=>{h==="created"?G(f):s.message(f)}}),r=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${r}s)`);let a=bf(e.themePath);for(let h of a)G(`Auto-fixed: ${h}`);let l=Sf(e.themePath,i),c=[];for(let h of l){let f=h.passed?"\u2705":"\u274C",b=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${f} ${h.label}${b}`)}let d=l.filter(h=>h.passed).length;c.push(`
|
|
2915
2915
|
${d}/${l.length} checks passed`),await yt(c.join(`
|
|
2916
2916
|
`),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),m=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(V(`${u.length} critical issue(s) \u2014 upload will likely fail:
|
|
2917
2917
|
`+u.map(f=>` - ${f.label}`).join(`
|
|
2918
2918
|
`)),!await Me({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else m.length>0&&se(`${m.length} non-critical issue(s) \u2014 page will work but may look incomplete:
|
|
2919
2919
|
`+m.map(h=>` - ${h.label}`).join(`
|
|
2920
|
-
`));let g=nt(e.themePath,"..","vibespot-conversion.log");return x(g)&&(await Me({message:"Keep conversion log file for debugging?",initialValue:!1})?G(`Log saved: ${g}`):
|
|
2921
|
-
`,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&B(i,a);let c=nt(n,o,"module.html");if(x(c)){let d=P(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),B(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=nt(e,"templates");if(x(s))for(let o of
|
|
2920
|
+
`));let g=nt(e.themePath,"..","vibespot-conversion.log");return x(g)&&(await Me({message:"Keep conversion log file for debugging?",initialValue:!1})?G(`Log saved: ${g}`):Ol(g)),await fe("Files ready for upload!"),i}function bf(e){let t=[];vf(e),xf(e);let n=nt(e,"modules");if(x(n))for(let o of ps(n)){if(!o.endsWith(".module"))continue;let i=nt(n,o,"fields.json");if(!x(i))continue;let r=o.replace(".module",""),a=P(i),l=!1;a.includes('"textarea"')&&(a=a.replace(/"textarea"/g,'"text"'),l=!0,t.push(`${r}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(a)&&(a=a.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,t.push(`${r}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(a),u=!1;Fl(d)&&(u=!0,t.push(`${r}: fixed choice field format`)),Dl(d)&&(u=!0,t.push(`${r}: fixed link field default value`)),u&&(a=JSON.stringify(d,null,2)+`
|
|
2921
|
+
`,l=!0)}catch{t.push(`${r}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&B(i,a);let c=nt(n,o,"module.html");if(x(c)){let d=P(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),B(c,d),t.push(`${r}: now() \u2192 local_dt`))}}let s=nt(e,"templates");if(x(s))for(let o of ps(s)){if(!o.endsWith(".html"))continue;let i=nt(s,o),r=P(i);(r.includes("hubdb_table")||r.includes("hubdb_table_rows"))&&(Ol(i),t.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return t}function Fl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let r=i.charAt(0).toUpperCase()+i.slice(1);return[i,r]}return i}),t=!0),Array.isArray(s.children)&&Fl(s.children)&&(t=!0)}return t}function Dl(e){let t=!1;for(let n of e){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let r=typeof o=="string"?o:"";s.default={url:{href:r,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},t=!0}}Array.isArray(s.children)&&Dl(s.children)&&(t=!0)}return t}function Sf(e,t){let n=[],s=t.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of t.modules)if(u.fieldsJson.includes('"textarea"')||/"name":\s*"name"/.test(u.fieldsJson)){o=!1;break}n.push({label:"fields.json valid (no textarea, no reserved names)",passed:s>0&&o,critical:!0});let i=t.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let r=t.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),a=r.length===0;n.push({label:a?"module.css created for each module":`module.css missing for: ${r.join(", ")}`,passed:s>0&&a,critical:!1});let l=t.modules.some(u=>u.fieldsJson.includes('"STYLE"'));n.push({label:"Style tab fields (color pickers)",passed:l,critical:!1}),n.push({label:"Shared CSS with design system variables",passed:t.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:t.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:t.template.length>0&&t.template.includes("dnd_area"),critical:!0});let c=nt(e,"templates"),d=!1;if(x(c))for(let u of ps(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let m=P(nt(c,u));if(m.includes("dnd_area")&&/templateType\s*:\s*page/i.test(m)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function vf(e){let t=nt(e,"templates");if(x(t))for(let n of ps(t)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=nt(t,n),o=P(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),r=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&r)continue;let a=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);i||(c+=`
|
|
2922
2922
|
templateType: page`),r||(c+=`
|
|
2923
2923
|
isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
|
|
2924
2924
|
label: ${a}`),o=c+o.slice(l)}else o=`<!--
|
|
@@ -2926,11 +2926,11 @@ ${d}/${l.length} checks passed`),await yt(c.join(`
|
|
|
2926
2926
|
isAvailableForNewContent: true
|
|
2927
2927
|
label: ${a}
|
|
2928
2928
|
-->
|
|
2929
|
-
`+o;B(s,o),G(`Template "${n}" \u2014 annotations verified`)}}function
|
|
2930
|
-
`)}catch{}}}y();
|
|
2931
|
-
`);c=
|
|
2932
|
-
You can check your HubSpot Design Manager to verify.`),await Me({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Me({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?
|
|
2933
|
-
The theme may work \u2014 check HubSpot Design Manager.`),await Me({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await
|
|
2929
|
+
`+o;B(s,o),G(`Template "${n}" \u2014 annotations verified`)}}function xf(e){let t=nt(e,"modules");if(x(t))for(let n of ps(t)){if(!n.endsWith(".module"))continue;let s=nt(t,n,"meta.json");if(x(s))try{let o=JSON.parse(P(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&B(s,JSON.stringify(o,null,2)+`
|
|
2930
|
+
`)}catch{}}}y();Qt();Qe();_o();ee();sr();import{join as ql,basename as If}from"path";function Pf(e){return(e.match(/^Uploaded file /gm)||[]).length}async function In(e){await ge("Uploading to HubSpot");let t=If(e)||e,n=R(),s=Le(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await De(),r=3;for(let a=1;a<=r;a++){i.start(a===1?"Uploading theme...":`Retrying upload (attempt ${a}/${r})...`);let l=[],c=0,d=!1;if(o){let m=await $o(s,e,t,{onFileComplete:()=>{c++}});d=m.success,d?c=m.uploaded:l=ko(m.errors)}else{let m=ie(`hs cms upload "${e}" "${t}"`,{cwd:ql(e,"..")}),g=[m.stdout,m.stderr].filter(Boolean).join(`
|
|
2931
|
+
`);c=Pf(g),d=m.success,d||(l=To(g))}if(d)return i.stop(`All files uploaded! (${c} files)`),await fe("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(V("Upload failed with unknown error."),c>0&&(se(`Most files uploaded successfully. The theme may already be usable in HubSpot.
|
|
2932
|
+
You can check your HubSpot Design Manager to verify.`),await Me({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(a<r){if(!await Me({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let m of l)m.fixable?jl(e,m)?(G(`Auto-fixed: ${m.message}`),u=!0):se(`Could not auto-fix: ${m.message}`):V(m.message);if(!(u&&a<r)){if(c>0&&(se(`${c} files uploaded successfully despite errors.
|
|
2933
|
+
The theme may work \u2014 check HubSpot Design Manager.`),await Me({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await Hi(s,`${t}/modules`)}catch{}else ie(`hs cms delete "${t}/modules"`,{cwd:ql(e,"..")});i.stop("Cleaned up modules, retrying...")}}}return V("Upload failed after multiple attempts."),!1}y();Qe();gt();nn();oe();import{execFileSync as or}from"child_process";import{rmSync as Nf}from"fs";import{basename as Xl}from"path";async function Zl(e){let{portalId:t,sourceDir:n,themePath:s,wasCloned:o}=e;await ge("You're all set!");let r=ts(t)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await yt(`Your React page has been converted and uploaded to HubSpot.
|
|
2934
2934
|
The theme and modules are now in your account, but you still
|
|
2935
2935
|
need to ${I.bold("create a new landing page")} that uses them.
|
|
2936
2936
|
|
|
@@ -2942,15 +2942,15 @@ Next steps:
|
|
|
2942
2942
|
${I.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
|
|
2943
2943
|
${I.bold("5.")} Click each section to edit text, images, and colors
|
|
2944
2944
|
${I.bold("6.")} Upload images via File Manager ${I.muted("(Settings \u2192 Files)")}
|
|
2945
|
-
${I.bold("7.")} Preview and publish!`,"What's next"),await Me({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${r}/page-ui/${t}/management/pages/landing`:`https://${r}`;try{let d=process.platform;d==="darwin"?
|
|
2946
|
-
`));let n=
|
|
2947
|
-
`)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?
|
|
2945
|
+
${I.bold("7.")} Preview and publish!`,"What's next"),await Me({message:"Open HubSpot Landing Pages in your browser?"})){let c=t?`https://${r}/page-ui/${t}/management/pages/landing`:`https://${r}`;try{let d=process.platform;d==="darwin"?or("open",[c],{stdio:"ignore"}):d==="win32"?or("cmd",["/c","start","",c],{stdio:"ignore"}):or("xdg-open",[c],{stdio:"ignore"}),G("Opening HubSpot Landing Pages...")}catch{D(`Open this URL in your browser: ${I.info(c)}`)}}let l=[];if(o&&x(n)&&l.push({path:n,label:`Cloned source (${Xl(n)})`}),x(s)&&l.push({path:s,label:`Theme directory (${Xl(s)})`}),l.length>0&&await Me({message:"Clean up local working directories?"}))for(let d of l)try{Nf(d.path,{recursive:!0,force:!0}),G(`Removed ${d.label}`)}catch{se(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await fe(`Thanks for using hub${I.vibes("Vibes")}! ${I.vibes("~")}`)}ee();async function Ql(){Ee();let e=await co(),t=await uo();Y({lastSourcePath:t.sourceDir});let n=await go();Y({lastThemePath:n.themePath}),await Co({aiEngine:e.aiEngine,model:e.model,sourceDir:t.sourceDir,themePath:n.themePath}),await In(n.themePath),await Zl({portalId:e.portalId,sourceDir:t.sourceDir,themePath:n.themePath,wasCloned:t.wasCloned})}y();async function ec(){Ee(),await co()}y();mo();ee();Qe();async function tc(){Ee();let e=R();e.aiEngine||(V("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let t=await uo(),n=await go();await Co({aiEngine:e.aiEngine,sourceDir:t.sourceDir,themePath:n.themePath})}y();ee();Qe();async function nc(){Ee();let e=R();if(e.lastThemePath)if(await Me({message:`Upload from ${e.lastThemePath}?`}))await In(e.lastThemePath);else{let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await In(n)}else{let t=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await In(t)}}y();nn();ee();Qe();gt();async function sc(){Ee(),await ge("Environment Diagnostics");let e=0,t=Qn();t.found?oo(t.version)?G(`Node.js v${t.version}`):(se(`Node.js v${t.version} \u2014 too old (need 18+)`),D(" Update at https://nodejs.org"),e++):(V("Node.js \u2014 not installed"),D(" Install from https://nodejs.org"),e++);let n=es();n.found?G(`Git ${n.version}`):(V("Git \u2014 not installed"),D(" Install from https://git-scm.com"),e++);let s=ft();if(!s.found)se("HubSpot CLI \u2014 not installed (only needed for deployment)"),D(" Install: npm install -g @hubspot/cli");else if(!tl(s.version))se(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),D(" Update: npm install -g @hubspot/cli@latest"),e++;else{G(`HubSpot CLI v${s.version}`);let m=ht();m.authenticated?G(`HubSpot portal${m.portalName?`: ${m.portalName}`:""} (ID: ${m.portalId})`):(se("HubSpot \u2014 not authenticated"),D(" Run: hs init"))}let o=kn();o.found?G(`Claude Code ${o.version} at ${o.path}`):D(I.muted("Claude Code \u2014 not installed"));let i=Tn();i.found?G(`Gemini CLI ${i.version} at ${i.path}`):D(I.muted("Gemini CLI \u2014 not installed"));let r=An();r.found?G(`OpenAI Codex ${r.version} at ${r.path}`):D(I.muted("OpenAI Codex \u2014 not installed"));let a=R(),l=!!(a.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(a.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(a.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?G("Anthropic API key configured"):D(I.muted("Anthropic API key \u2014 not set")),c?G("OpenAI API key configured"):D(I.muted("OpenAI API key \u2014 not set")),d?G("Google AI API key configured"):D(I.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","claude-oauth":"Claude (OAuth)","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};a.aiEngine&&G(`AI engine: ${u[a.aiEngine]||a.aiEngine}`),a.lastThemePath&&D(I.muted(`Last theme: ${a.lastThemePath}`)),!o.found&&!i.found&&!r.found&&!l&&!c&&!d&&(se("No AI engine available"),D(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),D(" Or install: Claude Code \u2014 https://claude.ai/code"),D(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),D(" Codex CLI \u2014 https://github.com/openai/codex"),e++),console.log(),e===0?await fe("Everything looks good!"):await fe(I.warn(`${e} issue${e>1?"s":""} found \u2014 see above`))}y();Cs();Ce();import{dirname as dv,join as $i}from"path";import{existsSync as uv}from"fs";import{fileURLToPath as mv}from"url";import{execFileSync as Oa}from"child_process";import Ei from"chalk";var Qp=dv(mv(import.meta.url)),pv=4200;async function eg(){let e=Ei.hex("#e8613a"),t=Ei.dim;console.log(""),console.log(e(" v vibeSpot")),console.log(t(` Starting...
|
|
2946
|
+
`));let n=gv();n||(console.error(Ei.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));let s=parseInt(process.env.VIBESPOT_PORT||"",10)||pv;try{let{port:o,close:i}=await _i({port:s,uiDir:n}),r=`http://localhost:${o}`;if(console.log(e(` v ${r}`)),console.log(t(` Press Ctrl+C to stop
|
|
2947
|
+
`)),!process.env.VIBESPOT_NO_OPEN)try{process.platform==="darwin"?Oa("open",[r],{stdio:"ignore"}):process.platform==="win32"?Oa("cmd",["/c","start","",r],{stdio:"ignore"}):Oa("xdg-open",[r],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(t(`
|
|
2948
2948
|
Saving session...`)),L(),i(),console.log(t(` Goodbye!
|
|
2949
|
-
`)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(
|
|
2950
|
-
`),n.passed||process.exit(1);return}Ee(),await ge("Marketplace check");let s=`${n.errorCount} error${
|
|
2951
|
-
`),process.exit(0)),Ee(),await ge("Inverse pipeline analyzer");let o=s.summary;if(D(`${I.heading("Summary")} ${o.moduleCount} module(s), ${o.templateCount} template(s), ${o.orphanCount} orphan, ${o.paletteSize} colour(s), ${o.cssVarCount} CSS var(s), ${o.customMacroCount} macro(s)`),s.designTokens.palette.length>0){D(""),D(I.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?I.muted(` (${i.varName})`):"";D(` ${i.value} ${I.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){D(""),D(I.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))D(` ${i}`)}if(s.graph.templates.length>0){D(""),D(I.heading("Template \u2192 modules"));for(let i of s.graph.templates)D(` ${i.id}: ${i.modules.length===0?I.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){D(""),D(I.heading("Orphan modules"));for(let i of s.graph.orphanModules)D(` ${i}`)}if(s.roundTripDiff.hasSnapshot){D(""),D(I.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)D(` ${I.muted("No changes from imported snapshot.")}`);else{D(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))D(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&D(` ${I.muted(`...and ${i.files.length-12} more`)}`)}}
|
|
2952
|
-
`));let n=
|
|
2953
|
-
`));try{process.platform==="darwin"?
|
|
2949
|
+
`)),a(),setTimeout(()=>process.exit(0),500)})})}catch(o){console.error(Ei.red(` Failed to start: ${o instanceof Error?o.message:String(o)}`)),process.exit(1)}}function gv(){let e=[$i(Qp,"../../ui"),$i(Qp,"../ui"),$i(process.cwd(),"ui")];for(let t of e)if(uv($i(t,"index.html")))return t;return null}y();import{resolve as tg}from"path";import{existsSync as Fa}from"fs";gt();Qe();ee();Ma();async function ng(e={}){let t=await og(e.path);if(e.fix){let o=Ci(t);if(o.applied.length>0){G(`Applied ${o.applied.length} auto-fix${o.applied.length===1?"":"es"}:`);for(let i of o.applied)D(` ${i}`)}else D(I.muted("No auto-fixable issues found."));if(o.skipped.length>0)for(let i of o.skipped)se(i)}let n=Hs(t);if(e.json){process.stdout.write(JSON.stringify(n,null,2)+`
|
|
2950
|
+
`),n.passed||process.exit(1);return}Ee(),await ge("Marketplace check");let s=`${n.errorCount} error${ja(n.errorCount)}, ${n.warningCount} warning${ja(n.warningCount)}, ${n.infoCount} note${ja(n.infoCount)}`;n.passed?G(`Theme passes Marketplace checks (${s}).`):V(`Theme is not yet ready: ${s}.`),Da("Errors",n.findings.filter(o=>o.severity==="error")),Da("Warnings",n.findings.filter(o=>o.severity==="warning")),Da("Notes",n.findings.filter(o=>o.severity==="info")),n.passed||(D(""),D(`Tip: run ${I.accent("vibespot marketplace check --fix")} to apply auto-fixable issues, then re-check.`),process.exit(1)),await fe("Looks good! Submit the theme via your HubSpot Marketplace dashboard.")}async function sg(e={}){let t=await og(e.path);Ee(),await ge("Marketplace listing details");let n=qn(t)??{},s=await Mt({message:"Category",options:Zt.map(u=>({value:u,label:u}))}),o=await Se({message:"Description (1\u20132 sentences shown on the listing)",placeholder:"A clean, fast SaaS landing page theme...",defaultValue:n.description??"",validate:u=>u.trim().length<40?"Aim for at least 40 characters.":void 0}),r=(await Se({message:"Key features (comma-separated, 2\u20135 items)",placeholder:"Hero, Pricing, Testimonials, Footer",defaultValue:(n.features??[]).join(", "),validate:u=>{let m=u.split(",").map(g=>g.trim()).filter(Boolean).length;if(m<2)return"Provide at least 2 features.";if(m>5)return"Provide at most 5 features."}})).split(",").map(u=>u.trim()).filter(Boolean),a=await Se({message:"Public support URL",placeholder:"https://example.com/support",defaultValue:n.supportUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),l=await Se({message:"Documentation URL (optional)",placeholder:"https://example.com/docs",defaultValue:n.documentationUrl??"",validate:u=>u&&!/^https?:\/\//i.test(u)?"Must start with http(s)://":void 0}),c=await Mt({message:"Pricing tier",options:[{value:"free",label:"Free"},{value:"paid",label:"Paid"}]}),d={category:s,description:o.trim(),features:r,supportUrl:a.trim()||void 0,documentationUrl:l.trim()||void 0,pricingTier:c,tags:n.tags};wi(t,d),G("Saved marketplace.json"),await fe(`Run ${I.accent("vibespot marketplace check")} to confirm the theme is ready to submit.`)}async function og(e){if(e){let o=tg(e);if(!Fa(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&Fa(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=tg(n);if(!Fa(s))throw new Error(`Theme not found: ${s}`);return s}function Da(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}function ja(e){return e===1?"":"s"}y();import{resolve as ig}from"path";import{existsSync as La}from"fs";import{basename as fv}from"path";gt();Qe();ee();Uo();async function rg(e={}){let t=await hv(e.path),n=fv(t);if(e.applyTokens){let i=Ho(t,n);i?G(`Wrote design tokens to ${i}`):D(I.muted("Skipped: theme already has shared CSS or no tokens were inferred."))}if(e.snapshot){let i=mr(t);e.json||G(`Wrote imported theme snapshot to ${i}`)}let s=Bo(t);e.json&&(process.stdout.write(JSON.stringify(s,null,2)+`
|
|
2951
|
+
`),process.exit(0)),Ee(),await ge("Inverse pipeline analyzer");let o=s.summary;if(D(`${I.heading("Summary")} ${o.moduleCount} module(s), ${o.templateCount} template(s), ${o.orphanCount} orphan, ${o.paletteSize} colour(s), ${o.cssVarCount} CSS var(s), ${o.customMacroCount} macro(s)`),s.designTokens.palette.length>0){D(""),D(I.heading("Palette (top by frequency)"));for(let i of s.designTokens.palette.slice(0,6)){let r=i.varName?I.muted(` (${i.varName})`):"";D(` ${i.value} ${I.muted(`\xD7${i.count}`)}${r}`)}}if(s.designTokens.fontFamilies.length>0){D(""),D(I.heading("Typography"));for(let i of s.designTokens.fontFamilies.slice(0,4))D(` ${i}`)}if(s.graph.templates.length>0){D(""),D(I.heading("Template \u2192 modules"));for(let i of s.graph.templates)D(` ${i.id}: ${i.modules.length===0?I.muted("(empty)"):i.modules.join(", ")}`)}if(s.graph.orphanModules.length>0){D(""),D(I.heading("Orphan modules"));for(let i of s.graph.orphanModules)D(` ${i}`)}if(s.roundTripDiff.hasSnapshot){D(""),D(I.heading("Round-trip diff"));let i=s.roundTripDiff;if(i.filesChanged===0)D(` ${I.muted("No changes from imported snapshot.")}`);else{D(` ${i.filesChanged} changed file(s): ${i.added} added, ${i.modified} modified, ${i.deleted} deleted`);for(let r of i.files.slice(0,12))D(` ${r.status.padEnd(8)} ${r.file}`);i.files.length>12&&D(` ${I.muted(`...and ${i.files.length-12} more`)}`)}}Ja("Errors",s.findings.filter(i=>i.severity==="error")),Ja("Warnings",s.findings.filter(i=>i.severity==="warning")),Ja("Notes",s.findings.filter(i=>i.severity==="info")),!e.applyTokens&&s.summary.cssVarCount===0&&s.designTokens.palette.length>0&&(D(""),D(`Tip: run ${I.accent("vibespot inverse --apply-tokens")} to seed a :root block from the inferred palette.`)),await fe("Analysis complete."),process.exit(0)}async function hv(e){if(e){let o=ig(e);if(!La(o))throw new Error(`Theme not found: ${o}`);return o}let t=R();if(t.lastThemePath&&La(t.lastThemePath))return t.lastThemePath;Ee();let n=await Se({message:"Path to the imported HubSpot theme directory:",placeholder:"./my-theme",validate:o=>o.trim()?void 0:"Path is required"}),s=ig(n);if(!La(s))throw new Error(`Theme not found: ${s}`);return s}function Ja(e,t){if(t.length!==0){D(""),D(I.heading(e));for(let n of t){let s=n.file?I.muted(`[${n.file}] `):"",o=n.severity==="error"?I.error("\u2717"):n.severity==="warning"?I.warn("!"):I.muted("\xB7");D(` ${o} ${s}${n.message}`),n.fix&&D(` ${I.muted("\u2192 "+n.fix)}`)}}}y();Cs();Ce();import{dirname as yv,join as Mi}from"path";import{existsSync as bv}from"fs";import{fileURLToPath as Sv}from"url";import{execFileSync as Ba}from"child_process";import Ii from"chalk";var ag=yv(Sv(import.meta.url)),vv=4200;async function lg(){let e=Ii.hex("#e8613a"),t=Ii.dim;console.log(""),console.log(e(" v vibeSpot \u2014 Email Mode")),console.log(t(` Starting...
|
|
2952
|
+
`));let n=xv();n||(console.error(Ii.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await _i({port:vv,uiDir:n,contentMode:"email"}),i=`http://localhost:${s}`;console.log(e(` v ${i}`)),console.log(t(` Email template mode \u2014 Press Ctrl+C to stop
|
|
2953
|
+
`));try{process.platform==="darwin"?Ba("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ba("cmd",["/c","start","",i],{stdio:"ignore"}):Ba("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(r=>{process.on("SIGINT",()=>{console.log(t(`
|
|
2954
2954
|
Saving session...`)),L(),o(),console.log(t(` Goodbye!
|
|
2955
|
-
`)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(
|
|
2955
|
+
`)),r(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(Ii.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function xv(){let e=[Mi(ag,"../../ui"),Mi(ag,"../ui"),Mi(process.cwd(),"ui")];for(let t of e)if(bv(Mi(t,"index.html")))return t;return null}oe();function cg(){let e=new wv;e.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(Sn()).action(eg),e.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(Ql),e.command("init").description("Check and install required tools").action(ec),e.command("convert").description("Convert a React project to HubSpot modules").action(tc),e.command("upload").description("Upload theme to HubSpot").action(nc),e.command("doctor").description("Diagnose environment issues").action(sc);let t=e.command("marketplace").description("Prepare a theme for HubSpot Marketplace submission");return t.command("check").description("Audit the theme against Marketplace requirements").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--fix","Apply auto-fixable findings before checking").action(n=>ng(n)),t.command("edit").description("Edit Marketplace listing metadata (marketplace.json)").option("-p, --path <path>","Path to the theme directory").action(n=>sg(n)),e.command("email").description("Launch email template generation mode").action(lg),e.command("inverse").description("Analyze an imported HubSpot theme: design tokens, module graph, field flags, round-trip risks").option("-p, --path <path>","Path to the theme directory").option("--json","Emit machine-readable JSON instead of formatted output").option("--apply-tokens","Seed css/<theme>-theme.css with the inferred :root block when missing").option("--snapshot","Capture the current theme as the imported round-trip baseline before analysis").action(n=>rg(n)),e}var Cv=cg();Cv.parseAsync(process.argv).catch(e=>{console.error(e),process.exit(1)});
|
|
2956
2956
|
//# sourceMappingURL=index.js.map
|