vibespot 1.0.3 → 1.0.4
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/README.md +2 -1
- package/dist/index.js +98 -98
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/ui/chat.js +11 -12
- package/ui/dashboard.js +59 -3
- package/ui/index.html +1 -0
- package/ui/styles.css +1 -7
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var
|
|
2
|
-
## `,o+s.length);return i>=0?e.slice(o,i).trim():e.slice(o).trim()}function
|
|
1
|
+
var al=Object.defineProperty;var J=(t,e)=>()=>(t&&(e=t(t=0)),e);var lt=(t,e)=>{for(var n in e)al(t,n,{get:e[n],enumerable:!0})};import Au from"path";import{fileURLToPath as ku}from"url";var g=J(()=>{"use strict"});import{readFileSync as ys,writeFileSync as ll,mkdirSync as $o,existsSync as mn}from"fs";import{dirname as cl,join as We}from"path";function I(t){return ys(t,"utf-8")}function H(t,e){$o(cl(t),{recursive:!0}),ll(t,e,"utf-8")}function S(t){return mn(t)}function Ae(t){$o(t,{recursive:!0})}function pn(t){let e=[We(import.meta.dirname,"../../assets",t),We(import.meta.dirname,"../assets",t),We(process.cwd(),"assets",t)];for(let n of e)if(mn(n))return n;throw new Error(`Asset not found: ${t}`)}function St(){if(bt)return bt;let t=[We(import.meta.dirname,"../../package.json"),We(import.meta.dirname,"../package.json"),We(process.cwd(),"package.json")];for(let e of t)if(mn(e))try{let n=JSON.parse(ys(e,"utf-8"));if(n.name==="vibespot"&&n.version)return bt=n.version,bt}catch{}return bt="dev",bt}function To(){if(un)return un;let t=[We(import.meta.dirname,"../../CHANGELOG.md"),We(import.meta.dirname,"../CHANGELOG.md"),We(process.cwd(),"CHANGELOG.md")];for(let e of t)if(mn(e))try{return un=ys(e,"utf-8"),un}catch{}return""}var bt,un,Z=J(()=>{"use strict";g();bt="";un=""});import{execSync as Eo}from"child_process";function T(t,e={}){try{return{stdout:Eo(t,{encoding:"utf-8",stdio:["pipe","pipe","pipe"],timeout:12e4,...e}).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 No(t,e={}){try{return Eo(t,{stdio:"inherit",timeout:3e5,...e}),!0}catch{return!1}}var ct=J(()=>{"use strict";g()});var _o={};lt(_o,{addHubSpotAccount:()=>Ot,getActiveHubSpotAccount:()=>Xe,getApiKeyForEngine:()=>ge,getConfigDir:()=>ml,getHubSpotPak:()=>he,isCliToolEnabled:()=>jt,loadConfig:()=>P,maskApiKey:()=>gn,removeHubSpotAccount:()=>bs,saveConfig:()=>q,setActiveHubSpotAccount:()=>Ss,setCliToolEnabled:()=>vs});import{join as Po}from"path";import{homedir as dl}from"os";import{chmodSync as ul}from"fs";function P(){if(!S(fn))return{};try{let t=JSON.parse(I(fn));return t.aiEngine==="api"&&(t.aiEngine="anthropic-api"),t}catch{return{}}}function ge(t,e){let n=e||P();switch(t){case"anthropic-api":case"api":return n.anthropicApiKey||process.env.ANTHROPIC_API_KEY;case"openai-api":return n.openaiApiKey||process.env.OPENAI_API_KEY;case"gemini-api":return n.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY;default:return}}function gn(t){return t.length<=12?"***":t.slice(0,7)+"..."+t.slice(-4)}function q(t){let n={...P(),...t};if(H(fn,JSON.stringify(n,null,2)),process.platform!=="win32")try{ul(fn,384)}catch{}}function ml(){return Mo}function Xe(){let t=P();if(!t.hubspotAccounts?.length)return null;let e=t.activeHubSpotAccount;if(e){let n=t.hubspotAccounts.find(s=>s.portalId===e);if(n)return n}return t.hubspotAccounts[0]||null}function Ot(t,e,n,s){let i=P().hubspotAccounts||[],a=i.findIndex(l=>l.portalId===e),r={portalId:e,portalName:n,personalAccessKey:t,dataCenter:s,addedAt:new Date().toISOString()};a>=0?i[a]=r:i.push(r),q({hubspotAccounts:i,activeHubSpotAccount:e})}function bs(t){let e=P(),n=(e.hubspotAccounts||[]).filter(o=>o.portalId!==t),s={hubspotAccounts:n};e.activeHubSpotAccount===t&&(s.activeHubSpotAccount=n[0]?.portalId||void 0),q(s)}function Ss(t){q({activeHubSpotAccount:t})}function he(){return Xe()?.personalAccessKey||null}function jt(t){return P().enabledCLITools?.includes(t)??!1}function vs(t,e){let n=P(),s=new Set(n.enabledCLITools||[]);e?s.add(t):s.delete(t),q({enabledCLITools:[...s]})}var Mo,fn,ee=J(()=>{"use strict";g();Z();Mo=Po(dl(),".vibespot"),fn=Po(Mo,"config.json")});import{readFileSync as gl}from"fs";import{basename as hl}from"path";async function Jo(t){let e=Fo.get(t);if(e&&e.expiresAt-Date.now()>Sl)return e;let n=await fetch(`${Be}/localdevauth/v1/auth/refresh`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({encodedOAuthRefreshToken:t})});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 Fo.set(t,o),o}async function vt(t){let{accessToken:e}=await Jo(t);return{Authorization:`Bearer ${e}`}}function wn(t){return t.replace(/^\/+/,"").split("/").filter(Boolean).map(encodeURIComponent).join("/")}function vl(t){return t.startsWith("pat-eu1-")?"eu1":t.startsWith("pat-na1-")?"na1":t.startsWith("CiRldTE")?"eu1":"na1"}function wl(t){return new Promise(e=>setTimeout(e,t))}async function Ut(t,e){let n=`HTTP ${t.status}`,s,o;try{let i=await t.json();if(i.message&&typeof i.message=="string"&&(n=i.message),i.category&&typeof i.category=="string"&&(s=i.category),i.errors&&Array.isArray(i.errors)&&i.errors.length>0){let a=i.errors[0];o=a.message||JSON.stringify(a)}}catch{try{let i=await t.text();i&&(n=i.slice(0,500))}catch{}}return{status:t.status,message:e?`${n} (${e})`:n,category:s,detail:o}}async function Wt(t,e,n=yl){for(let s=0;s<=n;s++){let o=await fetch(t,e);if(o.status===429||o.status>=500&&s<n){let i=bl*Math.pow(2,s);await wl(i);continue}return o}return fetch(t,e)}async function xn(t){let e=await Jo(t),n=`${Be}/account-info/v3/details`,s=await Wt(n,{headers:await vt(t)});if(!s.ok){let r=await Ut(s);throw new Error(`Failed to get account info: ${r.message}`)}let o=await s.json(),i=String(o.portalId||e.hubId||""),a=e.hubName||o.uiDomain||i;return{portalId:i,portalName:a,dataCenter:vl(t)}}async function Do(t,e,n){let s=gl(n),o=hl(n),i=new FormData,a=new Blob([s]);i.append("file",a,o);let r=`${Be}/cms/v3/source-code/published/content/${wn(e)}`,l=await Wt(r,{method:"PUT",headers:await vt(t),body:i});if(!l.ok){let c=await Ut(l,e);return{success:!1,path:e,error:c}}return{success:!0,path:e}}async function As(t,e){let n=`${Be}/cms/v3/source-code/published/content/${wn(e)}`,s=await Wt(n,{method:"DELETE",headers:await vt(t)});if(!s.ok&&s.status!==404){let o=await Ut(s,e);throw new Error(`Failed to delete ${e}: ${o.message}`)}}async function Lo(t,e){let n=`${Be}/cms/v3/source-code/published/content/${wn(e)}`,s=await Wt(n,{method:"GET",headers:await vt(t)});if(!s.ok){let i=await Ut(s,e);throw new Error(`Failed to download ${e}: ${i.message}`)}let o=await s.arrayBuffer();return Buffer.from(o)}async function Cn(t,e){let n=`${Be}/cms/v3/source-code/published/metadata/${wn(e)}`,s=await Wt(n,{method:"GET",headers:await vt(t)});if(s.status===404)return null;if(!s.ok){let o=await Ut(s,e);throw new Error(`Failed to get metadata for ${e}: ${o.message}`)}return await s.json()}async function Ho(t){let e=await vt(t),n=[`${Be}/cms/v3/source-code/published/metadata`,`${Be}/cms/v3/source-code/published/metadata/`,`${Be}/designmanager/v1/portals/content/listing`];for(let s of n)try{let o=await fetch(s,{method:"GET",headers:e});if(o.ok){let i=await o.json(),a=i.children||i.objects||(Array.isArray(i)?i:null);if(a&&a.length>0)return a.filter(r=>r.folder)}}catch{}return[]}var Be,yl,bl,Sl,Fo,ut=J(()=>{"use strict";g();Be="https://api.hubapi.com",yl=3,bl=1e3,Sl=300*1e3,Fo=new Map});var Vo={};lt(Vo,{fetchTheme:()=>Bt});import{mkdirSync as Ko,writeFileSync as Il}from"fs";import{join as kl,dirname as $l}from"path";async function Ts(t,e){let n=await Cn(t,e);if(!n)return[];if(!n.folder)return[n.path||e];let s=[],o=n.children||[];for(let i of o){let a=typeof i=="string"?i:i.name;if(!a)continue;let r=`${e}/${a}`;if(typeof i=="string")s.push(...await Ts(t,r));else{let l=i;l.folder?s.push(...await Ts(t,l.path||r)):s.push(l.path||r)}}return s}async function Tl(t,e,n){let s=0;async function o(){for(;s<t.length;){let a=s++;await n(t[a])}}let i=Array.from({length:Math.min(e,t.length)},()=>o());await Promise.all(i)}async function Bt(t,e,n,s={}){let o=s.concurrency??5,i=await Ts(t,e);if(i.length===0)throw new Error(`Theme "${e}" not found on HubSpot or is empty`);Ko(n,{recursive:!0}),await Tl(i,o,async a=>{let r=a.startsWith(e+"/")?a.slice(e.length+1):a,l=kl(n,r);Ko($l(l),{recursive:!0});let c=await Lo(t,a);Il(l,c),s.onFile?.(r)})}var Tn=J(()=>{"use strict";g();ut()});function xt(t){let e=Yo.get(t);if(e!==void 0)return e;try{e=I(pn(t))}catch{e=""}return Yo.set(t,e),e}function le(){return xt("conversion-guide.md")||"Conversion guide not found. Using built-in rules."}function zo(){return xt("design-guide.md")}function qo(){return xt("content-guide.md")}function Ze(){return xt("hubspot-rules.md")}function Xo(){return xt("humanify-guide.md")}function Qo(t){let e=xt("page-types.md");if(!e)return"";let s={landing_page:"## Landing Page",blog_post:"## Blog Post",website_page:"## Website Page",module_only:"## Module Only"}[t];if(!s)return"";let o=e.indexOf(s);if(o<0)return"";let i=e.indexOf(`
|
|
2
|
+
## `,o+s.length);return i>=0?e.slice(o,i).trim():e.slice(o).trim()}function Zo(t){return`You are a HubSpot CMS expert converting React/Tailwind pages to native HubSpot modules.
|
|
3
3
|
|
|
4
4
|
## Rules
|
|
5
5
|
Follow the conversion guide below EXACTLY. Key rules:
|
|
@@ -19,7 +19,7 @@ Follow the conversion guide below EXACTLY. Key rules:
|
|
|
19
19
|
${Ze()}
|
|
20
20
|
|
|
21
21
|
## Conversion Guide
|
|
22
|
-
${t}`}function
|
|
22
|
+
${t}`}function ei(t,e,n){return`Convert this React component to a HubSpot module named "${e}".
|
|
23
23
|
|
|
24
24
|
Return a JSON object with these keys:
|
|
25
25
|
- fieldsJson: complete fields.json content (as JSON string)
|
|
@@ -34,7 +34,7 @@ ${n}
|
|
|
34
34
|
React component source:
|
|
35
35
|
${t}
|
|
36
36
|
|
|
37
|
-
Return ONLY valid JSON, no markdown fences.`}function
|
|
37
|
+
Return ONLY valid JSON, no markdown fences.`}function ti(t,e,n){return`Create a shared CSS file for a HubSpot CMS landing page.
|
|
38
38
|
|
|
39
39
|
Extract the design system from the source CSS and Tailwind config below.
|
|
40
40
|
Use the class prefix ".${n}-" for all custom classes.
|
|
@@ -58,7 +58,7 @@ ${t}
|
|
|
58
58
|
Tailwind config:
|
|
59
59
|
${e}
|
|
60
60
|
|
|
61
|
-
Return ONLY the CSS content, no markdown fences.`}function
|
|
61
|
+
Return ONLY the CSS content, no markdown fences.`}function ni(t,e,n){return`Create a shared vanilla JS file for a HubSpot CMS landing page.
|
|
62
62
|
|
|
63
63
|
Convert the React hooks and interactive components below to plain JavaScript.
|
|
64
64
|
Use the class prefix "${n}-" to match the CSS.
|
|
@@ -76,7 +76,7 @@ ${t}
|
|
|
76
76
|
Interactive component sources:
|
|
77
77
|
${e}
|
|
78
78
|
|
|
79
|
-
Return ONLY the JavaScript content, no markdown fences.`}function
|
|
79
|
+
Return ONLY the JavaScript content, no markdown fences.`}function si(t,e,n){return`Create a HubSpot page template that assembles these modules:
|
|
80
80
|
|
|
81
81
|
${t.map((s,o)=>`${o+1}. ${s}.module`).join(`
|
|
82
82
|
`)}
|
|
@@ -91,21 +91,21 @@ Template requirements:
|
|
|
91
91
|
- Each module in its own dnd_section with padding zeroed and full_width=true
|
|
92
92
|
- dnd_area label: "${e} Landing Page"
|
|
93
93
|
|
|
94
|
-
Return ONLY the template HTML content, no markdown fences.`}var
|
|
95
|
-
`),"utf-8")}function
|
|
96
|
-
`)){let i=o.split("|");if(i.length<4)continue;let a=parseInt(i[3],10)*1e3;s.push({hash:i[0],fullHash:i[1],message:i[2],timestamp:a,date:new Date(a).toISOString()})}return s}function
|
|
97
|
-
`)){let r=a.split("|");if(r.length<4)continue;let l=parseInt(r[3],10)*1e3;i.push({hash:r[0],fullHash:r[1],message:r[2],timestamp:l,date:new Date(l).toISOString()})}return i}function Ni(t,e){if(!Ee())return{success:!1,error:"Git not available"};if(!ze(Je(t,".git")))return{success:!1,error:"Not a git repo"};if(!ki(e))return{success:!1,error:"Invalid commit hash"};let n=T(`git cat-file -t ${e}`,{cwd:t});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${e} not found`};let s=T(`git log --format="%s" -1 ${e}`,{cwd:t}),o=s.success?s.stdout:e,i=T(`git checkout ${e} -- .`,{cwd:t});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let a=`Rollback to: ${o}`.slice(0,72);return T(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:t}),{success:!0}}function Mi(t,e,n,s){if(!Ee())return{success:!1,error:"Git not available"};if(!ze(Je(t,".git")))return{success:!1,error:"Not a git repo"};if(!ki(n))return{success:!1,error:"Invalid commit hash"};let o=T(`git cat-file -t ${n}`,{cwd:t});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=T(`git log --format="%s" -1 ${n}`,{cwd:t}),a=i.success?i.stdout:n,r=0;for(let d of s)T(`git checkout ${n} -- "${d}"`,{cwd:t}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};T("git add -A",{cwd:t});let c=`${`[${e}] `}Rollback to: ${a}`.slice(0,72);return T(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:t}),{success:!0}}var Ln,Yt=J(()=>{"use strict";g();ct();Ln=null});import{readFileSync as tc,existsSync as nc,writeFileSync as sc,mkdirSync as oc}from"fs";import{join as Es}from"path";function mt(t){let e=v();e&&(e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages)}function et(){let t=v();if(!t)return;let e=Ce();e&&(e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages)}function tt(t,e,n){let s=v();if(!s)return;let o={role:t,content:e,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),et(),ic()}function Pi(t){let e=v();e&&(e.assets||(e.assets=[]),e.assets.push(t),e.updatedAt=Date.now(),D())}function De(t){let e=v();if(e){if(t.sharedCss!==void 0&&(e.sharedCss=t.sharedCss),t.sharedJs!==void 0&&(e.sharedJs=t.sharedJs),t.template!==void 0&&(e.template=t.template),t.modules)for(let n of t.modules){let s=n.moduleName.toLowerCase(),o=e.modules.findIndex(i=>i.moduleName.toLowerCase()===s);o>=0?e.modules[o]=n:(e.modules.push(n),e.moduleOrder.some(i=>i.toLowerCase()===s)||e.moduleOrder.push(n.moduleName))}e.updatedAt=Date.now(),et()}}function At(t){let e=v();e&&(e.moduleOrder=t,e.updatedAt=Date.now(),et())}function _i(t){let e=v();e&&(e.modules=e.modules.filter(n=>n.moduleName!==t),e.moduleOrder=e.moduleOrder.filter(n=>n!==t),e.updatedAt=Date.now(),et())}function Ri(t){let e=v();e&&(e.moduleOrder=e.moduleOrder.filter(n=>n!==t),e.updatedAt=Date.now(),et())}function Oi(t,e,n){let s=v();if(!s)return;let o=s.modules.find(i=>i.moduleName===t);if(o)try{let i=JSON.parse(o.fieldsJson);Fi(i,e,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),et()}catch{}}function me(){let t=v();if(!t)return[];let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function ic(){let t=v();if(t)try{let e=Es(t.themePath,".vibespot");oc(e,{recursive:!0});let n={sessionId:t.id,themeName:t.themeName,messages:t.messages,updatedAt:Date.now()};sc(Es(e,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function ji(t){let e=Es(t,".vibespot","chat.json");if(!nc(e))return[];try{let n=JSON.parse(tc(e,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Fi(t,e,n){let s=e.split("."),o=s[0],i=t.find(a=>a.name===o);i&&(s.length===1?i.default=n:i.children&&Fi(i.children,s.slice(1).join("."),n))}var Gn=J(()=>{"use strict";g();qt();zt()});function Un(t){if(t.templates&&t.templates.length>0)return;if(!t.modules||t.modules.length===0){t.templates=[],t.activeTemplateId="";return}let e=`lp-${t.themeName}`,n={id:e,label:`${t.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${t.themeName}.html`,modules:[...t.modules],moduleOrder:[...t.moduleOrder],sharedCss:t.sharedCss||"",sharedJs:t.sharedJs||"",template:t.template||"",messages:[...t.messages]};t.templates=[n],t.activeTemplateId=e}function Ce(){let t=v();return!t||!t.activeTemplateId||!t.templates?.length?null:t.templates.find(e=>e.id===t.activeTemplateId)||null}function Ns(t){let e=v();if(!e)return!1;let n=e.templates.find(s=>s.id===t);return n?(e.activeTemplateId=t,mt(n),e.updatedAt=Date.now(),!0):!1}function Ji(t,e){let n=v();if(!n)throw new Error("No active session");let s=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${t==="blog_post"?"bp":t==="website_page"?"wp":t==="module_only"?"mo":"lp"}-${s}`,a={id:i,label:e,pageType:t,templateFile:t==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(a),n.activeTemplateId=i,mt(a),n.updatedAt=Date.now(),a}function Di(t,e){let n=v();if(!n)return null;let s=n.templates.find(c=>c.id===t);if(!s)return null;let o=e||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),r=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:r,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${r}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[]};return n.templates.push(l),n.activeTemplateId=r,mt(l),n.updatedAt=Date.now(),l}function Li(t,e){let n=v();if(!n)return!1;let s=n.templates.find(o=>o.id===t);return s?(s.label=e,n.updatedAt=Date.now(),!0):!1}function Hi(t){let e=v();if(!e)return!1;let n=e.templates.findIndex(s=>s.id===t);return n<0?!1:(e.templates.splice(n,1),e.activeTemplateId===t&&(e.templates.length>0?Ns(e.templates[0].id):(e.activeTemplateId="",e.modules=[],e.moduleOrder=[],e.sharedCss="",e.sharedJs="",e.template="",e.messages=[])),e.updatedAt=Date.now(),!0)}function nt(){let t=v();if(!t)return[];let e=new Map;for(let n of t.templates)for(let s of n.modules){let o=e.get(s.moduleName);o?o.usedIn.push(n.label):e.set(s.moduleName,{module:s,usedIn:[n.label]})}return Array.from(e.values())}var zt=J(()=>{"use strict";g();qt();Gn()});import{readFileSync as qe,readdirSync as Os,existsSync as ye,writeFileSync as Wn,mkdirSync as Gi,rmSync as Ms,renameSync as Ps}from"fs";import{join as ie,dirname as rc}from"path";import{homedir as ac}from"os";function Bn(){if(It)return It;try{return ye(_s)?(It=JSON.parse(qe(_s,"utf-8")),It):Rs()}catch{return Rs()}}function Kn(t){It=t;try{Gi(te,{recursive:!0}),Wn(_s,JSON.stringify(t),"utf-8")}catch{}}function Rs(){if(!ye(te))return[];let t=[];for(let e of Os(te).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(qe(ie(te,e),"utf-8")),s=n.templates||[];t.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length})}catch{}return It=t,Kn(t),t}function lc(t){let e=Bn(),n=t.templates||[],s={id:t.id,themeName:t.themeName,updatedAt:t.updatedAt,moduleCount:n.reduce((i,a)=>i+(a.modules?.length||0),0),templateCount:n.length},o=e.findIndex(i=>i.id===t.id);o>=0?e[o]=s:e.push(s),Kn(e)}function cc(t){let e=Bn().filter(n=>n.id!==t);Kn(e)}function dc(t){let e=Bn().filter(n=>n.themeName!==t);Kn(e)}function v(){return be}function uc(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Xt(t,e){let n={id:uc(),themePath:t,themeName:e,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return be=n,Hn(t),n}function D(){if(!be)return;Gi(te,{recursive:!0});let t=ie(te,`${be.id}.json`);Wn(t,JSON.stringify(be,null,2),"utf-8"),lc(be)}function Vn(t){let e=ie(te,t+".json");if(!ye(e))return null;try{let n=JSON.parse(qe(e,"utf-8"));return n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Un(n),be=n,n}catch{return null}}function kt(){return ye(te)?Bn():[]}function Ui(t,e=!1){let n=ie(te,t+".json"),s="";if(e)try{let o=JSON.parse(qe(n,"utf-8"));s=o.themeName||"",o.themePath&&ye(o.themePath)&&Ms(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(qe(n,"utf-8")).themeName||""}catch{}try{ye(n)&&Ms(n)}catch{}if(s&&ye(te)){for(let o of Os(te).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(qe(ie(te,o),"utf-8")).themeName===s&&Ms(ie(te,o))}catch{}dc(s)}else cc(t);be?.id===t&&(be=null)}function Wi(t,e){let n=ie(te,t+".json");if(!ye(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(qe(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===e)return{ok:!0};let i=s.themePath,a=ie(rc(i),e);if(ye(i)){if(ye(a))return{ok:!1,error:"A project with that name already exists"};try{Ps(i,a)}catch(p){return{ok:!1,error:`Failed to rename folder: ${p instanceof Error?p.message:String(p)}`}}let r=ie(a,"css",`${o}-theme.css`),l=ie(a,"css",`${e}-theme.css`);if(ye(r))try{Ps(r,l)}catch{}let c=ie(a,"js",`${o}-animations.js`),d=ie(a,"js",`${e}-animations.js`);if(ye(c))try{Ps(c,d)}catch{}let u=ie(a,"theme.json");if(ye(u))try{let p=JSON.parse(qe(u,"utf-8"));p.label=e,p.name=e,Wn(u,JSON.stringify(p,null,2),"utf-8")}catch{}}if(ye(te))for(let r of Os(te).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(qe(ie(te,r),"utf-8"));l.themeName===o&&(l.themeName=e,l.themePath=a,l.updatedAt=Date.now(),Wn(ie(te,r),JSON.stringify(l,null,2),"utf-8"))}catch{}return be&&be.themeName===o&&(be.themeName=e,be.themePath=a,be.updatedAt=Date.now()),Rs(),{ok:!0}}var te,_s,It,be,qt=J(()=>{"use strict";g();Yt();zt();te=ie(ac(),".vibespot","sessions"),_s=ie(te,"_index.json"),It=null;be=null});import{readFileSync as js,readdirSync as Zt,existsSync as pe,writeFileSync as ke,mkdirSync as Qt,rmSync as Bi}from"fs";import{join as _}from"path";function re(t){try{return js(t,"utf-8")}catch{return""}}function mc(t){let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function pc(t,e){let n=re(t);if(!n||e==="home.html"||e.endsWith("-listing.html"))return null;let s=e.replace(/\.html$/,""),o="landing_page";s.startsWith("bp-")?o="blog_post":s.startsWith("wp-")?o="website_page":s.startsWith("mo-")&&(o="module_only");let i=s,a=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);a&&(i=a[1].trim());let r=/dnd_module\s+path=["']\.\.\/modules\/(.+?)\.module["']/g,l=[],c;for(;(c=r.exec(n))!==null;)l.push(c[1]);return{id:s,label:i,pageType:o,moduleNames:l,templateContent:n,filename:e}}function fc(t,e,n,s,o){if(!pe(t))return[];let i=[],a=Zt(t).filter(r=>r.endsWith(".html")&&r!=="home.html");for(let r of a){let l=_(t,r),c=pc(l,r);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let p of c.moduleNames){let f=e.get(p);f&&(d.push(f),u.push(p))}i.push({id:c.id,label:c.label,pageType:c.pageType,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:n,sharedJs:s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function en(t){let e=v();if(!e)return;let n=ji(t);n.length>0&&e.messages.length===0&&(e.messages=n),Hn(t);let s=_(t,"modules");if(!pe(s))return;let o=Zt(s,{withFileTypes:!0});for(let y of o){if(!y.isDirectory()||!y.name.endsWith(".module"))continue;let b=_(s,y.name),A=y.name.replace(/\.module$/,""),w={moduleName:A,fieldsJson:re(_(b,"fields.json")),metaJson:re(_(b,"meta.json")),moduleHtml:re(_(b,"module.html")),moduleCss:re(_(b,"module.css")),moduleJs:re(_(b,"module.js"))||void 0};w.fieldsJson&&w.moduleHtml&&(e.modules.push(w),e.moduleOrder.push(A))}let i=_(t,"css"),a=_(t,"js"),r="",l="";if(pe(i)){let y=Zt(i).filter(b=>b.endsWith("-theme.css"));y.length>0&&(r=re(_(i,y[0])),e.sharedCss=r)}if(pe(a)){let y=Zt(a).filter(b=>b.endsWith("-animations.js"));y.length>0&&(l=re(_(a,y[0])),e.sharedJs=l)}let c=_(t,".vibespot","styleguide.md"),d=_(t,".vibespot","brandvoice.md"),u=_(t,".vibespot","theme-context.md");(pe(c)||pe(d)||pe(u))&&(e.brandAssets||(e.brandAssets={}),pe(c)&&(e.brandAssets.styleguide=re(c)),pe(d)&&(e.brandAssets.brandvoice=re(d)),pe(u)&&(e.brandAssets.themeContext=re(u)));let p=_(t,"templates"),f=new Map(e.modules.map(y=>[y.moduleName,y])),h=fc(p,f,r,l,e.messages);if(h.length>0){e.templates=h,e.activeTemplateId=h[0].id;let y=h[0].moduleOrder;if(y.length>0){let b=new Set(e.moduleOrder),A=y.filter(w=>b.has(w));for(let w of e.moduleOrder)A.includes(w)||A.push(w);e.moduleOrder=A}mt(h[0])}else e.templates||(e.templates=[]),e.activeTemplateId||(e.activeTemplateId=""),Un(e)}function st(){let t=v();if(!t)return;let e=t.themePath,n=new Map;if(t.templates.length>0)for(let l of t.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of t.modules)n.set(l.moduleName,l);let s=_(e,"modules");Qt(s,{recursive:!0});for(let l of n.values())Qt(_(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=_(s,`${l.moduleName}.module`);ke(_(c,"fields.json"),l.fieldsJson,"utf-8"),ke(_(c,"meta.json"),l.metaJson,"utf-8"),ke(_(c,"module.html"),l.moduleHtml,"utf-8"),ke(_(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&ke(_(c,"module.js"),l.moduleJs,"utf-8")}if(t.sharedCss){let l=_(e,"css");Qt(l,{recursive:!0}),ke(_(l,`${t.themeName}-theme.css`),t.sharedCss,"utf-8")}if(t.sharedJs){let l=_(e,"js");Qt(l,{recursive:!0}),ke(_(l,`${t.themeName}-animations.js`),t.sharedJs,"utf-8")}let o=_(e,"templates");Qt(o,{recursive:!0});let i=_(o,"home.html");(t.templates.length>0||t.modules.length>0)&&pe(i)&&Bi(i,{force:!0});let r=new Set;if(t.templates.length>0)for(let l of t.templates){if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||yc(l),d=Ki(c,l.label,l.pageType),u=`${l.id}.html`;ke(_(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&(bc(o,l),r.add(`${l.id}-listing.html`))}else if(t.modules.length>0){let l=t.template||Sc(),c=Ki(l,`${t.themeName} Landing Page`),d=`lp-${t.themeName}.html`;ke(_(o,d),c,"utf-8"),r.add(d)}try{for(let l of Zt(o))l.startsWith("lp-")&&l.endsWith(".html")&&!r.has(l)&&Bi(_(o,l),{force:!0})}catch{}gc(),hc()}function Vi(){let t=v();t&&(t.modules=[],t.moduleOrder=[],t.sharedCss="",t.sharedJs="",t.template="",en(t.themePath),t.updatedAt=Date.now(),et())}function Yi(){let t=v();if(!t)return;let e=Ce();if(!e)return;let n=t.themePath,s=_(n,"modules");e.modules=[];for(let o of e.moduleOrder){let i=_(s,`${o}.module`);if(!pe(i))continue;let a={moduleName:o,fieldsJson:re(_(i,"fields.json")),metaJson:re(_(i,"meta.json")),moduleHtml:re(_(i,"module.html")),moduleCss:re(_(i,"module.css")),moduleJs:re(_(i,"module.js"))||void 0};a.fieldsJson&&a.moduleHtml&&e.modules.push(a)}if(e.templateFile){let o=_(n,e.templateFile);pe(o)&&(e.template=re(o))}mt(e),t.updatedAt=Date.now()}function gc(){let t=v();if(!t)return;let e=_(t.themePath,"templates","layouts","base.html");if(pe(e))try{let n=js(e,"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+`
|
|
94
|
+
Return ONLY the template HTML content, no markdown fences.`}var Yo,Ve=J(()=>{"use strict";g();Z();Yo=new Map});var $i=J(()=>{"use strict";g()});import{existsSync as ze,writeFileSync as nc,mkdirSync as sc}from"fs";import{join as Je}from"path";function Ei(t){return/^[0-9a-f]{4,40}$/i.test(t)}function Ee(){return Hn!==null||(Hn=T("git --version").success),Hn}function Gn(t){if(!Ee())return!1;if(ze(Je(t,".git")))return Ti(t),!0;let e=T("git init",{cwd:t});return e.success?(oc(t),Ti(t),T("git add -A",{cwd:t}),T('git commit -m "Initial theme"',{cwd:t}),!0):(console.warn(`[project-git] git init failed in ${t}: ${e.stderr}`),!1)}function Ti(t){let e=Je(t,".vibespot");ze(e)||sc(e,{recursive:!0})}function oc(t){let e=Je(t,".gitignore");nc(e,[".vibespot/","node_modules/",""].join(`
|
|
95
|
+
`),"utf-8")}function Ns(t,e){if(!Ee()||!ze(Je(t,".git"))||(T("git add -A",{cwd:t}),T("git diff --cached --quiet",{cwd:t}).success))return null;let s=e.length>72?e.slice(0,69)+"...":e,o=T(`git commit -m "${s.replace(/"/g,'\\"')}"`,{cwd:t});if(!o.success)return console.warn(`[project-git] commit failed: ${o.stderr}`),null;let i=T("git rev-parse --short HEAD",{cwd:t});return i.success?i.stdout:null}function Ni(t,e,n,s){if(!Ee()||!ze(Je(t,".git")))return null;for(let u of s){let p=Je(t,u);ze(p)&&T(`git add "${u}"`,{cwd:t})}if(T("git diff --cached --quiet",{cwd:t}).success)return null;let i=`[${e}] `,a=72-i.length,r=n.length>a?n.slice(0,a-3)+"...":n,l=i+r,c=T(`git commit -m "${l.replace(/"/g,'\\"')}"`,{cwd:t});if(!c.success)return console.warn(`[project-git] template commit failed: ${c.stderr}`),null;let d=T("git rev-parse --short HEAD",{cwd:t});return d.success?d.stdout:null}function Pi(t,e=50){if(!Ee())return[];if(!ze(Je(t,".git")))return[];let n=T(`git log --pretty=format:"%h|%H|%s|%at" -n ${e}`,{cwd:t});if(!n.success||!n.stdout.trim())return[];let s=[];for(let o of n.stdout.split(`
|
|
96
|
+
`)){let i=o.split("|");if(i.length<4)continue;let a=parseInt(i[3],10)*1e3;s.push({hash:i[0],fullHash:i[1],message:i[2],timestamp:a,date:new Date(a).toISOString()})}return s}function Mi(t,e,n=50){if(!Ee())return[];if(!ze(Je(t,".git")))return[];let s=e.replace(/[[\]\\]/g,"\\$&"),o=T(`git log --grep="\\[${s}\\]" --pretty=format:"%h|%H|%s|%at" -n ${n}`,{cwd:t});if(!o.success||!o.stdout.trim())return[];let i=[];for(let a of o.stdout.split(`
|
|
97
|
+
`)){let r=a.split("|");if(r.length<4)continue;let l=parseInt(r[3],10)*1e3;i.push({hash:r[0],fullHash:r[1],message:r[2],timestamp:l,date:new Date(l).toISOString()})}return i}function _i(t,e){if(!Ee())return{success:!1,error:"Git not available"};if(!ze(Je(t,".git")))return{success:!1,error:"Not a git repo"};if(!Ei(e))return{success:!1,error:"Invalid commit hash"};let n=T(`git cat-file -t ${e}`,{cwd:t});if(!n.success||n.stdout.trim()!=="commit")return{success:!1,error:`Commit ${e} not found`};let s=T(`git log --format="%s" -1 ${e}`,{cwd:t}),o=s.success?s.stdout:e,i=T(`git checkout ${e} -- .`,{cwd:t});if(!i.success)return{success:!1,error:`Checkout failed: ${i.stderr}`};let a=`Rollback to: ${o}`.slice(0,72);return T(`git commit -m "${a.replace(/"/g,'\\"')}"`,{cwd:t}),{success:!0}}function Ri(t,e,n,s){if(!Ee())return{success:!1,error:"Git not available"};if(!ze(Je(t,".git")))return{success:!1,error:"Not a git repo"};if(!Ei(n))return{success:!1,error:"Invalid commit hash"};let o=T(`git cat-file -t ${n}`,{cwd:t});if(!o.success||o.stdout.trim()!=="commit")return{success:!1,error:`Commit ${n} not found`};let i=T(`git log --format="%s" -1 ${n}`,{cwd:t}),a=i.success?i.stdout:n,r=0;for(let d of s)T(`git checkout ${n} -- "${d}"`,{cwd:t}).success&&r++;if(r===0)return{success:!1,error:"No files could be restored from that commit"};T("git add -A",{cwd:t});let c=`${`[${e}] `}Rollback to: ${a}`.slice(0,72);return T(`git commit -m "${c.replace(/"/g,'\\"')}"`,{cwd:t}),{success:!0}}var Hn,Yt=J(()=>{"use strict";g();ct();Hn=null});import{readFileSync as ic,existsSync as Oi,writeFileSync as rc,mkdirSync as ac,rmSync as lc}from"fs";import{join as Un}from"path";function mt(t){let e=v();e&&(e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages)}function et(){let t=v();if(!t)return;let e=Ce();e&&(e.modules=t.modules,e.moduleOrder=t.moduleOrder,e.sharedCss=t.sharedCss,e.sharedJs=t.sharedJs,e.template=t.template,e.messages=t.messages)}function tt(t,e,n){let s=v();if(!s)return;let o={role:t,content:e,timestamp:Date.now()};n&&(o.pipeline=n),s.messages.push(o),s.updatedAt=Date.now(),et(),cc()}function ji(t){let e=v();e&&(e.assets||(e.assets=[]),e.assets.push(t),e.updatedAt=Date.now(),D())}function De(t){let e=v();if(e){if(t.sharedCss!==void 0&&(e.sharedCss=t.sharedCss),t.sharedJs!==void 0&&(e.sharedJs=t.sharedJs),t.template!==void 0&&(e.template=t.template),t.modules)for(let n of t.modules){let s=n.moduleName.toLowerCase(),o=e.modules.findIndex(i=>i.moduleName.toLowerCase()===s);o>=0?e.modules[o]=n:(e.modules.push(n),e.moduleOrder.some(i=>i.toLowerCase()===s)||e.moduleOrder.push(n.moduleName))}e.updatedAt=Date.now(),et()}}function At(t){let e=v();e&&(e.moduleOrder=t,e.updatedAt=Date.now(),et())}function Fi(t){let e=v();if(e){e.modules=e.modules.filter(n=>n.moduleName!==t),e.moduleOrder=e.moduleOrder.filter(n=>n!==t);for(let n of e.templates)n.modules=n.modules.filter(s=>s.moduleName!==t),n.moduleOrder=n.moduleOrder.filter(s=>s!==t);if(e.themePath){let n=Un(e.themePath,"modules",`${t}.module`);Oi(n)&&lc(n,{recursive:!0,force:!0})}e.updatedAt=Date.now(),et()}}function Ji(t){let e=v();e&&(e.moduleOrder=e.moduleOrder.filter(n=>n!==t),e.updatedAt=Date.now(),et())}function Di(t,e,n){let s=v();if(!s)return;let o=s.modules.find(i=>i.moduleName===t);if(o)try{let i=JSON.parse(o.fieldsJson);Hi(i,e,n),o.fieldsJson=JSON.stringify(i,null,2),s.updatedAt=Date.now(),et()}catch{}}function me(){let t=v();if(!t)return[];let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function cc(){let t=v();if(t)try{let e=Un(t.themePath,".vibespot");ac(e,{recursive:!0});let n={sessionId:t.id,themeName:t.themeName,messages:t.messages,updatedAt:Date.now()};rc(Un(e,"chat.json"),JSON.stringify(n,null,2),"utf-8")}catch{}}function Li(t){let e=Un(t,".vibespot","chat.json");if(!Oi(e))return[];try{let n=JSON.parse(ic(e,"utf-8"));return Array.isArray(n.messages)?n.messages:[]}catch{return[]}}function Hi(t,e,n){let s=e.split("."),o=s[0],i=t.find(a=>a.name===o);i&&(s.length===1?i.default=n:i.children&&Hi(i.children,s.slice(1).join("."),n))}var Wn=J(()=>{"use strict";g();qt();zt()});import{existsSync as Ps,rmSync as Ms}from"fs";import{join as Xt}from"path";function Bn(t){if(t.templates&&t.templates.length>0)return;if(!t.modules||t.modules.length===0){t.templates=[],t.activeTemplateId="";return}let e=`lp-${t.themeName}`,n={id:e,label:`${t.themeName} Landing Page`,pageType:"landing_page",templateFile:`templates/lp-${t.themeName}.html`,modules:[...t.modules],moduleOrder:[...t.moduleOrder],sharedCss:t.sharedCss||"",sharedJs:t.sharedJs||"",template:t.template||"",messages:[...t.messages]};t.templates=[n],t.activeTemplateId=e}function Ce(){let t=v();return!t||!t.activeTemplateId||!t.templates?.length?null:t.templates.find(e=>e.id===t.activeTemplateId)||null}function _s(t){let e=v();if(!e)return!1;let n=e.templates.find(s=>s.id===t);return n?(e.activeTemplateId=t,mt(n),e.updatedAt=Date.now(),!0):!1}function Gi(t,e){let n=v();if(!n)throw new Error("No active session");let s=e.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),i=`${t==="blog_post"?"bp":t==="website_page"?"wp":t==="module_only"?"mo":"lp"}-${s}`,a={id:i,label:e,pageType:t,templateFile:t==="module_only"?"":`templates/${i}.html`,modules:[],moduleOrder:[],sharedCss:"",sharedJs:"",template:"",messages:[]};return n.templates.push(a),n.activeTemplateId=i,mt(a),n.updatedAt=Date.now(),a}function Ui(t,e){let n=v();if(!n)return null;let s=n.templates.find(c=>c.id===t);if(!s)return null;let o=e||`${s.label} (Copy)`,i=o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,""),r=`${s.pageType==="blog_post"?"bp":s.pageType==="website_page"?"wp":s.pageType==="module_only"?"mo":"lp"}-${i}`,l={id:r,label:o,pageType:s.pageType,templateFile:s.pageType==="module_only"?"":`templates/${r}.html`,modules:s.modules.map(c=>({...c})),moduleOrder:[...s.moduleOrder],sharedCss:s.sharedCss,sharedJs:s.sharedJs,template:s.template,messages:[]};return n.templates.push(l),n.activeTemplateId=r,mt(l),n.updatedAt=Date.now(),l}function Wi(t,e){let n=v();if(!n)return!1;let s=n.templates.find(o=>o.id===t);return s?(s.label=e,n.updatedAt=Date.now(),!0):!1}function Bi(t,e=!1){let n=v();if(!n)return!1;let s=n.templates.findIndex(i=>i.id===t);if(s<0)return!1;let o=n.templates.splice(s,1)[0];if(n.themePath){let i=Xt(n.themePath,"templates"),a=`${o.id}.html`,r=Xt(i,a);if(Ps(r)&&Ms(r,{force:!0}),o.pageType==="blog_post"){let l=Xt(i,`${o.id}-listing.html`);Ps(l)&&Ms(l,{force:!0})}}if(e&&o.modules.length>0){let i=new Set;for(let r of n.templates)for(let l of r.modules)i.add(l.moduleName);for(let r of n.modules)i.add(r.moduleName);let a=o.modules.map(r=>r.moduleName).filter(r=>!i.has(r));if(n.themePath&&a.length>0){let r=Xt(n.themePath,"modules");for(let l of a){let c=Xt(r,`${l}.module`);Ps(c)&&Ms(c,{recursive:!0,force:!0})}}}return n.activeTemplateId===t&&(n.templates.length>0?_s(n.templates[0].id):(n.activeTemplateId="",n.modules=[],n.moduleOrder=[],n.sharedCss="",n.sharedJs="",n.template="",n.messages=[])),n.updatedAt=Date.now(),!0}function nt(){let t=v();if(!t)return[];let e=new Map;for(let n of t.templates)for(let s of n.modules){let o=e.get(s.moduleName);o?o.usedIn.push(n.label):e.set(s.moduleName,{module:s,usedIn:[n.label]})}return Array.from(e.values())}var zt=J(()=>{"use strict";g();qt();Wn()});import{readFileSync as qe,readdirSync as Js,existsSync as ye,writeFileSync as Kn,mkdirSync as Ki,rmSync as Rs,renameSync as Os}from"fs";import{join as ie,dirname as dc}from"path";import{homedir as uc}from"os";function Vn(){if(It)return It;try{return ye(js)?(It=JSON.parse(qe(js,"utf-8")),It):Fs()}catch{return Fs()}}function Yn(t){It=t;try{Ki(te,{recursive:!0}),Kn(js,JSON.stringify(t),"utf-8")}catch{}}function Fs(){if(!ye(te))return[];let t=[];for(let e of Js(te).filter(n=>n.endsWith(".json")&&n!=="_index.json"))try{let n=JSON.parse(qe(ie(te,e),"utf-8")),s=n.templates||[];t.push({id:n.id,themeName:n.themeName,updatedAt:n.updatedAt,moduleCount:s.reduce((o,i)=>o+(i.modules?.length||0),0),templateCount:s.length})}catch{}return It=t,Yn(t),t}function mc(t){let e=Vn(),n=t.templates||[],s={id:t.id,themeName:t.themeName,updatedAt:t.updatedAt,moduleCount:n.reduce((i,a)=>i+(a.modules?.length||0),0),templateCount:n.length},o=e.findIndex(i=>i.id===t.id);o>=0?e[o]=s:e.push(s),Yn(e)}function pc(t){let e=Vn().filter(n=>n.id!==t);Yn(e)}function fc(t){let e=Vn().filter(n=>n.themeName!==t);Yn(e)}function v(){return be}function gc(){return`vibe-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,8)}`}function Qt(t,e){let n={id:gc(),themePath:t,themeName:e,templates:[],activeTemplateId:"",messages:[],modules:[],sharedCss:"",sharedJs:"",template:"",moduleOrder:[],createdAt:Date.now(),updatedAt:Date.now()};return be=n,Gn(t),n}function D(){if(!be)return;Ki(te,{recursive:!0});let t=ie(te,`${be.id}.json`);Kn(t,JSON.stringify(be,null,2),"utf-8"),mc(be)}function zn(t){let e=ie(te,t+".json");if(!ye(e))return null;try{let n=JSON.parse(qe(e,"utf-8"));return n.templates||(n.templates=[]),n.activeTemplateId||(n.activeTemplateId=""),Bn(n),be=n,n}catch{return null}}function kt(){return ye(te)?Vn():[]}function Vi(t,e=!1){let n=ie(te,t+".json"),s="";if(e)try{let o=JSON.parse(qe(n,"utf-8"));s=o.themeName||"",o.themePath&&ye(o.themePath)&&Rs(o.themePath,{recursive:!0,force:!0})}catch{}else try{s=JSON.parse(qe(n,"utf-8")).themeName||""}catch{}try{ye(n)&&Rs(n)}catch{}if(s&&ye(te)){for(let o of Js(te).filter(i=>i.endsWith(".json")&&i!=="_index.json"))try{JSON.parse(qe(ie(te,o),"utf-8")).themeName===s&&Rs(ie(te,o))}catch{}fc(s)}else pc(t);be?.id===t&&(be=null)}function Yi(t,e){let n=ie(te,t+".json");if(!ye(n))return{ok:!1,error:"Session not found"};let s;try{s=JSON.parse(qe(n,"utf-8"))}catch{return{ok:!1,error:"Failed to read session"}}let o=s.themeName;if(o===e)return{ok:!0};let i=s.themePath,a=ie(dc(i),e);if(ye(i)){if(ye(a))return{ok:!1,error:"A project with that name already exists"};try{Os(i,a)}catch(p){return{ok:!1,error:`Failed to rename folder: ${p instanceof Error?p.message:String(p)}`}}let r=ie(a,"css",`${o}-theme.css`),l=ie(a,"css",`${e}-theme.css`);if(ye(r))try{Os(r,l)}catch{}let c=ie(a,"js",`${o}-animations.js`),d=ie(a,"js",`${e}-animations.js`);if(ye(c))try{Os(c,d)}catch{}let u=ie(a,"theme.json");if(ye(u))try{let p=JSON.parse(qe(u,"utf-8"));p.label=e,p.name=e,Kn(u,JSON.stringify(p,null,2),"utf-8")}catch{}}if(ye(te))for(let r of Js(te).filter(l=>l.endsWith(".json")&&l!=="_index.json"))try{let l=JSON.parse(qe(ie(te,r),"utf-8"));l.themeName===o&&(l.themeName=e,l.themePath=a,l.updatedAt=Date.now(),Kn(ie(te,r),JSON.stringify(l,null,2),"utf-8"))}catch{}return be&&be.themeName===o&&(be.themeName=e,be.themePath=a,be.updatedAt=Date.now()),Fs(),{ok:!0}}var te,js,It,be,qt=J(()=>{"use strict";g();Yt();zt();te=ie(uc(),".vibespot","sessions"),js=ie(te,"_index.json"),It=null;be=null});import{readFileSync as Ds,readdirSync as en,existsSync as pe,writeFileSync as ke,mkdirSync as Zt,rmSync as zi}from"fs";import{join as _}from"path";function re(t){try{return Ds(t,"utf-8")}catch{return""}}function hc(t){let e=[];for(let n of t.moduleOrder){let s=t.modules.find(o=>o.moduleName===n);s&&e.push(s)}for(let n of t.modules)t.moduleOrder.includes(n.moduleName)||e.push(n);return e}function yc(t,e){let n=re(t);if(!n||e==="home.html"||e.endsWith("-listing.html"))return null;let s=e.replace(/\.html$/,""),o="landing_page";s.startsWith("bp-")?o="blog_post":s.startsWith("wp-")?o="website_page":s.startsWith("mo-")&&(o="module_only");let i=s,a=n.match(/<!--[\s\S]*?label:\s*"?([^"\n]+)"?\s*[\s\S]*?-->/);a&&(i=a[1].trim());let r=/dnd_module\s+path=["']\.\.\/modules\/(.+?)\.module["']/g,l=[],c;for(;(c=r.exec(n))!==null;)l.push(c[1]);return{id:s,label:i,pageType:o,moduleNames:l,templateContent:n,filename:e}}function bc(t,e,n,s,o){if(!pe(t))return[];let i=[],a=en(t).filter(r=>r.endsWith(".html")&&r!=="home.html");for(let r of a){let l=_(t,r),c=yc(l,r);if(!c||c.moduleNames.length===0&&i.length>0)continue;let d=[],u=[];for(let p of c.moduleNames){let f=e.get(p);f&&(d.push(f),u.push(p))}i.push({id:c.id,label:c.label,pageType:c.pageType,templateFile:`templates/${c.filename}`,modules:d,moduleOrder:u,sharedCss:n,sharedJs:s,template:c.templateContent,messages:i.length===0?[...o]:[]})}return i}function tn(t){let e=v();if(!e)return;let n=Li(t);n.length>0&&e.messages.length===0&&(e.messages=n),Gn(t);let s=_(t,"modules");if(!pe(s))return;let o=en(s,{withFileTypes:!0});for(let y of o){if(!y.isDirectory()||!y.name.endsWith(".module"))continue;let b=_(s,y.name),A=y.name.replace(/\.module$/,""),w={moduleName:A,fieldsJson:re(_(b,"fields.json")),metaJson:re(_(b,"meta.json")),moduleHtml:re(_(b,"module.html")),moduleCss:re(_(b,"module.css")),moduleJs:re(_(b,"module.js"))||void 0};w.fieldsJson&&w.moduleHtml&&(e.modules.push(w),e.moduleOrder.push(A))}let i=_(t,"css"),a=_(t,"js"),r="",l="";if(pe(i)){let y=en(i).filter(b=>b.endsWith("-theme.css"));y.length>0&&(r=re(_(i,y[0])),e.sharedCss=r)}if(pe(a)){let y=en(a).filter(b=>b.endsWith("-animations.js"));y.length>0&&(l=re(_(a,y[0])),e.sharedJs=l)}let c=_(t,".vibespot","styleguide.md"),d=_(t,".vibespot","brandvoice.md"),u=_(t,".vibespot","theme-context.md");(pe(c)||pe(d)||pe(u))&&(e.brandAssets||(e.brandAssets={}),pe(c)&&(e.brandAssets.styleguide=re(c)),pe(d)&&(e.brandAssets.brandvoice=re(d)),pe(u)&&(e.brandAssets.themeContext=re(u)));let p=_(t,"templates"),f=new Map(e.modules.map(y=>[y.moduleName,y])),h=bc(p,f,r,l,e.messages);if(h.length>0){e.templates=h,e.activeTemplateId=h[0].id;let y=h[0].moduleOrder;if(y.length>0){let b=new Set(e.moduleOrder),A=y.filter(w=>b.has(w));for(let w of e.moduleOrder)A.includes(w)||A.push(w);e.moduleOrder=A}mt(h[0])}else e.templates||(e.templates=[]),e.activeTemplateId||(e.activeTemplateId=""),Bn(e)}function st(){let t=v();if(!t)return;let e=t.themePath,n=new Map;if(t.templates.length>0)for(let l of t.templates)for(let c of l.modules)n.set(c.moduleName,c);for(let l of t.modules)n.set(l.moduleName,l);let s=_(e,"modules");Zt(s,{recursive:!0});for(let l of n.values())Zt(_(s,`${l.moduleName}.module`),{recursive:!0});for(let l of n.values()){let c=_(s,`${l.moduleName}.module`);ke(_(c,"fields.json"),l.fieldsJson,"utf-8"),ke(_(c,"meta.json"),l.metaJson,"utf-8"),ke(_(c,"module.html"),l.moduleHtml,"utf-8"),ke(_(c,"module.css"),l.moduleCss,"utf-8"),l.moduleJs&&ke(_(c,"module.js"),l.moduleJs,"utf-8")}if(t.sharedCss){let l=_(e,"css");Zt(l,{recursive:!0}),ke(_(l,`${t.themeName}-theme.css`),t.sharedCss,"utf-8")}if(t.sharedJs){let l=_(e,"js");Zt(l,{recursive:!0}),ke(_(l,`${t.themeName}-animations.js`),t.sharedJs,"utf-8")}let o=_(e,"templates");Zt(o,{recursive:!0});let i=_(o,"home.html");(t.templates.length>0||t.modules.length>0)&&pe(i)&&zi(i,{force:!0});let r=new Set;if(t.templates.length>0)for(let l of t.templates){if(l.pageType==="module_only"||l.modules.length===0)continue;let c=l.template||wc(l),d=qi(c,l.label,l.pageType),u=`${l.id}.html`;ke(_(o,u),d,"utf-8"),r.add(u),l.pageType==="blog_post"&&(xc(o,l),r.add(`${l.id}-listing.html`))}else if(t.modules.length>0){let l=t.template||Cc(),c=qi(l,`${t.themeName} Landing Page`),d=`lp-${t.themeName}.html`;ke(_(o,d),c,"utf-8"),r.add(d)}try{for(let l of en(o))l.startsWith("lp-")&&l.endsWith(".html")&&!r.has(l)&&zi(_(o,l),{force:!0})}catch{}Sc(),vc()}function Xi(){let t=v();t&&(t.modules=[],t.moduleOrder=[],t.sharedCss="",t.sharedJs="",t.template="",tn(t.themePath),t.updatedAt=Date.now(),et())}function Qi(){let t=v();if(!t)return;let e=Ce();if(!e)return;let n=t.themePath,s=_(n,"modules");e.modules=[];for(let o of e.moduleOrder){let i=_(s,`${o}.module`);if(!pe(i))continue;let a={moduleName:o,fieldsJson:re(_(i,"fields.json")),metaJson:re(_(i,"meta.json")),moduleHtml:re(_(i,"module.html")),moduleCss:re(_(i,"module.css")),moduleJs:re(_(i,"module.js"))||void 0};a.fieldsJson&&a.moduleHtml&&e.modules.push(a)}if(e.templateFile){let o=_(n,e.templateFile);pe(o)&&(e.template=re(o))}mt(e),t.updatedAt=Date.now()}function Sc(){let t=v();if(!t)return;let e=_(t.themePath,"templates","layouts","base.html");if(pe(e))try{let n=Ds(e,"utf-8");if(n.includes("template_js"))return;let s='{{ require_js(get_asset_url("../../js/main.js")) }}';n.includes(s)?n=n.replace(s,s+`
|
|
98
98
|
{% if template_js %}
|
|
99
99
|
{{ require_js(get_asset_url(template_js)) }}
|
|
100
100
|
{% endif %}`):n=n.replace("{{ standard_footer_includes }}",`{% if template_js %}
|
|
101
101
|
{{ require_js(get_asset_url(template_js)) }}
|
|
102
102
|
{% endif %}
|
|
103
|
-
{{ standard_footer_includes }}`),ke(e,n,"utf-8")}catch{}}function
|
|
103
|
+
{{ standard_footer_includes }}`),ke(e,n,"utf-8")}catch{}}function vc(){let t=v();if(!t)return;let e=_(t.themePath,"theme.json");if(pe(e))try{let n=JSON.parse(Ds(e,"utf-8"));n.label=t.themeName,n.name=t.themeName,ke(e,JSON.stringify(n,null,2),"utf-8")}catch{}}function qi(t,e,n="landing_page"){return t.includes("templateType")?t:`<!--
|
|
104
104
|
templateType: ${n==="blog_post"?"blog_post":"page"}
|
|
105
105
|
isAvailableForNewContent: true
|
|
106
106
|
label: "${e}"
|
|
107
107
|
-->
|
|
108
|
-
`+t}function
|
|
108
|
+
`+t}function wc(t){if(t.modules.length===0)return"";let n=v().themeName,o=hc(t).map(a=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
|
|
109
109
|
{% dnd_module path="../modules/${a.moduleName}.module" %}
|
|
110
110
|
{% end_dnd_module %}
|
|
111
111
|
{% end_dnd_section %}`).join(`
|
|
@@ -136,7 +136,7 @@ ${o}
|
|
|
136
136
|
|
|
137
137
|
{% block footer %}
|
|
138
138
|
{% endblock footer %}
|
|
139
|
-
`}function
|
|
139
|
+
`}function xc(t,e){let n=`<!--
|
|
140
140
|
templateType: blog_listing
|
|
141
141
|
isAvailableForNewContent: true
|
|
142
142
|
label: "${e.label} - Listing"
|
|
@@ -161,7 +161,7 @@ ${o}
|
|
|
161
161
|
{% endif %}
|
|
162
162
|
</div>
|
|
163
163
|
{% endblock body %}
|
|
164
|
-
`;ke(_(t,`${e.id}-listing.html`),n,"utf-8")}function
|
|
164
|
+
`;ke(_(t,`${e.id}-listing.html`),n,"utf-8")}function Cc(){let t=v();if(!t||t.modules.length===0)return"";let e=t.themeName,s=me().map(o=>` {% dnd_section padding={"top":"0","bottom":"0","left":"0","right":"0"}, full_width=true %}
|
|
165
165
|
{% dnd_module path="../modules/${o.moduleName}.module" %}
|
|
166
166
|
{% end_dnd_module %}
|
|
167
167
|
{% end_dnd_section %}`).join(`
|
|
@@ -192,7 +192,7 @@ ${s}
|
|
|
192
192
|
|
|
193
193
|
{% block footer %}
|
|
194
194
|
{% endblock footer %}
|
|
195
|
-
`}var
|
|
195
|
+
`}var Zi=J(()=>{"use strict";g();qt();Wn();zt();Yt()});var er=J(()=>{"use strict";g();$i();qt();Wn();Zi();zt()});var Se=J(()=>{"use strict";g();er()});function qn(t){let e={};for(let n of t)n.type==="group"&&n.occurrence&&Array.isArray(n.default)?e[n.name]=n.default:n.type==="group"&&n.children?e[n.name]=qn(n.children):e[n.name]=n.default??"";return e}function Hs(t,e){let n=t;return n=Mc(n),n=or(n,e),n=ir(n,e),n=rr(n,e),n=Rc(n),n}function Gs(t){let e=[t.sharedCss||"",...t.moduleCssArray].filter(Boolean).map(o=>`<style>${o}</style>`).join(`
|
|
196
196
|
`),n=[t.sharedJs||"",...t.moduleJsArray].filter(Boolean).map(o=>`<script>${o}</script>`).join(`
|
|
197
197
|
`),s=t.renderedModules.join(`
|
|
198
198
|
`);return`<!DOCTYPE html>
|
|
@@ -239,11 +239,11 @@ document.querySelectorAll('img').forEach(function(img){
|
|
|
239
239
|
});
|
|
240
240
|
</script>
|
|
241
241
|
</body>
|
|
242
|
-
</html>`}function
|
|
242
|
+
</html>`}function Mc(t){return t=t.replace(Ac,""),t=t.replace(Ic,""),t=t.replace(kc,""),tr.lastIndex=0,t=t.replace(tr,(e,n)=>`/theme-assets/${n}`),nr.lastIndex=0,t=t.replace(nr,""),t=t.replace($c,""),t=t.replace(Tc,""),t=t.replace(Ec,""),t=t.replace(Nc,""),t=t.replace(Pc,""),t}function or(t,e){let n=t,s=0;for(;s<30;){s++;let o=_c(n);if(!o)break;let{varName:i,iterExpr:a,body:r,start:l,end:c}=o,d=Oc(a,e),u="";Array.isArray(d)&&(u=d.map((p,f)=>{let h={...e,[i]:p,loop:{index:f+1,index0:f,first:f===0,last:f===d.length-1,length:d.length}},y=or(r,h);return y=ir(y,h),y=rr(y,h),y}).join("")),n=n.slice(0,l)+u+n.slice(c)}return n}function _c(t){let e=/\{%[-\s]*for\s+(\w+)\s+in\s+([\w.]+(?:\([^)]*\))?(?:\|[\w(),"' ]+)*)\s*-?%\}/g,n=/\{%[-\s]*(for\s|endfor)\s*.*?-?%\}/g,s=e.exec(t);if(!s)return null;let o=s[1],i=s[2],a=s.index+s[0].length;n.lastIndex=a;let r=1,l;for(;(l=n.exec(t))!==null;)if(l[1].startsWith("for"))r++;else if(r--,r===0){let c=t.slice(a,l.index);return{varName:o,iterExpr:i,body:c,start:s.index,end:l.index+l[0].length}}return null}function ir(t,e){let n=t,s=0;for(;Ls.test(n)&&s<50;)s++,n=n.replace(Ls,(o,i,a)=>{let r=a.split(/\{%[-\s]*else\s*-?%\}/),l=r[0],c=r[1]||"",d=l.split(/\{%[-\s]*elif\s+(.*?)\s*-?%\}/);if(d.length>1){if($t(i,e))return d[0];for(let u=1;u<d.length;u+=2){let p=d[u],f=d[u+1]||"";if($t(p,e))return f}return c}return $t(i,e)?l:c}),Ls.lastIndex=0;return n}function rr(t,e){return t.replace(/\{\{[-\s]*(.*?)[-\s]*\}\}/g,(n,s)=>{let i=s.trim().split("|"),a=i[0].trim(),r=pt(e,a);for(let c=1;c<i.length;c++)r=lr(r,i[c].trim());if(r==null)return"";if(typeof r=="object")return JSON.stringify(r);let l=String(r);return l=l.replace(/\\n/g," ").replace(/\n/g," "),l})}function Rc(t){return t=t.replace(/\{%.*?%\}/gs,""),t=t.replace(/\{\{.*?\}\}/gs,""),t}function Oc(t,e){let n=t.match(/^range\(\s*(.+?)\s*,\s*(.+?)\s*\)$/);if(n){let o=sr(n[1],e),i=sr(n[2],e),a=[];for(let r=o;r<i;r++)a.push(r);return a}let s=t.match(/^(.+?)\|split\(['"](.+?)['"]\)$/);if(s){let o=pt(e,s[1].trim());return typeof o=="string"?o.split(s[2]):[]}return pt(e,t)}function sr(t,e){let s=t.trim().split("|"),o=s[0].trim();if(!isNaN(Number(o)))return Number(o);let i=pt(e,o);for(let a=1;a<s.length;a++)i=lr(i,s[a].trim());return Number(i)||0}function pt(t,e){let n=e.split("."),s=t;for(let o of n){if(s==null||typeof s!="object")return;s=s[o]}return s}function $t(t,e){let n=t.trim();if(n.startsWith("not "))return!$t(n.slice(4),e);if(n.includes(" and "))return n.split(" and ").every(i=>$t(i,e));if(n.includes(" or "))return n.split(" or ").some(i=>$t(i,e));let s=n.match(/^(.+?)\s*(==|!=|>=|<=|>|<)\s*(.+)$/);if(s){let i=pt(e,s[1].trim()),a=s[2],r=s[3].trim();switch(typeof r=="string"&&r.startsWith('"')&&r.endsWith('"')||typeof r=="string"&&r.startsWith("'")&&r.endsWith("'")?r=r.slice(1,-1):isNaN(Number(r))?r=pt(e,r):r=Number(r),a){case"==":return i==r;case"!=":return i!=r;case">":return Number(i)>Number(r);case"<":return Number(i)<Number(r);case">=":return Number(i)>=Number(r);case"<=":return Number(i)<=Number(r)}}let o=pt(e,n);return ar(o)}function ar(t){return!(t==null||t===""||t===0||t===!1||Array.isArray(t)&&t.length===0)}function lr(t,e){let n=t==null?"":String(t),s=e.match(/^(\w+)\((.*)\)$/),o=s?s[1]:e,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 a=parseInt(i,10);return n.length>a?n.slice(0,a)+"...":n}return n;case"default":return ar(t)?t:i??"";case"length":return Array.isArray(t)?t.length:n.length;case"join":return Array.isArray(t)?t.join(i??", "):n;case"int":case"float":return Number(n)||0;case"abs":return Math.abs(Number(n));case"round":return Math.round(Number(n));default:return t}}var Ac,Ic,kc,tr,nr,$c,Tc,Ec,Nc,Pc,Ls,cr=J(()=>{"use strict";g();Ac=/\{%[-\s]*require_(css|js)\b.*?%\}/gs,Ic=/\{%[-\s]*end_require_(css|js)\s*%\}/gs,kc=/\{\{[-\s]*require_(css|js)\(.*?\)\s*\}\}/gs,tr=/\{\{[-\s]*get_asset_url\(["'](?:[^"'\/]+\/)?assets\/(.*?)["']\)\s*\}\}/gs,nr=/\{\{[-\s]*get_asset_url\(.*?\)\s*\}\}/gs,$c=/\{%[-\s]*(end_)?(dnd_area|dnd_section|dnd_column|dnd_row|dnd_module)\b.*?%\}/gs,Tc=/\{%[-\s]*module\b.*?%\}/gs,Ec=/\{%[-\s]*(extends|block|endblock|set)\b.*?%\}/gs,Nc=/\{#.*?#\}/gs,Pc=/\{\{[-\s]*content\.\w+.*?\}\}/gs,Ls=/\{%[-\s]*if\s+(.*?)\s*-?%\}((?:(?!\{%[-\s]*if\s)[\s\S])*?)\{%[-\s]*endif\s*-?%\}/g});var Bs={};lt(Bs,{buildModulePreviewHtml:()=>Ws,buildPreviewHtml:()=>Us});function jc(t){if(!t)return{bg:"#0f0f14",surface:"#1a1a20",text:"#ffffff",textMuted:"#666",border:"#333"};let e=(r,l)=>{for(let c of r){let d=new RegExp(`${c.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}\\s*:\\s*([^;})]+)`,"i"),u=t.match(d);if(u)return u[1].trim()}return l},n=e(["--bg","--background","--color-bg","--bg-primary","--body-bg"],"#0f0f14"),s=e(["--surface","--bg-secondary","--card-bg","--color-surface"],n),o=e(["--text","--color-text","--text-primary","--fg","--foreground"],"#ffffff"),i=e(["--text-muted","--text-secondary","--muted","--color-text-muted"],"#666"),a=e(["--border","--border-color","--color-border"],"#333");return{bg:n,surface:s,text:o,textMuted:i,border:a}}function Us(){let t=v();if(!t)return dr();let e=me(),n=t.moduleOrder||[];if(e.length===0&&n.length===0)return dr();let s=[],o=[],i=[],a=new Set;for(let c of e){if(c.moduleHtml.includes("dnd_area")||c.moduleHtml.includes("extends "))continue;let d;try{let f=JSON.parse(c.fieldsJson);d={module:qn(f)}}catch{d={module:{}}}let u=Hs(c.moduleHtml,d),p=c.moduleName.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module" id="${p}" data-module="${c.moduleName}">${u}</div>`),a.add(c.moduleName),c.moduleCss&&o.push(c.moduleCss),c.moduleJs&&i.push(c.moduleJs)}let r=jc(t.sharedCss);for(let c of n)if(!a.has(c)){let d=c.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"");s.push(`<div class="vibespot-module vibespot-module--pending" id="${d}" data-module="${c}">
|
|
243
243
|
<div class="vibespot-placeholder">
|
|
244
244
|
<div class="vibespot-placeholder__name">${c}</div>
|
|
245
245
|
</div>
|
|
246
|
-
</div>`)}let l=`body{background:${r.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${r.surface};border:1px dashed ${r.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${r.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return
|
|
246
|
+
</div>`)}let l=`body{background:${r.bg}}.vibespot-placeholder{display:flex;align-items:center;justify-content:center;min-height:200px;padding:3rem;background:${r.surface};border:1px dashed ${r.border};border-radius:12px;margin:1rem 0}.vibespot-placeholder__name{font-size:1.5rem;font-weight:600;font-family:system-ui,sans-serif;color:${r.textMuted};letter-spacing:.5px;animation:vp-fade 2s ease-in-out infinite}@keyframes vp-fade{0%,100%{opacity:.3}50%{opacity:.8}}`;return Gs({renderedModules:s,sharedCss:t.sharedCss,moduleCssArray:[l,...o],sharedJs:t.sharedJs,moduleJsArray:i})}function dr(){return`<!DOCTYPE html>
|
|
247
247
|
<html lang="en">
|
|
248
248
|
<head>
|
|
249
249
|
<meta charset="utf-8">
|
|
@@ -294,8 +294,8 @@ document.querySelectorAll('img').forEach(function(img){
|
|
|
294
294
|
<div class="welcome__sub">Build Something Great</div>
|
|
295
295
|
</div>
|
|
296
296
|
</body>
|
|
297
|
-
</html>`}function
|
|
298
|
-
`)}catch{}}}var
|
|
297
|
+
</html>`}function Ws(t){let e=v();if(!e)return"";let n;for(let i of e.templates)if(n=i.modules.find(a=>a.moduleName===t),n)break;if(n||(n=e.modules.find(i=>i.moduleName===t)),!n)return"";let s;try{let i=JSON.parse(n.fieldsJson);s={module:qn(i)}}catch{s={module:{}}}let o=Hs(n.moduleHtml,s);return Gs({renderedModules:[`<div class="vibespot-module" data-module="${n.moduleName}">${o}</div>`],sharedCss:e.sharedCss,moduleCssArray:n.moduleCss?[n.moduleCss]:[],sharedJs:e.sharedJs,moduleJsArray:n.moduleJs?[n.moduleJs]:[]})}var Xn=J(()=>{"use strict";g();cr();Se()});import{appendFileSync as Fc,mkdirSync as Jc,readdirSync as Dc,unlinkSync as Lc}from"fs";import{join as zs}from"path";import{homedir as Hc}from"os";function Uc(){if(!Vs)try{Jc(Qn,{recursive:!0}),Vs=!0}catch{}}function Wc(){if(!Ys){Ys=!0;try{let t=Date.now()-Gc*864e5;for(let e of Dc(Qn)){if(!e.startsWith("vibespot-")||!e.endsWith(".log"))continue;let n=e.slice(9,19),s=new Date(n).getTime();if(s&&s<t)try{Lc(zs(Qn,e))}catch{}}}catch{}}}function Bc(){let e=new Date().toISOString().slice(0,10);return zs(Qn,`vibespot-${e}.log`)}function Kc(){return new Date().toISOString().slice(11,23)}function Ks(t,e){if(Uc(),!!Vs){Ys||Wc();try{Fc(Bc(),`${Kc()} ${t} ${e}
|
|
298
|
+
`)}catch{}}}var Qn,Gc,Vs,Ys,E,ve=J(()=>{"use strict";g();Qn=zs(Hc(),".vibespot","logs"),Gc=7,Vs=!1,Ys=!1;E={info(t,e,n){let s=n?`[${t}] ${e} ${JSON.stringify(n)}`:`[${t}] ${e}`;console.log(s),Ks("INFO",s)},warn(t,e,n){let s=n?`[${t}] ${e} ${JSON.stringify(n)}`:`[${t}] ${e}`;console.warn(s),Ks("WARN",s)},error(t,e,n){let s=n instanceof Error?n.message:n?String(n):"",o=s?`[${t}] ${e}: ${s}`:`[${t}] ${e}`;console.error(o),Ks("ERROR",o)}}});function Le(t){try{return JSON.parse(t)}catch{}let e=t,n=-1;for(let s=0;s<20;s++)try{return JSON.parse(e)}catch(o){if(!(o instanceof SyntaxError))return null;let i=/position (\d+)/.exec(o.message);if(!i)return null;let a=parseInt(i[1],10);if(a<=n)return null;n=a;let r=Math.max(0,a-5),c=e.slice(r,a+1).lastIndexOf('"');if(c===-1)return null;let d=r+c;if(d>0&&e[d-1]==="\\")return null;e=e.slice(0,d)+'\\"'+e.slice(d+1)}return null}function nn(t){let e=t.indexOf('"modules"');if(e===-1)return null;let n=t.indexOf("[",e);if(n===-1)return null;let s=-1,o=0,i=!1,a=!1;for(let d=n+1;d<t.length;d++){let u=t[d];if(a){a=!1;continue}if(u==="\\"){a=!0;continue}if(u==='"'){i=!i;continue}i||(u==="{"&&o++,u==="}"&&(o--,o===0&&(s=d)))}if(s===-1)return null;let l=t.slice(0,s+1)+"]}",c=l.trimStart().startsWith("{")?l:"{"+l;return Le(c)}function qs(t){return{moduleName:String(t.moduleName||""),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:String(t.moduleHtml||""),moduleCss:String(t.moduleCss||""),moduleJs:t.moduleJs?String(t.moduleJs):void 0}}function ur(t,e){let n=!1,s,o=/```vibespot-modules\s*\n?([\s\S]*?)```/g;for(;(s=o.exec(t))!==null;)try{E.info("parse","Found vibespot-modules block",{length:s[1].length});let i=Le(s[1]);if(!i||typeof i!="object")throw E.warn("parse","tryParseJSON returned non-object",{result:typeof i}),new Error("Invalid JSON after repair");let a=i;a.modules&&Array.isArray(a.modules)&&(De({modules:a.modules.map(r=>qs(r)),sharedCss:a.sharedCss!==void 0?String(a.sharedCss):void 0,sharedJs:a.sharedJs!==void 0?String(a.sharedJs):void 0}),n=!0)}catch(i){E.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(t))!==null;)if(s[1].includes('"modules"'))try{let a=Le(s[1]);if(!a||typeof a!="object")throw new Error("Invalid JSON after repair");let r=a;r.modules&&Array.isArray(r.modules)&&(De({modules:r.modules.map(l=>qs(l)),sharedCss:r.sharedCss!==void 0?String(r.sharedCss):void 0,sharedJs:r.sharedJs!==void 0?String(r.sharedJs):void 0}),n=!0)}catch(a){E.warn("parse","Failed to parse JSON module block",{error:a instanceof Error?a.message:String(a)})}}if(!n&&(t.match(/```/g)||[]).length%2!==0&&t.includes('"modules"')){E.info("parse","Detected truncated response (odd fence count), attempting salvage");let a=t.lastIndexOf("```"),r=t.slice(a+3);r=r.replace(/^[\w-]*\s*\n?/,"");let l=nn(r);if(l){let c=l;c.modules&&Array.isArray(c.modules)&&c.modules.length>0&&(E.info("parse","Salvaged modules from truncated response",{count:c.modules.length}),De({modules:c.modules.map(d=>qs(d)),sharedCss:c.sharedCss!==void 0?String(c.sharedCss):void 0,sharedJs:c.sharedJs!==void 0?String(c.sharedJs):void 0}),n=!0,e&&e("Response was truncated \u2014 some modules may be incomplete. Try sending your request again for the full set."))}}if(!n){E.info("parse","No modules applied",{responseLength:t.length,hasVibespot:t.includes("vibespot-modules"),hasModules:t.includes('"modules"'),fenceCount:(t.match(/```/g)||[]).length});let i=t.includes("vibespot-modules")||t.includes('"modules"'),a=/\bmodule|modul/i.test(t)&&(/\bcreated?\b|\berstellt\b|\bgenerat/i.test(t)||/\|.*\|.*\|/m.test(t));if(i||a){let r=i?"Module changes could not be applied \u2014 the AI response contained invalid JSON. Try sending your request again.":"The AI described modules but did not include the required structured data. Try sending your request again.";E.warn("parse",r),e&&e(r)}}}var Zn=J(()=>{"use strict";g();Se();ve()});function Tt(){let t=v();return t?{pageType:Ce()?.pageType,brandAssets:t.brandAssets}:{}}function Et(t,e,n=!1,s,o){let i=`You are vibeSpot, an AI that builds HubSpot CMS landing pages from natural language descriptions.
|
|
299
299
|
|
|
300
300
|
## Your Role
|
|
301
301
|
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.
|
|
@@ -374,7 +374,7 @@ The current template's modules are listed in page order in the user message. Thi
|
|
|
374
374
|
- **Rearrange**: When the user asks to reorder sections, include a "moduleOrder" array in the vibespot-modules JSON with the new sequence of module names.
|
|
375
375
|
- **Remove**: When the user asks to remove a section, omit it from the output.
|
|
376
376
|
- **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.
|
|
377
|
-
- **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,a=s?
|
|
377
|
+
- **Design consistency**: Match the existing theme's design language \u2014 reuse the same CSS custom properties, class naming prefix, spacing scale, and typography.`,a=s?Qo(s):"",r=a?`
|
|
378
378
|
|
|
379
379
|
## Page Type Context
|
|
380
380
|
${a}`:"",l="";if(o?.styleguide&&(l+=`
|
|
@@ -383,7 +383,7 @@ ${a}`:"",l="";if(o?.styleguide&&(l+=`
|
|
|
383
383
|
${o.styleguide}`),o?.brandvoice&&(l+=`
|
|
384
384
|
|
|
385
385
|
## Brand Voice
|
|
386
|
-
${o.brandvoice}`),o?.humanify!==!1){let d=
|
|
386
|
+
${o.brandvoice}`),o?.humanify!==!1){let d=Xo();d&&(l+=`
|
|
387
387
|
|
|
388
388
|
## Anti-AI Copy Rules (Humanify)
|
|
389
389
|
${d}`)}let c="\n\n## REMINDER \u2014 Output Format (CRITICAL)\nYour response MUST contain a ```vibespot-modules code block with the full JSON. Without this block, no modules will be created. Do NOT respond with only text, tables, or descriptions. The JSON block is mandatory.";return n?i+r+l+`
|
|
@@ -417,16 +417,16 @@ When using scroll-animate classes (opacity: 0 \u2192 visible), you MUST include
|
|
|
417
417
|
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.
|
|
418
418
|
|
|
419
419
|
## Design Guide
|
|
420
|
-
${
|
|
420
|
+
${zo()}
|
|
421
421
|
|
|
422
422
|
## Content & Copywriting Guide
|
|
423
|
-
${
|
|
423
|
+
${qo()}
|
|
424
424
|
|
|
425
425
|
## HubSpot CMS Rules
|
|
426
426
|
${Ze()}
|
|
427
427
|
|
|
428
428
|
## Conversion Guide Reference
|
|
429
|
-
${t}`+c}function
|
|
429
|
+
${t}`+c}function sn(){let t=v(),e=[],n=t.modules,s=n.length;if(s>0){e.push(`
|
|
430
430
|
|
|
431
431
|
## Page Narrative (module sequence)
|
|
432
432
|
`),e.push(`This template has ${s} module${s===1?"":"s"} in this order:
|
|
@@ -469,7 +469,7 @@ ${t.sharedJs}
|
|
|
469
469
|
`);for(let r of a)e.push(`- ${r.module.moduleName} (used in: ${r.usedIn.join(", ")})
|
|
470
470
|
`);e.push(`
|
|
471
471
|
The user can ask to reuse any of these modules by name.
|
|
472
|
-
`)}return e.join("")}function
|
|
472
|
+
`)}return e.join("")}function Xs(t,e){let n=v(),s=n.messages.slice(-20);s.length>0&&s[s.length-1].role==="user"&&s[s.length-1].content===t&&(s=s.slice(0,-1));let o=s.map(d=>({role:d.role,content:d.content})),i=sn(),a="";if(n.assets?.length){let d=n.assets.filter(u=>u.type==="image"&&u.usage==="asset");d.length>0&&(a=`
|
|
473
473
|
|
|
474
474
|
## Available Theme Assets
|
|
475
475
|
These images are in the theme's assets/ folder. Reference them with get_asset_url("${n.themeName}/assets/filename"):
|
|
@@ -483,13 +483,13 @@ ${i}`),a&&(r+=a),r+="\n\n---\nRemember: respond with a ```vibespot-modules JSON
|
|
|
483
483
|
[Attached document: ${d.originalName}]
|
|
484
484
|
${d.extractedText}`),d.type==="image"&&d.usage==="asset"&&d.assetPath&&(r+=`
|
|
485
485
|
|
|
486
|
-
[Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?e.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:r}),o.push({role:"user",content:d})}else o.push({role:"user",content:r});return o}var
|
|
486
|
+
[Uploaded image: ${d.originalName} \u2192 available as get_asset_url("${d.assetPath}")]`);let c=l?e.filter(d=>d.type==="image"&&d.base64):[];if(c.length>0){let d=[];for(let u of c)d.push({type:"image",source:{type:"base64",media_type:u.mimeType,data:u.base64}});d.push({type:"text",text:r}),o.push({role:"user",content:d})}else o.push({role:"user",content:r});return o}var mr=J(()=>{"use strict";g();Ve();Se()});import{spawn as Vc}from"child_process";async function Yc(){return Qs||(Qs=(await import("@anthropic-ai/sdk")).default),Qs}function pr(t){if(!t?.length)return"";let e=[];for(let n of t)n.type==="image"&&n.usage==="asset"&&n.assetPath&&e.push(`
|
|
487
487
|
[Uploaded image: ${n.originalName} \u2192 use get_asset_url("${n.assetPath}")]`),n.type==="document"&&n.extractedText&&e.push(`
|
|
488
488
|
|
|
489
489
|
---
|
|
490
490
|
[Attached document: ${n.originalName}]
|
|
491
|
-
${n.extractedText}`);return e.join("")}async function
|
|
492
|
-
`);R=L.pop()||"";for(let ne of L){if(!ne.startsWith("data: "))continue;let U=ne.slice(6).trim();if(U==="[DONE]")break;try{let O=JSON.parse(U).choices?.[0]?.delta?.content;O&&(A+=O,o(O))}catch{}}}}finally{clearInterval(b)}a&&a(A)}async function
|
|
491
|
+
${n.extractedText}`);return e.join("")}async function fr(t,e,n,s,o,i,a,r){let l=await Yc(),c=new l({apiKey:e}),d=le(),p=v().modules.length>0,f=Xs(t,r),h=Tt(),y=Et(d,n,p,h.pageType,h.brandAssets);E.info("anthropic","API call",{model:s,systemPromptLength:y.length,messageCount:f.length,messageRoles:f.map(b=>b.role),lastMessageLength:typeof f[f.length-1]?.content=="string"?f[f.length-1].content.length:"multimodal",conversionGuideLength:d.length});for(let b=0;;b++)try{let A="",w=0,$=i||(()=>{});$(fe[0]);let R=setInterval(()=>{w++,$(fe[Math.min(w,fe.length-1)])},6e3);try{let M=c.messages.stream({model:s,max_tokens:48e3,system:y,messages:f});for await(let N of M)if(N.type==="content_block_delta"&&N.delta.type==="text_delta"){let L=N.delta.text;A+=L,o(L)}}finally{clearInterval(R)}a&&a(A);return}catch(A){let w=A.status,$=A.error?.type;if(!(w===429||$==="rate_limit_error"||A instanceof Error&&A.message.includes("429"))||b>=Zs.length)throw A;let M=Zs[b];E.warn("ai-engine",`Rate limited (429), attempt ${b+1}/${Zs.length} \u2014 waiting ${M}s`),i&&i(`Rate limited by Anthropic API \u2014 retrying in ${M}s...`),await new Promise(N=>setTimeout(N,M*1e3)),i&&i("Retrying...")}}async function gr(t,e,n,s,o,i,a,r){let l=le(),c=v().modules.length>0,d=Xs(t,r),u=Tt(),p=d.map(M=>typeof M.content=="string"?M:{role:M.role,content:M.content.map(N=>N.type==="text"?{type:"text",text:N.text}:{type:"image_url",image_url:{url:`data:${N.source.media_type};base64,${N.source.data}`}})}),f=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${e}`},body:JSON.stringify({model:s,max_tokens:48e3,stream:!0,messages:[{role:"system",content:Et(l,n,c,u.pageType,u.brandAssets)},...p]})});if(!f.ok){let M=await f.text();throw new Error(`OpenAI API error (${f.status}): ${M}`)}let h=0,y=i||(()=>{});y(fe[0]);let b=setInterval(()=>{h++,y(fe[Math.min(h,fe.length-1)])},6e3),A="",w=f.body.getReader(),$=new TextDecoder,R="";try{for(;;){let{done:M,value:N}=await w.read();if(M)break;R+=$.decode(N,{stream:!0});let L=R.split(`
|
|
492
|
+
`);R=L.pop()||"";for(let ne of L){if(!ne.startsWith("data: "))continue;let U=ne.slice(6).trim();if(U==="[DONE]")break;try{let O=JSON.parse(U).choices?.[0]?.delta?.content;O&&(A+=O,o(O))}catch{}}}}finally{clearInterval(b)}a&&a(A)}async function hr(t,e,n,s,o,i,a){let r=le(),l=v(),c=l.modules.length>0,d=sn(),u=Tt(),p=[];for(let U of l.messages.slice(-20))p.push({role:U.role==="assistant"?"model":"user",parts:[{text:U.content}]});let f=d?`${t}
|
|
493
493
|
|
|
494
494
|
---
|
|
495
495
|
${d}`:t;if(a?.length)for(let U of a)U.type==="document"&&U.extractedText&&(f+=`
|
|
@@ -498,29 +498,29 @@ ${d}`:t;if(a?.length)for(let U of a)U.type==="document"&&U.extractedText&&(f+=`
|
|
|
498
498
|
[Attached document: ${U.originalName}]
|
|
499
499
|
${U.extractedText}`),U.type==="image"&&U.usage==="asset"&&U.assetPath&&(f+=`
|
|
500
500
|
|
|
501
|
-
[Uploaded image: ${U.originalName} \u2192 available as get_asset_url("${U.assetPath}")]`);let h=[];if(a?.length)for(let U of a)U.type==="image"&&U.base64&&h.push({inlineData:{mimeType:U.mimeType,data:U.base64}});h.push({text:f}),p.push({role:"user",parts:h});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${e}`,A=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:Et(r,n,c,u.pageType,u.brandAssets)}]},contents:p,generationConfig:{maxOutputTokens:48e3}})});if(!A.ok){let U=await A.text();throw new Error(`Gemini API error (${A.status}): ${U}`)}let w=0,$=o||(()=>{});$(fe[0]);let R=setInterval(()=>{w++,$(fe[Math.min(w,fe.length-1)])},6e3),
|
|
502
|
-
`);ne=O.pop()||"";for(let z of O){if(!z.startsWith("data: "))continue;let ae=z.slice(6).trim();try{let Rt=JSON.parse(ae).candidates?.[0]?.content?.parts?.[0]?.text;Rt&&(
|
|
501
|
+
[Uploaded image: ${U.originalName} \u2192 available as get_asset_url("${U.assetPath}")]`);let h=[];if(a?.length)for(let U of a)U.type==="image"&&U.base64&&h.push({inlineData:{mimeType:U.mimeType,data:U.base64}});h.push({text:f}),p.push({role:"user",parts:h});let b=`https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:streamGenerateContent?alt=sse&key=${e}`,A=await fetch(b,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({systemInstruction:{parts:[{text:Et(r,n,c,u.pageType,u.brandAssets)}]},contents:p,generationConfig:{maxOutputTokens:48e3}})});if(!A.ok){let U=await A.text();throw new Error(`Gemini API error (${A.status}): ${U}`)}let w=0,$=o||(()=>{});$(fe[0]);let R=setInterval(()=>{w++,$(fe[Math.min(w,fe.length-1)])},6e3),M="",N=A.body.getReader(),L=new TextDecoder,ne="";try{for(;;){let{done:U,value:G}=await N.read();if(U)break;ne+=L.decode(G,{stream:!0});let O=ne.split(`
|
|
502
|
+
`);ne=O.pop()||"";for(let z of O){if(!z.startsWith("data: "))continue;let ae=z.slice(6).trim();try{let Rt=JSON.parse(ae).candidates?.[0]?.content?.parts?.[0]?.text;Rt&&(M+=Rt,s(Rt))}catch{}}}}finally{clearInterval(R)}i&&i(M)}function es(t,e,n,s){return new Promise((o,i)=>{let a={...process.env};delete a.CLAUDECODE;let r=Vc(t,e,{stdio:["pipe","pipe","pipe"],env:a}),l="",c="",d=!1,u=h=>{d||(d=!0,h())};r.stdout.on("data",h=>{let y=h.toString();l+=y,s&&s(y)}),r.stderr.on("data",h=>{c+=h.toString()}),r.on("error",h=>u(()=>i(new Error(`${t} failed to start: ${h.message}`)))),r.on("close",h=>{u(()=>{h!==0?i(new Error(`${t} exited with code ${h}.
|
|
503
503
|
`+(c?`Stderr: ${c.slice(0,500)}
|
|
504
504
|
`:"")+(l?`Output: ${l.slice(0,500)}`:"No output"))):o(l)})}),r.stdin.on("error",()=>{}),r.stdin.write(n)?r.stdin.end():r.stdin.once("drain",()=>r.stdin.end());let f=setTimeout(()=>{r.kill(),u(()=>i(new Error(`${t} timed out after 5 minutes.
|
|
505
505
|
`+(c?`Stderr: ${c.slice(0,500)}
|
|
506
|
-
`:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},3e5);r.on("close",()=>clearTimeout(f))})}async function
|
|
506
|
+
`:"")+`Partial output (${l.length} chars): ${l.slice(0,500)}`)))},3e5);r.on("close",()=>clearTimeout(f))})}async function yr(t,e,n,s,o,i){let a=le(),r=P(),l=v().modules.length>0,c=Tt(),d=Et(a,e,l,c.pageType,c.brandAssets);d+=`
|
|
507
507
|
|
|
508
508
|
## User Request
|
|
509
|
-
`+t,d+=
|
|
509
|
+
`+t,d+=sn(),d+=pr(i),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u=["--print"];r.claudeCodeModel&&u.push("--model",r.claudeCodeModel);let p=0,f=s||(()=>{});f(fe[0]);let h=setInterval(()=>{p++;let y=fe[Math.min(p,fe.length-1)];f(y)},6e3);try{let y=await es("claude",u,d,b=>{n(b)});o&&o(y)}finally{clearInterval(h)}}async function eo(t,e,n,s,o,i,a){let r=le(),l=v().modules.length>0,c=Tt(),d=Et(r,n,l,c.pageType,c.brandAssets);d+=`
|
|
510
510
|
|
|
511
511
|
## User Request
|
|
512
|
-
`+e,d+=
|
|
512
|
+
`+e,d+=sn(),d+=pr(a),d+="\n\n---\nRemember: respond with a ```vibespot-modules JSON block containing ALL modules. No text-only responses.";let u,p;t==="gemini"?(u="gemini",p=[]):(u="codex",p=["exec","--full-auto"]);let f=0,h=o||(()=>{});h(fe[0]);let y=setInterval(()=>{f++;let b=fe[Math.min(f,fe.length-1)];h(b)},6e3);try{let b=await es(u,p,d,A=>{s(A)});i&&i(b)}finally{clearInterval(y)}}var Qs,fe,Zs,to=J(()=>{"use strict";g();Ve();ee();Se();mr();ve();Qs=null;fe=["Analyzing your request...","Reading the conversion guide...","Planning module structure...","Generating HTML templates...","Writing CSS styles...","Creating field definitions...","Building module metadata...","Assembling theme assets...","Polishing the output...","Almost there \u2014 hang tight..."],Zs=[10,20,40,60,120]});function m(t,e,n){t.writeHead(e,{"Content-Type":"application/json"}),t.end(JSON.stringify(n))}function j(t,e){let n=[];t.on("data",s=>n.push(s)),t.on("end",()=>e(Buffer.concat(n).toString("utf-8")))}function no(t,e,n){j(t,s=>{try{n(JSON.parse(s||"{}"))}catch{m(e,400,{error:"Invalid JSON in request body"})}})}var ot=J(()=>{"use strict";g()});import{createWriteStream as zc,mkdirSync as br,existsSync as so,readFileSync as oo}from"fs";import{join as ft,extname as qc}from"path";import{randomUUID as Xc}from"crypto";import Qc from"busboy";function nd(t){return t.replace(/[^a-zA-Z0-9._-]/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").toLowerCase()}function sd(t,e){if(!so(ft(t,e)))return e;let n=qc(e),s=e.slice(0,-n.length||void 0),o=1;for(;so(ft(t,`${s}-${o}${n}`));)o++;return`${s}-${o}${n}`}async function od(t){let e=(await import("pdf-parse")).default,n=oo(t);return(await e(n)).text}async function id(t){return(await(await import("mammoth")).extractRawText({path:t})).value}function rd(t){return oo(t,"utf-8")}function vr(t,e){let n=v();if(!n){m(e,400,{error:"No active session"});return}if(!(t.headers["content-type"]||"").includes("multipart/form-data")){m(e,400,{error:"Expected multipart/form-data"});return}let o=[],i=[],a=0,r=[],l=Qc({headers:t.headers,limits:{fileSize:Zc,files:10}});l.on("file",(c,d,u)=>{let{filename:p,mimeType:f}=u;if(a++,!td.has(f)){i.push(`Unsupported file type: ${p} (${f})`),d.resume();return}let h=Sr.has(f),y=nd(p),b=Xc(),A,w;h?(A=ft(n.themePath,"assets"),br(A,{recursive:!0}),w=sd(A,y)):(A=ft(n.themePath,".vibespot","uploads"),br(A,{recursive:!0}),w=`${b}-${y}`);let $=ft(A,w),R=zc($),M=0,N=!1;d.on("data",L=>{M+=L.length}),d.on("limit",()=>{N=!0,i.push(`File too large (>10MB): ${p}`)}),d.pipe(R),r.push(new Promise(L=>{R.on("finish",()=>{if(!N){let ne={id:b,filename:w,originalName:p,type:h?"image":"document",usage:h?"asset":"context",mimeType:f,size:M,addedAt:new Date().toISOString()};o.push(ne),ji(ne)}L()}),R.on("error",()=>{i.push(`Failed to write: ${p}`),L()})}))}),l.on("finish",async()=>{await Promise.all(r);for(let c of o)if(c.type==="document"){let d=ft(n.themePath,".vibespot","uploads",c.filename);try{c.mimeType==="application/pdf"?c.extractedText=await od(d):c.mimeType==="application/vnd.openxmlformats-officedocument.wordprocessingml.document"?c.extractedText=await id(d):c.extractedText=rd(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(a===0){m(e,400,{error:"No files uploaded"});return}m(e,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}`),m(e,500,{error:"Upload failed"})}),t.pipe(l)}function wr(t){let e=v();return e?.assets?t.map(n=>{let s=e.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=ft(e.themePath,"assets",s.filename);so(i)&&(o.base64=oo(i).toString("base64")),o.assetPath=`${e.themeName}/assets/${s.filename}`}else s.type==="document"&&(o.extractedText=s.extractedText);return o}).filter(n=>n!==null):[]}var Zc,Sr,ed,td,io=J(()=>{"use strict";g();ot();Se();ve();Zc=10*1024*1024,Sr=new Set(["image/png","image/jpeg","image/jpg","image/svg+xml","image/webp","image/gif"]),ed=new Set(["application/pdf","application/vnd.openxmlformats-officedocument.wordprocessingml.document","text/markdown","text/plain"]),td=new Set([...Sr,...ed])});async function xr(t,e){for(let n=0;;n++)try{return await t()}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>=ro.length)throw s;let r=ro[n];E.warn("agent-adapter",`Rate limited (429), attempt ${n+1}/${ro.length} \u2014 waiting ${r}s`),e&&e(`Rate limited \u2014 retrying in ${r}s...`),await new Promise(l=>setTimeout(l,r*1e3)),e&&e("Retrying...")}}function ts(t){if(t&&typeof t=="object"&&!Array.isArray(t)){let e=t;for(let n of["fieldsJson","metaJson"])e[n]&&typeof e[n]=="object"&&(e[n]=JSON.stringify(e[n]))}return t}async function ad(){return ao||(ao=(await import("@anthropic-ai/sdk")).default),ao}async function ld(t,e,n){let s=await ad(),o=new s({apiKey:t}),i=n.messages;if(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};return xr(async()=>{let r=await o.messages.create({model:e,max_tokens:n.maxTokens||16e3,system:n.systemPrompt,messages:i,tools:[a],tool_choice:{type:"tool",name:n.structuredOutput.name}});for(let c of r.content)if(c.type==="tool_use")return{type:"structured",data:ts(c.input)};return{type:"text",text:r.content.filter(c=>c.type==="text").map(c=>c.text).join("")}},n.onStatus)}return xr(async()=>{let a="",r=o.messages.stream({model:e,max_tokens:n.maxTokens||16e3,system:n.systemPrompt,messages:i});for await(let l of r)l.type==="content_block_delta"&&l.delta.type==="text_delta"&&(a+=l.delta.text,n.onChunk&&n.onChunk(l.delta.text));return{type:"text",text:a}},n.onStatus)}function lo(t){let e={...t};if(e.type==="object"&&(e.additionalProperties=!1,e.properties&&typeof e.properties=="object")){let n={};for(let[s,o]of Object.entries(e.properties))n[s]=o&&typeof o=="object"?lo(o):o;e.properties=n}return e.items&&typeof e.items=="object"&&(e.items=lo(e.items)),e}async function cd(t,e,n){let s=[{role:"system",content:n.systemPrompt},...n.messages.map(l=>({role:l.role,content:typeof l.content=="string"?l.content:l.content.map(c=>({type:"text",text:c.text}))}))],o={model:e,max_tokens:n.maxTokens||16e3,messages:s};n.structuredOutput&&(o.response_format={type:"json_schema",json_schema:{name:n.structuredOutput.name,strict:!0,schema:lo(n.structuredOutput.schema)}});let i=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${t}`},body:JSON.stringify(o)});if(!i.ok){let l=await i.text(),c=i.status;if(c===429){let d=new Error(`OpenAI rate limit: ${l}`);throw d.status=429,d}throw new Error(`OpenAI API error (${c}): ${l}`)}let r=(await i.json()).choices?.[0]?.message?.content||"";if(n.structuredOutput)try{return{type:"structured",data:ts(JSON.parse(r))}}catch{return E.warn("agent-adapter","OpenAI structured output parse failed, returning raw text"),{type:"text",text:r}}return{type:"text",text:r}}async function dd(t,e,n){let s=e||"gemini-2.5-flash",o=n.messages.map(d=>({role:d.role==="assistant"?"model":"user",parts:typeof d.content=="string"?[{text:d.content}]:d.content.map(u=>({text:u.text}))})),i={systemInstruction:{parts:[{text:n.systemPrompt}]},contents:o,generationConfig:{maxOutputTokens:n.maxTokens||16e3,...n.structuredOutput?{responseMimeType:"application/json",responseSchema:n.structuredOutput.schema}:{}}},a=`https://generativelanguage.googleapis.com/v1beta/models/${s}:generateContent?key=${t}`,r=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)});if(!r.ok){let d=await r.text(),u=r.status;if(u===429){let p=new Error(`Gemini rate limit: ${d}`);throw p.status=429,p}throw new Error(`Gemini API error (${u}): ${d}`)}let c=(await r.json()).candidates?.[0]?.content?.parts?.[0]?.text||"";if(n.structuredOutput)try{return{type:"structured",data:ts(JSON.parse(c))}}catch{return E.warn("agent-adapter","Gemini structured output parse failed, returning raw text"),{type:"text",text:c}}return{type:"text",text:c}}function ud(t){switch(t){case"claude-code":{let e=P(),n=["--print"];return e.claudeCodeModel&&n.push("--model",e.claudeCodeModel),{bin:"claude",args:n}}case"gemini-cli":return{bin:"gemini",args:[]};case"codex-cli":return{bin:"codex",args:["exec","--full-auto"]};default:throw new Error(`Not a CLI engine: ${t}`)}}function md(t){let e=[t.systemPrompt];for(let n of t.messages){let s=n.role==="user"?"User":"Assistant",o=typeof n.content=="string"?n.content:n.content.map(i=>i.text).join(`
|
|
513
513
|
`);e.push(`
|
|
514
514
|
|
|
515
515
|
## ${s}
|
|
516
|
-
${o}`)}if(t.structuredOutput){let n=
|
|
516
|
+
${o}`)}if(t.structuredOutput){let n=Cr(t.structuredOutput.schema);e.push(`
|
|
517
517
|
|
|
518
518
|
## Output Format \u2014 CRITICAL
|
|
519
519
|
Respond with a JSON code block. Wrap your JSON in \`\`\`json fences. No prose or explanation before or after the code block.
|
|
520
520
|
|
|
521
521
|
The JSON must match this structure:
|
|
522
|
-
${n}`)}return e.join("")}function
|
|
523
|
-
`)}function
|
|
522
|
+
${n}`)}return e.join("")}function Cr(t,e=0){let n=" ".repeat(e),s=t.properties,o=t.required||[];if(!s)return`${n}${JSON.stringify(t)}`;let i=["{"];for(let[a,r]of Object.entries(s)){let l=o.includes(a)?" (required)":"",c=r.type||"any",d=r.description?` \u2014 ${r.description}`:"",u=r.enum?` [${r.enum.join(", ")}]`:"";if(c==="array"&&r.items){let p=r.items.type||"object";i.push(`${n} "${a}": ${c}<${p}>${l}${d}${u}`)}else c==="object"&&r.properties?i.push(`${n} "${a}": ${Cr(r,e+1)}${l}${d}`):i.push(`${n} "${a}": ${c}${l}${d}${u}`)}return i.push(`${n}}`),i.join(`
|
|
523
|
+
`)}function pd(t){let e=t.trim(),n=Le(e);if(n&&typeof n=="object")return n;let s=e.match(/```(?:json|vibespot-modules)?\s*\n([\s\S]*?)```/i);if(s){let r=s[1].trim(),l=Le(r);if(l&&typeof l=="object")return l;let c=nn(r);if(c&&typeof c=="object")return c}let o=e.indexOf("{"),i=e.lastIndexOf("}");if(o!==-1&&i>o){let r=e.slice(o,i+1),l=Le(r);if(l&&typeof l=="object")return l;let c=nn(r);if(c&&typeof c=="object")return c}let a=nn(e);return a&&typeof a=="object"?a:null}async function fd(t,e,n){let{bin:s,args:o}=ud(t),i=md(n),a=await es(s,o,i,n.onChunk);if(!n.structuredOutput)return{type:"text",text:a};let r=pd(a);return r?{type:"structured",data:ts(r)}:(E.warn("agent-cli",`${t}: failed to parse structured output, returning text`,{outputPreview:a.slice(0,500),outputLength:a.length}),{type:"text",text:a})}async function hd(t,e,n,s){switch(E.info("agent-adapter",`${t} API call`,{model:n,structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),t){case"anthropic-api":return ld(e,n,s);case"openai-api":return cd(e,n,s);case"gemini-api":return dd(e,n,s);default:throw new Error(`Unsupported API engine: ${t}`)}}async function Ne(t,e,n,s){return gd.has(t)?hd(t,e,n,s):(E.info("agent-adapter",`${t} CLI call`,{structured:!!s.structuredOutput,schemaName:s.structuredOutput?.name,systemPromptLength:s.systemPrompt.length,messageCount:s.messages.length}),fd(t,n,s))}function ns(t){return t==="anthropic-api"||t==="openai-api"||t==="gemini-api"||t==="claude-code"||t==="gemini-cli"||t==="codex-cli"}function on(t){return t==="claude-code"||t==="gemini-cli"||t==="codex-cli"}var ro,ao,gd,it=J(()=>{"use strict";g();to();Zn();ee();ve();ro=[10,20,40,60,120];ao=null;gd=new Set(["anthropic-api","openai-api","gemini-api"])});function Ar(t,e,n,s){let o=e.length>0?`Current template modules (in page order):
|
|
524
524
|
${e.map((r,l)=>`${l+1}. ${r}`).join(`
|
|
525
525
|
`)}`:"No modules yet (new page).",i=n.length>0?`
|
|
526
526
|
|
|
@@ -576,7 +576,7 @@ CRITICAL: When the user corrects a misclassification (e.g., "I was referencing t
|
|
|
576
576
|
If the user asks for multiple things (e.g., "make hero taller AND add testimonials"), capture ALL parts:
|
|
577
577
|
- Affected existing modules in \`affectedModules\`
|
|
578
578
|
- New modules in \`newModules\`
|
|
579
|
-
- Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var
|
|
579
|
+
- Set the broadest applicable intent (prefer "modify" + newModules over splitting)`}var Ir,kr=J(()=>{"use strict";g();Ir={type:"object",properties:{intent:{type:"string",enum:["create","modify","add","remove","rearrange","style_change","question"]},affectedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that need changes"},unchangedModules:{type:"array",items:{type:"string"},description:"Names of existing modules that stay as-is"},newModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},description:{type:"string"},position:{type:"number"}},required:["name","description","position"]},description:"New modules to create"},reuseModules:{type:"array",items:{type:"object",properties:{name:{type:"string"},sourceTemplate:{type:"string"},position:{type:"number"}},required:["name","sourceTemplate","position"]},description:"Modules to copy from the library (immutable structure)"},guidesNeeded:{type:"array",items:{type:"string",enum:["design","content","conversion","hubspot_rules","humanify"]}},designSystemChanges:{type:"boolean",description:"True if shared CSS / design system needs regeneration"},answer:{type:"string",description:'For "question" intent only \u2014 the answer to return directly'}},required:["intent","affectedModules","unchangedModules","newModules","guidesNeeded","designSystemChanges"]}});async function $r(t,e,n,s,o,i,a){i({type:"agent_step",step:"analyzing",label:"Analyzing your request..."});let r=e.modules.map(f=>f.moduleName),l=Ar(e.themeName,r,a,e.brandAssets?.themeContext),c=[],d=e.messages.slice(-6);for(let f of d)if(f.role==="user"||f.role==="assistant"){let h=f.role==="assistant"&&f.content.length>300?f.content.slice(0,300)+"...":f.content;c.push({role:f.role,content:h})}c.push({role:"user",content:t});let u=await Ne(n,s,o,{systemPrompt:l,messages:c,structuredOutput:{schema:Ir,name:"pipeline_plan"},maxTokens:2e3});if(u.type!=="structured"){E.warn("intent-analyzer","Did not get structured output, falling back");let f=e.modules.length===0;return{intent:f?"create":"modify",affectedModules:f?[]:r,unchangedModules:[],newModules:[],guidesNeeded:["design","content","conversion","hubspot_rules","humanify"],designSystemChanges:f}}let p=u.data;return p.affectedModules=p.affectedModules||[],p.unchangedModules=p.unchangedModules||[],p.newModules=p.newModules||[],p.guidesNeeded=p.guidesNeeded||[],E.info("intent-analyzer","Plan",{intent:p.intent,affected:p.affectedModules.length,unchanged:p.unchangedModules.length,new:p.newModules.length,reuse:p.reuseModules?.length||0,designSystem:p.designSystemChanges}),i({type:"agent_decision",step:"analyzing",decision:yd(p)}),p}function yd(t){let e=[`Intent: ${t.intent}`];return t.affectedModules.length>0&&e.push(`Modifying: ${t.affectedModules.join(", ")}`),t.unchangedModules.length>0&&e.push(`Unchanged: ${t.unchangedModules.join(", ")}`),t.newModules.length>0&&e.push(`New: ${t.newModules.map(n=>n.name).join(", ")}`),t.reuseModules?.length&&e.push(`Reuse: ${t.reuseModules.map(n=>`${n.name} from ${n.sourceTemplate}`).join(", ")}`),t.designSystemChanges&&e.push("Design system changes: yes"),e.join(" | ")}var Tr=J(()=>{"use strict";g();it();kr();ve()});function Er(t,e){let n=[];return n.push(`You are the Design System Architect for vibeSpot, a HubSpot CMS page builder.
|
|
580
580
|
|
|
581
581
|
Your job: create a complete, production-ready CSS design system for a landing page theme. You produce the :root custom properties, shared utility/component CSS, and optional shared JS (scroll animations). Downstream agents will use YOUR CSS classes and variables to build individual modules.
|
|
582
582
|
|
|
@@ -663,13 +663,13 @@ Good system font stacks by style:
|
|
|
663
663
|
| Geometric | Futura, "Century Gothic", "Trebuchet MS", sans-serif | system-ui, sans-serif |`),n.push(`
|
|
664
664
|
|
|
665
665
|
## Design Guide
|
|
666
|
-
${
|
|
666
|
+
${bd()}`),e?.styleguide&&n.push(`
|
|
667
667
|
|
|
668
668
|
## Brand Style Guide
|
|
669
669
|
${e.styleguide}`),e?.themeContext&&n.push(`
|
|
670
670
|
|
|
671
671
|
## Product Context
|
|
672
|
-
${e.themeContext}`),n.join("")}function
|
|
672
|
+
${e.themeContext}`),n.join("")}function Pr(t,e,n,s){let o=[];return o.push(`You are the Module Planner for vibeSpot, a HubSpot CMS page builder.
|
|
673
673
|
|
|
674
674
|
Your job: plan the modules for a landing page. You define what each module contains (content brief) and how it should be laid out. You do NOT write module code \u2014 downstream Module Developers handle that.
|
|
675
675
|
|
|
@@ -692,7 +692,7 @@ ${e}
|
|
|
692
692
|
- moduleOrder: list module names in the order they should appear on the page`),(!s||s.includes("content"))&&o.push(`
|
|
693
693
|
|
|
694
694
|
## Content & Copywriting Guide
|
|
695
|
-
${
|
|
695
|
+
${Sd()}`),n?.brandvoice&&o.push(`
|
|
696
696
|
|
|
697
697
|
## Brand Voice
|
|
698
698
|
${n.brandvoice}`),n?.themeContext&&o.push(`
|
|
@@ -701,7 +701,7 @@ ${n.brandvoice}`),n?.themeContext&&o.push(`
|
|
|
701
701
|
${n.themeContext}`),n?.humanify!==!1&&s?.includes("humanify")&&o.push(`
|
|
702
702
|
|
|
703
703
|
## Anti-AI Copy Rules
|
|
704
|
-
${
|
|
704
|
+
${vd()}`),o.join("")}function bd(){return`### Design Philosophy
|
|
705
705
|
You are a senior UI designer. Every page must look professionally designed, not like AI output.
|
|
706
706
|
Avoid "AI slop": purple gradients on white, cookie-cutter card grids, no personality.
|
|
707
707
|
|
|
@@ -804,7 +804,7 @@ Include these in shared CSS:
|
|
|
804
804
|
| All animations same speed | Stagger with increasing delays |
|
|
805
805
|
| Skip hover/focus states | Every interactive element needs feedback |
|
|
806
806
|
| Use \`<br>\` tags for spacing | Use proper margin/padding |
|
|
807
|
-
| Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function
|
|
807
|
+
| Put everything in a shadowed card | Vary: full-bleed, contained, floating |`}function Sd(){return`### Mandatory Page Sections (generate all)
|
|
808
808
|
1. **Navigation Bar** \u2014 Logo, 4-5 nav links, CTA button, sticky on scroll
|
|
809
809
|
2. **Hero** \u2014 Badge/pill, primary headline, subheadline, primary + secondary CTA, trust signals, visual element
|
|
810
810
|
3. **Social Proof Bar** \u2014 Logo strip of 4-6 clients OR stats bar (compact, py-8)
|
|
@@ -892,7 +892,7 @@ Alternate backgrounds every 2-3 sections to create visual "chapters." Sprinkle t
|
|
|
892
892
|
- Invent plausible specifics: neighborhood names, "48 hours" not "quickly", "\u20AC49" not "affordable"
|
|
893
893
|
- Keep paragraphs to 2-3 sentences max
|
|
894
894
|
- Aim for 6th-grade reading level
|
|
895
|
-
- Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function
|
|
895
|
+
- Include section labels (UPPERCASE, letter-spacing 0.1em, accent color, 2-3 words) above every headline`}function vd(){return`### Banned Punctuation
|
|
896
896
|
- **Em dashes (\u2014)**: NEVER use. Biggest AI tell. Replace with periods, commas, or parentheses.
|
|
897
897
|
- **Semicolons**: Feel academic, not conversational. Use periods instead.
|
|
898
898
|
- **Exclamation marks**: One per page maximum. Zero is ideal for B2B.
|
|
@@ -922,28 +922,28 @@ seamless, cutting-edge, groundbreaking, game-changer, revolutionary, transformat
|
|
|
922
922
|
- Use plain short words: use > utilize, start > commence, help > facilitate
|
|
923
923
|
- Vary sentence length aggressively: mix 3-word, 12-word, and 25-word sentences
|
|
924
924
|
- Front-load the benefit in the first 5 words
|
|
925
|
-
- Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var
|
|
925
|
+
- Write like you'd explain it in a bar \u2014 if you wouldn't say it holding a beer, rewrite it`}var Nr,Mr,_r=J(()=>{"use strict";g();Nr={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"]};Mr={type:"object",properties:{modules:{type:"array",items:{type:"object",properties:{name:{type:"string",description:"Module name in title-case"},description:{type:"string",description:"What this module does"},contentBrief:{type:"string",description:"Specific content: headlines, body copy, stats, CTAs"},layoutNotes:{type:"string",description:"Visual layout approach referencing shared CSS classes"}},required:["name","description","contentBrief","layoutNotes"]}},moduleOrder:{type:"array",items:{type:"string"},description:"Module names in page display order"},narrative:{type:"string",description:"Brief description of the page story/flow"}},required:["modules","moduleOrder","narrative"]}});async function Rr(t,e,n,s,o,i,a){a({type:"agent_step",step:"designing",label:"Creating design system..."});let r=Er(n.themeName,n.brandAssets),l=`## User Request
|
|
926
926
|
${t}`;n.modules.length>0&&e.designSystemChanges&&(l+=`
|
|
927
927
|
|
|
928
928
|
## Current Shared CSS (update this)
|
|
929
929
|
\`\`\`css
|
|
930
930
|
${n.sharedCss}
|
|
931
|
-
\`\`\``);let c=await Ne(s,o,i,{systemPrompt:r,messages:[{role:"user",content:l}],structuredOutput:{schema:
|
|
931
|
+
\`\`\``);let c=await Ne(s,o,i,{systemPrompt:r,messages:[{role:"user",content:l}],structuredOutput:{schema:Nr,name:"design_system"},maxTokens:16e3}),d;c.type!=="structured"?(E.warn("page-architect","Design system: did not get structured output, using fallback"),d={cssVariables:{},sharedCss:n.sharedCss||"",sharedJs:n.sharedJs||"",aesthetic:"default"}):(d=c.data,E.info("page-architect","Design system created",{aesthetic:d.aesthetic,varCount:Object.keys(d.cssVariables||{}).length,cssLength:d.sharedCss?.length||0}));let u=d.sharedCss||"",p=d.cssVariables;p&&typeof p=="object"&&Object.keys(p).length>0&&(u.includes(":root")||(u=`:root {
|
|
932
932
|
${Object.entries(p).map(([N,L])=>` ${N.startsWith("--")?N:`--${N}`}: ${L};`).join(`
|
|
933
933
|
`)}
|
|
934
934
|
}
|
|
935
935
|
|
|
936
|
-
${u}`));let f=[],h=/\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,y=[...new Set((t.match(h)||[]).map(
|
|
937
|
-
`)}),a({type:"design_system_ready",sharedCss:u,sharedJs:d.sharedJs||"",aesthetic:d.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let A
|
|
936
|
+
${u}`));let f=[],h=/\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,y=[...new Set((t.match(h)||[]).map(M=>M.trim()))];if(y.length>0){let M=y.filter(L=>u.toLowerCase().includes(L.toLowerCase())),N=y.filter(L=>!M.includes(L));N.length>0&&f.push(`Note: ${N.join(", ")} not available \u2014 HubSpot modules use system font stacks (no external font imports allowed)`)}let b=[`Design system: ${d.aesthetic||"created"} | ${Object.keys(p||{}).length} variables, ${u.length} chars CSS`,...f];a({type:"agent_decision",step:"designing",decision:b.join(`
|
|
937
|
+
`)}),a({type:"design_system_ready",sharedCss:u,sharedJs:d.sharedJs||"",aesthetic:d.aesthetic||""}),a({type:"agent_step",step:"designing",label:"Planning modules..."});let A=Pr(n.themeName,u,n.brandAssets,e.guidesNeeded),w=`## User Request
|
|
938
938
|
${t}`;e.newModules.length>0&&(w+=`
|
|
939
939
|
|
|
940
940
|
## Planned Modules
|
|
941
|
-
${e.newModules.map((
|
|
941
|
+
${e.newModules.map((M,N)=>`${N+1}. **${M.name}** \u2014 ${M.description}`).join(`
|
|
942
942
|
`)}`),n.modules.length>0&&!e.designSystemChanges&&(w+=`
|
|
943
943
|
|
|
944
944
|
## Existing Modules (keeping)
|
|
945
|
-
${n.modules.map(
|
|
946
|
-
`)}`);let $=await Ne(s,o,i,{systemPrompt:A,messages:[{role:"user",content:w}],structuredOutput:{schema:
|
|
945
|
+
${n.modules.map(M=>`- ${M.moduleName}`).join(`
|
|
946
|
+
`)}`);let $=await Ne(s,o,i,{systemPrompt:A,messages:[{role:"user",content:w}],structuredOutput:{schema:Mr,name:"module_plan"},maxTokens:8e3}),R;return $.type!=="structured"?(E.warn("page-architect","Module planner: did not get structured output, using fallback"),R={modules:e.newModules.map(M=>({name:M.name,description:M.description,contentBrief:"Generate appropriate content",layoutNotes:"Use responsive layout"})),moduleOrder:e.newModules.map(M=>M.name),narrative:"Page generated from user request"}):(R=$.data,E.info("page-architect","Module plan",{moduleCount:R.modules.length})),a({type:"agent_decision",step:"designing",decision:`Page: ${R.narrative} | ${R.modules.length} modules planned`}),{designSystem:{cssVariables:d.cssVariables||{},sharedCss:u,sharedJs:d.sharedJs},modules:R.modules,moduleOrder:R.moduleOrder,narrative:R.narrative}}var Or=J(()=>{"use strict";g();it();_r();ve()});function jr(t){let e=0,n=[];return async function(o){e>=t&&await new Promise(i=>n.push(i)),e++;try{return await o()}finally{e--,n.length>0&&n.shift()()}}}var Fr=J(()=>{"use strict";g()});function Jr(t,e,n,s){let o=[];return o.push(`You are a Module Developer for vibeSpot, a HubSpot CMS page builder.
|
|
947
947
|
|
|
948
948
|
Your job: generate ONE HubSpot CMS module. You receive a module specification and must produce the complete module code.
|
|
949
949
|
|
|
@@ -1004,7 +1004,7 @@ ${le()}`),s?.themeContext&&o.push(`
|
|
|
1004
1004
|
${s.themeContext}`),s?.humanify!==!1&&n?.includes("humanify")&&o.push(`
|
|
1005
1005
|
|
|
1006
1006
|
## Anti-AI Copy Rules
|
|
1007
|
-
${
|
|
1007
|
+
${wd()}`),o.join("")}function wd(){return`### Banned Punctuation
|
|
1008
1008
|
- **Em dashes (\u2014)**: NEVER use. Replace with periods, commas, or parentheses. Hyphens for compounds fine.
|
|
1009
1009
|
- **Semicolons**: Use periods instead in marketing copy.
|
|
1010
1010
|
- **Exclamation marks**: One per page max. Zero ideal for B2B.
|
|
@@ -1043,7 +1043,7 @@ Never end with: "The future of [X] is here", "Your journey starts here", "Join t
|
|
|
1043
1043
|
- Keep slightly imperfect (fragments OK, mild hedging like "honestly didn't think")
|
|
1044
1044
|
- Full names, specific roles (not "John D., CEO")
|
|
1045
1045
|
- Never start with "This product is..." \u2014 start with the person's situation
|
|
1046
|
-
- Vary length and voice across testimonials`}function
|
|
1046
|
+
- Vary length and voice across testimonials`}function Dr(t,e,n){let s=[];return s.push(`## User Request
|
|
1047
1047
|
${t}`),s.push(`
|
|
1048
1048
|
|
|
1049
1049
|
## Module Specification
|
|
@@ -1070,33 +1070,33 @@ ${n.moduleCss}
|
|
|
1070
1070
|
**module.js:**
|
|
1071
1071
|
\`\`\`js
|
|
1072
1072
|
${n.moduleJs}
|
|
1073
|
-
\`\`\``)),s.join("")}var
|
|
1073
|
+
\`\`\``)),s.join("")}var Lr,Hr=J(()=>{"use strict";g();Ve();Lr={type:"object",properties:{moduleName:{type:"string"},fieldsJson:{type:"string",description:"Complete fields.json content as a JSON string"},metaJson:{type:"string",description:"Complete meta.json content as a JSON string"},moduleHtml:{type:"string",description:"Complete module.html HubL template content"},moduleCss:{type:"string",description:"Complete module.css vanilla CSS content"},moduleJs:{type:"string",description:"Optional module.js vanilla JS content, or empty string if not needed"}},required:["moduleName","fieldsJson","metaJson","moduleHtml","moduleCss"]}});async function Gr(t,e,n,s,o,i,a,r,l,c,d){l({type:"agent_step",step:"developing",label:`Generating ${e.length} module${e.length===1?"":"s"}...`});let u=Jr(s,n,c,d),p=jr(r),f=e.length,h=e.map((b,A)=>p(async()=>{l({type:"module_progress",module:b.name,status:"generating",current:A+1,total:f});let w="";for(let $=0;$<2;$++)try{$>0&&(E.warn("module-developer",`${b.name}: retrying after failure (attempt ${$+1})`),l({type:"module_progress",module:b.name,status:"retrying",current:A+1,total:f}));let R=await Ur(t,b,u,o,i,a);return l({type:"module_progress",module:b.name,status:"complete",current:A+1,total:f,moduleFiles:R}),{moduleName:b.name,module:R}}catch(R){w=R instanceof Error?R.message:typeof R=="object"&&R!==null?JSON.stringify(R):String(R),E.error("module-developer",`Failed: ${b.name} (attempt ${$+1})`,{error:w})}return l({type:"module_progress",module:b.name,status:"failed",current:A+1,total:f}),{moduleName:b.name,error:w}}));return(await Promise.allSettled(h)).map(b=>b.status==="fulfilled"?b.value:{moduleName:"unknown",error:b.reason instanceof Error?b.reason.message:String(b.reason)})}async function Ur(t,e,n,s,o,i,a=0){let r=Dr(t,e,e.existingCode),l=await Ne(s,o,i,{systemPrompt:n,messages:[{role:"user",content:r}],structuredOutput:{schema:Lr,name:"module_output"},maxTokens:16e3});if(l.type!=="structured"){if(a<2)return E.warn("module-developer",`${e.name}: no structured output, retry ${a+1}`),Ur(t,e,n,s,o,i,a+1);throw new Error(`Module "${e.name}" failed to produce structured output after ${a+1} attempts`)}let c=l.data,d=typeof c.fieldsJson=="string"?c.fieldsJson:JSON.stringify(c.fieldsJson,null,2),u=typeof c.metaJson=="string"?c.metaJson:JSON.stringify(c.metaJson,null,2);return{moduleName:e.name,fieldsJson:d,metaJson:u,moduleHtml:String(c.moduleHtml||""),moduleCss:String(c.moduleCss||""),moduleJs:c.moduleJs?String(c.moduleJs):void 0}}var Wr=J(()=>{"use strict";g();it();Fr();Hr();ve()});function Kr(t,e,n){return n({type:"agent_step",step:"quality_check",label:"Quality check..."}),t.map(s=>{let o=[],i={...s};i.fieldsJson=Br(i.fieldsJson,i.moduleName,"fieldsJson",o),i.metaJson=Br(i.metaJson,i.moduleName,"metaJson",o),i.fieldsJson=xd(i.fieldsJson,i.moduleName,o),i.fieldsJson=Cd(i.fieldsJson,i.moduleName,o),i.moduleCss=Ad(i.moduleCss,i.moduleName,"moduleCss",o),Id(i.moduleCss,i.moduleName,e,o),i.moduleHtml=kd(i.moduleHtml,i.moduleName,o),i.metaJson=$d(i.metaJson,i.moduleName,o);let a=o.every(r=>r.autoFixed);return o.length>0&&E.info("validator",`${i.moduleName}: ${o.length} issues`,{autoFixed:o.filter(r=>r.autoFixed).length,unfixed:o.filter(r=>!r.autoFixed).length}),{module:i,issues:o,valid:a}})}function Br(t,e,n,s){return!t||t.trim()===""?(s.push({module:e,field:n,message:`Empty ${n}`,autoFixed:n==="metaJson"}),n==="metaJson"?JSON.stringify({host_template_types:["PAGE"],is_available_for_new_content:!0}):t):(Le(t)===null&&s.push({module:e,field:n,message:`Invalid JSON in ${n}`,autoFixed:!1}),t)}function xd(t,e,n){let s=t;return/"name"\s*:\s*"name"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"name" is a reserved field name \u2192 renamed to "item_name"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"name"/g,'"name": "item_name"')),/"name"\s*:\s*"label"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"label" is a reserved field name \u2192 renamed to "section_label"',autoFixed:!0}),s=s.replace(/"name"\s*:\s*"label"/g,'"name": "section_label"')),s}function Cd(t,e,n){let s=t;return/"type"\s*:\s*"textarea"/g.test(s)&&(n.push({module:e,field:"fieldsJson",message:'"textarea" is deprecated \u2192 changed to "text"',autoFixed:!0}),s=s.replace(/"type"\s*:\s*"textarea"/g,'"type": "text"')),s}function Ad(t,e,n,s){if(!t)return t;let o=t,i=/@import\s+url\([^)]*(?:fonts\.googleapis|cdnjs|unpkg|jsdelivr)[^)]*\)\s*;?/gi;return i.test(o)&&(s.push({module:e,field:n,message:"CDN @import removed (external imports not allowed)",autoFixed:!0}),o=o.replace(i,"/* CDN import removed */")),o}function Id(t,e,n,s){if(!t)return;let o=/\.([a-zA-Z][\w-]*)/g,i,a=0;for(;(i=o.exec(t))!==null;){let r=i[1];r.startsWith(n+"-")||r==="visible"||r==="active"||r==="scroll-animate"||r.startsWith("body-wrapper")||r.startsWith("dnd-")||r.startsWith("row-")||a++}a>3&&s.push({module:e,field:"moduleCss",message:`${a} CSS classes without "${n}-" prefix`,autoFixed:!1})}function kd(t,e,n){if(!t)return t;let s=t,o=/\{%[-~]?\s*(if|for|block|macro|endif|endfor|endblock|endmacro)\b[^%]*%\}/g,i=[],a;for(;(a=o.exec(s))!==null;){let c=a[1],d=!c.startsWith("end"),u=d?c:c.replace("end","");i.push({tag:c,isOpen:d,baseTag:u,start:a.index,end:a.index+a[0].length})}let r=[],l=[];for(let c=0;c<i.length;c++)if(i[c].isOpen)r.push(c);else{let d=-1;for(let u=r.length-1;u>=0;u--)if(i[r[u]].baseTag===i[c].baseTag){d=u;break}d!==-1?r.splice(d,1):l.push(c)}if(l.length>0){for(let c=l.length-1;c>=0;c--){let d=i[l[c]];s=s.slice(0,d.start)+`<!-- removed orphan {% ${d.tag} %} -->`+s.slice(d.end)}n.push({module:e,field:"moduleHtml",message:`Removed ${l.length} orphan closing tag${l.length===1?"":"s"} with no matching opener`,autoFixed:!0})}if(r.length>0){let c=r.map(u=>i[u].baseTag),d=c.reverse().map(u=>`{% end${u} %}`).join(`
|
|
1074
1074
|
`);s=`${s}
|
|
1075
|
-
${d}`,n.push({module:e,field:"moduleHtml",message:`Added ${c.length} missing closing tag${c.length===1?"":"s"}: ${c.map(u=>`{% end${u} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:e,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function
|
|
1075
|
+
${d}`,n.push({module:e,field:"moduleHtml",message:`Added ${c.length} missing closing tag${c.length===1?"":"s"}: ${c.map(u=>`{% end${u} %}`).join(", ")}`,autoFixed:!0})}return/\bnow\(\)/.test(s)&&(s=s.replace(/\bnow\(\)/g,"local_dt"),n.push({module:e,field:"moduleHtml",message:"Replaced now() with local_dt (now() is not valid HubL)",autoFixed:!0})),s}function $d(t,e,n){let s=Le(t);if(!s||typeof s!="object")return t;let o=s,i=!1;return o.host_template_types||(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content===void 0&&(o.is_available_for_new_content=!0,i=!0),i?(n.push({module:e,field:"metaJson",message:"Added missing meta.json required fields",autoFixed:!0}),JSON.stringify(o,null,2)):t}var Vr=J(()=>{"use strict";g();Zn();ve()});import{execSync as Td}from"child_process";async function Yr(t,e,n,s,o,i,a,r){let l=Date.now(),c=i;if(on(n)){let O={"claude-code":"claude","gemini-cli":"gemini","codex-cli":"codex"}[n];if(O)try{Td(`command -v ${O}`,{stdio:"ignore"})}catch{throw new Error(`CLI engine "${n}" requires "${O}" to be installed and on your PATH.`)}}let d=await $r(t,e,n,s,o,a,r);if(d.intent==="question"&&d.answer){let G=Date.now()-l;return a({type:"pipeline_complete",modulesGenerated:0,modulesUnchanged:e.modules.length,durationMs:G}),{modules:[...e.modules],moduleOrder:e.moduleOrder,sharedCss:e.sharedCss,sharedJs:e.sharedJs,assistantMessage:d.answer,stats:{modulesGenerated:0,modulesUnchanged:e.modules.length,modulesFailed:0,durationMs:G}}}let u=null,p=e.sharedCss,f=e.sharedJs;(d.intent==="create"||d.designSystemChanges)&&(u=await Rr(t,d,e,n,s,o,a),p=u.designSystem.sharedCss||p,f=u.designSystem.sharedJs||f,a({type:"blueprint_ready",moduleOrder:u.moduleOrder,sharedCss:p,sharedJs:f}));let y=[];if(u)for(let G of u.modules)y.push({name:G.name,description:G.description,contentBrief:G.contentBrief,layoutNotes:G.layoutNotes});else{for(let G of d.newModules)y.push({name:G.name,description:G.description,contentBrief:"Generate appropriate content based on the user request",layoutNotes:"Use responsive layout matching the existing design system"});for(let G of d.affectedModules){let O=e.modules.find(z=>z.moduleName===G);O&&y.push({name:G,description:`Modify existing module: ${G}`,contentBrief:"Apply the user's requested changes",layoutNotes:"Preserve existing layout unless changes are requested",existingCode:O})}}let b=[],A=[];if(y.length>0){let G=await Gr(t,y,p,e.themeName,n,s,o,c,a,d.guidesNeeded,e.brandAssets);for(let O of G)O.module?b.push(O.module):A.push(O.moduleName)}let w=null;if(b.length>0){w=Kr(b,e.themeName,a),b=w.map(O=>O.module);let G=w.reduce((O,z)=>O+z.issues.length,0);if(G>0){let O=w.reduce((ae,Io)=>ae+Io.issues.filter(Rt=>Rt.autoFixed).length,0);E.info("pipeline",`Quality check: ${G} issues, ${O} auto-fixed`);let z=w.flatMap(ae=>ae.issues).map(ae=>`${ae.autoFixed?"\u2713":"\u26A0"} ${ae.module}: ${ae.message}`).join(`
|
|
1076
1076
|
`);a({type:"agent_decision",step:"quality_check",decision:`${G} issues found, ${O} auto-fixed
|
|
1077
|
-
${z}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let $=
|
|
1077
|
+
${z}`})}else a({type:"agent_decision",step:"quality_check",decision:"All modules passed quality checks"})}let $=Ed(e,d,b,u,r),R=Nd(e,d,u,$);if(u?.moduleOrder?.length){let G=new Set(u.moduleOrder),O=$.filter(z=>!G.has(z.moduleName)).map(z=>z.moduleName);O.length>0&&a({type:"agent_decision",step:"quality_check",decision:`\u26A0 ${O.length} module${O.length===1?"":"s"} missing from page order \u2014 auto-inserted: ${O.join(", ")}`})}let M=Date.now()-l,N=b.length,L=d.unchangedModules.length,ne=w?w.flatMap(G=>G.issues):[],U=Pd(d,N,L,A,M,u,ne);return A.length>0?a({type:"pipeline_partial",succeeded:b.map(G=>G.moduleName),failed:A,durationMs:M}):a({type:"pipeline_complete",modulesGenerated:N,modulesUnchanged:L,durationMs:M}),{modules:$,moduleOrder:R,sharedCss:p,sharedJs:f,assistantMessage:U,stats:{modulesGenerated:N,modulesUnchanged:L,modulesFailed:A.length,durationMs:M}}}function Ed(t,e,n,s,o){let i=[],a=new Set;for(let r of n)i.push(r),a.add(r.moduleName);for(let r of e.unchangedModules){if(a.has(r))continue;let l=t.modules.find(c=>c.moduleName===r);l&&(i.push(l),a.add(r))}if(e.reuseModules)for(let r of e.reuseModules){if(a.has(r.name))continue;let l=o.find(c=>c.name===r.name&&c.module);l&&l.module&&(i.push(l.module),a.add(r.name))}return i}function Nd(t,e,n,s){if(n?.moduleOrder?.length){let r=[...n.moduleOrder],l=new Set(r);for(let c of s)if(!l.has(c.moduleName)){let d=r.findIndex(u=>u.toLowerCase().includes("footer"));d!==-1?r.splice(d,0,c.moduleName):r.push(c.moduleName),l.add(c.moduleName),E.warn("pipeline",`Module "${c.moduleName}" missing from blueprint order \u2014 inserted`)}return r}if(e.intent==="create")return s.map(r=>r.moduleName);let o=[...t.moduleOrder],i=[...e.newModules.map(r=>({name:r.name,position:r.position})),...(e.reuseModules||[]).map(r=>({name:r.name,position:r.position}))].sort((r,l)=>r.position-l.position);for(let r of i){let l=Math.min(r.position,o.length);o.splice(l,0,r.name)}let a=new Set(s.map(r=>r.moduleName));return o.filter(r=>a.has(r))}function Pd(t,e,n,s,o,i,a){let r=Math.round(o/1e3),l=[];if(t.intent==="create")l.push(`Created ${e} module${e===1?"":"s"} in ${r}s.`);else if(t.intent==="modify"||t.intent==="style_change")l.push(`Updated ${e} module${e===1?"":"s"} in ${r}s.`),n>0&&l.push(`${n} module${n===1?"":"s"} unchanged.`);else if(t.intent==="add"){let u=t.newModules.map(p=>p.name).join(", ");l.push(`Added ${u} in ${r}s.`)}else t.intent==="remove"?l.push(`Removed modules in ${r}s.`):t.intent==="rearrange"&&l.push(`Rearranged modules in ${r}s.`);i?.narrative&&l.push(`
|
|
1078
1078
|
|
|
1079
1079
|
${i.narrative}`),s.length>0&&l.push(`
|
|
1080
1080
|
|
|
1081
1081
|
**Failed:** ${s.join(", ")}. You can retry these individually.`);let c=a.filter(u=>!u.autoFixed),d=a.filter(u=>u.autoFixed);if(d.length>0||c.length>0){let u=[];d.length>0&&u.push(`**Auto-fixed:** ${d.map(p=>`${p.module}: ${p.message}`).join(", ")}`),c.length>0&&u.push(`**Warnings:** ${c.map(p=>`${p.module}: ${p.message}`).join(", ")}`),l.push(`
|
|
1082
1082
|
|
|
1083
1083
|
${u.join(`
|
|
1084
|
-
`)}`)}return l.join("")}var
|
|
1084
|
+
`)}`)}return l.join("")}var zr=J(()=>{"use strict";g();it();Tr();Or();Wr();Vr();ve();it()});var qr={};lt(qr,{applyPipelineResult:()=>go,handleAgenticGenerate:()=>fo,handleGenerate:()=>Md,handleGenerateStream:()=>rn,isGenerating:()=>Pt,resolveAgenticEngine:()=>ss,setParseWarningCallback:()=>mo,shouldUseAgenticMode:()=>ho});import{execSync as co}from"child_process";function mo(t){uo=t}function Pt(){return gt!==null}function Nt(t){if(gt){let e=v();if(!e||e.id!==gt){E.warn("ai-handler","Session changed during generation \u2014 discarding AI output");return}}tt("assistant",t),ur(t,uo||void 0),D()}async function rn(t,e,n,s){let o=v();if(!o)throw new Error("No active session");gt=o.id;let a=s?.length?wr(s):void 0;try{let r=P(),l=r.aiEngine||po();switch(l){case"anthropic-api":case"api":{let c=ge("anthropic-api",r);if(!c)throw new Error("Anthropic API key not configured. Open Settings to add one.");await fr(t,c,o.themeName,r.anthropicApiModel||"claude-sonnet-4-6",e,n,Nt,a);break}case"openai-api":{let c=ge("openai-api",r);if(!c)throw new Error("OpenAI API key not configured. Open Settings to add one.");await gr(t,c,o.themeName,r.openaiApiModel||"gpt-4o",e,n,Nt,a);break}case"gemini-api":{let c=ge("gemini-api",r);if(!c)throw new Error("Gemini API key not configured. Open Settings to add one.");await hr(t,c,o.themeName,e,n,Nt,a);break}case"claude-code":await yr(t,o.themeName,e,n,Nt,a);break;case"gemini-cli":await eo("gemini",t,o.themeName,e,n,Nt,a);break;case"codex-cli":await eo("codex",t,o.themeName,e,n,Nt,a);break;default:throw new Error(`Unknown AI engine: ${l}. Open Settings to configure one.`)}}finally{gt=null,uo=null}}function po(){let t=P();if(t.anthropicApiKey||process.env.ANTHROPIC_API_KEY)return"anthropic-api";if(t.openaiApiKey||process.env.OPENAI_API_KEY)return"openai-api";if(t.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY)return"gemini-api";try{return co("claude --version",{stdio:"pipe"}),"claude-code"}catch{}try{return co("gemini --version",{stdio:"pipe"}),"gemini-cli"}catch{}try{return co("codex --version",{stdio:"pipe"}),"codex-cli"}catch{}throw new Error("No AI engine available. Open Settings to configure one.")}async function Md(t){let e="";return await rn(t,n=>{e+=n}),e}function _d(){let t=v(),e=Ce(),n=e?[...e.modules]:[...t.modules],s=e?[...e.moduleOrder]:[...t.moduleOrder];return{modules:n,moduleOrder:s,sharedCss:e?.sharedCss||t.sharedCss,sharedJs:e?.sharedJs||t.sharedJs,messages:[...t.messages],themeName:t.themeName,themePath:t.themePath,brandAssets:t.brandAssets?{...t.brandAssets}:void 0}}function ss(t){let e=t.aiEngine||po();if(!ns(e))throw new Error("Agentic pipeline is not available for this engine.");if(on(e)){let o="";return e==="claude-code"&&(o=t.claudeCodeModel||""),{engine:e,apiKey:"",model:o}}let n=ge(e,t);if(!n)throw new Error(`API key not configured for ${e}. Open Settings to add one.`);let s;switch(e){case"anthropic-api":s=t.anthropicApiModel||"claude-sonnet-4-6";break;case"openai-api":s=t.openaiApiModel||"gpt-4o";break;case"gemini-api":s="gemini-2.5-flash";break;default:s=""}return{engine:e,apiKey:n,model:s}}async function fo(t,e,n){let s=v();if(!s)throw new Error("No active session");let o=s.id;gt=o;try{let i=P(),{engine:a,apiKey:r,model:l}=ss(i),c=i.agenticConcurrency||20,d=_d(),u=nt(),p=new Set(d.modules.map(b=>b.moduleName)),f=u.filter(b=>!p.has(b.module.moduleName)).map(b=>({name:b.module.moduleName,usedIn:b.usedIn})),h=await Yr(t,d,a,r,l,c,e,f),y=v();if(!y||y.id!==o)throw E.warn("ai-handler","Session changed during agentic generation \u2014 discarding output"),new Error("Session changed during generation");return h}finally{gt=null}}function go(t,e){De({modules:t.modules,sharedCss:t.sharedCss,sharedJs:t.sharedJs}),At(t.moduleOrder),tt("assistant",t.assistantMessage,e),D()}function ho(){let t=P(),e=t.aiEngine||po();return ns(e)?t.agenticMode===void 0?{useAgentic:!1,needsPrompt:!0}:{useAgentic:t.agenticMode,needsPrompt:!1}:{useAgentic:!1,needsPrompt:!1,reason:"Agentic pipeline is not available for this engine."}}var uo,gt,os=J(()=>{"use strict";g();ee();Se();Zn();ve();to();io();zr();uo=null;gt=null});var ms={};lt(ms,{collectThemeFiles:()=>Na,extractDesignContext:()=>tu});import{existsSync as cs,readdirSync as ds,readFileSync as qd}from"fs";import{join as He}from"path";import{spawn as Xd}from"child_process";async function Qd(){return bo||(bo=(await import("@anthropic-ai/sdk")).default),bo}function cn(t){try{return qd(t,"utf-8")}catch{return""}}function Na(t){let e=[],n=0;function s(r,l){if(!l.trim())return!0;let c=`
|
|
1085
1085
|
### ${r}
|
|
1086
1086
|
\`\`\`
|
|
1087
1087
|
${l}
|
|
1088
1088
|
\`\`\`
|
|
1089
|
-
`;return n+c.length>
|
|
1090
|
-
${n}`;e?.({status:"Analyzing design patterns..."});let i=
|
|
1089
|
+
`;return n+c.length>Zd?!1:(e.push(c),n+=c.length,!0)}let o=cn(He(t,"theme.json"));o&&s("theme.json",o);let i=He(t,"css");if(cs(i)){for(let r of ds(i).filter(l=>l.endsWith(".css")))if(!s(`css/${r}`,cn(He(i,r))))break}let a=He(t,"modules");if(cs(a))for(let r of ds(a).filter(l=>l.endsWith(".module"))){let l=He(a,r),c=cn(He(l,"module.css"));if(c&&!s(`modules/${r}/module.css`,c))break}if(cs(a))for(let r of ds(a).filter(l=>l.endsWith(".module"))){let l=He(a,r),c=cn(He(l,"module.html"));if(c&&!s(`modules/${r}/module.html`,c))break}if(cs(a))for(let r of ds(a).filter(l=>l.endsWith(".module"))){let l=He(a,r),c=cn(He(l,"fields.json"));if(c&&!s(`modules/${r}/fields.json`,c))break}return e.join("")}function eu(){if(!us)try{us=I(pn("extraction-prompt.md"))}catch{us=""}return us}function So(t,e,n){return new Promise((s,o)=>{let i={...process.env};delete i.CLAUDECODE;let a=Xd(t,e,{stdio:["pipe","pipe","pipe"],env:i,shell:!0}),r="",l="";a.stdout.on("data",c=>{r+=c.toString()}),a.stderr.on("data",c=>{l+=c.toString()}),a.on("error",c=>o(new Error(`${t} failed to start: ${c.message}`))),a.on("close",c=>{c===0||r.trim()?s(r.trim()):o(new Error(`${t} exited with code ${c}: ${l.trim()}`))}),a.stdin.write(n),a.stdin.end()})}async function tu(t,e){e?.({status:"Collecting theme files..."});let n=Na(t);if(!n.trim())throw new Error("No CSS, HTML, or fields.json files found in theme.");let s=eu();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:
|
|
1090
|
+
${n}`;e?.({status:"Analyzing design patterns..."});let i=P(),a=i.aiEngine||"anthropic-api",r="";switch(a){case"anthropic-api":case"api":{let l=ge("anthropic-api");if(!l)throw new Error("Anthropic API key not configured. Open Settings to add one.");let c=await Qd();r=(await new c({apiKey:l}).messages.create({model:i.anthropicApiModel||"claude-sonnet-4-6",max_tokens:8e3,system:s,messages:[{role:"user",content:o}]})).content.filter(p=>p.type==="text").map(p=>p.text).join("");break}case"openai-api":{let l=ge("openai-api");if(!l)throw new Error("OpenAI API key not configured. Open Settings to add one.");let c=await fetch("https://api.openai.com/v1/chat/completions",{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${l}`},body:JSON.stringify({model:i.openaiApiModel||"gpt-4o",max_tokens:8e3,messages:[{role:"system",content:s},{role:"user",content:o}]})});if(!c.ok)throw new Error(`OpenAI API error: ${c.status} ${await c.text()}`);r=(await c.json()).choices?.[0]?.message?.content||"";break}case"gemini-api":{let l=ge("gemini-api");if(!l)throw new Error("Gemini API key not configured. Open Settings to add one.");let c=i.geminiApiModel||"gemini-2.5-flash",d=await fetch(`https://generativelanguage.googleapis.com/v1beta/models/${c}:generateContent?key=${l}`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({system_instruction:{parts:[{text:s}]},contents:[{role:"user",parts:[{text:o}]}],generationConfig:{maxOutputTokens:8e3}})});if(!d.ok)throw new Error(`Gemini API error: ${d.status} ${await d.text()}`);r=(await d.json()).candidates?.[0]?.content?.parts?.map(p=>p.text).join("")||"";break}case"claude-code":{let l=`${s}
|
|
1091
1091
|
|
|
1092
1092
|
## User Request
|
|
1093
|
-
${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await
|
|
1093
|
+
${o}`,c=["--print"];i.claudeCodeModel&&c.push("--model",i.claudeCodeModel),r=await So("claude",c,l);break}case"gemini-cli":{let l=`${s}
|
|
1094
1094
|
|
|
1095
1095
|
## User Request
|
|
1096
|
-
${o}`;r=await
|
|
1096
|
+
${o}`;r=await So("gemini",[],l);break}case"codex-cli":{let l=`${s}
|
|
1097
1097
|
|
|
1098
1098
|
## User Request
|
|
1099
|
-
${o}`;r=await
|
|
1099
|
+
${o}`;r=await So("codex",[],l);break}default:throw new Error(`Unknown AI engine: ${a}. Open Settings to configure one.`)}if(!r.trim())throw new Error("AI returned empty response.");return e?.({status:"Design extraction complete."}),r}var bo,Zd,us,ps=J(()=>{"use strict";g();Z();ee();bo=null;Zd=8e4;us=""});var Pa={};lt(Pa,{extractBrandvoice:()=>nu});async function nu(t,e,n,s){if(!t||t.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.
|
|
1100
1100
|
|
|
1101
1101
|
Return a markdown document with these sections (skip any section where the content provides no signal):
|
|
1102
1102
|
|
|
@@ -1116,7 +1116,7 @@ Typical sentence length, structure, use of questions, imperatives, etc.
|
|
|
1116
1116
|
## Dos and Don'ts
|
|
1117
1117
|
3-4 practical rules for writing in this voice (e.g., "Do: Lead with benefits, not features", "Don't: Use jargon without context").
|
|
1118
1118
|
|
|
1119
|
-
Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Ne(e,n,s,{systemPrompt:o,messages:[{role:"user",content:t}],maxTokens:1e3}),a=i.type==="text"?i.text:JSON.stringify(i.data);return!a||a.trim().length<20?null:(E.info("brandvoice-extractor",`Extracted brand voice (${a.length} chars)`),a.trim())}catch(i){let a=i instanceof Error?i.message:String(i);return E.warn("brandvoice-extractor",`Brand voice extraction failed: ${a}`),null}}var
|
|
1119
|
+
Keep it actionable \u2014 this guide will be fed to AI to maintain consistent copy across pages.`;try{let i=await Ne(e,n,s,{systemPrompt:o,messages:[{role:"user",content:t}],maxTokens:1e3}),a=i.type==="text"?i.text:JSON.stringify(i.data);return!a||a.trim().length<20?null:(E.info("brandvoice-extractor",`Extracted brand voice (${a.length} chars)`),a.trim())}catch(i){let a=i instanceof Error?i.message:String(i);return E.warn("brandvoice-extractor",`Brand voice extraction failed: ${a}`),null}}var Ma=J(()=>{"use strict";g();it();ve()});var vo={};lt(vo,{extractThemeContext:()=>su});async function su(t,e,n,s,o){if(!t||t.length<50)return null;let a=`You are a content analyst. Extract a concise product/company brief from the rendered landing page HTML below. The HTML contains the actual text content (headings, paragraphs, button labels, image alt text, etc.) with all template variables resolved to their default values.
|
|
1120
1120
|
|
|
1121
1121
|
Return a markdown document with these sections (skip any section where the content provides no information):
|
|
1122
1122
|
|
|
@@ -1138,11 +1138,11 @@ Specific terms, product names, or branded language used consistently.
|
|
|
1138
1138
|
Keep it concise \u2014 this brief is used as context for AI-generated content on other pages in the same theme.${e?`
|
|
1139
1139
|
|
|
1140
1140
|
Existing product context (update if the new content adds info, keep what's still accurate):
|
|
1141
|
-
${e}`:""}`;try{let r=await Ne(n,s,o,{systemPrompt:a,messages:[{role:"user",content:t}],maxTokens:1e3}),l=r.type==="text"?r.text:JSON.stringify(r.data);return!l||l.trim().length<20?null:(E.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(r){let l=r instanceof Error?r.message:String(r);return E.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var
|
|
1142
|
-
`);for(let a of i){let r=a.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(r&&!/Account ID/i.test(a)&&!/^-+$/.test(a.trim())&&!/^Name\s/i.test(a.trim())){let l=r[1].trim(),c=r[2].trim(),d=r[3]?.trim()||"unknown";e.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:e}:e.length>0?{authenticated:!0,portalName:e[0].name,portalId:e[0].portalId,accounts:e}:{authenticated:t.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Ht(){let t=T("gemini --version");if(!t.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=
|
|
1143
|
-
`)[0]?.replace("gh version ","").split(" ")[0]||"",path:T(`${dt} gh`).stdout}}function
|
|
1141
|
+
${e}`:""}`;try{let r=await Ne(n,s,o,{systemPrompt:a,messages:[{role:"user",content:t}],maxTokens:1e3}),l=r.type==="text"?r.text:JSON.stringify(r.data);return!l||l.trim().length<20?null:(E.info("context-extractor",`Extracted theme context (${l.length} chars)`),l.trim())}catch(r){let l=r instanceof Error?r.message:String(r);return E.warn("context-extractor",`Theme context extraction failed: ${l}`),null}}var wo=J(()=>{"use strict";g();it();ve()});g();g();import{Command as vu}from"commander";g();g();g();import yt from"chalk";var Me={accent:"#FF7A59",accentBright:"#FF9A7A",success:"#00BDA5",info:"#0066FF",warn:"#FFB020",error:"#E23D2D",muted:"#8B8D91",vibes:"#00BDD6"},ko=!!process.env.NO_COLOR;function Ue(t){return ko?yt:yt.hex(t)}var k={accent:Ue(Me.accent),accentBright:Ue(Me.accentBright),success:Ue(Me.success),info:Ue(Me.info),warn:Ue(Me.warn),error:Ue(Me.error),muted:Ue(Me.muted),vibes:Ue(Me.vibes),heading:ko?yt.bold:yt.bold.hex(Me.accent),command:Ue(Me.accentBright),dim:yt.dim,bold:yt.bold};Z();function _e(){let t=k.vibes,e=k.accent,n=k.muted,s=[`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584\u2584")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\u2584\u2584\u2584\u2584\u2584 \u2588\u2588\u2588\u2588\u2588 \u2584\u2584\u2584\u2584 \u2580\u2580\u2588\u2588\u2580\u2580")}`,`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t("\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B ")}${e("\u2580\u2580\u2580\u2584 \u2588\u2588\u2588\u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t(" \u2588\u2584\u2584\u2588\u2580 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B ")}${e(" \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 \u2588\u2588 ")}`,`${t(" \u2580\u2580\u2580 \u2588\u2588 \u2588\u2588\u2588\u2588\u2588 \u2580\u2580\u2580\u2580\u2580")}${t(" \u224B\u224B\u224B\u224B\u224B\u224B\u224B\u224B ")}${e("\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")} ${k.dim(`v${St()}`)}`),console.log()}g();g();ct();ee();import{join as hn}from"path";import{homedir as yn}from"os";import{readFileSync as Ro,existsSync as bn,readdirSync as pl}from"fs";var dt=process.platform==="win32"?"where":"which";function Ft(){let t=T("node --version");return{name:"Node.js",found:t.success,version:t.stdout.replace(/^v/,""),path:T(`${dt} node`).stdout}}function Jt(){let t=T("git --version");return{name:"Git",found:t.success,version:t.stdout.replace("git version ",""),path:T(`${dt} git`).stdout}}function Re(){let t=T("hs --version");return{name:"HubSpot CLI",found:t.success,version:t.stdout,path:T(`${dt} hs`).stdout}}function Dt(){let t=T("claude --version");if(!t.success)return{name:"Claude Code",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=hn(yn(),".claude"),n=!1,s="Not signed in \u2014 run `claude` to authenticate";try{if(bn(e)){let o=pl(e);(o.some(a=>a.includes("credentials")||a.includes("auth")||a.includes("token")||a===".credentials.json")||o.length>2)&&(n=!0,s="Authenticated")}}catch{}return{name:"Claude Code",found:!0,version:t.stdout,path:T(`${dt} claude`).stdout,authenticated:n,authDetail:s}}function Lt(t){try{let e=hn(yn(),".hscli","config.yml");if(!bn(e))return"na1";let n=Ro(e,"utf-8"),s=n.indexOf(`accountId: ${t}`);if(s===-1)return"na1";let o=n.indexOf("personalAccessKey:",s);if(o===-1)return"na1";let a=n.slice(o,o+300).match(/personalAccessKey:[\s>-]*\n\s+(\S+)/);if(!a)return"na1";if(a[1].startsWith("CiRldTE"))return"eu1"}catch{}return"na1"}function Oe(){let t=T("hs accounts list");if(!t.success||!t.stdout)return{authenticated:!1,portalName:"",portalId:"",accounts:[]};let e=[],n="",s="",o=t.stdout.match(/Account:\s*(.+?)\s*\((\d+)\)/);o&&(n=o[1].trim(),s=o[2].trim());let i=t.stdout.split(`
|
|
1142
|
+
`);for(let a of i){let r=a.match(/^\s*(.+?)\s+(\d{5,})\s+(.*)/);if(r&&!/Account ID/i.test(a)&&!/^-+$/.test(a.trim())&&!/^Name\s/i.test(a.trim())){let l=r[1].trim(),c=r[2].trim(),d=r[3]?.trim()||"unknown";e.push({name:l,portalId:c,authType:d,isDefault:c===s})}}return o?{authenticated:!0,portalName:n,portalId:s,accounts:e}:e.length>0?{authenticated:!0,portalName:e[0].name,portalId:e[0].portalId,accounts:e}:{authenticated:t.stdout.length>0,portalName:"",portalId:"",accounts:[]}}function Ht(){let t=T("gemini --version");if(!t.success)return{name:"Gemini CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=hn(yn(),".config","gcloud","application_default_credentials.json"),n=bn(e),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:t.stdout,path:T(`${dt} gemini`).stdout,authenticated:o,authDetail:o?"Authenticated":"Run `gemini` to sign in with Google"}}function Gt(){let t=T("codex --version");if(!t.success)return{name:"OpenAI Codex CLI",found:!1,version:"",path:"",authenticated:!1,authDetail:"Not installed"};let e=!!process.env.OPENAI_API_KEY,n=!1;try{let i=hn(yn(),".codex","auth.json");bn(i)&&(n=Ro(i,"utf-8").length>10)}catch{}let s=e||n,o=n?"Authenticated (OAuth)":e?"Authenticated (API key)":"Not authenticated";return{name:"OpenAI Codex CLI",found:!0,version:t.stdout,path:T(`${dt} codex`).stdout,authenticated:s,authDetail:o}}function xs(){let t=T("gh --version");return{name:"GitHub CLI",found:t.success,version:t.stdout.split(`
|
|
1143
|
+
`)[0]?.replace("gh version ","").split(" ")[0]||"",path:T(`${dt} gh`).stdout}}function Cs(){let t=T("gh auth status 2>&1");if(!t.success&&!t.stdout)return{authenticated:!1,username:""};let e=t.stdout||t.stderr||"",n=e.match(/Logged in to github\.com.*account\s+(\S+)/);if(n)return{authenticated:!0,username:n[1]};let s=e.match(/account\s+(\S+)/);return s&&e.includes("Logged in")?{authenticated:!0,username:s[1]}:{authenticated:e.includes("Logged in"),username:""}}function Oo(){return!!process.env.ANTHROPIC_API_KEY}function Sn(t){return parseInt(t.split(".")[0],10)>=18}function jo(t){let e=parseInt(t.split(".")[0],10);return!isNaN(e)&&e>=8}function fl(){let t=P(),e=t.hubspotUploadMode||"api",n=t.hubspotAccounts||[],s=n.map(i=>({name:i.portalName,portalId:i.portalId,authType:"personalaccesskey",isDefault:i.portalId===(t.activeHubSpotAccount||n[0]?.portalId)})),o=Xe();return{authenticated:!!o,portalName:o?.portalName||"",portalId:o?.portalId||"",dataCenter:o?o.dataCenter:"na1",accounts:s,uploadMode:e}}var ws={name:"",found:!1,version:"",path:"",authenticated:!1,authDetail:"Disabled"};function vn(){let t=P(),e=Ft(),n=Jt(),s=t.hubspotUploadMode||"api",o;if(s==="cli"){let b=Re(),A=b.found?Oe():{authenticated:!1,portalName:"",portalId:"",accounts:[]},w=A.portalId?Lt(A.portalId):"na1";o={...b,...A,dataCenter:w,uploadMode:"cli"}}else o={name:"HubSpot API",found:!0,version:"v3",path:"",...fl()};let i=xs(),a=i.found?Cs():{authenticated:!1,username:""},r=t.enabledCLITools||[],l=jt("claude-code")?Dt():{...ws,name:"Claude Code"},c=jt("gemini-cli")?Ht():{...ws,name:"Gemini CLI"},d=jt("codex-cli")?Gt():{...ws,name:"OpenAI Codex CLI"};function u(b,...A){if(b)return{configured:!0,masked:gn(b),source:"config"};for(let w of A)if(process.env[w])return{configured:!0,masked:gn(process.env[w]),source:"env"};return{configured:!1,masked:"",source:null}}let p=u(t.anthropicApiKey,"ANTHROPIC_API_KEY"),f=u(t.openaiApiKey,"OPENAI_API_KEY"),h=u(t.geminiApiKey,"GEMINI_API_KEY","GOOGLE_AI_API_KEY"),y=[];return l.found&&l.authenticated&&y.push("claude-code"),p.configured&&y.push("anthropic-api"),f.configured&&y.push("openai-api"),c.found&&c.authenticated&&y.push("gemini-cli"),h.configured&&y.push("gemini-api"),d.found&&d.authenticated&&y.push("codex-cli"),{tools:{node:e,git:n,hubspot:o,github:{...i,...a},claudeCode:l,geminiCli:c,codexCli:d},apiKeys:{anthropic:p,openai:f,gemini:h},activeEngine:t.aiEngine||null,availableEngines:y,enabledCLITools:r}}ct();ee();ut();g();import*as K from"@clack/prompts";function Is(t){K.isCancel(t)&&(K.cancel(k.muted("Operation cancelled.")),process.exit(0))}async function ce(t){K.intro(k.heading(t))}async function de(t){K.outro(k.success(t))}async function je(t,e){K.note(t,e?k.heading(e):void 0)}async function $e(t){let e=await K.text({message:k.accent(t.message),placeholder:t.placeholder,defaultValue:t.defaultValue,validate:t.validate});return Is(e),e}async function se(t){let e=await K.confirm({message:k.accent(t.message),initialValue:t.initialValue??!0});return Is(e),e}async function wt(t){let e=await K.select({message:k.accent(t.message),options:t.options});return Is(e),e}async function ue(){let t=K.spinner();return{start:e=>t.start(k.muted(e)),stop:e=>t.stop(k.success(e)),message:e=>t.message(k.muted(e))}}function X(t){K.log.info(t)}function F(t){K.log.success(k.success(t))}function V(t){K.log.warn(k.warn(t))}function W(t){K.log.error(k.error(t))}async function An(){await ce("Checking your environment");let t=Ft();t.found||(W("Node.js not found. Install it from https://nodejs.org"),process.exit(1)),Sn(t.version)||(W(`Node.js ${t.version} is too old. Version 18+ required. Update at https://nodejs.org`),process.exit(1)),F(`Node.js v${t.version}`);let e=Jt();e.found||(W("Git not found. Install it from https://git-scm.com"),process.exit(1)),F(`Git ${e.version}`);let n=P(),s=n.hubspotUploadMode!=="cli",o="",i="";if(s){let y=he(),b=Xe();if(y)o=b?.portalId||"",i=b?.portalName||"",F(`HubSpot${i?`: ${i}`:""}${o?` (${o})`:""} \u2014 API mode`);else{V("No HubSpot account connected"),await je(`You need a Personal Access Key to deploy themes.
|
|
1144
1144
|
Create one at: https://app.hubspot.com/l/personal-access-key
|
|
1145
|
-
Make sure the Content scope is enabled.`,"HubSpot connection required");let A=await $e({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:$=>$.trim()?void 0:"Key is required"}),w=await ue();w.start("Validating key...");try{let $=await
|
|
1145
|
+
Make sure the Content scope is enabled.`,"HubSpot connection required");let A=await $e({message:"Paste your Personal Access Key:",placeholder:"pat-na1-...",validate:$=>$.trim()?void 0:"Key is required"}),w=await ue();w.start("Validating key...");try{let $=await xn(A);Ot(A,$.portalId,$.portalName,$.dataCenter),y=A,o=$.portalId,i=$.portalName,w.stop(`Connected to ${$.portalName} (${$.portalId})`)}catch($){w.stop("Validation failed"),W(`Invalid key: ${$ instanceof Error?$.message:String($)}`),process.exit(1)}}}else{let y=Re();if(y.found)F(`HubSpot CLI v${y.version}`);else{V("HubSpot CLI not found"),await se({message:"Install HubSpot CLI globally?"})||(W("HubSpot CLI is required in CLI mode. Install: npm install -g @hubspot/cli"),process.exit(1));let w=await ue();w.start("Installing HubSpot CLI..."),T("npm install -g @hubspot/cli").success||(w.stop("Failed"),W("Try: npm install -g @hubspot/cli"),process.exit(1)),y=Re(),w.stop(`HubSpot CLI v${y.version} installed`)}let b=Oe();if(b.authenticated)F(`HubSpot portal${b.portalName?`: ${b.portalName}`:""} (ID: ${b.portalId})`);else{V("HubSpot not authenticated"),await se({message:"Run `hs init` now?"})||(W("Run `hs init` manually."),process.exit(1));let w=await ue();w.start("Waiting for HubSpot authentication..."),No("hs init")||(w.stop("Authentication failed"),process.exit(1)),b=Oe(),w.stop(`Connected to portal${b.portalName?`: ${b.portalName}`:""} (ID: ${b.portalId})`)}o=b.portalId,i=b.portalName}let a=Dt(),r=Ht(),l=Gt(),c=Oo(),d={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"},u,p=n.aiEngine,f=[];if(a.found&&f.push({value:"claude-code",label:"Claude Code",hint:p==="claude-code"?"last used \u2014 recommended":"uses your existing Claude subscription \u2014 recommended"}),r.found&&f.push({value:"gemini-cli",label:"Gemini CLI",hint:p==="gemini-cli"?"last used":"uses your existing Gemini setup"}),l.found&&f.push({value:"codex-cli",label:"OpenAI Codex",hint:p==="codex-cli"?"last used":"uses your existing OpenAI setup"}),c&&f.push({value:"api",label:"Anthropic API",hint:p==="api"?"last used":"uses your API key"}),p&&f.sort((y,b)=>y.value===p?-1:b.value===p?1:0),f.length===1)u=f[0].value,F(`AI engine: ${d[u]} (auto-detected)`);else if(f.length>1)u=await wt({message:"Choose your AI engine:",options:f});else if(await je(`You need an AI coding assistant to power the conversion.
|
|
1146
1146
|
|
|
1147
1147
|
${k.bold("Option 1:")} Install Claude Code ${k.muted("(recommended)")}
|
|
1148
1148
|
https://claude.ai/code
|
|
@@ -1155,13 +1155,13 @@ ${k.bold("Option 3:")} Install OpenAI Codex
|
|
|
1155
1155
|
|
|
1156
1156
|
${k.bold("Option 4:")} Set an Anthropic API key
|
|
1157
1157
|
export ANTHROPIC_API_KEY=sk-ant-...
|
|
1158
|
-
(get one at https://console.anthropic.com)`,"AI engine required"),u=await wt({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"}]}),u==="api"){let y=await $e({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:b=>b.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=y,q({anthropicApiKey:y})}let h;return u==="claude-code"&&(h=await wt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),q({aiEngine:u}),await de("Environment ready!"),{aiEngine:u,model:h,portalId:o,portalName:i}}g();ct();Z();import{readdirSync as
|
|
1158
|
+
(get one at https://console.anthropic.com)`,"AI engine required"),u=await wt({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"}]}),u==="api"){let y=await $e({message:"Enter your Anthropic API key:",placeholder:"sk-ant-api03-...",validate:b=>b.startsWith("sk-ant-")?void 0:"Key should start with sk-ant-"});process.env.ANTHROPIC_API_KEY=y,q({anthropicApiKey:y})}let h;return u==="claude-code"&&(h=await wt({message:"Which model?",options:[{value:"sonnet",label:"Sonnet",hint:"fast, recommended"},{value:"opus",label:"Opus",hint:"most capable"},{value:"haiku",label:"Haiku",hint:"fastest, cheapest"}]})),q({aiEngine:u}),await de("Environment ready!"),{aiEngine:u,model:h,portalId:o,portalName:i}}g();ct();Z();import{readdirSync as ks,statSync as xl}from"fs";import{join as Q,basename as $s,extname as Cl}from"path";function Go(t){let e=[],n=[Q(t,"src/components/landing"),Q(t,"src/components/sections"),Q(t,"src/components"),Q(t,"src/pages"),Q(t,"app/components"),Q(t,"components")];for(let s of n)if(S(s))try{let o=ks(s);for(let i of o){let a=Q(s,i);if(!xl(a).isFile())continue;let l=Cl(i);if(![".tsx",".jsx"].includes(l))continue;let c=$s(i,l);if(c.startsWith("ui")||c==="index")continue;let d=I(a),u=Al(c,d);e.push({name:c,path:a,description:u})}}catch{}return e}function Al(t,e){let n=[];return/carousel|slider|swiper|embla/i.test(e)&&n.push("carousel"),/accordion|collapsible|expand/i.test(e)&&n.push("accordion"),/form|submit|input.*email/i.test(e)&&n.push("form"),/nav|navigation|menu/i.test(e)&&n.push("navigation"),/hero|headline|tagline/i.test(e)&&n.push("hero"),/footer|copyright/i.test(e)&&n.push("footer"),/testimonial|quote|review/i.test(e)&&n.push("testimonials"),/pricing|plan|tier/i.test(e)&&n.push("pricing"),/faq|question.*answer/i.test(e)&&n.push("FAQ"),/feature|benefit|advantage/i.test(e)&&n.push("features"),/contact|get.in.touch/i.test(e)&&n.push("contact"),/cta|call.to.action/i.test(e)&&n.push("CTA"),/team|member|bio/i.test(e)&&n.push("team"),n.length===0?t.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim():n.join(", ")}function Uo(t){let e=[Q(t,"src/index.css"),Q(t,"src/globals.css"),Q(t,"src/app/globals.css"),Q(t,"app/globals.css")],n=0,s=[];for(let o of e){if(!S(o))continue;let i=I(o),a=i.match(/--[\w-]+:/g);a&&(n+=a.length);let r=i.match(/font-family:\s*['"]([^'"]+)['"]/g);if(r)for(let c of r){let d=c.match(/['"]([^'"]+)['"]/)?.[1];d&&!s.includes(d)&&s.push(d)}let l=i.match(/@import\s+url\([^)]*fonts\.googleapis\.com[^)]*family=([^&)]+)/g);if(l)for(let c of l){let d=c.match(/family=([^&)]+)/)?.[1]?.replace(/\+/g," ");d&&!s.includes(d)&&s.push(d)}}return{varCount:n,fonts:s}}function Wo(t){let e=[],n=Q(t,"src/hooks");if(S(n))try{let o=ks(n);for(let i of o)/scroll/i.test(i)&&e.push("Scroll animations"),/intersection/i.test(i)&&e.push("Scroll animations")}catch{}let s=Q(t,"src/components/landing");if(S(s))try{let o=ks(s);for(let i of o){if(!i.endsWith(".tsx")&&!i.endsWith(".jsx"))continue;let a=I(Q(s,i));/carousel|embla|swiper/i.test(a)&&!e.includes("Carousel")&&e.push("Carousel"),/accordion|collapsible/i.test(a)&&!e.includes("Accordion")&&e.push("Accordion"),/typing|typewriter/i.test(a)&&!e.includes("Typing animation")&&e.push("Typing animation"),/parallax|requestAnimationFrame/i.test(a)&&!e.includes("Parallax")&&e.push("Parallax")}}catch{}return e.length===0&&e.push("Scroll animations"),e}function Bo(t){let e,n=!1;if(t.startsWith("http")||t.startsWith("git@")){n=!0;let l=$s(t.replace(/\.git$/,""))||"react-source";if(e=Q(process.cwd(),"workspace",l),!S(e)){let c=T(`git clone --depth 1 "${t}" "${e}"`);if(!c.success)throw new Error(`Failed to clone ${t}: ${c.stderr}`)}}else if(e=t,!S(e))throw new Error(`Directory not found: ${e}`);let s=Go(e),o=S(Q(e,"tailwind.config.ts"))||S(Q(e,"tailwind.config.js")),{varCount:i,fonts:a}=Uo(e),r=Wo(e);return{sourceDir:e,wasCloned:n,components:s,hasTailwind:o,cssVarCount:i,fonts:a,interactions:r}}async function In(){await ce("Source Project");let t=await $e({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"}}),e,n=!1;if(t.startsWith("http")||t.startsWith("git@")){n=!0;let h=$s(t.replace(/\.git$/,""))||"react-source";if(e=Q(process.cwd(),"workspace",h),S(e))F(`Using existing clone: ${k.dim(e)}`);else{let y=await ue();y.start("Cloning repository..."),T(`git clone --depth 1 "${t}" "${e}"`).success||(y.stop("Clone failed"),W(`Failed to clone ${t}. Check the URL and your access permissions.`),process.exit(1)),y.stop(`Cloned to ${k.dim(e)}`)}}else e=t,S(e)||(W(`Directory not found: ${e}`),process.exit(1)),F(`Using local source: ${k.dim(e)}`);let s=await ue();s.start("Analyzing project structure...");let o=Go(e),i=S(Q(e,"tailwind.config.ts"))||S(Q(e,"tailwind.config.js")),{varCount:a,fonts:r}=Uo(e),l=Wo(e);s.stop(`Found ${o.length} landing page components`),o.length===0&&(V("No components found. Make sure the React source has .tsx/.jsx files in src/components/"),process.exit(1));let c=o.map((h,y)=>` ${k.dim(`${y+1}.`)} ${k.bold(h.name)} ${k.muted(`\u2014 ${h.description}`)}`).join(`
|
|
1159
1159
|
`),d=i?`Tailwind + custom CSS (${a} variables)`:`Custom CSS (${a} variables)`,u=r.length>0?r.join(", "):"System fonts",p=l.join(", ");return await je(`${c}
|
|
1160
1160
|
|
|
1161
1161
|
CSS: ${d}
|
|
1162
1162
|
JS: ${p}
|
|
1163
|
-
Font: ${u}`,`${o.length} components detected`),await se({message:"Does this look right?"})||(W("Please adjust your source directory and try again."),process.exit(0)),await de("Source analyzed!"),{sourceDir:e,wasCloned:n,components:o,hasTailwind:i,cssVarCount:a,fonts:r,interactions:l}}g();ct();Z();import{join as Kt}from"path";ee();g();import{mkdirSync as Qe,writeFileSync as
|
|
1164
|
-
`),
|
|
1163
|
+
Font: ${u}`,`${o.length} components detected`),await se({message:"Does this look right?"})||(W("Please adjust your source directory and try again."),process.exit(0)),await de("Source analyzed!"),{sourceDir:e,wasCloned:n,components:o,hasTailwind:i,cssVarCount:a,fonts:r,interactions:l}}g();ct();Z();import{join as Kt}from"path";ee();g();import{mkdirSync as Qe,writeFileSync as kn}from"fs";import{join as Te}from"path";function $n(t,e){Qe(t,{recursive:!0}),Qe(Te(t,"templates"),{recursive:!0}),Qe(Te(t,"modules"),{recursive:!0}),Qe(Te(t,"css"),{recursive:!0}),Qe(Te(t,"js"),{recursive:!0}),Qe(Te(t,"images"),{recursive:!0}),Qe(Te(t,"assets"),{recursive:!0});let n={label:e,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"}};kn(Te(t,"theme.json"),JSON.stringify(n,null,2)+`
|
|
1164
|
+
`),kn(Te(t,"fields.json"),`[]
|
|
1165
1165
|
`);let s=`<!--
|
|
1166
1166
|
templateType: page
|
|
1167
1167
|
isAvailableForNewContent: false
|
|
@@ -1177,7 +1177,7 @@ ${k.bold("Option 4:")} Set an Anthropic API key
|
|
|
1177
1177
|
%}
|
|
1178
1178
|
{% end_dnd_area %}
|
|
1179
1179
|
{% endblock body %}
|
|
1180
|
-
`;
|
|
1180
|
+
`;kn(Te(t,"templates","home.html"),s);let o=`<!--
|
|
1181
1181
|
templateType: none
|
|
1182
1182
|
isAvailableForNewContent: false
|
|
1183
1183
|
label: Base Layout
|
|
@@ -1200,7 +1200,7 @@ ${k.bold("Option 4:")} Set an Anthropic API key
|
|
|
1200
1200
|
{{ standard_footer_includes }}
|
|
1201
1201
|
</body>
|
|
1202
1202
|
</html>
|
|
1203
|
-
`;Qe(Te(t,"templates","layouts"),{recursive:!0}),
|
|
1203
|
+
`;Qe(Te(t,"templates","layouts"),{recursive:!0}),kn(Te(t,"templates","layouts","base.html"),o)}Tn();async function En(){await ce("HubSpot Theme Setup");let t=await wt({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"}]}),e,n,s=Kt(process.cwd(),"workspace");if(Ae(s),t==="fetch"){e=await $e({message:"What's your theme name in HubSpot?",placeholder:"My-Company-Theme",validate:u=>u.trim()?void 0:"Theme name is required"}),n=Kt(s,e);let l=await ue();l.start("Fetching theme from HubSpot...");let c=P(),d=he();if(c.hubspotUploadMode==="cli"||!d)T(`hs cms fetch "${e}" "${n}"`).success||(l.stop("Fetch failed"),W(`Could not fetch theme "${e}". Check the name in HubSpot Design Manager.`),process.exit(1));else try{await Bt(d,e,n)}catch(u){l.stop("Fetch failed"),W(`Could not fetch theme "${e}": ${u instanceof Error?u.message:String(u)}`),process.exit(1)}l.stop(`Theme fetched: ${k.dim(n)}`)}else{e=await $e({message:"Name for your new theme:",placeholder:"my-theme",defaultValue:"my-theme"}),n=Kt(s,e);let l=await ue();l.start("Creating theme...");try{$n(n,e)}catch(c){l.stop("Creation failed"),W(`Could not create theme "${e}": ${c instanceof Error?c.message:String(c)}`),process.exit(1)}l.stop(`Theme created: ${k.dim(n)}`)}await ce("Checking theme compatibility");let o=Kt(n,"templates/layouts/base.html");S(o)||(W(`base.html not found at ${o}. Your theme may have a different structure.`),process.exit(1)),F("base.html found");let i=I(o),a=!1;if(i.includes("template_css"))F("template_css support");else{V("Missing template_css support in base.html");let l=i.indexOf("theme-overrides.css")!==-1?i.indexOf("{{",i.lastIndexOf(`
|
|
1204
1204
|
`,i.indexOf("theme-overrides.css"))):i.lastIndexOf("require_css");if(l>0){let c=i.lastIndexOf(`
|
|
1205
1205
|
`,l);i=i.slice(0,c)+`
|
|
1206
1206
|
{% if template_css %}
|
|
@@ -1219,11 +1219,11 @@ docs/
|
|
|
1219
1219
|
*.md
|
|
1220
1220
|
node_modules/
|
|
1221
1221
|
.git
|
|
1222
|
-
`),F("Created .hsignore");return await de("Theme ready!"),{themePath:n,themeName:e}}g();import{join as Ie}from"path";import{readdirSync as Vt,rmSync as
|
|
1222
|
+
`),F("Created .hsignore");return await de("Theme ready!"),{themePath:n,themeName:e}}g();import{join as Ie}from"path";import{readdirSync as Vt,rmSync as ri}from"fs";g();Ve();Z();import{spawn as El}from"child_process";import{join as B,basename as Nl}from"path";import{readdirSync as Fe,statSync as oi,writeFileSync as Pl}from"fs";var Ml=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"]),Nn=class{model;reported=new Set;moduleCount=0;expectedModules=0;constructor(e){this.model=e}async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||le();this.reported.clear(),this.moduleCount=0,this.expectedModules=0;let a=this.countSourceComponents(n),r=this.listModules(s),l=this.listDir(B(s,"css")),c=this.listDir(B(s,"js")),d=this.listDir(B(s,"templates")),u=this.buildFullPrompt(n,s,i);o("convert",`Starting Claude Code (${a} source components found)...`);let p="",f="",h=setInterval(()=>{this.reportProgress(s,r,l,c,d,o)},3e3);try{await new Promise((w,$)=>{let R={...process.env};delete R.CLAUDECODE;let M=["--print","--max-turns","50","--allowedTools","Read,Glob,Grep,Write,Edit,Bash"];this.model&&M.push("--model",this.model);let N=El("claude",M,{cwd:s,stdio:["pipe","pipe","pipe"],env:R,shell:!0});N.stdout.on("data",L=>{p+=L.toString()}),N.stderr.on("data",L=>{f+=L.toString()}),N.on("error",L=>$(new Error(`Claude Code failed to start: ${L.message}`))),N.on("close",L=>{L!==0?$(new Error(`Claude Code exited with code ${L}.
|
|
1223
1223
|
`+(f?`Stderr: ${f.slice(0,500)}
|
|
1224
1224
|
`:"")+(p?`Output: ${p.slice(0,500)}`:"No output"))):w()}),N.stdin.on("error",()=>{}),N.stdin.write(u),N.stdin.end(),setTimeout(()=>{N.kill(),$(new Error("Claude Code timed out after 30 minutes"))},18e5)})}finally{clearInterval(h)}let y=B(s,"..","vibespot-conversion.log");try{let $=["=== vibeSpot Conversion Log ===",`Timestamp: ${new Date().toISOString()}`,`Source: ${n}`,`Theme: ${s}`,`Model: ${this.model||"default"}`,"","=== PROMPT SENT ===",u.slice(0,500)+`
|
|
1225
1225
|
... (truncated, full guide follows)`,"","=== CLAUDE CODE STDOUT ===",p||"(empty)","","=== CLAUDE CODE STDERR ===",f||"(empty)",""].join(`
|
|
1226
|
-
`)
|
|
1226
|
+
`);Pl(y,$,"utf-8"),o("status",`Log written to ${Nl(y)}`)}catch{}o("scan","Scanning generated files...");let b=this.scanGeneratedFiles(s);if(b.modules.filter(w=>!r.has(w.moduleName+".module")).length===0){let w=p.slice(0,1500)||"(no output)",$=f.slice(0,500);throw new Error(`Claude Code did not create any new module files.
|
|
1227
1227
|
|
|
1228
1228
|
This usually means the model described the conversion instead of using Write tool to create files.
|
|
1229
1229
|
|
|
@@ -1285,13 +1285,13 @@ HUBSPOT CMS RULES:
|
|
|
1285
1285
|
${Ze()}
|
|
1286
1286
|
|
|
1287
1287
|
CONVERSION GUIDE:
|
|
1288
|
-
${s}`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=B(e,"css");if(S(s)){for(let r of Fe(s))if(r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(B(s,r));break}}let o=B(e,"js");if(S(o)){for(let r of Fe(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(B(o,r));break}}let i=B(e,"templates");if(S(i)){for(let r of Fe(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=I(B(i,r));break}if(!n.template){for(let r of Fe(i))if(r.endsWith(".html")&&!
|
|
1288
|
+
${s}`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=B(e,"css");if(S(s)){for(let r of Fe(s))if(r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(B(s,r));break}}let o=B(e,"js");if(S(o)){for(let r of Fe(o))if(r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(B(o,r));break}}let i=B(e,"templates");if(S(i)){for(let r of Fe(i))if(r.startsWith("lp-")&&r.endsWith(".html")){n.template=I(B(i,r));break}if(!n.template){for(let r of Fe(i))if(r.endsWith(".html")&&!Ml.has(r)&&!r.startsWith("system")){let l=I(B(i,r));if(l.includes("dnd_area")){n.template=l;break}}}if(!n.template){for(let r of Fe(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(B(i,r));if(l.includes("dnd_area")){n.template=l;break}}}}let a=B(e,"modules");if(S(a))for(let r of Fe(a)){if(!r.endsWith(".module"))continue;let l=B(a,r);if(!oi(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=B(l,"fields.json");S(d)&&(c.fieldsJson=I(d));let u=B(l,"meta.json");S(u)&&(c.metaJson=I(u));let p=B(l,"module.html");S(p)&&(c.moduleHtml=I(p));let f=B(l,"module.css");S(f)&&(c.moduleCss=I(f));let h=B(l,"module.js");S(h)&&(c.moduleJs=I(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}listModules(e){let n=B(e,"modules");return S(n)?new Set(Fe(n).filter(s=>s.endsWith(".module"))):new Set}listDir(e){return S(e)?new Set(Fe(e)):new Set}detectExpectedModules(e,n){let s=B(e,"templates");if(!S(s))return 0;for(let o of Fe(s))if(!n.has(o)&&!(!o.endsWith(".html")||o==="base.html"||o.startsWith("system")))try{let i=I(B(s,o));if(i.includes("dnd_area")){let a=i.match(/dnd_module/g);return a?a.length:0}}catch{}return 0}countSourceComponents(e){let n=B(e,"src");return S(n)?this.countComponentsRecursive(n):0}countComponentsRecursive(e){let n=0;for(let s of Fe(e)){let o=B(e,s);try{oi(o).isDirectory()&&s!=="node_modules"&&s!==".git"?n+=this.countComponentsRecursive(o):/\.(tsx|jsx)$/.test(s)&&!s.includes(".test.")&&!s.includes(".spec.")&&n++}catch{}}return n}};g();Ve();Z();import _l from"@anthropic-ai/sdk";import{join as Y,basename as Rl}from"path";import{readdirSync as ii}from"fs";var Pn=class{client;model="claude-sonnet-4-6";constructor(e){this.client=new _l({apiKey:e||process.env.ANTHROPIC_API_KEY})}async convert(e){let{sourceDir:n,themePath:s,conversionGuide:o,onProgress:i}=e,a=Zo(o),r=Rl(n)||"page",l=r.toLowerCase().replace(/[^a-z0-9]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,"").slice(0,15);i("css","Analyzing design system...");let c=this.findAndReadCSS(n),d=this.findAndReadTailwind(n),u=await this.complete(a,ti(c,d,l)),p=Y(s,"css",`${l}-theme.css`);H(p,u),i("css-done",`Created css/${l}-theme.css`),i("js","Creating shared JavaScript...");let f=this.findAndReadHooks(n),h=this.findInteractiveComponents(n),y=await this.complete(a,ni(f,h,l)),b=Y(s,"js",`${l}-animations.js`);H(b,y),i("js-done",`Created js/${l}-animations.js`),i("modules","Building modules...");let A=this.findComponents(n),w=[];for(let N=0;N<A.length;N++){let L=A[N],ne=L.name.replace(/Section$/,"").replace(/([A-Z])/g," $1").trim();i("module",`Building ${ne}.module (${N+1}/${A.length})...`);let U=I(L.path),G=await this.complete(a,ei(U,ne,`See css/${l}-theme.css`));try{let O=JSON.parse(G),z={moduleName:ne,fieldsJson:typeof O.fieldsJson=="string"?O.fieldsJson:JSON.stringify(O.fieldsJson,null,2),metaJson:typeof O.metaJson=="string"?O.metaJson:JSON.stringify(O.metaJson,null,2),moduleHtml:O.moduleHtml||"",moduleCss:O.moduleCss||"",moduleJs:O.moduleJs||void 0},ae=Y(s,"modules",`${ne}.module`);Ae(ae),H(Y(ae,"fields.json"),z.fieldsJson),H(Y(ae,"meta.json"),z.metaJson),H(Y(ae,"module.html"),z.moduleHtml),H(Y(ae,"module.css"),z.moduleCss),z.moduleJs&&H(Y(ae,"module.js"),z.moduleJs),w.push(z),i("module-done",`${ne}.module (${this.countFiles(z)} files)`)}catch{i("module-error",`Failed to parse ${ne} \u2014 skipping`)}}i("template","Creating page template...");let $=w.map(N=>N.moduleName),R=await this.complete(a,si($,r,l)),M=Y(s,"templates",`lp-${l}.html`);return H(M,R),i("template-done",`Created templates/lp-${l}.html`),{sharedCss:u,sharedJs:y,template:R,modules:w}}async complete(e,n){return(await this.client.messages.create({model:this.model,max_tokens:8192,system:e,messages:[{role:"user",content:n}]})).content.find(i=>i.type==="text")?.text||""}findAndReadCSS(e){let n=[Y(e,"src/index.css"),Y(e,"src/globals.css"),Y(e,"src/app/globals.css"),Y(e,"app/globals.css")];for(let s of n)if(S(s))return I(s);return""}findAndReadTailwind(e){let n=[Y(e,"tailwind.config.ts"),Y(e,"tailwind.config.js"),Y(e,"tailwind.config.mjs")];for(let s of n)if(S(s))return I(s);return""}findAndReadHooks(e){let n=Y(e,"src/hooks");if(!S(n))return"";try{return ii(n).filter(s=>s.endsWith(".ts")||s.endsWith(".tsx")).map(s=>`// ${s}
|
|
1289
1289
|
${I(Y(n,s))}`).join(`
|
|
1290
1290
|
|
|
1291
1291
|
`)}catch{return""}}findInteractiveComponents(e){let n=this.findComponents(e),s=[];for(let o of n){let i=I(o.path);/carousel|accordion|typing|parallax|embla|swiper|collapsible/i.test(i)&&s.push(`// ${o.name}
|
|
1292
1292
|
${i}`)}return s.join(`
|
|
1293
1293
|
|
|
1294
|
-
`)}findComponents(e){let n=[Y(e,"src/components/landing"),Y(e,"src/components/sections"),Y(e,"src/components")];for(let s of n)if(S(s))try{return
|
|
1294
|
+
`)}findComponents(e){let n=[Y(e,"src/components/landing"),Y(e,"src/components/sections"),Y(e,"src/components")];for(let s of n)if(S(s))try{return ii(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:Y(s,o)}))}catch{continue}return[]}countFiles(e){let n=3;return e.moduleCss&&n++,e.moduleJs&&n++,n}};g();Ve();Z();import{spawn as Ol}from"child_process";import{join as we}from"path";import{readdirSync as Mn,statSync as jl}from"fs";var _n=class{async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||le(),a=this.buildFullPrompt(n,s,i);return o("convert","Running Gemini CLI (this may take a few minutes)..."),await new Promise((r,l)=>{let c=Ol("gemini",["-p",a],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",p=>{d+=p.toString()}),c.stderr.on("data",p=>{u+=p.toString()}),c.on("error",p=>l(new Error(`Gemini CLI failed: ${p.message}`))),c.on("close",p=>{p!==0&&u&&!d?l(new Error(`Gemini CLI failed: ${u}`)):r()}),setTimeout(()=>{c.kill(),l(new Error("Gemini CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(e,n,s){return`Read the conversion guide below, then convert the React landing page at ${e} into native HubSpot CMS modules for the theme at ${n}.
|
|
1295
1295
|
|
|
1296
1296
|
INSTRUCTIONS:
|
|
1297
1297
|
1. Analyze all .tsx/.jsx components in the React source
|
|
@@ -1306,7 +1306,7 @@ CONVERSION GUIDE:
|
|
|
1306
1306
|
${s}
|
|
1307
1307
|
|
|
1308
1308
|
Do NOT run hs upload \u2014 I will handle that separately.
|
|
1309
|
-
Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=we(e,"css");if(S(s)){for(let r of Mn(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(we(s,r));break}}let o=we(e,"js");if(S(o)){for(let r of Mn(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(we(o,r));break}}let i=we(e,"templates");if(S(i)){for(let r of Mn(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(we(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=we(e,"modules");if(S(a))for(let r of Mn(a)){if(!r.endsWith(".module"))continue;let l=we(a,r);if(!
|
|
1309
|
+
Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=we(e,"css");if(S(s)){for(let r of Mn(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(we(s,r));break}}let o=we(e,"js");if(S(o)){for(let r of Mn(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(we(o,r));break}}let i=we(e,"templates");if(S(i)){for(let r of Mn(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(we(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=we(e,"modules");if(S(a))for(let r of Mn(a)){if(!r.endsWith(".module"))continue;let l=we(a,r);if(!jl(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=we(l,"fields.json");S(d)&&(c.fieldsJson=I(d));let u=we(l,"meta.json");S(u)&&(c.metaJson=I(u));let p=we(l,"module.html");S(p)&&(c.moduleHtml=I(p));let f=we(l,"module.css");S(f)&&(c.moduleCss=I(f));let h=we(l,"module.js");S(h)&&(c.moduleJs=I(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};g();Ve();Z();import{spawn as Fl}from"child_process";import{join as xe}from"path";import{readdirSync as Rn,statSync as Jl}from"fs";var On=class{async convert(e){let{sourceDir:n,themePath:s,onProgress:o}=e,i=e.conversionGuide||le(),a=this.buildFullPrompt(n,s,i);return o("convert","Running OpenAI Codex (this may take a few minutes)..."),await new Promise((r,l)=>{let c=Fl("codex",["exec","--full-auto",a],{cwd:s,stdio:["pipe","pipe","pipe"],env:{...process.env},shell:!0}),d="",u="";c.stdout.on("data",p=>{d+=p.toString()}),c.stderr.on("data",p=>{u+=p.toString()}),c.on("error",p=>l(new Error(`Codex CLI failed: ${p.message}`))),c.on("close",p=>{p!==0&&u&&!d?l(new Error(`Codex CLI failed: ${u}`)):r()}),setTimeout(()=>{c.kill(),l(new Error("Codex CLI timed out after 10 minutes"))},6e5)}),o("scan","Scanning generated files..."),this.scanGeneratedFiles(s)}buildFullPrompt(e,n,s){return`Read the conversion guide below, then convert the React landing page at ${e} into native HubSpot CMS modules for the theme at ${n}.
|
|
1310
1310
|
|
|
1311
1311
|
INSTRUCTIONS:
|
|
1312
1312
|
1. Analyze all .tsx/.jsx components in the React source
|
|
@@ -1321,15 +1321,15 @@ CONVERSION GUIDE:
|
|
|
1321
1321
|
${s}
|
|
1322
1322
|
|
|
1323
1323
|
Do NOT run hs upload \u2014 I will handle that separately.
|
|
1324
|
-
Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=xe(e,"css");if(S(s)){for(let r of
|
|
1325
|
-
HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let e=
|
|
1324
|
+
Create all files directly in the theme directory.`}scanGeneratedFiles(e){let n={sharedCss:"",sharedJs:"",template:"",modules:[]},s=xe(e,"css");if(S(s)){for(let r of Rn(s))if((r.includes("theme")||r.includes("page"))&&r.endsWith(".css")&&r!=="theme-overrides.css"&&r!=="main.css"&&r!=="style.css"){n.sharedCss=I(xe(s,r));break}}let o=xe(e,"js");if(S(o)){for(let r of Rn(o))if((r.includes("animation")||r.includes("page"))&&r.endsWith(".js")&&r!=="main.js"){n.sharedJs=I(xe(o,r));break}}let i=xe(e,"templates");if(S(i)){for(let r of Rn(i))if(r.endsWith(".html")&&!r.startsWith("system")&&r!=="base.html"){let l=I(xe(i,r));if(l.includes("dnd_area")){n.template=l;break}}}let a=xe(e,"modules");if(S(a))for(let r of Rn(a)){if(!r.endsWith(".module"))continue;let l=xe(a,r);if(!Jl(l).isDirectory())continue;let c={moduleName:r.replace(".module",""),fieldsJson:"",metaJson:"",moduleHtml:"",moduleCss:""},d=xe(l,"fields.json");S(d)&&(c.fieldsJson=I(d));let u=xe(l,"meta.json");S(u)&&(c.metaJson=I(u));let p=xe(l,"module.html");S(p)&&(c.moduleHtml=I(p));let f=xe(l,"module.css");S(f)&&(c.moduleCss=I(f));let h=xe(l,"module.js");S(h)&&(c.moduleJs=I(h)),c.fieldsJson&&c.moduleHtml&&n.modules.push(c)}return n}};Ve();Z();function Dl(t,e){switch(t){case"claude-code":return new Nn(e);case"gemini-cli":return new _n;case"codex-cli":return new On;case"api":return new Pn}}async function jn(t){await ce("Converting React to HubSpot Modules"),await je(`AI will now analyze your React code and create
|
|
1325
|
+
HubSpot-native modules. This takes 2-5 minutes.`,"AI Conversion");let e=Dl(t.aiEngine,t.model),n=le(),s=await ue();s.start("Starting AI conversion...");let o=Date.now(),i=await e.convert({sourceDir:t.sourceDir,themePath:t.themePath,conversionGuide:n,onProgress:(h,y)=>{h==="created"?F(y):s.message(y)}}),a=((Date.now()-o)/1e3).toFixed(0);s.stop(`AI conversion complete (${a}s)`);let r=Ll(t.themePath);for(let h of r)F(`Auto-fixed: ${h}`);let l=Hl(t.themePath,i),c=[];for(let h of l){let y=h.passed?"\u2705":"\u274C",b=h.passed?"":h.critical?" (CRITICAL)":" (cosmetic)";c.push(`${y} ${h.label}${b}`)}let d=l.filter(h=>h.passed).length;c.push(`
|
|
1326
1326
|
${d}/${l.length} checks passed`),await je(c.join(`
|
|
1327
1327
|
`),"Conversion Checklist");let u=l.filter(h=>!h.passed&&h.critical),p=l.filter(h=>!h.passed&&!h.critical);if(u.length>0){if(W(`${u.length} critical issue(s) \u2014 upload will likely fail:
|
|
1328
1328
|
`+u.map(y=>` - ${y.label}`).join(`
|
|
1329
1329
|
`)),!await se({message:"Continue with upload anyway?",initialValue:!1}))throw new Error("Conversion aborted due to critical checklist failures.")}else p.length>0&&V(`${p.length} non-critical issue(s) \u2014 page will work but may look incomplete:
|
|
1330
1330
|
`+p.map(h=>` - ${h.label}`).join(`
|
|
1331
|
-
`));let f=Ie(t.themePath,"..","vibespot-conversion.log");return S(f)&&(await se({message:"Keep conversion log file for debugging?",initialValue:!1})?F(`Log saved: ${f}`):
|
|
1332
|
-
`,l=!0)}catch{e.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&H(i,r);let c=Ie(n,o,"module.html");if(S(c)){let d=I(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),H(c,d),e.push(`${a}: now() \u2192 local_dt`))}}let s=Ie(t,"templates");if(S(s))for(let o of Vt(s)){if(!o.endsWith(".html"))continue;let i=Ie(s,o),a=I(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(
|
|
1331
|
+
`));let f=Ie(t.themePath,"..","vibespot-conversion.log");return S(f)&&(await se({message:"Keep conversion log file for debugging?",initialValue:!1})?F(`Log saved: ${f}`):ri(f)),await de("Files ready for upload!"),i}function Ll(t){let e=[];Gl(t),Ul(t);let n=Ie(t,"modules");if(S(n))for(let o of Vt(n)){if(!o.endsWith(".module"))continue;let i=Ie(n,o,"fields.json");if(!S(i))continue;let a=o.replace(".module",""),r=I(i),l=!1;r.includes('"textarea"')&&(r=r.replace(/"textarea"/g,'"text"'),l=!0,e.push(`${a}: "textarea" \u2192 "text"`)),/"name":\s*"name"/.test(r)&&(r=r.replace(/"name":\s*"name"/g,'"name": "item_name"'),l=!0,e.push(`${a}: reserved field name "name" \u2192 "item_name"`));try{let d=JSON.parse(r),u=!1;ai(d)&&(u=!0,e.push(`${a}: fixed choice field format`)),li(d)&&(u=!0,e.push(`${a}: fixed link field default value`)),u&&(r=JSON.stringify(d,null,2)+`
|
|
1332
|
+
`,l=!0)}catch{e.push(`${a}: fields.json has invalid JSON \u2014 manual fix needed`)}l&&H(i,r);let c=Ie(n,o,"module.html");if(S(c)){let d=I(c);d.includes("now()")&&(d=d.replace(/now\(\)/g,"local_dt"),H(c,d),e.push(`${a}: now() \u2192 local_dt`))}}let s=Ie(t,"templates");if(S(s))for(let o of Vt(s)){if(!o.endsWith(".html"))continue;let i=Ie(s,o),a=I(i);(a.includes("hubdb_table")||a.includes("hubdb_table_rows"))&&(ri(i),e.push(`Removed ${o} (HubDB requires CMS Hub Pro/Enterprise)`))}return e}function ai(t){let e=!1;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;s.type==="choice"&&Array.isArray(s.choices)&&s.choices.some(i=>typeof i=="string")&&(s.choices=s.choices.map(i=>{if(typeof i=="string"){let a=i.charAt(0).toUpperCase()+i.slice(1);return[i,a]}return i}),e=!0),Array.isArray(s.children)&&ai(s.children)&&(e=!0)}return e}function li(t){let e=!1;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},e=!0}}Array.isArray(s.children)&&li(s.children)&&(e=!0)}return e}function Hl(t,e){let n=[],s=e.modules.length;n.push({label:`Modules created (${s})`,passed:s>0,critical:!0});let o=!0;for(let u of e.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=e.modules.every(u=>u.moduleHtml.length>0);n.push({label:"module.html created for each module",passed:s>0&&i,critical:!0});let a=e.modules.filter(u=>!u.moduleCss).map(u=>u.moduleName),r=a.length===0;n.push({label:r?"module.css created for each module":`module.css missing for: ${a.join(", ")}`,passed:s>0&&r,critical:!1});let l=e.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:e.sharedCss.length>50,critical:!1}),n.push({label:"Shared JS for scroll animations",passed:e.sharedJs.length>50,critical:!1}),n.push({label:"Page template with dnd_area",passed:e.template.length>0&&e.template.includes("dnd_area"),critical:!0});let c=Ie(t,"templates"),d=!1;if(S(c))for(let u of Vt(c)){if(!u.endsWith(".html")||u==="base.html"||u.startsWith("system"))continue;let p=I(Ie(c,u));if(p.includes("dnd_area")&&/templateType\s*:\s*page/i.test(p)){d=!0;break}}return n.push({label:"Template annotations (templateType: page)",passed:d,critical:!0}),n}function Gl(t){let e=Ie(t,"templates");if(S(e))for(let n of Vt(e)){if(!n.endsWith(".html")||n==="base.html"||n.startsWith("system"))continue;let s=Ie(e,n),o=I(s);if(!o.includes("dnd_area")&&!o.includes("extends"))continue;let i=/templateType\s*:\s*page/i.test(o),a=/isAvailableForNewContent\s*:\s*true/i.test(o);if(i&&a)continue;let r=n.replace(".html","").replace(/[-_]/g," ").replace(/\b\w/g,l=>l.toUpperCase());if(o.includes("<!--")&&o.indexOf("-->")<200){let l=o.indexOf("-->"),c=o.slice(0,l);i||(c+=`
|
|
1333
1333
|
templateType: page`),a||(c+=`
|
|
1334
1334
|
isAvailableForNewContent: true`),/label\s*:/i.test(c)||(c+=`
|
|
1335
1335
|
label: ${r}`),o=c+o.slice(l)}else o=`<!--
|
|
@@ -1337,13 +1337,13 @@ ${d}/${l.length} checks passed`),await je(c.join(`
|
|
|
1337
1337
|
isAvailableForNewContent: true
|
|
1338
1338
|
label: ${r}
|
|
1339
1339
|
-->
|
|
1340
|
-
`+o;H(s,o),F(`Template "${n}" \u2014 annotations verified`)}}function
|
|
1341
|
-
`)}catch{}}}g();ct();import{join as
|
|
1342
|
-
`),e=!0)}catch{}}return e}function
|
|
1343
|
-
`),e=!0)}catch{}}return e}function
|
|
1344
|
-
`);c=
|
|
1345
|
-
You can check your HubSpot Design Manager to verify.`),await se({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(r<a){if(!await se({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let p of l)p.fixable?
|
|
1346
|
-
The theme may work \u2014 check HubSpot Design Manager.`),await se({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await
|
|
1340
|
+
`+o;H(s,o),F(`Template "${n}" \u2014 annotations verified`)}}function Ul(t){let e=Ie(t,"modules");if(S(e))for(let n of Vt(e)){if(!n.endsWith(".module"))continue;let s=Ie(e,n,"meta.json");if(S(s))try{let o=JSON.parse(I(s)),i=!1;(!o.host_template_types||!o.host_template_types.includes("PAGE"))&&(o.host_template_types=["PAGE"],i=!0),o.is_available_for_new_content||(o.is_available_for_new_content=!0,i=!0),i&&H(s,JSON.stringify(o,null,2)+`
|
|
1341
|
+
`)}catch{}}}g();ct();import{join as Si,basename as Zl}from"path";g();Z();import{join as oe}from"path";import{readdirSync as Ye,rmSync as Wl}from"fs";function Fn(t){let e=[];for(let n of t){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),e.push({file:n.file||"unknown",message:s,fixable:o})}return e}function Jn(t){let e=[];if(/textarea.*not.*valid|unknown.*field.*type/i.test(t)){let n=t.match(/(?:in|file:?)\s+(\S+fields\.json)/i);e.push({file:n?.[1]||"fields.json",message:'"textarea" is not a valid field type',fixable:!0})}if(/missing field name|field null/i.test(t)){let n=t.match(/(?:in|file:?)\s+(\S+fields\.json)/i);e.push({file:n?.[1]||"fields.json",message:'"name" is a reserved field name',fixable:!0})}if(/could not resolve.*now/i.test(t)&&e.push({file:"module.html",message:"now() is not a valid HubL function",fixable:!0}),/hubdb|do not have access to hubdb/i.test(t)&&e.push({file:"templates",message:"HubDB requires CMS Hub Pro/Enterprise",fixable:!0}),/invalid default value|link.*field.*invalid/i.test(t)){let n=t.match(/field.*?(\w+)\s+has an invalid/i);e.push({file:n?.[1]||"fields.json",message:"Link field has invalid default value",fixable:!0})}if(/failed to deserialize/i.test(t)){let n=t.match(/file '([^']+)'/i);e.push({file:n?.[1]||"fields.json",message:"fields.json deserialization error",fixable:!0})}return/format for the color value is invalid/i.test(t)&&e.push({file:"fields.json",message:"Color field has invalid format (rgba/rgb/named \u2014 must be hex)",fixable:!0}),e}function Dn(t){let e=[];return di(t)&&e.push("textarea \u2192 text"),ui(t)&&e.push("name \u2192 item_name"),mi(t)&&e.push("now() \u2192 local_dt"),pi(t)&&e.push("Removed HubDB templates"),fi(t)&&e.push("Fixed link field defaults"),gi(t)&&e.push("Fixed rgba/invalid color values \u2192 hex"),Bl(t)&&e.push("Stripped CDN @import statements"),e}function ci(t,e){return e.message.includes("textarea")?di(t):e.message.includes("reserved field name")?ui(t):e.message.includes("now()")?mi(t):e.message.includes("HubDB")?pi(t):e.message.includes("invalid default value")||e.message.includes("deserialization")?fi(t):e.message.includes("invalid format")&&e.message.includes("color")?gi(t):!1}function di(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(!S(o))continue;let i=I(o);i.includes('"textarea"')&&(i=i.replace(/"textarea"/g,'"text"'),H(o,i),e=!0)}return e}function ui(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(!S(o))continue;let i=I(o);/"name":\s*"name"/g.test(i)&&(i=i.replace(/"name":\s*"name"/g,'"name": "item_name"'),H(o,i),e=!0)}return e}function mi(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"module.html");if(!S(o))continue;let i=I(o);i.includes("now()")&&(i=i.replace(/now\(\)/g,"local_dt"),H(o,i),e=!0)}return e}function pi(t){let e=!1,n=oe(t,"templates");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".html"))continue;let o=oe(n,s),i=I(o);(i.includes("hubdb_table")||i.includes("hubdb_table_rows"))&&(Wl(o),e=!0)}return e}function fi(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(S(o))try{let i=JSON.parse(I(o));yi(i)&&(H(o,JSON.stringify(i,null,2)+`
|
|
1342
|
+
`),e=!0)}catch{}}return e}function Bl(t){let e=!1,n=oe(t,"css");if(S(n))for(let o of Ye(n)){if(!o.endsWith(".css"))continue;let i=oe(n,o),a=I(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(H(i,r),e=!0)}let s=oe(t,"modules");if(S(s))for(let o of Ye(s)){if(!o.endsWith(".module"))continue;let i=oe(s,o,"module.css");if(!S(i))continue;let a=I(i),r=a.replace(/@import\s+url\(['"]?https?:\/\/[^)]+['"]?\)\s*;?/gi,"");r!==a&&(H(i,r),e=!0)}if(S(s))for(let o of Ye(s)){if(!o.endsWith(".module"))continue;let i=oe(s,o,"module.html");if(!S(i))continue;let a=I(i),r=a.replace(/<link[^>]+href=['"]https?:\/\/[^'"]+['"][^>]*>/gi,"");r!==a&&(H(i,r),e=!0)}return e}function gi(t){let e=!1,n=oe(t,"modules");if(!S(n))return!1;for(let s of Ye(n)){if(!s.endsWith(".module"))continue;let o=oe(n,s,"fields.json");if(S(o))try{let i=JSON.parse(I(o));hi(i)&&(H(o,JSON.stringify(i,null,2)+`
|
|
1343
|
+
`),e=!0)}catch{}}return e}function hi(t){let e=!1;for(let n of t){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"&&!Kl(i)){let a=Vl(i);a&&(o.color=a.hex,a.opacity!==void 0&&(o.opacity=a.opacity),e=!0)}}Array.isArray(s.children)&&hi(s.children)&&(e=!0)}return e}function Kl(t){return/^#[0-9a-fA-F]{6}$/.test(t)}function Vl(t){let e=t.match(/^#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])$/);if(e)return{hex:`#${e[1]}${e[1]}${e[2]}${e[2]}${e[3]}${e[3]}`};let n=t.match(/rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*([\d.]+))?\s*\)/i);if(n){let i=Math.min(255,parseInt(n[1])),a=Math.min(255,parseInt(n[2])),r=Math.min(255,parseInt(n[3])),l=`#${i.toString(16).padStart(2,"0")}${a.toString(16).padStart(2,"0")}${r.toString(16).padStart(2,"0")}`,c=n[4]!==void 0?Math.round(parseFloat(n[4])*100):void 0;return{hex:l,opacity:c}}let s={white:"#ffffff",black:"#000000",red:"#ff0000",green:"#008000",blue:"#0000ff",yellow:"#ffff00",orange:"#ffa500",purple:"#800080",gray:"#808080",grey:"#808080",transparent:"#000000"},o=t.toLowerCase().trim();return s[o]?{hex:s[o],opacity:o==="transparent"?0:void 0}:null}function yi(t){let e=!1;for(let n of t){if(typeof n!="object"||n===null)continue;let s=n;if(s.type==="link"){let o=s.default;if(typeof o=="string"||o===void 0||o===null||typeof o=="object"&&!o.url){let a=typeof o=="string"?o:"";s.default={url:{href:a,type:"EXTERNAL"},open_in_new_tab:!1,no_follow:!1},e=!0}}Array.isArray(s.children)&&yi(s.children)&&(e=!0)}return e}ee();g();ut();ut();import{readdirSync as Yl}from"fs";import{join as zl,relative as ql}from"path";var Xl=new Set([".git","node_modules",".vibespot",".DS_Store"]);function bi(t){let e=[];for(let n of Yl(t,{withFileTypes:!0})){if(Xl.has(n.name)||n.name.startsWith(".")&&n.name!==".gitkeep")continue;let s=zl(t,n.name);n.isDirectory()?e.push(...bi(s)):n.isFile()&&e.push(s)}return e}async function Ql(t,e,n){let s=0;async function o(){for(;s<t.length;){let a=s++;await n(t[a])}}let i=Array.from({length:Math.min(e,t.length)},()=>o());await Promise.all(i)}async function Ln(t,e,n,s={}){let o=s.concurrency??5,i=bi(e),a=i.length,r=0,l=0,c=[];return await Ql(i,o,async d=>{let u=ql(e,d).replace(/\\/g,"/"),p=`${n}/${u}`;s.onFileStart?.(u);let f=await Do(t,p,d);if(f.success)r++,s.onFileComplete?.(u);else{l++;let h={file:u,status:f.error?.status||0,message:f.error?.message||"Unknown error",category:f.error?.category,detail:f.error?.detail};c.push(h),s.onFileError?.(u,h)}s.onProgress?.(r+l,a)}),{success:l===0,uploaded:r,failed:l,total:a,errors:c}}function ec(t){return(t.match(/^Uploaded file /gm)||[]).length}async function Ct(t){await ce("Uploading to HubSpot");let e=Zl(t)||t,n=P(),s=he(),o=n.hubspotUploadMode!=="cli"&&!!s,i=await ue(),a=3;for(let r=1;r<=a;r++){i.start(r===1?"Uploading theme...":`Retrying upload (attempt ${r}/${a})...`);let l=[],c=0,d=!1;if(o){let p=await Ln(s,t,e,{onFileComplete:()=>{c++}});d=p.success,d?c=p.uploaded:l=Fn(p.errors)}else{let p=T(`hs cms upload "${t}" "${e}"`,{cwd:Si(t,"..")}),f=[p.stdout,p.stderr].filter(Boolean).join(`
|
|
1344
|
+
`);c=ec(f),d=p.success,d||(l=Jn(f))}if(d)return i.stop(`All files uploaded! (${c} files)`),await de("Upload complete!"),!0;if(c>0?i.stop(`${c} files uploaded, but some errors occurred`):i.stop("Upload failed"),l.length===0){if(W("Upload failed with unknown error."),c>0&&(V(`Most files uploaded successfully. The theme may already be usable in HubSpot.
|
|
1345
|
+
You can check your HubSpot Design Manager to verify.`),await se({message:"Continue anyway (theme is likely uploaded)?",initialValue:!0})))return!0;if(r<a){if(!await se({message:"Try uploading again?"}))break;continue}break}let u=!1;for(let p of l)p.fixable?ci(t,p)?(F(`Auto-fixed: ${p.message}`),u=!0):V(`Could not auto-fix: ${p.message}`):W(p.message);if(!(u&&r<a)){if(c>0&&(V(`${c} files uploaded successfully despite errors.
|
|
1346
|
+
The theme may work \u2014 check HubSpot Design Manager.`),await se({message:"Continue anyway?",initialValue:!0})))return!0;if(!u){if(i.start("Cleaning up stuck modules..."),o)try{await As(s,`${e}/modules`)}catch{}else T(`hs cms delete "${e}/modules"`,{cwd:Si(t,"..")});i.stop("Cleaned up modules, retrying...")}}}return W("Upload failed after multiple attempts."),!1}g();import{execFileSync as Es}from"child_process";import{rmSync as tc}from"fs";import{basename as vi}from"path";Z();async function wi(t){let{portalId:e,sourceDir:n,themePath:s,wasCloned:o}=t;await ce("You're all set!");let a=Lt(e)==="eu1"?"app-eu1.hubspot.com":"app.hubspot.com";if(await je(`Your React page has been converted and uploaded to HubSpot.
|
|
1347
1347
|
The theme and modules are now in your account, but you still
|
|
1348
1348
|
need to ${k.bold("create a new landing page")} that uses them.
|
|
1349
1349
|
|
|
@@ -1355,14 +1355,14 @@ Next steps:
|
|
|
1355
1355
|
${k.bold("4.")} Your converted modules will appear \u2014 drag them onto the page
|
|
1356
1356
|
${k.bold("5.")} Click each section to edit text, images, and colors
|
|
1357
1357
|
${k.bold("6.")} Upload images via File Manager ${k.muted("(Settings \u2192 Files)")}
|
|
1358
|
-
${k.bold("7.")} Preview and publish!`,"What's next"),await se({message:"Open HubSpot Landing Pages in your browser?"})){let c=e?`https://${a}/page-ui/${e}/management/pages/landing`:`https://${a}`;try{let d=process.platform;d==="darwin"
|
|
1358
|
+
${k.bold("7.")} Preview and publish!`,"What's next"),await se({message:"Open HubSpot Landing Pages in your browser?"})){let c=e?`https://${a}/page-ui/${e}/management/pages/landing`:`https://${a}`;try{let d=process.platform;d==="darwin"?Es("open",[c],{stdio:"ignore"}):d==="win32"?Es("cmd",["/c","start","",c],{stdio:"ignore"}):Es("xdg-open",[c],{stdio:"ignore"}),F("Opening HubSpot Landing Pages...")}catch{X(`Open this URL in your browser: ${k.info(c)}`)}}let l=[];if(o&&S(n)&&l.push({path:n,label:`Cloned source (${vi(n)})`}),S(s)&&l.push({path:s,label:`Theme directory (${vi(s)})`}),l.length>0&&await se({message:"Clean up local working directories?"}))for(let d of l)try{tc(d.path,{recursive:!0,force:!0}),F(`Removed ${d.label}`)}catch{V(`Could not remove ${d.label} \u2014 delete manually if needed.`)}await de(`Thanks for using hub${k.vibes("Vibes")}! ${k.vibes("~")}`)}ee();async function xi(){_e();let t=await An(),e=await In();q({lastSourcePath:e.sourceDir});let n=await En();q({lastThemePath:n.themePath}),await jn({aiEngine:t.aiEngine,model:t.model,sourceDir:e.sourceDir,themePath:n.themePath}),await Ct(n.themePath),await wi({portalId:t.portalId,sourceDir:e.sourceDir,themePath:n.themePath,wasCloned:e.wasCloned})}g();async function Ci(){_e(),await An()}g();ee();async function Ai(){_e();let t=P();t.aiEngine||(W("AI engine not configured. Run `vibespot init` first or use the full wizard with `vibespot`."),process.exit(1));let e=await In(),n=await En();await jn({aiEngine:t.aiEngine,sourceDir:e.sourceDir,themePath:n.themePath})}g();ee();async function Ii(){_e();let t=P();if(t.lastThemePath)if(await se({message:`Upload from ${t.lastThemePath}?`}))await Ct(t.lastThemePath);else{let n=await $e({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme"});await Ct(n)}else{let e=await $e({message:"Path to your HubSpot theme directory:",placeholder:"./my-theme",validate:n=>n.trim()?void 0:"Path is required"});await Ct(e)}}g();ee();async function ki(){_e(),await ce("Environment Diagnostics");let t=0,e=Ft();e.found?Sn(e.version)?F(`Node.js v${e.version}`):(V(`Node.js v${e.version} \u2014 too old (need 18+)`),X(" Update at https://nodejs.org"),t++):(W("Node.js \u2014 not installed"),X(" Install from https://nodejs.org"),t++);let n=Jt();n.found?F(`Git ${n.version}`):(W("Git \u2014 not installed"),X(" Install from https://git-scm.com"),t++);let s=Re();if(!s.found)V("HubSpot CLI \u2014 not installed (only needed for deployment)"),X(" Install: npm install -g @hubspot/cli");else if(!jo(s.version))V(`HubSpot CLI v${s.version} \u2014 too old (need v8+)`),X(" Update: npm install -g @hubspot/cli@latest"),t++;else{F(`HubSpot CLI v${s.version}`);let p=Oe();p.authenticated?F(`HubSpot portal${p.portalName?`: ${p.portalName}`:""} (ID: ${p.portalId})`):(V("HubSpot \u2014 not authenticated"),X(" Run: hs init"))}let o=Dt();o.found?F(`Claude Code ${o.version} at ${o.path}`):X(k.muted("Claude Code \u2014 not installed"));let i=Ht();i.found?F(`Gemini CLI ${i.version} at ${i.path}`):X(k.muted("Gemini CLI \u2014 not installed"));let a=Gt();a.found?F(`OpenAI Codex ${a.version} at ${a.path}`):X(k.muted("OpenAI Codex \u2014 not installed"));let r=P(),l=!!(r.anthropicApiKey||process.env.ANTHROPIC_API_KEY),c=!!(r.openaiApiKey||process.env.OPENAI_API_KEY),d=!!(r.geminiApiKey||process.env.GEMINI_API_KEY||process.env.GOOGLE_AI_API_KEY);l?F("Anthropic API key configured"):X(k.muted("Anthropic API key \u2014 not set")),c?F("OpenAI API key configured"):X(k.muted("OpenAI API key \u2014 not set")),d?F("Google AI API key configured"):X(k.muted("Google AI API key \u2014 not set"));let u={"claude-code":"Claude Code",api:"Anthropic API","anthropic-api":"Anthropic API","openai-api":"OpenAI API","gemini-api":"Gemini API","gemini-cli":"Gemini CLI","codex-cli":"OpenAI Codex"};r.aiEngine&&F(`AI engine: ${u[r.aiEngine]||r.aiEngine}`),r.lastThemePath&&X(k.muted(`Last theme: ${r.lastThemePath}`)),!o.found&&!i.found&&!a.found&&!l&&!c&&!d&&(V("No AI engine available"),X(" Fastest: Set an API key (ANTHROPIC_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY)"),X(" Or install: Claude Code \u2014 https://claude.ai/code"),X(" Gemini CLI \u2014 https://github.com/google-gemini/gemini-cli"),X(" Codex CLI \u2014 https://github.com/openai/codex"),t++),console.log(),t===0?await de("Everything looks good!"):await de(k.warn(`${t} issue${t>1?"s":""} found \u2014 see above`))}g();import{join as gs}from"path";import{existsSync as yu}from"fs";import{execFileSync as Ao}from"child_process";import hs from"chalk";g();Se();Yt();Xn();os();ee();import{createServer as cu}from"http";import{readFileSync as Co,existsSync as dn}from"fs";import{join as at,extname as nl}from"path";import{createHash as du}from"crypto";import{WebSocketServer as uu}from"ws";g();import{spawn as yo}from"child_process";var rt=new Map;function Xr(t,e,n){t.stdout?.on("data",o=>{e.output+=o.toString()}),t.stderr?.on("data",o=>{e.output+=o.toString()}),t.on("close",o=>{e.status=o===0?"completed":"failed",e.exitCode=o,e.completedAt=Date.now()}),t.on("error",o=>{e.status="failed",e.output+=`
|
|
1359
1359
|
Process error: ${o.message}`,e.completedAt=Date.now()}),setTimeout(()=>{e.status==="running"&&(t.kill(),e.status="failed",e.output+=`
|
|
1360
|
-
Process timed out`,e.completedAt=Date.now())},n||3e5)}function
|
|
1360
|
+
Process timed out`,e.completedAt=Date.now())},n||3e5)}function an(t,e,n,s){let o=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,i={id:o,command:`${t} ${e.join(" ")}`,description:n,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};rt.set(o,i);let a=yo(t,e,{cwd:s?.cwd,stdio:[s?.stdin?"pipe":"ignore","pipe","pipe"],env:{...process.env,...s?.env},shell:process.platform==="win32"});return s?.stdin&&a.stdin&&(a.stdin.write(s.stdin),a.stdin.end()),Xr(a,i,s?.timeout),o}function ht(t,e,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:t,description:e,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null};rt.set(s,o);let i=t.split(" "),a=yo(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0});return Xr(a,o,n?.timeout),s}function is(t){return rt.get(t)}function Rd(){let t=Date.now()-18e5;for(let[e,n]of rt)n.completedAt&&n.completedAt<t&&rt.delete(e)}setInterval(Rd,600*1e3);function rs(t,e,n){let s=`job-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,6)}`,o={id:s,command:t,description:e,status:"running",output:"",exitCode:null,startedAt:Date.now(),completedAt:null,listeners:new Set};rt.set(s,o);let i=t.split(" "),a=yo(i[0],i.slice(1),{cwd:n?.cwd,stdio:["ignore","pipe","pipe"],env:{...process.env,...n?.env},shell:!0}),r=c=>{for(let d of o.listeners)try{d(c)}catch{}};a.stdout?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.stderr?.on("data",c=>{let d=c.toString();o.output+=d,r(d)}),a.on("close",c=>{o.status=c===0?"completed":"failed",o.exitCode=c,o.completedAt=Date.now(),o.listeners.clear()}),a.on("error",c=>{o.status="failed",o.output+=`
|
|
1361
1361
|
Process error: ${c.message}`,o.completedAt=Date.now(),o.listeners.clear()});let l=n?.timeout||3e5;return setTimeout(()=>{o.status==="running"&&(a.kill(),o.status="failed",o.output+=`
|
|
1362
|
-
Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Yr(t,e){let n=rt.get(t);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{e(s.output)}catch{}s.listeners.add(e)}function zr(t,e){let n=rt.get(t);!n||!("listeners"in n)||n.listeners.delete(e)}ot();Z();g();ot();ee();import{existsSync as Pt,readdirSync as qr,rmSync as Md}from"fs";import{join as _t,basename as Pd}from"path";import{homedir as _d}from"os";import{execFileSync as Xr}from"child_process";$n();ut();Se();ns();ee();Z();var Qr=process.platform==="win32"?{shell:!0}:{},Me=_t(_d(),"vibespot-themes"),is=null,Rd=5e3;function rs(){if(is&&Date.now()-is.ts<Rd)return is.data;let t=[];if(Pt(Me))try{for(let e of qr(Me,{withFileTypes:!0}))if(e.isDirectory()){let n=_t(Me,e.name,"theme.json");if(Pt(n)){let s=0,o=_t(Me,e.name,"modules");if(Pt(o))try{s=qr(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}t.push({name:e.name,moduleCount:s})}}}catch{}return is={data:t,ts:Date.now()},t}function Zr(t){let e=v(),n=Sn(),s=!1;try{Xr("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...Qr}),s=!0}catch{}let o=kt().sort((a,r)=>r.updatedAt-a.updatedAt).slice(0,10),i=rs();m(t,200,{hasActiveSession:!!e,activeSession:e?{id:e.id,themeName:e.themeName,moduleCount:e.modules.length}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i})}function ea(t,e){j(t,n=>{try{if(Mt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,""),i=_t(Me,o);Ae(Me),Pt(i)&&Md(i,{recursive:!0,force:!0}),kn(i,o),Xt(i,o),D(),m(e,200,{ok:!0,themeName:o,themePath:i})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ta(t,e){j(t,n=>{try{if(Mt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){m(e,400,{error:"Theme name is required"});return}let i=he(),a=M(),r=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=_t(Me,r);Ae(Me),a.hubspotUploadMode==="cli"||!i?(Xr("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...Qr}),Xt(l,r),en(l),D(),m(e,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})):Bt(i,o,l).then(()=>{Xt(l,r),en(l),D(),m(e,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})}).catch(c=>{m(e,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function na(t,e){j(t,n=>{try{if(Mt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme path is required"});return}let o=s;if(Pt(o)||(o=_t(Me,s)),!Pt(o)){m(e,400,{error:`Theme folder not found: ${s}`});return}let i=Pd(o);Xt(o,i),en(o),D(),m(e,200,{ok:!0,themeName:i,themePath:o,moduleCount:v()?.modules.length||0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function sa(t,e){j(t,n=>{try{if(Mt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Session ID is required"});return}let o=Vn(s);if(!o){m(e,404,{error:"Session not found"});return}m(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function oa(t,e){j(t,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"API key is required"});return}q({anthropicApiKey:s}),m(e,200,{ok:!0})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ia(t){let e=he();if(!e){m(t,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Jo(e);if(n.length===0){m(t,200,{themes:[]});return}let s=[],o=n.map(async r=>{let l=r.path||r.name;try{let c=await xn(e,`${l}/theme.json`);c&&!c.folder&&s.push({name:r.name,path:l})}catch{}});await Promise.all(o),s.sort((r,l)=>r.name.localeCompare(l.name));let i=rs(),a=new Set(i.map(r=>r.name));m(t,200,{themes:s.map(r=>({...r,existsLocally:a.has(r.name)}))})})().catch(n=>{m(t,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}g();ot();ee();Se();import{existsSync as Od,readFileSync as jd,appendFileSync as Fd}from"fs";import{join as ra}from"path";import{homedir as aa}from"os";ut();Z();var an={data:{},ts:0},Jd=600*1e3,la={"claude-code":[{id:"sonnet",label:"Claude Sonnet (default)"},{id:"opus",label:"Claude Opus"},{id:"haiku",label:"Claude Haiku"}],"codex-cli":[{id:"o4-mini",label:"o4 Mini (default)"},{id:"o3",label:"o3"},{id:"gpt-4o",label:"GPT-4o"}]};async function Dd(t){let e=await fetch("https://api.anthropic.com/v1/models",{headers:{"x-api-key":t,"anthropic-version":"2023-06-01"}});return e.ok?(await e.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 Ld(t){let e=await fetch("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${t}`}});if(!e.ok)return[];let n=await e.json(),s=/^(gpt-4o|gpt-4o-mini|o[1-4](-mini)?|o[1-4]-pro)$/;return n.data.filter(o=>s.test(o.id)).sort((o,i)=>o.id.localeCompare(i.id)).map(o=>({id:o.id,label:o.id}))}async function Hd(t){let e=await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${t}`);return e.ok?(await e.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function Gd(){if(Date.now()-an.ts<Jd&&Object.keys(an.data).length>0)return an.data;let t=M(),e={...la},n=[],s=ge("anthropic-api",t);s&&n.push(Dd(s).then(a=>{a.length&&(e["anthropic-api"]=a)}).catch(()=>{}));let o=ge("openai-api",t);o&&n.push(Ld(o).then(a=>{a.length&&(e["openai-api"]=a)}).catch(()=>{}));let i=ge("gemini-api",t);return i&&n.push(Hd(i).then(a=>{a.length&&(e["gemini-api"]=a,e["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n),an.data=e,an.ts=Date.now(),e}function ca(t){let e=Sn(),n=M(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(r=>({portalId:r.portalId,portalName:r.portalName,dataCenter:r.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency},o=kt().length,i=rs().length,a=St();Gd().then(r=>{m(t,200,{version:a,environment:e,config:s,models:r,sessionCount:o,localThemeCount:i})}).catch(()=>{m(t,200,{version:a,environment:e,config:s,models:la,sessionCount:o,localThemeCount:i})})}function da(t,e){j(t,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","openai-api","gemini-cli","gemini-api","codex-cli"].includes(s)){m(e,400,{error:`Invalid engine: ${s}`});return}let a={aiEngine:s};if(o)switch(s){case"claude-code":a.claudeCodeModel=o;break;case"anthropic-api":a.anthropicApiModel=o;break;case"openai-api":a.openaiApiModel=o;break}q(a),m(e,200,{ok:!0,engine:s})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ua(t,e){j(t,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;default:m(e,400,{error:`Unknown provider: ${s}`});return}q(l),m(e,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;default:m(e,400,{error:`Unknown provider: ${s}`});return}q(i);let a=null;if(!M().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(q({aiEngine:c}),a=c)}m(e,200,{ok:!0,provider:s,autoSelectedEngine:a})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ma(t,e){j(t,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){m(e,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let a=ht(i.cmd,i.desc,{timeout:12e4});m(e,200,{ok:!0,jobId:a})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function pa(t,e){j(t,n=>{try{let s=JSON.parse(n||"{}"),o=M(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){wn(s.personalAccessKey).then(a=>{Ot(s.personalAccessKey,a.portalId,a.portalName,a.dataCenter),m(e,200,{ok:!0,portalName:a.portalName,portalId:a.portalId,dataCenter:a.dataCenter})}).catch(a=>{m(e,400,{error:a instanceof Error?a.message:String(a)})});return}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=rn("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});m(e,200,{ok:!0,jobId:r});return}if(i==="api"){let a=o.hubspotAccounts||[];if(a.length>0&&!s.force){let r=a.find(l=>l.portalId===o.activeHubSpotAccount)||a[0];m(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=Oe();if(r.authenticated&&!s.force){m(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}m(e,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function fa(t,e){j(t,n=>{try{let s=JSON.parse(n||"{}");if(!vs().found){m(e,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=ws();if(i.authenticated&&!s.force){m(e,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let r=rn("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});m(e,200,{ok:!0,jobId:r});return}let a=ht("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});m(e,200,{ok:!0,jobId:a,browserAuthRequired:!0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ga(t,e){j(t,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((M().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){hs(s),m(e,200,{ok:!0});return}if(s){ys(s),m(e,200,{ok:!0});return}}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){m(e,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=rn("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});m(e,200,{ok:!0,jobId:c});return}if(l){let c=rn("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});m(e,200,{ok:!0,jobId:c});return}}m(e,400,{error:"portalId required"})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ha(t){let e=ht("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});m(t,200,{ok:!0,jobId:e})}function ya(t,e){j(t,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=ht("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=ht("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,q({openaiApiKey:i}),process.platform!=="win32"){let a=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(a){let r=`export OPENAI_API_KEY="${a}"`,l=process.env.SHELL?.includes("zsh")?ra(aa(),".zshrc"):ra(aa(),".bashrc");try{(Od(l)?jd(l,"utf-8"):"").includes("OPENAI_API_KEY")||Fd(l,`
|
|
1362
|
+
Process timed out`,o.completedAt=Date.now(),o.listeners.clear())},l),s}function Qr(t,e){let n=rt.get(t);if(!n||!("listeners"in n))return;let s=n;if(s.output)try{e(s.output)}catch{}s.listeners.add(e)}function Zr(t,e){let n=rt.get(t);!n||!("listeners"in n)||n.listeners.delete(e)}ot();Z();g();ot();ee();import{existsSync as Mt,readdirSync as ea,rmSync as Od}from"fs";import{join as _t,basename as jd}from"path";import{homedir as Fd}from"os";import{execFileSync as ta}from"child_process";Tn();ut();Se();os();ee();Z();var na=process.platform==="win32"?{shell:!0}:{},Pe=_t(Fd(),"vibespot-themes"),as=null,Jd=5e3;function ls(){if(as&&Date.now()-as.ts<Jd)return as.data;let t=[];if(Mt(Pe))try{for(let e of ea(Pe,{withFileTypes:!0}))if(e.isDirectory()){let n=_t(Pe,e.name,"theme.json");if(Mt(n)){let s=0,o=_t(Pe,e.name,"modules");if(Mt(o))try{s=ea(o,{withFileTypes:!0}).filter(i=>i.isDirectory()).length}catch{}t.push({name:e.name,moduleCount:s})}}}catch{}return as={data:t,ts:Date.now()},t}function sa(t){let e=v(),n=vn(),s=!1;try{ta("hs",["--version"],{encoding:"utf-8",stdio:"pipe",...na}),s=!0}catch{}let o=kt().sort((a,r)=>r.updatedAt-a.updatedAt).slice(0,10),i=ls();m(t,200,{hasActiveSession:!!e,activeSession:e?{id:e.id,themeName:e.themeName,moduleCount:e.modules.length}:null,hsInstalled:s,aiAvailable:n.availableEngines.length>0,availableEngines:n.availableEngines,activeEngine:n.activeEngine,sessions:o,localThemes:i})}function oa(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=s.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-+/g,"-").replace(/^-|-$/g,""),i=_t(Pe,o);Ae(Pe),Mt(i)&&Od(i,{recursive:!0,force:!0}),$n(i,o),Qt(i,o),D(),m(e,200,{ok:!0,themeName:o,themePath:i})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ia(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{name:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=s.replace(/^\/+|\/+$/g,"");if(!o){m(e,400,{error:"Theme name is required"});return}let i=he(),a=P(),r=o.includes("/")||o.includes("@")?o.replace(/[@/]/g,"_").replace(/_+/g,"_").replace(/^_|_$/g,""):o,l=_t(Pe,r);Ae(Pe),a.hubspotUploadMode==="cli"||!i?(ta("hs",["cms","fetch",o,l],{encoding:"utf-8",stdio:"pipe",...na}),Qt(l,r),tn(l),D(),m(e,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})):Bt(i,o,l).then(()=>{Qt(l,r),tn(l),D(),m(e,200,{ok:!0,themeName:r,themePath:l,moduleCount:v()?.modules.length||0})}).catch(c=>{m(e,500,{error:c instanceof Error?c.message:String(c)})})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ra(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{path:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme path is required"});return}let o=s;if(Mt(o)||(o=_t(Pe,s)),!Mt(o)){m(e,400,{error:`Theme folder not found: ${s}`});return}let i=jd(o);Qt(o,i),tn(o),D(),m(e,200,{ok:!0,themeName:i,themePath:o,moduleCount:v()?.modules.length||0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function aa(t,e){j(t,n=>{try{if(Pt()){m(e,409,{error:"Cannot switch projects while AI is generating.",generating:!0});return}let{sessionId:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Session ID is required"});return}let o=zn(s);if(!o){m(e,404,{error:"Session not found"});return}m(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath,moduleCount:o.modules.length,messageCount:o.messages.length})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function la(t,e){j(t,n=>{try{let{apiKey:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"API key is required"});return}q({anthropicApiKey:s}),m(e,200,{ok:!0})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ca(t){let e=he();if(!e){m(t,200,{themes:[],error:"No HubSpot account connected"});return}(async()=>{let n=await Ho(e);if(n.length===0){m(t,200,{themes:[]});return}let s=[],o=n.map(async r=>{let l=r.path||r.name;try{let c=await Cn(e,`${l}/theme.json`);c&&!c.folder&&s.push({name:r.name,path:l})}catch{}});await Promise.all(o),s.sort((r,l)=>r.name.localeCompare(l.name));let i=ls(),a=new Set(i.map(r=>r.name));m(t,200,{themes:s.map(r=>({...r,existsLocally:a.has(r.name)}))})})().catch(n=>{m(t,200,{themes:[],error:n instanceof Error?n.message:String(n)})})}g();ot();ee();Se();import{existsSync as Dd,readFileSync as Ld,appendFileSync as Hd}from"fs";import{join as da}from"path";import{homedir as ua}from"os";ut();Z();var ln={data:{},ts:0},Gd=600*1e3,ma={"claude-code":[{id:"sonnet",label:"Claude Sonnet (default)"},{id:"opus",label:"Claude Opus"},{id:"haiku",label:"Claude Haiku"}],"codex-cli":[{id:"o4-mini",label:"o4 Mini (default)"},{id:"o3",label:"o3"},{id:"gpt-4o",label:"GPT-4o"}]};async function Ud(t){let e=await fetch("https://api.anthropic.com/v1/models",{headers:{"x-api-key":t,"anthropic-version":"2023-06-01"}});return e.ok?(await e.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 Wd(t){let e=await fetch("https://api.openai.com/v1/models",{headers:{Authorization:`Bearer ${t}`}});if(!e.ok)return[];let n=await e.json(),s=/^(gpt-4o|gpt-4o-mini|o[1-4](-mini)?|o[1-4]-pro)$/;return n.data.filter(o=>s.test(o.id)).sort((o,i)=>o.id.localeCompare(i.id)).map(o=>({id:o.id,label:o.id}))}async function Bd(t){let e=await fetch(`https://generativelanguage.googleapis.com/v1beta/models?key=${t}`);return e.ok?(await e.json()).models.filter(s=>s.name.includes("gemini-2")).map(s=>({id:s.name.replace("models/",""),label:s.displayName})):[]}async function Kd(){if(Date.now()-ln.ts<Gd&&Object.keys(ln.data).length>0)return ln.data;let t=P(),e={...ma},n=[],s=ge("anthropic-api",t);s&&n.push(Ud(s).then(a=>{a.length&&(e["anthropic-api"]=a)}).catch(()=>{}));let o=ge("openai-api",t);o&&n.push(Wd(o).then(a=>{a.length&&(e["openai-api"]=a)}).catch(()=>{}));let i=ge("gemini-api",t);return i&&n.push(Bd(i).then(a=>{a.length&&(e["gemini-api"]=a,e["gemini-cli"]=a)}).catch(()=>{})),await Promise.all(n),ln.data=e,ln.ts=Date.now(),e}function pa(t){let e=vn(),n=P(),s={aiEngine:n.aiEngine||null,claudeCodeModel:n.claudeCodeModel||null,anthropicApiModel:n.anthropicApiModel||null,openaiApiModel:n.openaiApiModel||null,hubspotUploadMode:n.hubspotUploadMode||"api",hubspotAccounts:(n.hubspotAccounts||[]).map(r=>({portalId:r.portalId,portalName:r.portalName,dataCenter:r.dataCenter})),activeHubSpotAccount:n.activeHubSpotAccount||null,enabledCLITools:n.enabledCLITools||[],agenticMode:n.agenticMode,agenticConcurrency:n.agenticConcurrency},o=kt().length,i=ls().length,a=St();Kd().then(r=>{m(t,200,{version:a,environment:e,config:s,models:r,sessionCount:o,localThemeCount:i})}).catch(()=>{m(t,200,{version:a,environment:e,config:s,models:ma,sessionCount:o,localThemeCount:i})})}function fa(t,e){j(t,n=>{try{let{engine:s,model:o}=JSON.parse(n);if(!["claude-code","anthropic-api","openai-api","gemini-cli","gemini-api","codex-cli"].includes(s)){m(e,400,{error:`Invalid engine: ${s}`});return}let a={aiEngine:s};if(o)switch(s){case"claude-code":a.claudeCodeModel=o;break;case"anthropic-api":a.anthropicApiModel=o;break;case"openai-api":a.openaiApiModel=o;break}q(a),m(e,200,{ok:!0,engine:s})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ga(t,e){j(t,n=>{try{let{provider:s,apiKey:o}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"provider is required"});return}if(!o){let l={};switch(s){case"anthropic":l.anthropicApiKey="";break;case"openai":l.openaiApiKey="";break;case"gemini":l.geminiApiKey="";break;default:m(e,400,{error:`Unknown provider: ${s}`});return}q(l),m(e,200,{ok:!0,provider:s,deleted:!0});return}let i={};switch(s){case"anthropic":i.anthropicApiKey=o;break;case"openai":i.openaiApiKey=o;break;case"gemini":i.geminiApiKey=o;break;default:m(e,400,{error:`Unknown provider: ${s}`});return}q(i);let a=null;if(!P().aiEngine){let c={anthropic:"anthropic-api",openai:"openai-api",gemini:"gemini-api"}[s];c&&(q({aiEngine:c}),a=c)}m(e,200,{ok:!0,provider:s,autoSelectedEngine:a})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ha(t,e){j(t,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){m(e,400,{error:`Unknown tool: ${s}. Valid: ${Object.keys(o).join(", ")}`});return}let a=ht(i.cmd,i.desc,{timeout:12e4});m(e,200,{ok:!0,jobId:a})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ya(t,e){j(t,n=>{try{let s=JSON.parse(n||"{}"),o=P(),i=o.hubspotUploadMode||"api";if(s.personalAccessKey)if(i==="api"){xn(s.personalAccessKey).then(a=>{Ot(s.personalAccessKey,a.portalId,a.portalName,a.dataCenter),m(e,200,{ok:!0,portalName:a.portalName,portalId:a.portalId,dataCenter:a.dataCenter})}).catch(a=>{m(e,400,{error:a instanceof Error?a.message:String(a)})});return}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=an("hs",["auth",`--pak=${s.personalAccessKey}`],"Authenticating with HubSpot",{timeout:3e4});m(e,200,{ok:!0,jobId:r});return}if(i==="api"){let a=o.hubspotAccounts||[];if(a.length>0&&!s.force){let r=a.find(l=>l.portalId===o.activeHubSpotAccount)||a[0];m(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed",needsInstall:!0});return}let r=Oe();if(r.authenticated&&!s.force){m(e,200,{ok:!0,alreadyAuthenticated:!0,portalName:r.portalName,portalId:r.portalId});return}}m(e,200,{needsKey:!0,instructions:"Create a personal access key in HubSpot",url:"https://app.hubspot.com/portal-recommend/l?slug=personal-access-key",steps:["Click the link above to open HubSpot","Select your account","Create a Personal Access Key with CMS permissions","Copy the key and paste it below"]})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ba(t,e){j(t,n=>{try{let s=JSON.parse(n||"{}");if(!xs().found){m(e,400,{error:"GitHub CLI not installed",needsInstall:!0});return}let i=Cs();if(i.authenticated&&!s.force){m(e,200,{ok:!0,alreadyAuthenticated:!0,username:i.username});return}if(s.token){let r=an("gh",["auth","login","--with-token"],"Authenticating with GitHub",{timeout:3e4,stdin:s.token});m(e,200,{ok:!0,jobId:r});return}let a=ht("gh auth login --web --git-protocol https","GitHub authentication (check your browser)",{timeout:3e5});m(e,200,{ok:!0,jobId:a,browserAuthRequired:!0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Sa(t,e){j(t,n=>{try{let{portalId:s,action:o}=JSON.parse(n);if((P().hubspotUploadMode||"api")==="api"){if(o==="remove"&&s){bs(s),m(e,200,{ok:!0});return}if(s){Ss(s),m(e,200,{ok:!0});return}}else{if(!Re().found){m(e,400,{error:"HubSpot CLI not installed"});return}let l=String(s).replace(/[^0-9]/g,"");if(!l){m(e,400,{error:"Invalid portalId"});return}if(o==="remove"){let c=an("hs",["accounts","remove",l],`Removing HubSpot account ${l}`,{timeout:15e3});m(e,200,{ok:!0,jobId:c});return}if(l){let c=an("hs",["accounts","use",l],`Switching to HubSpot account ${l}`,{timeout:15e3});m(e,200,{ok:!0,jobId:c});return}}m(e,400,{error:"portalId required"})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function va(t){let e=ht("gh auth logout --hostname github.com -y","Logging out of GitHub",{timeout:15e3});m(t,200,{ok:!0,jobId:e})}function wa(t,e){j(t,n=>{try{let{cli:s,apiKey:o}=JSON.parse(n||"{}");switch(s){case"claude":{let i=ht("CLAUDECODE= claude --print -p 'reply OK'","Authenticating Claude Code (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"If Claude Code opens a browser window, complete the sign-in there."});break}case"gemini":{let i=ht("gemini -p 'reply OK'","Authenticating Gemini CLI (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"If Gemini opens a browser window, complete the sign-in there."});break}case"codex":{if(o&&o.trim()){let i=o.trim();if(process.env.OPENAI_API_KEY=i,q({openaiApiKey:i}),process.platform!=="win32"){let a=/^[A-Za-z0-9_\-.:]+$/.test(i)?i:"";if(a){let r=`export OPENAI_API_KEY="${a}"`,l=process.env.SHELL?.includes("zsh")?da(ua(),".zshrc"):da(ua(),".bashrc");try{(Dd(l)?Ld(l,"utf-8"):"").includes("OPENAI_API_KEY")||Hd(l,`
|
|
1363
1363
|
# Added by vibeSpot
|
|
1364
1364
|
${r}
|
|
1365
|
-
`)}catch{}}}m(e,200,{ok:!0,message:"API key saved"})}else{let i=ht("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:m(e,400,{error:`Unknown CLI: ${s}`})}}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function ba(t,e){j(t,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){m(e,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}q({hubspotUploadMode:s}),m(e,200,{ok:!0,mode:s})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Sa(t,e){j(t,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){m(e,400,{error:"toolId (string) and enabled (boolean) required"});return}bs(s,o),m(e,200,{ok:!0,toolId:s,enabled:o})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function va(t,e){j(t,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency"],i={};for(let a of o)a in s&&(i[a]=s[a]);if(Object.keys(i).length===0){m(e,400,{error:"No valid settings fields provided"});return}q(i),m(e,200,{ok:!0,updated:Object.keys(i)})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function wa(t,e){let n=t.replace("/api/settings/job/","");if(!n){m(e,400,{error:"Job ID required"});return}let s=ss(n);if(!s){m(e,404,{error:"Job not found"});return}m(e,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}g();ot();Se();import{existsSync as Ud,rmSync as Wd}from"fs";import{join as Bd}from"path";function xa(t,e,n){if(t==="GET"){let s=v(),o=kt().sort((i,a)=>a.updatedAt-i.updatedAt);m(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName}:null,sessions:o});return}if(t==="DELETE"){j(e,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Ui(o,i),m(n,200,{ok:!0})}catch(o){m(n,500,{error:o instanceof Error?o.message:String(o)})}});return}m(n,405,{error:"Method not allowed"})}function Ca(t,e){j(t,n=>{try{let{sessionId:s}=JSON.parse(n),o=Vn(s);if(!o){m(e,404,{error:"Session not found"});return}m(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Aa(t,e){j(t,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=Bd(Me,s);if(!Ud(o)){m(e,404,{error:"Theme not found on disk"});return}Wd(o,{recursive:!0,force:!0}),m(e,200,{ok:!0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ia(t,e){j(t,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(e,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){m(e,400,{error:"Invalid name"});return}let a=Wi(s,i);a.ok?m(e,200,{ok:!0,newName:i}):m(e,400,{error:a.error})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}g();ot();ve();ee();Se();Z();import{existsSync as ms,readFileSync as eu,rmSync as So}from"fs";import{join as Ge,basename as tu}from"path";import{execFileSync as nu}from"child_process";var su=process.platform==="win32"?{shell:!0}:{};function Ma(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}let n=nt();m(t,200,{themeName:e.themeName,themePath:e.themePath,templates:e.templates.map(s=>({id:s.id,label:s.label,pageType:s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:e.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!e.brandAssets?.styleguide,hasBrandvoice:!!e.brandAssets?.brandvoice,hasThemeContext:!!e.brandAssets?.themeContext,humanify:e.brandAssets?.humanify!==!1}})}function Pa(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}let n=e.themePath;if(!ms(n)){m(t,404,{error:"Theme directory not found"});return}let s=e.themeName||"theme",o=Ge(n,".."),i=tu(n);try{let a=`${s}.zip`,r=Ge(o,a);ms(r)&&So(r),nu("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...su});let l=eu(r);So(r),t.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${a}"`,"Content-Length":l.length}),t.end(l)}catch(a){E.error("download-zip","Failed to create zip archive",a),m(t,500,{error:"Failed to create zip archive"})}}function _a(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){m(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(t==="POST"){j(e,o=>{try{let{pageType:i,label:a}=JSON.parse(o);if(!i||!a){m(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only"].includes(i)){m(n,400,{error:`Invalid pageType: ${i}`});return}let l=Ji(i,a);D(),m(n,200,{ok:!0,template:{id:l.id,label:l.label,pageType:l.pageType}})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){j(e,o=>{try{let{templateId:i}=JSON.parse(o);if(!i){m(n,400,{error:"templateId is required"});return}if(!Hi(i)){m(n,404,{error:"Template not found"});return}D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}m(n,405,{error:"Method not allowed"})}function Ra(t,e){j(t,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){m(e,400,{error:"templateId is required"});return}if(!Ns(s)){m(e,404,{error:"Template not found"});return}D();let i=v();m(e,200,{ok:!0,modules:me().map(a=>a.moduleName),messageCount:i?.messages.length||0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Oa(t,e){j(t,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(e,400,{error:"templateId and newLabel are required"});return}if(!Li(s,o.trim())){m(e,404,{error:"Template not found"});return}D(),m(e,200,{ok:!0,newLabel:o.trim()})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function ja(t,e){j(t,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){m(e,400,{error:"templateId is required"});return}let i=Di(s,o);if(!i){m(e,404,{error:"Template not found"});return}D(),m(e,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Fa(t){let e=nt();m(t,200,{modules:e.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Ja(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}j(e,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){m(n,400,{error:"moduleName is required"});return}let r=nt().find(d=>d.module.moduleName===i);if(!r){m(n,404,{error:`Module "${i}" not found in library`});return}let l={...r.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}})}function Da(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){m(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(t==="POST"){j(e,o=>{try{let{type:i,content:a}=JSON.parse(o);if(!i){m(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=a==="on",s.updatedAt=Date.now(),D(),m(n,200,{ok:!0});return}if(!a){m(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let r=i==="themeContext"?"theme-context.md":`${i}.md`;s.brandAssets[i]=a,s.updatedAt=Date.now();let l=Ge(s.themePath,".vibespot");Ae(l),H(Ge(l,r),a),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){j(e,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(n,400,{error:`Invalid type: ${i}`});return}s.brandAssets&&delete s.brandAssets[i],s.updatedAt=Date.now();let a=i==="themeContext"?"theme-context.md":`${i}.md`,r=Ge(s.themePath,".vibespot",a);ms(r)&&So(r),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}m(n,405,{error:"Method not allowed"})}function Ea(t,e,n){if(!t)return;t.brandAssets||(t.brandAssets={}),t.brandAssets[e]=n,t.updatedAt=Date.now();let s=e==="themeContext"?"theme-context.md":`${e}.md`,o=Ge(t.themePath,".vibespot");Ae(o),H(Ge(o,s),n)}async function Na(t,e,n){if(e==="styleguide"){let{extractDesignContext:p}=await Promise.resolve().then(()=>(us(),ds));return p(n||t.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(ns(),Kr)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),No)),i=o(),{engine:a,apiKey:r,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(zn(),Gs)),d=c();if(!d||d.length<50)return null;if(e==="brandvoice"){let{extractBrandvoice:p}=await Promise.resolve().then(()=>(Ta(),$a));return p(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(bo(),yo));return u(d,t.brandAssets?.themeContext,a,r,l)}function La(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",a=o.sourcePath;if(i==="all"){let l=["styleguide","brandvoice","themeContext"],c=await Promise.allSettled(l.map(u=>Na(n,u,a))),d={};for(let u=0;u<l.length;u++){let p=c[u],f=p.status==="fulfilled"?p.value:null;f&&Ea(n,l[u],f),d[l[u]]=f}D(),m(e,200,{ok:!0,type:"all",extracted:d});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(e,400,{error:`Invalid type: ${i}`});return}let r=await Na(n,i,a);if(!r){m(e,200,{ok:!1,type:i,error:"No content to extract from"});return}Ea(n,i,r),D(),m(e,200,{ok:!0,type:i,content:r})}catch(o){m(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}function Ha(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{(async()=>{try{let{source:o,themeName:i,localPath:a}=JSON.parse(s),r;if(o==="hubspot"){if(!i){m(e,400,{error:"themeName is required for HubSpot import"});return}let u=he();if(!u){m(e,400,{error:"No HubSpot account connected"});return}let p=i.replace(/^\/+|\/+$/g,"");if(!p){m(e,400,{error:"Invalid theme name"});return}let f=p.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),y=Ge(h(),"vibespot-themes",".references",f);Ae(y);let{fetchTheme:b}=await Promise.resolve().then(()=>($n(),Wo));await b(u,p,y),r=y}else if(o==="local"){if(!a){m(e,400,{error:"localPath is required for local import"});return}if(!ms(a)){m(e,400,{error:`Path not found: ${a}`});return}r=a}else{m(e,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(us(),ds)),c=await l(r);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ge(n.themePath,".vibespot");Ae(d),H(Ge(d,"styleguide.md"),c),D(),m(e,200,{ok:!0,styleguide:c,source:r})}catch(o){m(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}g();ot();Se();import{join as ou}from"path";Yt();function Ga(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}m(e,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function Ua(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){let o=me();m(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(t==="DELETE"){Zs(e,n,o=>{o.deleteEntirely?_i(o.moduleName):Ri(o.moduleName),D(),m(n,200,{ok:!0})});return}m(n,405,{error:"Method not allowed"})}function Wa(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{m(e,400,{error:"Invalid shared type"});return}let c=Ce();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),D(),st(),m(e,200,{ok:!0});return}let{moduleName:i,fileType:a,content:r}=o;if(!i||!a){m(e,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){m(e,404,{error:`Module "${i}" not found`});return}switch(a){case"html":l.moduleHtml=r;break;case"css":l.moduleCss=r;break;case"js":l.moduleJs=r||void 0;break;case"fields":try{JSON.parse(r)}catch{m(e,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=r;break;default:m(e,400,{error:`Invalid fileType: ${a}`});return}n.updatedAt=Date.now(),D(),st(),m(e,200,{ok:!0})}catch(o){m(e,400,{error:String(o)})}})}function Ba(t,e){Zs(t,e,n=>{Array.isArray(n.order)?(At(n.order),D(),m(e,200,{ok:!0})):m(e,400,{error:"order must be an array"})})}async function Ka(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}try{st();let n=Jn(e.themePath),s=os(`hs cms upload "${e.themePath}" "${e.themeName}"`,"Uploading to HubSpot",{cwd:ou(e.themePath,".."),timeout:18e4});m(t,200,{ok:!0,jobId:s,fixes:n})}catch(n){m(t,500,{error:String(n)})}}function Va(t,e){j(t,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Oi(s,o,i),D(),m(e,200,{ok:!0})}catch(s){m(e,400,{error:String(s)})}})}function Ya(t,e){j(t,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"url is required"});return}let o=Go(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
|
|
1365
|
+
`)}catch{}}}m(e,200,{ok:!0,message:"API key saved"})}else{let i=ht("codex login","Authenticating Codex CLI (check your browser if prompted)",{timeout:12e4});m(e,200,{ok:!0,jobId:i,hint:"Complete the sign-in in your browser."})}break}default:m(e,400,{error:`Unknown CLI: ${s}`})}}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function xa(t,e){j(t,n=>{try{let{mode:s}=JSON.parse(n);if(s!=="api"&&s!=="cli"){m(e,400,{error:`Invalid mode: ${s}. Must be "api" or "cli".`});return}q({hubspotUploadMode:s}),m(e,200,{ok:!0,mode:s})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Ca(t,e){j(t,n=>{try{let{toolId:s,enabled:o}=JSON.parse(n);if(!s||typeof o!="boolean"){m(e,400,{error:"toolId (string) and enabled (boolean) required"});return}vs(s,o),m(e,200,{ok:!0,toolId:s,enabled:o})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Aa(t,e){j(t,n=>{try{let s=JSON.parse(n),o=["agenticMode","agenticConcurrency"],i={};for(let a of o)a in s&&(i[a]=s[a]);if(Object.keys(i).length===0){m(e,400,{error:"No valid settings fields provided"});return}q(i),m(e,200,{ok:!0,updated:Object.keys(i)})}catch(s){m(e,400,{error:s instanceof Error?s.message:String(s)})}})}function Ia(t,e){let n=t.replace("/api/settings/job/","");if(!n){m(e,400,{error:"Job ID required"});return}let s=is(n);if(!s){m(e,404,{error:"Job not found"});return}m(e,200,{id:s.id,status:s.status,description:s.description,output:s.output,exitCode:s.exitCode,startedAt:s.startedAt,completedAt:s.completedAt})}g();ot();Se();import{existsSync as Vd,rmSync as Yd}from"fs";import{join as zd}from"path";function ka(t,e,n){if(t==="GET"){let s=v(),o=kt().sort((i,a)=>a.updatedAt-i.updatedAt);m(n,200,{activeTheme:s?{id:s.id,themeName:s.themeName}:null,sessions:o});return}if(t==="DELETE"){j(e,s=>{try{let{sessionId:o,deleteFiles:i}=JSON.parse(s);Vi(o,i),m(n,200,{ok:!0})}catch(o){m(n,500,{error:o instanceof Error?o.message:String(o)})}});return}m(n,405,{error:"Method not allowed"})}function $a(t,e){j(t,n=>{try{let{sessionId:s}=JSON.parse(n),o=zn(s);if(!o){m(e,404,{error:"Session not found"});return}m(e,200,{ok:!0,themeName:o.themeName,themePath:o.themePath})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ta(t,e){j(t,n=>{try{let{themeName:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"Theme name is required"});return}let o=zd(Pe,s);if(!Vd(o)){m(e,404,{error:"Theme not found on disk"});return}Yd(o,{recursive:!0,force:!0}),m(e,200,{ok:!0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ea(t,e){j(t,n=>{try{let{sessionId:s,newName:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(e,400,{error:"sessionId and newName are required"});return}let i=o.toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/^-|-$/g,"").replace(/-{2,}/g,"-");if(!i){m(e,400,{error:"Invalid name"});return}let a=Yi(s,i);a.ok?m(e,200,{ok:!0,newName:i}):m(e,400,{error:a.error})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}g();ot();ve();ee();Se();Z();import{existsSync as fs,readFileSync as ou,rmSync as xo}from"fs";import{join as Ge,basename as iu}from"path";import{execFileSync as ru}from"child_process";var au=process.platform==="win32"?{shell:!0}:{};function Oa(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}let n=nt();m(t,200,{themeName:e.themeName,themePath:e.themePath,templates:e.templates.map(s=>({id:s.id,label:s.label,pageType:s.pageType,moduleCount:s.modules.length,messageCount:s.messages.length})),activeTemplateId:e.activeTemplateId,moduleLibrary:n.map(s=>({moduleName:s.module.moduleName,usedIn:s.usedIn})),brandAssets:{hasStyleguide:!!e.brandAssets?.styleguide,hasBrandvoice:!!e.brandAssets?.brandvoice,hasThemeContext:!!e.brandAssets?.themeContext,humanify:e.brandAssets?.humanify!==!1}})}function ja(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}let n=e.themePath;if(!fs(n)){m(t,404,{error:"Theme directory not found"});return}let s=e.themeName||"theme",o=Ge(n,".."),i=iu(n);try{let a=`${s}.zip`,r=Ge(o,a);fs(r)&&xo(r),ru("zip",["-r",a,i,"-x",`${i}/.git/*`,`${i}/.vibespot/*`,`${i}/node_modules/*`],{cwd:o,timeout:3e4,...au});let l=ou(r);xo(r),t.writeHead(200,{"Content-Type":"application/zip","Content-Disposition":`attachment; filename="${a}"`,"Content-Length":l.length}),t.end(l)}catch(a){E.error("download-zip","Failed to create zip archive",a),m(t,500,{error:"Failed to create zip archive"})}}function Fa(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){m(n,200,{templates:s.templates.map(o=>({id:o.id,label:o.label,pageType:o.pageType,moduleCount:o.modules.length})),activeTemplateId:s.activeTemplateId});return}if(t==="POST"){j(e,o=>{try{let{pageType:i,label:a}=JSON.parse(o);if(!i||!a){m(n,400,{error:"pageType and label are required"});return}if(!["landing_page","blog_post","website_page","module_only"].includes(i)){m(n,400,{error:`Invalid pageType: ${i}`});return}let l=Gi(i,a);D(),m(n,200,{ok:!0,template:{id:l.id,label:l.label,pageType:l.pageType}})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){j(e,o=>{try{let{templateId:i,deleteModules:a}=JSON.parse(o);if(!i){m(n,400,{error:"templateId is required"});return}if(!Bi(i,!!a)){m(n,404,{error:"Template not found"});return}D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}m(n,405,{error:"Method not allowed"})}function Ja(t,e){j(t,n=>{try{let{templateId:s}=JSON.parse(n);if(!s){m(e,400,{error:"templateId is required"});return}if(!_s(s)){m(e,404,{error:"Template not found"});return}D();let i=v();m(e,200,{ok:!0,modules:me().map(a=>a.moduleName),messageCount:i?.messages.length||0})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Da(t,e){j(t,n=>{try{let{templateId:s,newLabel:o}=JSON.parse(n);if(!s||!o||typeof o!="string"){m(e,400,{error:"templateId and newLabel are required"});return}if(!Wi(s,o.trim())){m(e,404,{error:"Template not found"});return}D(),m(e,200,{ok:!0,newLabel:o.trim()})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function La(t,e){j(t,n=>{try{let{templateId:s,label:o}=JSON.parse(n);if(!s){m(e,400,{error:"templateId is required"});return}let i=Ui(s,o);if(!i){m(e,404,{error:"Template not found"});return}D(),m(e,200,{ok:!0,template:{id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Ha(t){let e=nt();m(t,200,{modules:e.map(n=>({moduleName:n.module.moduleName,usedIn:n.usedIn,fieldsJson:n.module.fieldsJson}))})}function Ga(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}j(e,o=>{try{let{moduleName:i}=JSON.parse(o);if(!i){m(n,400,{error:"moduleName is required"});return}let r=nt().find(d=>d.module.moduleName===i);if(!r){m(n,404,{error:`Module "${i}" not found in library`});return}let l={...r.module};s.modules.find(d=>d.moduleName===l.moduleName)||(s.modules.push(l),s.moduleOrder.push(l.moduleName),s.updatedAt=Date.now()),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}})}function Ua(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){m(n,200,{styleguide:s.brandAssets?.styleguide||null,brandvoice:s.brandAssets?.brandvoice||null,themeContext:s.brandAssets?.themeContext||null});return}if(t==="POST"){j(e,o=>{try{let{type:i,content:a}=JSON.parse(o);if(!i){m(n,400,{error:"type is required"});return}if(s.brandAssets||(s.brandAssets={}),i==="humanify"){s.brandAssets.humanify=a==="on",s.updatedAt=Date.now(),D(),m(n,200,{ok:!0});return}if(!a){m(n,400,{error:"content is required"});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(n,400,{error:`Invalid type: ${i}. Must be "styleguide", "brandvoice", or "themeContext"`});return}let r=i==="themeContext"?"theme-context.md":`${i}.md`;s.brandAssets[i]=a,s.updatedAt=Date.now();let l=Ge(s.themePath,".vibespot");Ae(l),H(Ge(l,r),a),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}if(t==="DELETE"){j(e,o=>{try{let{type:i}=JSON.parse(o);if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(n,400,{error:`Invalid type: ${i}`});return}s.brandAssets&&delete s.brandAssets[i],s.updatedAt=Date.now();let a=i==="themeContext"?"theme-context.md":`${i}.md`,r=Ge(s.themePath,".vibespot",a);fs(r)&&xo(r),D(),m(n,200,{ok:!0})}catch(i){m(n,500,{error:i instanceof Error?i.message:String(i)})}});return}m(n,405,{error:"Method not allowed"})}function _a(t,e,n){if(!t)return;t.brandAssets||(t.brandAssets={}),t.brandAssets[e]=n,t.updatedAt=Date.now();let s=e==="themeContext"?"theme-context.md":`${e}.md`,o=Ge(t.themePath,".vibespot");Ae(o),H(Ge(o,s),n)}async function Ra(t,e,n){if(e==="styleguide"){let{extractDesignContext:p}=await Promise.resolve().then(()=>(ps(),ms));return p(n||t.themePath)}let{resolveAgenticEngine:s}=await Promise.resolve().then(()=>(os(),qr)),{loadConfig:o}=await Promise.resolve().then(()=>(ee(),_o)),i=o(),{engine:a,apiKey:r,model:l}=s(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Xn(),Bs)),d=c();if(!d||d.length<50)return null;if(e==="brandvoice"){let{extractBrandvoice:p}=await Promise.resolve().then(()=>(Ma(),Pa));return p(d,a,r,l)}let{extractThemeContext:u}=await Promise.resolve().then(()=>(wo(),vo));return u(d,t.brandAssets?.themeContext,a,r,l)}function Wa(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{(async()=>{try{let o=s?JSON.parse(s):{},i=o.type||"styleguide",a=o.sourcePath;if(i==="all"){let l=["styleguide","brandvoice","themeContext"],c=await Promise.allSettled(l.map(u=>Ra(n,u,a))),d={};for(let u=0;u<l.length;u++){let p=c[u],f=p.status==="fulfilled"?p.value:null;f&&_a(n,l[u],f),d[l[u]]=f}D(),m(e,200,{ok:!0,type:"all",extracted:d});return}if(i!=="styleguide"&&i!=="brandvoice"&&i!=="themeContext"){m(e,400,{error:`Invalid type: ${i}`});return}let r=await Ra(n,i,a);if(!r){m(e,200,{ok:!1,type:i,error:"No content to extract from"});return}_a(n,i,r),D(),m(e,200,{ok:!0,type:i,content:r})}catch(o){m(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}function Ba(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{(async()=>{try{let{source:o,themeName:i,localPath:a}=JSON.parse(s),r;if(o==="hubspot"){if(!i){m(e,400,{error:"themeName is required for HubSpot import"});return}let u=he();if(!u){m(e,400,{error:"No HubSpot account connected"});return}let p=i.replace(/^\/+|\/+$/g,"");if(!p){m(e,400,{error:"Invalid theme name"});return}let f=p.replace(/[@/]/g,"_").replace(/_+/g,"_"),{homedir:h}=await import("os"),y=Ge(h(),"vibespot-themes",".references",f);Ae(y);let{fetchTheme:b}=await Promise.resolve().then(()=>(Tn(),Vo));await b(u,p,y),r=y}else if(o==="local"){if(!a){m(e,400,{error:"localPath is required for local import"});return}if(!fs(a)){m(e,400,{error:`Path not found: ${a}`});return}r=a}else{m(e,400,{error:"source must be 'hubspot' or 'local'"});return}let{extractDesignContext:l}=await Promise.resolve().then(()=>(ps(),ms)),c=await l(r);n.brandAssets||(n.brandAssets={}),n.brandAssets.styleguide=c,n.updatedAt=Date.now();let d=Ge(n.themePath,".vibespot");Ae(d),H(Ge(d,"styleguide.md"),c),D(),m(e,200,{ok:!0,styleguide:c,source:r})}catch(o){m(e,500,{error:o instanceof Error?o.message:String(o)})}})()})}g();ot();Se();import{join as lu}from"path";Yt();function Ka(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}m(e,200,{id:n.id,themeName:n.themeName,themePath:n.themePath,messageCount:n.messages.length,moduleCount:n.modules.length,moduleOrder:n.moduleOrder})}function Va(t,e,n){let s=v();if(!s){m(n,404,{error:"No active session"});return}if(t==="GET"){let o=me();m(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(t==="DELETE"){no(e,n,o=>{o.deleteEntirely?Fi(o.moduleName):Ji(o.moduleName),D(),m(n,200,{ok:!0})});return}m(n,405,{error:"Method not allowed"})}function Ya(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}j(t,s=>{try{let o=JSON.parse(s);if(o.shared){if(o.shared==="css")n.sharedCss=o.content;else if(o.shared==="js")n.sharedJs=o.content;else{m(e,400,{error:"Invalid shared type"});return}let c=Ce();c&&(o.shared==="css"?c.sharedCss=o.content:c.sharedJs=o.content),n.updatedAt=Date.now(),D(),st(),m(e,200,{ok:!0});return}let{moduleName:i,fileType:a,content:r}=o;if(!i||!a){m(e,400,{error:"moduleName and fileType required"});return}let l=n.modules.find(c=>c.moduleName===i);if(!l){m(e,404,{error:`Module "${i}" not found`});return}switch(a){case"html":l.moduleHtml=r;break;case"css":l.moduleCss=r;break;case"js":l.moduleJs=r||void 0;break;case"fields":try{JSON.parse(r)}catch{m(e,400,{error:"Invalid JSON in fields.json"});return}l.fieldsJson=r;break;default:m(e,400,{error:`Invalid fileType: ${a}`});return}n.updatedAt=Date.now(),D(),st(),m(e,200,{ok:!0})}catch(o){m(e,400,{error:String(o)})}})}function za(t,e){no(t,e,n=>{Array.isArray(n.order)?(At(n.order),D(),m(e,200,{ok:!0})):m(e,400,{error:"order must be an array"})})}async function qa(t){let e=v();if(!e){m(t,404,{error:"No active session"});return}try{st();let n=Dn(e.themePath),s=rs(`hs cms upload "${e.themePath}" "${e.themeName}"`,"Uploading to HubSpot",{cwd:lu(e.themePath,".."),timeout:18e4});m(t,200,{ok:!0,jobId:s,fixes:n})}catch(n){m(t,500,{error:String(n)})}}function Xa(t,e){j(t,n=>{try{let{moduleName:s,fieldPath:o,value:i}=JSON.parse(n);Di(s,o,i),D(),m(e,200,{ok:!0})}catch(s){m(e,400,{error:String(s)})}})}function Qa(t,e){j(t,n=>{try{let{url:s}=JSON.parse(n);if(!s||typeof s!="string"){m(e,400,{error:"url is required"});return}let o=Bo(s),i=o.components.map(r=>`- ${r.name}: ${r.description}`).join(`
|
|
1366
1366
|
`),a={sourceDir:o.sourceDir,componentCount:o.components.length,components:o.components.map(r=>({name:r.name,description:r.description})),hasTailwind:o.hasTailwind,cssVarCount:o.cssVarCount,fonts:o.fonts,interactions:o.interactions,conversionPrompt:`Import and convert the React landing page from ${s} to native HubSpot modules.
|
|
1367
1367
|
|
|
1368
1368
|
Source analysis found ${o.components.length} components:
|
|
@@ -1372,11 +1372,11 @@ Design system: ${o.hasTailwind?"Tailwind CSS":"Custom CSS"}, ${o.cssVarCount} CS
|
|
|
1372
1372
|
Fonts: ${o.fonts.length>0?o.fonts.join(", "):"System fonts"}
|
|
1373
1373
|
Interactions: ${o.interactions.join(", ")}
|
|
1374
1374
|
|
|
1375
|
-
Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};m(e,200,a)}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function za(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}if(!Ee()){m(e,200,{available:!1,commits:[]});return}let o=new URL(t.url||"/","http://localhost").searchParams.get("templateId"),i=o?Ei(n.themePath,o,50):Ti(n.themePath,50);m(e,200,{available:!0,commits:i,filtered:!!o})}function qa(t,e){j(t,n=>{try{let s=v();if(!s){m(e,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){m(e,400,{error:"Commit hash is required"});return}if(tt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let a=s.templates.find(c=>c.id===i);if(!a){m(e,404,{error:"Template not found"});return}let r=a.moduleOrder.map(c=>`modules/${c}.module`);a.templateFile&&r.push(a.templateFile);let l=Mi(s.themePath,i,o,r);if(!l.success){m(e,500,{error:l.error||"Rollback failed"});return}Yi()}else{let a=Ni(s.themePath,o);if(!a.success){m(e,500,{error:a.error||"Rollback failed"});return}Vi()}D(),m(e,200,{ok:!0,modules:me().map(a=>a.moduleName)})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}no();var Za={".html":"text/html",".css":"text/css",".js":"application/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".ico":"image/x-icon",".woff2":"font/woff2"};function el(t){let{port:e,uiDir:n}=t,s=iu((i,a)=>lu(i,a,n)),o=new au({server:s});return o.on("connection",i=>du(i)),new Promise((i,a)=>{s.on("error",r=>{r.code==="EADDRINUSE"?s.listen(e+1,()=>{i({port:e+1,close:()=>{s.close(),o.close()}})}):a(r)}),s.listen(e,()=>{i({port:e,close:()=>{s.close(),o.close()}})})})}function lu(t,e,n){let s=new URL(t.url||"/",`http://${t.headers.host}`),o=t.method||"GET";if(e.setHeader("X-Content-Type-Options","nosniff"),e.setHeader("X-Frame-Options","DENY"),e.setHeader("X-XSS-Protection","1; mode=block"),e.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname.startsWith("/api/")){cu(o,s.pathname,t,e);return}if(s.pathname==="/preview"){let i=Ls();e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",a=Hs(i);e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(a||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){uu(s.pathname.slice(14),e);return}mu(s.pathname,n,t,e)}function cu(t,e,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(o)&&s.setHeader("Access-Control-Allow-Origin",o),s.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type"),t==="OPTIONS"){s.writeHead(204),s.end();return}switch(e){case"/api/session":Ga(t,s);break;case"/api/modules":Ua(t,n,s);break;case"/api/modules/reorder":Ba(n,s);break;case"/api/modules/code":Wa(n,s);break;case"/api/upload":Ka(s);break;case"/api/upload-files":t==="POST"?hr(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/field":Va(n,s);break;case"/api/import":Ya(n,s);break;case"/api/setup":Zr(s);break;case"/api/setup/create":ea(n,s);break;case"/api/setup/fetch":ta(n,s);break;case"/api/setup/open":na(n,s);break;case"/api/setup/resume":sa(n,s);break;case"/api/setup/apikey":oa(n,s);break;case"/api/setup/remote-themes":t==="GET"?ia(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/status":t==="GET"?ca(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":t==="POST"?da(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":t==="POST"?ua(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/install":t==="POST"?ma(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":t==="POST"?pa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":t==="POST"?fa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":t==="POST"?ga(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":t==="POST"?ha(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":t==="POST"?ya(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":t==="POST"?ba(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":t==="POST"?Sa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings":t==="POST"?va(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/changelog":t==="GET"?m(s,200,{changelog:Io()}):m(s,405,{error:"Method not allowed"});break;case"/api/themes":xa(t,n,s);break;case"/api/themes/switch":t==="POST"?Ca(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":t==="POST"?Aa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":t==="POST"?Ia(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/history":t==="GET"?za(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/rollback":t==="POST"?qa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/dashboard":t==="GET"?Ma(s):m(s,405,{error:"Method not allowed"});break;case"/api/templates":_a(t,n,s);break;case"/api/templates/activate":t==="POST"?Ra(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":t==="POST"?Oa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":t==="POST"?ja(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/module-library":t==="GET"?Fa(s):m(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":Da(t,n,s);break;case"/api/brand-assets/extract":t==="POST"?La(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":t==="POST"?Ha(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/download-zip":t==="GET"?Pa(s):m(s,405,{error:"Method not allowed"});break;default:e.startsWith("/api/settings/job/")&&t==="GET"?wa(e,s):e.match(/^\/api\/templates\/[^/]+\/add-module$/)&&t==="POST"?Ja(e,n,s):m(s,404,{error:"Not found"})}}function du(t){t.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{t.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;tt("user",o),D();let i=Array.isArray(s.fileIds)?s.fileIds:void 0,a=po();a.needsPrompt&&t.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await uo(o,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:p,...f}=u;t.send(JSON.stringify(f))}else t.send(JSON.stringify(u));if(u.type==="agent_step")l.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let p=l[l.length-1];p&&(p.decisions||(p.decisions=[]),p.decisions.push(u.decision))}else u.type==="design_system_ready"?De({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(De({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),At(u.moduleOrder),t.send(JSON.stringify({type:"modules_updated",modules:me().map(p=>p.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(De({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),t.send(JSON.stringify({type:"modules_updated",modules:me().map(p=>p.moduleName)})),c.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&c.push({name:u.module,status:"failed"})},i);mo(d,{steps:l,modules:c,stats:d.stats})}else lo(l=>{t.send(JSON.stringify({type:"parse_warning",message:l}))}),await on(o,l=>{t.send(JSON.stringify({type:"stream",content:l}))},l=>{t.send(JSON.stringify({type:"stream_status",content:l}))},i);let r=v();if(r){st();let l=Ce(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${r.themeName}-theme.css`),l.sharedJs&&d.push(`js/${r.themeName}-animations.js`),c=$i(r.themePath,l.id,o,d)}else c=Ts(r.themePath,o);c&&t.send(JSON.stringify({type:"version_created",hash:c}))}t.send(JSON.stringify({type:"generation_complete"})),t.send(JSON.stringify({type:"modules_updated",modules:me().map(l=>l.moduleName)}));{let l=v();l&&a.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&t.send(JSON.stringify({type:"suggest_brand_extraction"}))}}catch(r){t.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"extract_brand_assets":{let o=v();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=M(),{engine:a,apiKey:r,model:l}=ts(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(zn(),Gs)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(bo(),yo)),p=await u(d,o.brandAssets?.themeContext,a,r,l),{mkdirSync:f,writeFileSync:h}=await import("fs");if(p){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=p,o.updatedAt=Date.now();let y=at(o.themePath,".vibespot");cn(y)||f(y,{recursive:!0}),h(at(y,"theme-context.md"),p),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:y}=await Promise.resolve().then(()=>(us(),ds)),b=await y(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let A=at(o.themePath,".vibespot");cn(A)||f(A,{recursive:!0}),h(at(A,"styleguide.md"),b),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}t.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){t.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=v();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}try{st();let i=Jn(o.themePath);if(i.length>0&&t.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(M().hubspotUploadMode||"api")==="api"){let l=he();if(!l){t.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}t.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await Dn(l,o.themePath,o.themeName,{onFileStart:d=>{t.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
|
|
1375
|
+
Read the React source files from ${o.sourceDir} and convert each component to a HubSpot module. Preserve the design, layout, colors, and content. Generate fields.json so marketers can edit all text, images, colors, and links in the HubSpot page editor.`};m(e,200,a)}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}function Za(t,e){let n=v();if(!n){m(e,404,{error:"No active session"});return}if(!Ee()){m(e,200,{available:!1,commits:[]});return}let o=new URL(t.url||"/","http://localhost").searchParams.get("templateId"),i=o?Mi(n.themePath,o,50):Pi(n.themePath,50);m(e,200,{available:!0,commits:i,filtered:!!o})}function el(t,e){j(t,n=>{try{let s=v();if(!s){m(e,404,{error:"No active session"});return}let{hash:o,templateId:i}=JSON.parse(n);if(!o||typeof o!="string"){m(e,400,{error:"Commit hash is required"});return}if(tt("assistant",`Rolled back to version ${o.slice(0,7)}.`),i){let a=s.templates.find(c=>c.id===i);if(!a){m(e,404,{error:"Template not found"});return}let r=a.moduleOrder.map(c=>`modules/${c}.module`);a.templateFile&&r.push(a.templateFile);let l=Ri(s.themePath,i,o,r);if(!l.success){m(e,500,{error:l.error||"Rollback failed"});return}Qi()}else{let a=_i(s.themePath,o);if(!a.success){m(e,500,{error:a.error||"Rollback failed"});return}Xi()}D(),m(e,200,{ok:!0,modules:me().map(a=>a.moduleName)})}catch(s){m(e,500,{error:s instanceof Error?s.message:String(s)})}})}io();var sl={".html":"text/html",".css":"text/css",".js":"application/javascript",".json":"application/json",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".ico":"image/x-icon",".woff2":"font/woff2"};function ol(t){let{port:e,uiDir:n}=t,s=cu((i,a)=>mu(i,a,n)),o=new uu({server:s});return o.on("connection",i=>fu(i)),new Promise((i,a)=>{s.on("error",r=>{r.code==="EADDRINUSE"?s.listen(e+1,()=>{i({port:e+1,close:()=>{s.close(),o.close()}})}):a(r)}),s.listen(e,()=>{i({port:e,close:()=>{s.close(),o.close()}})})})}function mu(t,e,n){let s=new URL(t.url||"/",`http://${t.headers.host}`),o=t.method||"GET";if(e.setHeader("X-Content-Type-Options","nosniff"),e.setHeader("X-Frame-Options","DENY"),e.setHeader("X-XSS-Protection","1; mode=block"),e.setHeader("Referrer-Policy","strict-origin-when-cross-origin"),s.pathname.startsWith("/api/")){pu(o,s.pathname,t,e);return}if(s.pathname==="/preview"){let i=Us();e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(i);return}if(s.pathname==="/module-preview"){let i=s.searchParams.get("module")||"",a=Ws(i);e.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),e.end(a||"<!-- module not found -->");return}if(s.pathname.startsWith("/theme-assets/")){gu(s.pathname.slice(14),e);return}hu(s.pathname,n,t,e)}function pu(t,e,n,s){let o=n.headers.origin||"";if(/^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/.test(o)&&s.setHeader("Access-Control-Allow-Origin",o),s.setHeader("Access-Control-Allow-Methods","GET, POST, PUT, DELETE, OPTIONS"),s.setHeader("Access-Control-Allow-Headers","Content-Type"),t==="OPTIONS"){s.writeHead(204),s.end();return}switch(e){case"/api/session":Ka(t,s);break;case"/api/modules":Va(t,n,s);break;case"/api/modules/reorder":za(n,s);break;case"/api/modules/code":Ya(n,s);break;case"/api/upload":qa(s);break;case"/api/upload-files":t==="POST"?vr(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/field":Xa(n,s);break;case"/api/import":Qa(n,s);break;case"/api/setup":sa(s);break;case"/api/setup/create":oa(n,s);break;case"/api/setup/fetch":ia(n,s);break;case"/api/setup/open":ra(n,s);break;case"/api/setup/resume":aa(n,s);break;case"/api/setup/apikey":la(n,s);break;case"/api/setup/remote-themes":t==="GET"?ca(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/status":t==="GET"?pa(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/engine":t==="POST"?fa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/apikey":t==="POST"?ga(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/install":t==="POST"?ha(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-auth":t==="POST"?ya(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-auth":t==="POST"?ba(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-switch":t==="POST"?Sa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/gh-logout":t==="POST"?va(s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-auth":t==="POST"?wa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/hs-mode":t==="POST"?xa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings/cli-toggle":t==="POST"?Ca(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/settings":t==="POST"?Aa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/changelog":t==="GET"?m(s,200,{changelog:To()}):m(s,405,{error:"Method not allowed"});break;case"/api/themes":ka(t,n,s);break;case"/api/themes/switch":t==="POST"?$a(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/themes/delete-local":t==="POST"?Ta(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/themes/rename":t==="POST"?Ea(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/history":t==="GET"?Za(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/rollback":t==="POST"?el(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/dashboard":t==="GET"?Oa(s):m(s,405,{error:"Method not allowed"});break;case"/api/templates":Fa(t,n,s);break;case"/api/templates/activate":t==="POST"?Ja(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/templates/rename":t==="POST"?Da(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/templates/clone":t==="POST"?La(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/module-library":t==="GET"?Ha(s):m(s,405,{error:"Method not allowed"});break;case"/api/brand-assets":Ua(t,n,s);break;case"/api/brand-assets/extract":t==="POST"?Wa(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/brand-assets/import-reference":t==="POST"?Ba(n,s):m(s,405,{error:"Method not allowed"});break;case"/api/download-zip":t==="GET"?ja(s):m(s,405,{error:"Method not allowed"});break;default:e.startsWith("/api/settings/job/")&&t==="GET"?Ia(e,s):e.match(/^\/api\/templates\/[^/]+\/add-module$/)&&t==="POST"?Ga(e,n,s):m(s,404,{error:"Not found"})}}function fu(t){t.on("message",async n=>{let s;try{s=JSON.parse(n.toString())}catch{t.send(JSON.stringify({type:"error",message:"Invalid JSON"}));return}switch(s.type){case"chat":{let o=String(s.message||"");if(!o.trim())return;tt("user",o),D();let i=Array.isArray(s.fileIds)?s.fileIds:void 0,a=ho();a.needsPrompt&&t.send(JSON.stringify({type:"agentic_prompt"}));try{if(a.useAgentic){let l=[],c=[],d=await fo(o,u=>{if(u.type==="module_progress"&&u.moduleFiles){let{moduleFiles:p,...f}=u;t.send(JSON.stringify(f))}else t.send(JSON.stringify(u));if(u.type==="agent_step")l.push({step:u.step,label:u.label});else if(u.type==="agent_decision"){let p=l[l.length-1];p&&(p.decisions||(p.decisions=[]),p.decisions.push(u.decision))}else u.type==="design_system_ready"?De({sharedCss:u.sharedCss,sharedJs:u.sharedJs}):u.type==="blueprint_ready"?(De({sharedCss:u.sharedCss,sharedJs:u.sharedJs}),At(u.moduleOrder),t.send(JSON.stringify({type:"modules_updated",modules:me().map(p=>p.moduleName)}))):u.type==="module_progress"&&u.status==="complete"&&u.moduleFiles?(De({modules:[{moduleName:u.module,fieldsJson:u.moduleFiles.fieldsJson,metaJson:u.moduleFiles.metaJson,moduleHtml:u.moduleFiles.moduleHtml,moduleCss:u.moduleFiles.moduleCss,moduleJs:u.moduleFiles.moduleJs}]}),t.send(JSON.stringify({type:"modules_updated",modules:me().map(p=>p.moduleName)})),c.push({name:u.module,status:"complete"})):u.type==="module_progress"&&u.status==="failed"&&c.push({name:u.module,status:"failed"})},i);go(d,{steps:l,modules:c,stats:d.stats})}else mo(l=>{t.send(JSON.stringify({type:"parse_warning",message:l}))}),await rn(o,l=>{t.send(JSON.stringify({type:"stream",content:l}))},l=>{t.send(JSON.stringify({type:"stream_status",content:l}))},i);let r=v();if(r){st();let l=Ce(),c=null;if(l){let d=l.moduleOrder.map(u=>`modules/${u}.module`);l.templateFile&&d.push(l.templateFile),l.sharedCss&&d.push(`css/${r.themeName}-theme.css`),l.sharedJs&&d.push(`js/${r.themeName}-animations.js`),c=Ni(r.themePath,l.id,o,d)}else c=Ns(r.themePath,o);c&&t.send(JSON.stringify({type:"version_created",hash:c}))}t.send(JSON.stringify({type:"generation_complete"})),t.send(JSON.stringify({type:"modules_updated",modules:me().map(l=>l.moduleName)}));{let l=v();l&&a.useAgentic&&!l.brandAssets?.styleguide&&!l.brandAssets?.brandvoice&&!l.brandAssets?.themeContext&&t.send(JSON.stringify({type:"suggest_brand_extraction"}))}}catch(r){t.send(JSON.stringify({type:"error",message:r instanceof Error?r.message:String(r)}))}break}case"extract_brand_assets":{let o=v();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}(async()=>{try{let i=P(),{engine:a,apiKey:r,model:l}=ss(i),{buildPreviewHtml:c}=await Promise.resolve().then(()=>(Xn(),Bs)),d=c();if(!d||d.length<50)return;let{extractThemeContext:u}=await Promise.resolve().then(()=>(wo(),vo)),p=await u(d,o.brandAssets?.themeContext,a,r,l),{mkdirSync:f,writeFileSync:h}=await import("fs");if(p){o.brandAssets||(o.brandAssets={}),o.brandAssets.themeContext=p,o.updatedAt=Date.now();let y=at(o.themePath,".vibespot");dn(y)||f(y,{recursive:!0}),h(at(y,"theme-context.md"),p),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"themeContext"}))}if(!o.brandAssets?.styleguide)try{let{extractDesignContext:y}=await Promise.resolve().then(()=>(ps(),ms)),b=await y(o.themePath);if(b){o.brandAssets||(o.brandAssets={}),o.brandAssets.styleguide=b,o.updatedAt=Date.now();let A=at(o.themePath,".vibespot");dn(A)||f(A,{recursive:!0}),h(at(A,"styleguide.md"),b),D(),t.send(JSON.stringify({type:"brand_asset_extracted",assetType:"styleguide"}))}}catch{}t.send(JSON.stringify({type:"brand_extraction_complete"}))}catch(i){t.send(JSON.stringify({type:"brand_extraction_error",message:i instanceof Error?i.message:String(i)}))}})();break}case"start_upload":{let o=v();if(!o){t.send(JSON.stringify({type:"error",message:"No active session"}));break}try{st();let i=Dn(o.themePath);if(i.length>0&&t.send(JSON.stringify({type:"upload_status",phase:"autofix",fixes:i})),(P().hubspotUploadMode||"api")==="api"){let l=he();if(!l){t.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}t.send(JSON.stringify({type:"upload_started",jobId:"api-upload"}));let c=await Ln(l,o.themePath,o.themeName,{onFileStart:d=>{t.send(JSON.stringify({type:"upload_output",chunk:`Uploading ${d}
|
|
1376
1376
|
`}))},onFileComplete:d=>{t.send(JSON.stringify({type:"upload_output",chunk:` \u2713 ${d}
|
|
1377
1377
|
`}))},onFileError:(d,u)=>{t.send(JSON.stringify({type:"upload_output",chunk:` \u2717 ${d}: ${u.message}
|
|
1378
|
-
`}))},onProgress:(d,u)=>{t.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Xe();t.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName}))}else{let d=
|
|
1379
|
-
`),errors:d}))}}else{let l=
|
|
1378
|
+
`}))},onProgress:(d,u)=>{t.send(JSON.stringify({type:"upload_progress",completed:d,total:u}))}});if(c.success){let d=Xe();t.send(JSON.stringify({type:"upload_complete",output:`Uploaded ${c.uploaded} files`,portalId:d?.portalId||"",dataCenter:d?.dataCenter||"na1",themeName:o.themeName}))}else{let d=Fn(c.errors);t.send(JSON.stringify({type:"upload_failed",output:c.errors.map(u=>`${u.file}: ${u.message}`).join(`
|
|
1379
|
+
`),errors:d}))}}else{let l=rs(`hs cms upload "${o.themePath}" "${o.themeName}"`,"Uploading to HubSpot",{cwd:at(o.themePath,".."),timeout:18e4});t.send(JSON.stringify({type:"upload_started",jobId:l}));let c=u=>{t.send(JSON.stringify({type:"upload_output",chunk:u}))};Qr(l,c);let d=setInterval(()=>{let u=is(l);if(!(!u||u.status==="running"))if(clearInterval(d),Zr(l,c),u.status==="completed"){let p=Oe(),f=p.portalId?Lt(p.portalId):"na1";t.send(JSON.stringify({type:"upload_complete",output:u.output,portalId:p.portalId||"",dataCenter:f,themeName:o.themeName}))}else{let p=Jn(u.output);t.send(JSON.stringify({type:"upload_failed",output:u.output,errors:p,exitCode:u.exitCode}))}},500)}}catch(i){t.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()){t.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.
|
|
1380
1380
|
|
|
1381
1381
|
IMPORTANT: Be verbose in your response. For each error:
|
|
1382
1382
|
1. State exactly which file has the problem and what the error is
|
|
@@ -1389,9 +1389,9 @@ CRITICAL: After fixing the reported errors, scan ALL other module files in the t
|
|
|
1389
1389
|
After fixing all errors, summarize the changes you made.
|
|
1390
1390
|
|
|
1391
1391
|
Upload log:
|
|
1392
|
-
${o}`;tt("user",i),D(),t.send(JSON.stringify({type:"upload_fix_started"}));try{await
|
|
1393
|
-
`));let n=
|
|
1394
|
-
`));try{process.platform==="darwin"?
|
|
1392
|
+
${o}`;tt("user",i),D(),t.send(JSON.stringify({type:"upload_fix_started"}));try{await rn(i,r=>{t.send(JSON.stringify({type:"stream",content:r})),t.send(JSON.stringify({type:"upload_fix_stream",content:r}))});let a=v();if(a){st();let r=Ns(a.themePath,"AI fix: upload errors");r&&t.send(JSON.stringify({type:"version_created",hash:r}))}t.send(JSON.stringify({type:"upload_fix_complete"})),t.send(JSON.stringify({type:"modules_updated",modules:me().map(r=>r.moduleName)}))}catch(a){t.send(JSON.stringify({type:"upload_failed",output:a instanceof Error?a.message:String(a),errors:[{file:"AI fix",message:a instanceof Error?a.message:String(a),fixable:!1}]}))}break}case"ping":t.send(JSON.stringify({type:"pong"}));break;default:t.send(JSON.stringify({type:"error",message:`Unknown type: ${s.type}`}))}});let e=v();if(e){let n=P(),s={"claude-code":"Claude Code","anthropic-api":"Anthropic API","openai-api":"OpenAI API","gemini-cli":"Gemini CLI","gemini-api":"Gemini API","codex-cli":"Codex CLI",api:"Anthropic API"},o=Ce();t.send(JSON.stringify({type:"init",sessionId:e.id,themeName:e.themeName,modules:me().map(i=>i.moduleName),messageCount:e.messages.length,messages:e.messages,gitAvailable:Ee(),engine:n.aiEngine?s[n.aiEngine]||n.aiEngine:"",templateId:o?.id||null,pageType:o?.pageType||null,templates:(e.templates||[]).map(i=>({id:i.id,label:i.label,pageType:i.pageType,moduleCount:i.modules.length}))}))}else t.send(JSON.stringify({type:"needs_setup"}))}function gu(t,e){let n=v();if(!n){e.writeHead(404,{"Content-Type":"text/plain"}),e.end("No session");return}let s=at(n.themePath,"assets",t);if(!dn(s)){e.writeHead(404,{"Content-Type":"text/plain"}),e.end("Asset not found");return}let o=nl(s),i=sl[o]||"application/octet-stream",a=Co(s);e.writeHead(200,{"Content-Type":i,"Cache-Control":"no-cache"}),e.end(a)}var tl=new Map;function hu(t,e,n,s){let i=at(e,t==="/"?"/index.html":t);if(!dn(i)){let c=at(e,"index.html");if(dn(c)){let d=Co(c);s.writeHead(200,{"Content-Type":"text/html","Cache-Control":"no-cache"}),s.end(d)}else s.writeHead(404,{"Content-Type":"text/plain"}),s.end("Not found");return}let a=nl(i),r=sl[a]||"application/octet-stream",l=a===".html";try{let c=tl.get(i);if(!c){let u=Co(i),p='"'+du("md5").update(u).digest("hex").slice(0,16)+'"';c={buffer:u,etag:p,contentType:r},tl.set(i,c)}if(n.headers["if-none-match"]===c.etag){s.writeHead(304),s.end();return}s.writeHead(200,{"Content-Type":c.contentType,"Cache-Control":l?"no-cache":"public, max-age=3600",ETag:c.etag}),s.end(c.buffer)}catch{s.writeHead(500,{"Content-Type":"text/plain"}),s.end("Internal Server Error")}}Se();var bu=4200;async function il(){let t=hs.hex("#e8613a"),e=hs.dim;console.log(""),console.log(t(" v vibeSpot")),console.log(e(` Starting...
|
|
1393
|
+
`));let n=Su();n||(console.error(hs.red(" Could not find UI assets. Is the package installed correctly?")),process.exit(1));try{let{port:s,close:o}=await ol({port:bu,uiDir:n}),i=`http://localhost:${s}`;console.log(t(` v ${i}`)),console.log(e(` Press Ctrl+C to stop
|
|
1394
|
+
`));try{process.platform==="darwin"?Ao("open",[i],{stdio:"ignore"}):process.platform==="win32"?Ao("cmd",["/c","start","",i],{stdio:"ignore"}):Ao("xdg-open",[i],{stdio:"ignore"})}catch{}await new Promise(a=>{process.on("SIGINT",()=>{console.log(e(`
|
|
1395
1395
|
Saving session...`)),D(),o(),console.log(e(` Goodbye!
|
|
1396
|
-
`)),a(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(
|
|
1396
|
+
`)),a(),setTimeout(()=>process.exit(0),500)})})}catch(s){console.error(hs.red(` Failed to start: ${s instanceof Error?s.message:String(s)}`)),process.exit(1)}}function Su(){let t=[gs(import.meta.dirname,"../../ui"),gs(import.meta.dirname,"../ui"),gs(process.cwd(),"ui")];for(let e of t)if(yu(gs(e,"index.html")))return e;return null}Z();function rl(){let t=new vu;return t.name("vibespot").description("AI-powered HubSpot CMS landing page builder").version(St()).action(il),t.command("wizard").description("Classic CLI wizard \u2014 step-by-step conversion flow").action(xi),t.command("init").description("Check and install required tools").action(Ci),t.command("convert").description("Convert a React project to HubSpot modules").action(Ai),t.command("upload").description("Upload theme to HubSpot").action(Ii),t.command("doctor").description("Diagnose environment issues").action(ki),t}var wu=rl();wu.parseAsync(process.argv).catch(t=>{console.error(t),process.exit(1)});
|
|
1397
1397
|
//# sourceMappingURL=index.js.map
|