aem-eds-kit 0.4.48 → 0.4.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (4) hide show
  1. package/CHANGELOG.md +110 -58
  2. package/README.md +130 -28
  3. package/dist/bin/eds.js +157 -121
  4. package/package.json +1 -1
package/dist/bin/eds.js CHANGED
@@ -1,16 +1,16 @@
1
1
  #!/usr/bin/env node
2
- var ac=Object.defineProperty;var k=(e,t)=>()=>(e&&(t=e(e=0)),t);var O=(e,t)=>{for(var n in t)ac(e,n,{get:t[n],enumerable:!0})};import gu from"path";import{fileURLToPath as wu}from"url";var f=k(()=>{"use strict"});import N from"chalk";function Gt(e){return J[e]}function Ci(e){return e.replace(lc,"").length}function ct(e,t){let n=t-Ci(e);return n>0?e+" ".repeat(n):e}function dc(){return N.bgHex("#ff5a36").hex("#0d0d0c").bold(" >_ ")}function ji(){return`${dc()} ${N.bold("aem-eds-kit")}`}function pc(){return Array.from({length:mc},()=>M.accent("\u25CF")).join(" ")}function uc(e,t=""){return t?`${ji()} ${e} ${N.dim(t)}`:`${ji()} ${e}`}function Pi(e){let t=e.replace("#","");return[Number.parseInt(t.slice(0,2),16),Number.parseInt(t.slice(2,4),16),Number.parseInt(t.slice(4,6),16)]}function fc(e,t,n){let[o,i,s]=Pi(e),[a,l,c]=Pi(t),d=Math.round(o+(a-o)*n),m=Math.round(i+(l-i)*n),p=Math.round(s+(c-s)*n);return`#${[d,m,p].map(u=>u.toString(16).padStart(2,"0")).join("")}`}function gc(e,t,n){let o=[...e],i=Math.max(n-1,1);return o.map((s,a)=>{if(s===" ")return s;let l=a/i*(t.length-1),c=Math.min(Math.floor(l),t.length-2);return N.hex(fc(t[c],t[c+1],l-c))(s)}).join("")}function wc(){let e=U(Ei);return Ei.map(t=>` ${gc(t,hc,e)}`).join(`
3
- `)}function T(e="AEM Edge Delivery Services"){return`
4
- ${wc()}
5
-
6
- ${uc(pc(),e)}
7
- `}function S(e,t){let n=M.red("\u258A"),o=t?` ${N.dim(t)}`:"";return`
8
- ${n} ${N.bold(e)}${o}
9
- `}function R(e,t,n,o=0){let i=o?ct(t,o):t,s=n?` ${N.dim(n)}`:"";return` ${J[e]} ${i}${s}`}function j(e,t,n=0){let o=n?ct(e,n):e,i=t?` ${N.dim(t)}`:"";return` ${M.accent("\u2714")} ${o}${i}`}function U(e){return e.reduce((t,n)=>Math.max(t,Ci(n)),0)}function I(e,t=M.red){let n=U(e),o=t(`\u256D${"\u2500".repeat(n+2)}\u256E`),i=t(`\u2570${"\u2500".repeat(n+2)}\u256F`),s=e.map(a=>`${t("\u2502")} ${ct(a,n)} ${t("\u2502")}`).join(`
2
+ var qc=Object.defineProperty;var v=(e,t)=>()=>(e&&(t=e(e=0)),t);var M=(e,t)=>{for(var n in t)qc(e,n,{get:t[n],enumerable:!0})};import mf from"path";import{fileURLToPath as uf}from"url";var f=v(()=>{"use strict"});import _ from"chalk";function Vt(e){return X[e]}function qi(e){return e.replace(Xc,"").length}function ht(e,t){let n=t-qi(e);return n>0?e+" ".repeat(n):e}function Vc(){return _.bgHex("#ff5a36").hex("#0d0d0c").bold(" >_ ")}function Wi(){return`${Vc()} ${_.bold("aem-eds-kit")}`}function Qc(){return Array.from({length:Yc},()=>N.accent("\u25CF")).join(" ")}function Zc(e,t=""){return t?`${Wi()} ${e} ${_.dim(t)}`:`${Wi()} ${e}`}function zi(e){let t=e.replace("#","");return[Number.parseInt(t.slice(0,2),16),Number.parseInt(t.slice(2,4),16),Number.parseInt(t.slice(4,6),16)]}function el(e,t,n){let[o,i,r]=zi(e),[s,l,c]=zi(t),d=Math.round(o+(s-o)*n),m=Math.round(i+(l-i)*n),p=Math.round(r+(c-r)*n);return`#${[d,m,p].map(u=>u.toString(16).padStart(2,"0")).join("")}`}function tl(e,t,n){let o=[...e],i=Math.max(n-1,1);return o.map((r,s)=>{if(r===" ")return r;let l=s/i*(t.length-1),c=Math.min(Math.floor(l),t.length-2);return _.hex(el(t[c],t[c+1],l-c))(r)}).join("")}function ol(){let e=I(Ji);return Ji.map(t=>` ${tl(t,nl,e)}`).join(`
3
+ `)}function A(e="AEM Edge Delivery Services"){return`
4
+ ${ol()}
5
+
6
+ ${Zc(Qc(),e)}
7
+ `}function j(e,t){let n=N.red("\u258A"),o=t?` ${_.dim(t)}`:"";return`
8
+ ${n} ${_.bold(e)}${o}
9
+ `}function R(e,t,n,o=0){let i=o?ht(t,o):t,r=n?` ${_.dim(n)}`:"";return` ${X[e]} ${i}${r}`}function P(e,t,n=0){let o=n?ht(e,n):e,i=t?` ${_.dim(t)}`:"";return` ${N.accent("\u2714")} ${o}${i}`}function I(e){return e.reduce((t,n)=>Math.max(t,qi(n)),0)}function B(e,t=N.red){let n=I(e),o=t(`\u256D${"\u2500".repeat(n+2)}\u256E`),i=t(`\u2570${"\u2500".repeat(n+2)}\u256F`),r=e.map(s=>`${t("\u2502")} ${ht(s,n)} ${t("\u2502")}`).join(`
10
10
  `);return`${o}
11
- ${s}
12
- ${i}`}function be(e){let t=[];return e.pass&&t.push(`${J.pass} ${e.pass} passed`),e.warn&&t.push(`${J.warn} ${e.warn} ${bc(e.warn,"warning")}`),e.fail&&t.push(`${J.fail} ${e.fail} failed`),e.info&&t.push(`${J.info} ${e.info} info`),t.join(N.dim(" "))}function bc(e,t){return e===1?t:`${t}s`}var M,J,lc,mc,Ti,Ei,hc,_=k(()=>{"use strict";f();M={red:N.hex("#FA0F00"),ember:N.hex("#FF4B1F"),orange:N.hex("#FF7B00"),blue:N.hex("#2680EB"),accent:N.hex("#ff5a36"),dotOrange:N.hex("#F24E1E"),dotPurple:N.hex("#A259FF"),dotBlue:N.hex("#1ABCFE"),dotGreen:N.hex("#0ACF83"),dotPink:N.hex("#FF7262"),ok:N.hex("#2D9D78"),warn:N.hex("#E68619"),err:N.hex("#D7373F"),info:N.hex("#2680EB")},J={pass:M.ok("\u2713"),warn:M.warn("\u26A0"),fail:M.err("\u2717"),info:M.info("\u2139"),bullet:N.dim("\u2022"),arrow:N.dim("\u21B3"),figma:M.dotPurple("\u25C6")};lc=/\[[0-9;]*m/g;mc=5;Ti={prefix:"",style:{highlight:e=>N.hex("#ff5a36").bold(e)}};Ei=["\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588","\u2588 \u2588 \u2588 \u2588 ","\u2588\u2588\u2588\u2588 \u2588 \u2588 \u2588\u2588\u2588\u2588\u2588","\u2588 \u2588 \u2588 \u2588","\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"],hc=["#ff3b1e","#ff5a36","#ff7d52"]});import Wt from"chalk";function yc(){let e=process.env.EDS_LOG_LEVEL?.toLowerCase();return e&&e in Ln?e:"info"}function Te(e){return Ai?e==="error":Ln[e]>=Ln[Ri]}var Ln,Ri,Ai,zt,r,D=k(()=>{"use strict";f();_();Ln={debug:0,info:1,warn:2,error:3,silent:4};Ri=yc(),Ai=!1,zt=!1;r={setLevel(e){Ri=e},setQuiet(e){Ai=e},debug(...e){Te("debug")&&console.error(Wt.gray("[debug]"),...e)},info(...e){Te("info")&&console.error(...e)},logoOnce(e){zt||(zt=!0,Te("info")&&console.error(e))},async logoOnceAnimated(e){zt||(zt=!0,Te("info")&&console.error(T(e)))},success(...e){Te("info")&&console.error(Wt.green("\u2713"),...e)},warn(...e){Te("warn")&&console.error(Wt.yellow("\u26A0"),...e)},error(...e){Te("error")&&console.error(Wt.red("\u2717"),...e)}}});function We(e){return{Authorization:`Bearer ${e}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"aem-eds-kit","Content-Type":"application/json"}}function vc(e){return`${Ge}/repos/${e}/generate`}async function Jt(e){let t=await fetch(`${Ge}/user`,{headers:We(e)});if(!t.ok)throw new Error(`GitHub auth failed: ${t.status}`);return(await t.json()).login}async function Fi(e,t,n){let o=await fetch(`${Ge}/repos/${t}/${n}`,{headers:We(e)});if(o.status===404)return!1;if(o.ok)return!0;throw new Error(`existence check failed: ${o.status} ${await o.text()}`)}async function Di(e,t,n){let o=await fetch(vc(t),{method:"POST",headers:We(e),body:JSON.stringify({owner:n.owner,name:n.name,private:!!n.private,include_all_branches:!1})});if(!o.ok)throw new Error(`create failed: ${o.status} ${await o.text()}`);let i=await o.json();return{fullName:i.full_name,htmlUrl:i.html_url,cloneUrl:i.clone_url}}async function Li(e,t,n,o){await fetch(`${Ge}/repos/${t}/${n}/topics`,{method:"PUT",headers:We(e),body:JSON.stringify({names:o})})}async function Ni(e,t,n){let o=await fetch(`${Ge}/repos/${t}/${n}`,{method:"DELETE",headers:We(e)});if(!o.ok&&o.status!==204)throw new Error(`delete failed: ${o.status} ${await o.text()}`)}async function Oi(e,t,n){let o=encodeURIComponent(`user:${t} topic:${n} fork:true`),i=await fetch(`${Ge}/search/repositories?q=${o}&per_page=100`,{headers:We(e)});if(!i.ok)throw new Error(`search failed: ${i.status}`);return(await i.json()).items.map(a=>a.full_name)}var Ge,Mi=k(()=>{"use strict";f();Ge="https://api.github.com"});import{existsSync as Ii}from"fs";import{mkdir as kc,readFile as xc,rm as $c,writeFile as Sc}from"fs/promises";import jc from"os";import _i from"path";async function Bi(){let e=process.env.GITHUB_TOKEN||process.env.GH_TOKEN;if(e)return e;if(Ii(lt))try{return JSON.parse(await xc(lt,"utf-8")).token??null}catch{return null}return null}async function Nn(e){await kc(Ui,{recursive:!0,mode:448}),await Sc(lt,`${JSON.stringify({token:e},null,2)}
13
- `,{mode:384})}async function Hi(){Ii(lt)&&await $c(lt)}async function Gi(e){let t=await fetch("https://github.com/login/device/code",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({client_id:qt,scope:e.join(" ")})});if(!t.ok)throw new Error(`device code request failed: ${t.status}`);return await t.json()}async function Wi(e,t,n){let o=Math.max(t,1),i=Date.now()+n*1e3;for(;Date.now()<i;){await new Promise(l=>setTimeout(l,o*1e3));let a=await(await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({client_id:qt,device_code:e,grant_type:"urn:ietf:params:oauth:grant-type:device_code"})})).json();if(a.access_token)return a.access_token;if(a.error==="slow_down")o+=5;else if(a.error!=="authorization_pending")throw new Error(a.error??"device flow failed")}throw new Error("device flow timed out")}var Ui,lt,qt,zi=k(()=>{"use strict";f();Ui=_i.join(jc.homedir(),".eds"),lt=_i.join(Ui,"github.json"),qt=process.env.EDS_GITHUB_CLIENT_ID??""});function On(e,t,n="main"){return`https://${n}--${t}--${e}.aem.page/`}function Mn(){return"https://github.com/apps/aem-code-sync/installations/new"}function Ji(e,t){return["repo","create",e,"--template",t.template,t.private?"--private":"--public",...t.clone?["--clone"]:[]]}var ze,dt,qi=k(()=>{"use strict";f();ze="eds-sandbox",dt={document:"adobe/aem-boilerplate",ue:"adobe/aem-boilerplate-xwalk"}});var B={};O(B,{checkbox:()=>Oc,confirm:()=>Nc,input:()=>Lc,isEscape:()=>Ac,isExit:()=>Fc,select:()=>Dc});import{emitKeypressEvents as Pc}from"readline";import{checkbox as Ec,confirm as Cc,input as Tc,select as Rc}from"@inquirer/prompts";function Kt(e){let t={...Ti,...e.theme??{}};return{...e,theme:t}}function Vt(e,t){let n=process.stdin;if(!n.isTTY)return e(t??{});let o=new AbortController;t?.signal?.addEventListener("abort",()=>o.abort(),{once:!0}),Pc(n);let i=(a,l)=>{l?.name==="escape"&&o.abort()};n.on("keypress",i);let s=e({...t,signal:o.signal});return Promise.resolve(s).catch(()=>{}).finally(()=>n.off("keypress",i)),s}function Ac(e){return e instanceof Error&&e.name==="AbortPromptError"}function Fc(e){return e instanceof Error&&e.name==="ExitPromptError"}var Dc,Lc,Nc,Oc,H=k(()=>{"use strict";f();_();Dc=(e,t)=>Vt(n=>Rc(Kt(e),n),t),Lc=(e,t)=>Vt(n=>Tc(Kt(e),n),t),Nc=(e,t)=>Vt(n=>Cc(Kt(e),n),t),Oc=(e,t)=>Vt(n=>Ec(Kt(e),n),t)});import{z as F}from"zod";var Uu,In,Ki,Bu,Re,Je=k(()=>{"use strict";f();Uu=F.object({fileKey:F.string().min(1),nodeId:F.string().optional(),fileName:F.string().optional()}),In=F.object({agent:F.enum(["claude","cursor","codex"]).optional(),model:F.string().optional(),figma:F.object({mcpEndpoint:F.string().url().optional(),token:F.string().optional(),restPerMinute:F.number().int().positive().optional()}).optional(),admin:F.object({org:F.string().optional(),site:F.string().optional(),ref:F.string().default("main")}).optional()}),Ki=F.object({root:F.string(),hasFstab:F.boolean(),hasBlocks:F.boolean(),hasHeadHtml:F.boolean()}),Bu=F.object({figmaFileKey:F.string(),figmaNodeId:F.string().optional(),lastSyncedAt:F.string().datetime(),promptVersion:F.string(),agentUsed:F.string().optional(),breakpoints:F.array(F.object({width:F.number(),label:F.string().optional(),source:F.enum(["figma","scrape","default"]).optional()})).optional()}),Re=/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/});import{existsSync as mt}from"fs";import ye from"path";function E(e=process.cwd()){let t=ye.resolve(e),{root:n}=ye.parse(t);for(;t!==n;){if(Vi.some(o=>mt(ye.join(t,o))))return t;t=ye.dirname(t)}if(Vi.some(o=>mt(ye.join(n,o))))return n}function Xi(e){return Ki.parse({root:e,hasFstab:mt(ye.join(e,"fstab.yaml")),hasBlocks:mt(ye.join(e,"blocks")),hasHeadHtml:mt(ye.join(e,"head.html"))})}var Vi,z=k(()=>{"use strict";f();Je();Vi=["fstab.yaml","head.html","helix-query.yaml","component-definition.json","paths.json","scripts/scripts.js","scripts/aem.js"]});import{existsSync as Mc}from"fs";import{mkdir as Ic,writeFile as _c}from"fs/promises";import Yi from"path";async function Xt(e){let t=Yi.join(e,".github","workflows","eds.yml");return Mc(t)?{path:Qi,created:!1}:(await Ic(Yi.dirname(t),{recursive:!0}),await _c(t,Uc),{path:Qi,created:!0})}var Qi,Uc,_n=k(()=>{"use strict";f();Qi=".github/workflows/eds.yml",Uc=`name: EDS checks
11
+ ${r}
12
+ ${i}`}function $e(e){let t=[];return e.pass&&t.push(`${X.pass} ${e.pass} passed`),e.warn&&t.push(`${X.warn} ${e.warn} ${il(e.warn,"warning")}`),e.fail&&t.push(`${X.fail} ${e.fail} failed`),e.info&&t.push(`${X.info} ${e.info} info`),t.join(_.dim(" "))}function il(e,t){return e===1?t:`${t}s`}var N,X,Xc,Yc,Ki,Ji,nl,U=v(()=>{"use strict";f();N={red:_.hex("#FA0F00"),ember:_.hex("#FF4B1F"),orange:_.hex("#FF7B00"),blue:_.hex("#2680EB"),accent:_.hex("#ff5a36"),dotOrange:_.hex("#F24E1E"),dotPurple:_.hex("#A259FF"),dotBlue:_.hex("#1ABCFE"),dotGreen:_.hex("#0ACF83"),dotPink:_.hex("#FF7262"),ok:_.hex("#2D9D78"),warn:_.hex("#E68619"),err:_.hex("#D7373F"),info:_.hex("#2680EB")},X={pass:N.ok("\u2713"),warn:N.warn("\u26A0"),fail:N.err("\u2717"),info:N.info("\u2139"),bullet:_.dim("\u2022"),arrow:_.dim("\u21B3"),figma:N.dotPurple("\u25C6")};Xc=/\[[0-9;]*m/g;Yc=5;Ki={prefix:"",style:{highlight:e=>_.hex("#ff5a36").bold(e)}};Ji=["\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588","\u2588 \u2588 \u2588 \u2588 ","\u2588\u2588\u2588\u2588 \u2588 \u2588 \u2588\u2588\u2588\u2588\u2588","\u2588 \u2588 \u2588 \u2588","\u2588\u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588 \u2588\u2588\u2588\u2588\u2588"],nl=["#ff3b1e","#ff5a36","#ff7d52"]});import Yt from"chalk";function rl(){let e=process.env.EDS_LOG_LEVEL?.toLowerCase();return e&&e in zn?e:"info"}function Oe(e){return Vi?e==="error":zn[e]>=zn[Xi]}var zn,Xi,Vi,Qt,a,D=v(()=>{"use strict";f();U();zn={debug:0,info:1,warn:2,error:3,silent:4};Xi=rl(),Vi=!1,Qt=!1;a={setLevel(e){Xi=e},setQuiet(e){Vi=e},debug(...e){Oe("debug")&&console.error(Yt.gray("[debug]"),...e)},info(...e){Oe("info")&&console.error(...e)},logoOnce(e){Qt||(Qt=!0,Oe("info")&&console.error(e))},async logoOnceAnimated(e){Qt||(Qt=!0,Oe("info")&&console.error(A(e)))},success(...e){Oe("info")&&console.error(Yt.green("\u2713"),...e)},warn(...e){Oe("warn")&&console.error(Yt.yellow("\u26A0"),...e)},error(...e){Oe("error")&&console.error(Yt.red("\u2717"),...e)}}});function Jn(e,t,n="main"){return`https://${n}--${t}--${e}.aem.page/`}function qn(){return"https://github.com/apps/aem-code-sync/installations/new"}function Yi(e,t){return["repo","create",e,"--template",t.template,t.private?"--private":"--public",...t.clone?["--clone"]:[]]}var Ve,Q,Zt=v(()=>{"use strict";f();Ve="eds-sandbox",Q={document:"adobe/aem-boilerplate",ue:"adobe-rnd/aem-boilerplate-xwalk"}});import{existsSync as Xn}from"fs";import{readdir as Zi,rm as Kn}from"fs/promises";import Qi from"path";function er(e,t=!1){let n=(e??(t?Q.ue:Q.document)).trim(),o=al[n.toLowerCase()]??n,i=s=>/xwalk/i.test(s);if(/^[\w.-]+\/[\w.-]+$/.test(o)&&!Xn(o))return{url:`https://github.com/${o}.git`,label:o,ue:i(o)};let r=o.match(/github\.com[/:]([\w.-]+\/[\w.-]+?)(?:\.git)?\/?$/)?.[1];return{url:o,label:r??o,ue:i(o)}}async function tr(e){if(!Xn(e))return!0;try{return(await Zi(e)).length===0}catch{return!1}}async function nr(e,t,n={}){let{execa:o}=await import("execa"),i=(d,m,p="pipe")=>o("git",d,{cwd:m,stdio:p}),r=Xn(t),s=n.ref?["--branch",n.ref]:[];try{n.keepHistory?await i(["clone",...s,"--origin","upstream",e.url,t],void 0,n.stdio):await i(["clone","--depth","1",...s,e.url,t],void 0,n.stdio)}catch(d){if(!r)await Kn(t,{recursive:!0,force:!0});else for(let u of await Zi(t))await Kn(Qi.join(t,u),{recursive:!0,force:!0});let m=d;if(m.code==="ENOENT")throw new Error("git isn't installed (or not on PATH).");let p=(m.stderr??"").trim().split(`
13
+ `).pop()||m.shortMessage||String(d);throw/could not read Username|Repository not found|not found/i.test(p)?new Error(`Couldn't clone ${e.label}: the repo doesn't exist, or it's private (check the name; for a private repo use an SSH URL or set up git credentials).`):new Error(`Couldn't clone ${e.label}: ${p}`)}let l=(await i(["rev-parse","HEAD"],t)).stdout.trim(),c=!1;if(!n.keepHistory){await Kn(Qi.join(t,".git"),{recursive:!0,force:!0}),await i(["init","--quiet"],t),await i(["symbolic-ref","HEAD","refs/heads/main"],t),await i(["add","-A"],t);try{await i(["commit","--quiet","-m",`Initial commit from ${e.label}@${l.slice(0,7)}`],t)}catch{c=!0}}return n.remote&&await i(["remote","add","origin",n.remote],t),{commit:l,uncommitted:c}}var en,al,or=v(()=>{"use strict";f();Zt();en="hlxsites/aem-boilerplate-commerce",al={commerce:en,document:Q.document,doc:Q.document,da:Q.document,ue:Q.ue,xwalk:Q.ue,crosswalk:Q.ue}});var H={};M(H,{checkbox:()=>wl,confirm:()=>hl,input:()=>gl,isEscape:()=>pl,isExit:()=>ul,select:()=>fl});import{emitKeypressEvents as sl}from"readline";import{checkbox as cl,confirm as ll,input as dl,select as ml}from"@inquirer/prompts";function tn(e){let t={...Ki,...e.theme??{}};return{...e,theme:t}}function nn(e,t){let n=process.stdin;if(!n.isTTY)return e(t??{});let o=new AbortController;t?.signal?.addEventListener("abort",()=>o.abort(),{once:!0}),sl(n);let i=(s,l)=>{l?.name==="escape"&&o.abort()};n.on("keypress",i);let r=e({...t,signal:o.signal});return Promise.resolve(r).catch(()=>{}).finally(()=>n.off("keypress",i)),r}function pl(e){return e instanceof Error&&e.name==="AbortPromptError"}function ul(e){return e instanceof Error&&e.name==="ExitPromptError"}var fl,gl,hl,wl,G=v(()=>{"use strict";f();U();fl=(e,t)=>nn(n=>ml(tn(e),n),t),gl=(e,t)=>nn(n=>dl(tn(e),n),t),hl=(e,t)=>nn(n=>ll(tn(e),n),t),wl=(e,t)=>nn(n=>cl(tn(e),n),t)});import{z as F}from"zod";var Df,Vn,ir,Of,Ne,Ye=v(()=>{"use strict";f();Df=F.object({fileKey:F.string().min(1),nodeId:F.string().optional(),fileName:F.string().optional()}),Vn=F.object({agent:F.enum(["claude","cursor","codex","ollama","omlx","local"]).optional(),local:F.object({baseUrl:F.string().url().optional(),model:F.string().optional(),contextTokens:F.number().int().positive().optional(),apiKey:F.string().optional()}).optional(),model:F.string().optional(),figma:F.object({mcpEndpoint:F.string().url().optional(),token:F.string().optional(),restPerMinute:F.number().int().positive().optional()}).optional(),admin:F.object({org:F.string().optional(),site:F.string().optional(),ref:F.string().default("main")}).optional()}),ir=F.object({root:F.string(),hasFstab:F.boolean(),hasBlocks:F.boolean(),hasHeadHtml:F.boolean()}),Of=F.object({figmaFileKey:F.string(),figmaNodeId:F.string().optional(),lastSyncedAt:F.string().datetime(),promptVersion:F.string(),agentUsed:F.string().optional(),breakpoints:F.array(F.object({width:F.number(),label:F.string().optional(),source:F.enum(["figma","scrape","default"]).optional()})).optional()}),Ne=/^[a-z][a-z0-9]*(-[a-z0-9]+)*$/});import{existsSync as wt}from"fs";import Se from"path";function E(e=process.cwd()){let t=Se.resolve(e),{root:n}=Se.parse(t);for(;t!==n;){if(rr.some(o=>wt(Se.join(t,o))))return t;t=Se.dirname(t)}if(rr.some(o=>wt(Se.join(n,o))))return n}function ar(e){return ir.parse({root:e,hasFstab:wt(Se.join(e,"fstab.yaml")),hasBlocks:wt(Se.join(e,"blocks")),hasHeadHtml:wt(Se.join(e,"head.html"))})}var rr,J=v(()=>{"use strict";f();Ye();rr=["fstab.yaml","head.html","helix-query.yaml","component-definition.json","paths.json","scripts/scripts.js","scripts/aem.js"]});import{existsSync as bl}from"fs";import{mkdir as yl,writeFile as vl}from"fs/promises";import sr from"path";async function on(e){let t=sr.join(e,".github","workflows","eds.yml");return bl(t)?{path:cr,created:!1}:(await yl(sr.dirname(t),{recursive:!0}),await vl(t,kl),{path:cr,created:!0})}var cr,kl,Yn=v(()=>{"use strict";f();cr=".github/workflows/eds.yml",kl=`name: EDS checks
14
14
 
15
15
  # Generated by aem-eds-kit (\`eds scaffold ci\`). Runs the project's own
16
16
  # lint/build plus the eds audits as a gatekeeper on every PR and push to main.
@@ -53,18 +53,18 @@ jobs:
53
53
  run: npx --yes aem-eds-kit@latest audit loading
54
54
  - name: Security & exploit scan
55
55
  run: npx --yes aem-eds-kit@latest audit security
56
- `});import{existsSync as Zi}from"fs";import{readFile as Bc,writeFile as er}from"fs/promises";import tr from"path";function Hc(e={}){let t=e.open??"/",n=e.port??3007,o=e.pagesUrl??"";return`AEM_OPEN=${t}
56
+ `});import{existsSync as lr}from"fs";import{readFile as xl,writeFile as dr}from"fs/promises";import mr from"path";function $l(e={}){let t=e.open??"/",n=e.port??3007,o=e.pagesUrl??"";return`AEM_OPEN=${t}
57
57
  AEM_PORT=${n}
58
58
  AEM_PAGES_URL=${o}
59
- `}async function Gc(e){let t=tr.join(e,".gitignore"),n="";if(Zi(t)&&(n=await Bc(t,"utf-8")),n.split(/\r?\n/).some(i=>i.trim()===".env"))return!1;let o=n&&!n.endsWith(`
59
+ `}async function Sl(e){let t=mr.join(e,".gitignore"),n="";if(lr(t)&&(n=await xl(t,"utf-8")),n.split(/\r?\n/).some(i=>i.trim()===".env"))return!1;let o=n&&!n.endsWith(`
60
60
  `)?`
61
- `:"";return await er(t,`${n}${o}.env
62
- `),!0}async function Yt(e,t={}){let n=tr.join(e,".env"),o=!Zi(n);o&&await er(n,Hc(t));let i=await Gc(e);return{path:".env",created:o,gitignoreUpdated:i}}var Un=k(()=>{"use strict";f()});import{writeFile as nr}from"fs/promises";import or from"path";function Qt(e){return e!=="ue"}function ir(e,t){return`https://content.da.live/${e}/${t}/`}function Wc(e){return`mountpoints:
61
+ `:"";return await dr(t,`${n}${o}.env
62
+ `),!0}async function rn(e,t={}){let n=mr.join(e,".env"),o=!lr(n);o&&await dr(n,$l(t));let i=await Sl(e);return{path:".env",created:o,gitignoreUpdated:i}}var Qn=v(()=>{"use strict";f()});import{existsSync as pr}from"fs";import{readFile as jl,writeFile as ur}from"fs/promises";import an from"path";function sn(e){return e!=="ue"}function fr(e,t){return`https://content.da.live/${e}/${t}/`}function Pl(e){return`mountpoints:
63
63
  /: ${e}
64
- `}async function rr(e,t){return await nr(or.join(e,"fstab.yaml"),Wc(t)),"fstab.yaml"}function zc(e){return`${JSON.stringify({mappings:[`/content/${e}/:/`],includes:[`/content/${e}/`]},null,2)}
65
- `}async function sr(e,t){return await nr(or.join(e,"paths.json"),zc(t)),"paths.json"}var Ae,ar=k(()=>{"use strict";f();Ae={ue:"Universal Editor (crosswalk)",da:"Document Authoring (da.live)",gdrive:"Document Authoring (Google Drive)",sharepoint:"Document Authoring (SharePoint)"}});import{existsSync as Jc}from"fs";import{writeFile as qc}from"fs/promises";import Kc from"path";function Xc(){return`${JSON.stringify(Vc,null,2)}
66
- `}async function Zt(e){let t=Kc.join(e,"xwalk.json");return Jc(t)?{path:"xwalk.json",created:!1}:(await qc(t,Xc()),{path:"xwalk.json",created:!0})}var Vc,Bn=k(()=>{"use strict";f();Vc={public:{xwalk:{"multi-field":{enabled:!0}}}}});function qe(e){let t=e.trim().match(/github\.com[:/]([^/]+)\/(.+?)(?:\.git)?\/?$/i);return t?{owner:t[1],repo:t[2]}:null}function Ke(e,t,n="main"){return`${n}--${t}--${e}.aem.page`}function cr({host:e,path:t="/",org:n}){let o=e.replace(/^https?:\/\//,"").replace(/\/+$/,""),i=t.startsWith("/")?t:`/${t}`;return`https://experience.adobe.com/#/${n?`@${n}/`:""}aem/editor/canvas/${o}${i}`}var en=k(()=>{"use strict";f()});function pt(e){return`${JSON.stringify(e,null,2)}
67
- `}function Gn(e){return Fe.find(t=>t.id===e)}var Hn,lr,dr,Fe,Wn=k(()=>{"use strict";f();Hn=(e,t,n)=>({title:e,id:t,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:e,model:n}}}}}),lr=(e,t,n)=>({title:e,id:t,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:e,filter:n}}}}}),dr=(e,t,n)=>({title:e,id:t,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block/item",template:{name:e,model:n}}}}}),Fe=[{id:"hero",title:"Hero",js:`// Block: hero
64
+ `}async function gr(e,t){return await ur(an.join(e,"fstab.yaml"),Pl(t)),"fstab.yaml"}function El(e){return`${JSON.stringify({mappings:[`/content/${e}/:/`],includes:[`/content/${e}/`]},null,2)}
65
+ `}async function hr(e,t){return await ur(an.join(e,"paths.json"),El(t)),"paths.json"}function Cl(e){if(/content\.da\.live|\/\/da\.live\//i.test(e))return"da";if(/drive\.google\.com|docs\.google\.com/i.test(e))return"gdrive";if(/sharepoint\.com|onedrive\.live\.com|1drv\.ms/i.test(e))return"sharepoint";if(/adobeaemcloud\.(com|net)|\/bin\/franklin\.delivery/i.test(e))return"ue"}async function wr(e){let t=an.join(e,"fstab.yaml");if(pr(t)){let n=(await jl(t,"utf-8")).match(/https?:\/\/[^\s"']+/)?.[0],o=n&&Cl(n);if(o)return o}if(pr(an.join(e,"paths.json")))return"ue"}var je,br=v(()=>{"use strict";f();je={ue:"Universal Editor (crosswalk)",da:"Document Authoring (da.live)",gdrive:"Document Authoring (Google Drive)",sharepoint:"Document Authoring (SharePoint)"}});import{existsSync as Tl}from"fs";import{writeFile as Al}from"fs/promises";import Rl from"path";function Ll(){return`${JSON.stringify(Fl,null,2)}
66
+ `}async function cn(e){let t=Rl.join(e,"xwalk.json");return Tl(t)?{path:"xwalk.json",created:!1}:(await Al(t,Ll()),{path:"xwalk.json",created:!0})}var Fl,Zn=v(()=>{"use strict";f();Fl={public:{xwalk:{"multi-field":{enabled:!0}}}}});function Qe(e){let t=e.trim().match(/github\.com[:/]([^/]+)\/(.+?)(?:\.git)?\/?$/i);return t?{owner:t[1],repo:t[2]}:null}function Ze(e,t,n="main"){return`${n}--${t}--${e}.aem.page`}function yr({host:e,path:t="/",org:n}){let o=e.replace(/^https?:\/\//,"").replace(/\/+$/,""),i=t.startsWith("/")?t:`/${t}`;return`https://experience.adobe.com/#/${n?`@${n}/`:""}aem/editor/canvas/${o}${i}`}var ln=v(()=>{"use strict";f()});function bt(e){return`${JSON.stringify(e,null,2)}
67
+ `}function to(e){return Me.find(t=>t.id===e)}var eo,vr,kr,Me,no=v(()=>{"use strict";f();eo=(e,t,n)=>({title:e,id:t,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:e,model:n}}}}}),vr=(e,t,n)=>({title:e,id:t,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:e,filter:n}}}}}),kr=(e,t,n)=>({title:e,id:t,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block/item",template:{name:e,model:n}}}}}),Me=[{id:"hero",title:"Hero",js:`// Block: hero
68
68
  export default function decorate(block) {
69
69
  block.classList.add('hero');
70
70
  const picture = block.querySelector('picture');
@@ -93,7 +93,7 @@ export default function decorate(block) {
93
93
  margin: 0 auto;
94
94
  padding: 0 var(--spacing-m, 16px);
95
95
  }
96
- `,model:pt({definitions:[Hn("Hero","hero","hero")],models:[{id:"hero",fields:[{component:"reference",valueType:"string",name:"image",label:"Image"},{component:"text",valueType:"string",name:"imageAlt",label:"Alt"},{component:"text",valueType:"string",name:"title",label:"Title"},{component:"richtext",valueType:"string",name:"text",value:"",label:"Text"}]}],filters:[]})},{id:"cards",title:"Cards",js:`// Block: cards
96
+ `,model:bt({definitions:[eo("Hero","hero","hero")],models:[{id:"hero",fields:[{component:"reference",valueType:"string",name:"image",label:"Image"},{component:"text",valueType:"string",name:"imageAlt",label:"Alt"},{component:"text",valueType:"string",name:"title",label:"Title"},{component:"richtext",valueType:"string",name:"text",value:"",label:"Text"}]}],filters:[]})},{id:"cards",title:"Cards",js:`// Block: cards
97
97
  export default function decorate(block) {
98
98
  const ul = document.createElement('ul');
99
99
  [...block.children].forEach((row) => {
@@ -132,7 +132,7 @@ export default function decorate(block) {
132
132
  .cards .cards-card-body {
133
133
  padding: var(--spacing-m, 16px);
134
134
  }
135
- `,model:pt({definitions:[lr("Cards","cards","cards"),dr("Card","card","card")],models:[{id:"card",fields:[{component:"reference",valueType:"string",name:"image",label:"Image"},{component:"text",valueType:"string",name:"imageAlt",label:"Alt"},{component:"text",valueType:"string",name:"title",label:"Title"},{component:"richtext",valueType:"string",name:"text",value:"",label:"Text"},{component:"aem-content",name:"link",label:"Link"}]}],filters:[{id:"cards",components:["card"]}]})},{id:"columns",title:"Columns",js:`// Block: columns
135
+ `,model:bt({definitions:[vr("Cards","cards","cards"),kr("Card","card","card")],models:[{id:"card",fields:[{component:"reference",valueType:"string",name:"image",label:"Image"},{component:"text",valueType:"string",name:"imageAlt",label:"Alt"},{component:"text",valueType:"string",name:"title",label:"Title"},{component:"richtext",valueType:"string",name:"text",value:"",label:"Text"},{component:"aem-content",name:"link",label:"Link"}]}],filters:[{id:"cards",components:["card"]}]})},{id:"columns",title:"Columns",js:`// Block: columns
136
136
  export default function decorate(block) {
137
137
  const cols = [...block.firstElementChild.children];
138
138
  block.classList.add(\`columns-\${cols.length}-cols\`);
@@ -159,7 +159,7 @@ export default function decorate(block) {
159
159
  }
160
160
 
161
161
  .columns img { width: 100%; height: auto; }
162
- `,model:pt({definitions:[Hn("Columns","columns","columns")],models:[{id:"columns",fields:[{component:"richtext",valueType:"string",name:"content",value:"",label:"Content"}]}],filters:[]})},{id:"accordion",title:"Accordion",js:`// Block: accordion
162
+ `,model:bt({definitions:[eo("Columns","columns","columns")],models:[{id:"columns",fields:[{component:"richtext",valueType:"string",name:"content",value:"",label:"Content"}]}],filters:[]})},{id:"accordion",title:"Accordion",js:`// Block: accordion
163
163
  export default function decorate(block) {
164
164
  [...block.children].forEach((row) => {
165
165
  const [label, body] = row.children;
@@ -192,7 +192,7 @@ export default function decorate(block) {
192
192
  .accordion .accordion-item-body {
193
193
  padding-bottom: var(--spacing-m, 16px);
194
194
  }
195
- `,model:pt({definitions:[lr("Accordion","accordion","accordion"),dr("Accordion Item","accordion-item","accordion-item")],models:[{id:"accordion-item",fields:[{component:"text",valueType:"string",name:"label",label:"Label"},{component:"richtext",valueType:"string",name:"body",value:"",label:"Body"}]}],filters:[{id:"accordion",components:["accordion-item"]}]})},{id:"embed",title:"Embed",js:`// Block: embed
195
+ `,model:bt({definitions:[vr("Accordion","accordion","accordion"),kr("Accordion Item","accordion-item","accordion-item")],models:[{id:"accordion-item",fields:[{component:"text",valueType:"string",name:"label",label:"Label"},{component:"richtext",valueType:"string",name:"body",value:"",label:"Body"}]}],filters:[{id:"accordion",components:["accordion-item"]}]})},{id:"embed",title:"Embed",js:`// Block: embed
196
196
  export default function decorate(block) {
197
197
  const link = block.querySelector('a');
198
198
  const url = link?.href;
@@ -221,12 +221,12 @@ export default function decorate(block) {
221
221
  height: 100%;
222
222
  border: 0;
223
223
  }
224
- `,model:pt({definitions:[Hn("Embed","embed","embed")],models:[{id:"embed",fields:[{component:"aem-content",name:"link",label:"Embed URL"}]}],filters:[]})}]});import{existsSync as Yc}from"fs";import{mkdir as Qc,writeFile as Zc}from"fs/promises";import mr from"path";function ur(e){return ut.find(t=>t.id===e)}function fr(e){let t=new Set,n=o=>{if(t.has(o))return;let i=ur(o);if(i){for(let s of i.deps??[])n(s);t.add(o)}};for(let o of e)n(o);return ut.filter(o=>t.has(o.id)).map(o=>o.id)}function el(e){return`// scripts/utils.js - common EDS helpers (generated by \`eds scaffold helpers\`).
224
+ `,model:bt({definitions:[eo("Embed","embed","embed")],models:[{id:"embed",fields:[{component:"aem-content",name:"link",label:"Embed URL"}]}],filters:[]})}]});import{existsSync as Dl}from"fs";import{mkdir as Ol,writeFile as Nl}from"fs/promises";import xr from"path";function Sr(e){return yt.find(t=>t.id===e)}function jr(e){let t=new Set,n=o=>{if(t.has(o))return;let i=Sr(o);if(i){for(let r of i.deps??[])n(r);t.add(o)}};for(let o of e)n(o);return yt.filter(o=>t.has(o.id)).map(o=>o.id)}function Ml(e){return`// scripts/utils.js - common EDS helpers (generated by \`eds scaffold helpers\`).
225
225
 
226
- ${fr(e).map(o=>ur(o)).filter(o=>!!o).map(o=>o.code).join(`
226
+ ${jr(e).map(o=>Sr(o)).filter(o=>!!o).map(o=>o.code).join(`
227
227
 
228
228
  `)}
229
- `}async function gr(e,t=zn){let n=fr(t),o=mr.join(e,"scripts","utils.js");return Yc(o)?{path:pr,created:!1,helpers:n}:(await Qc(mr.dirname(o),{recursive:!0}),await Zc(o,el(t)),{path:pr,created:!0,helpers:n})}var pr,ut,zn,hr=k(()=>{"use strict";f();pr="scripts/utils.js",ut=[{id:"getMetadata",label:"getMetadata (read a page meta value)",code:`/**
229
+ `}async function Pr(e,t=oo){let n=jr(t),o=xr.join(e,"scripts","utils.js");return Dl(o)?{path:$r,created:!1,helpers:n}:(await Ol(xr.dirname(o),{recursive:!0}),await Nl(o,Ml(t)),{path:$r,created:!0,helpers:n})}var $r,yt,oo,Er=v(()=>{"use strict";f();$r="scripts/utils.js",yt=[{id:"getMetadata",label:"getMetadata (read a page meta value)",code:`/**
230
230
  * Reads a page metadata value by name (meta[name] or meta[property]).
231
231
  * @param {string} name The metadata name.
232
232
  * @returns {string} The value, or an empty string.
@@ -323,8 +323,8 @@ export function isUEPreview() {
323
323
  */
324
324
  export function isUE() {
325
325
  return isUEEdit() || isUEPreview();
326
- }`}],zn=ut.map(e=>e.id)});function tl(){return[{component:"tab",name:"basics",label:"Basics"},{component:"text",valueType:"string",name:"text",label:"Text (single line)"},{component:"textarea",valueType:"string",name:"textarea",label:"Textarea (multi-line)"},{component:"richtext",valueType:"string",name:"richtext",value:"",label:"Rich text"},{component:"number",valueType:"number",name:"number",label:"Number"},{component:"boolean",valueType:"boolean",name:"boolean",value:!1,label:"Boolean"},{component:"date-time",valueType:"date",name:"date",label:"Date / time"},{component:"tab",name:"selection",label:"Selection"},{component:"select",valueType:"string",name:"select",label:"Select",value:"a",options:[{name:"Option A",value:"a"},{name:"Option B",value:"b"}]},{component:"radio-group",valueType:"string",name:"radio",label:"Radio group",value:"x",options:[{name:"X",value:"x"},{name:"Y",value:"y"}]},{component:"multiselect",valueType:"string",name:"classes",label:"Multiselect (CSS classes)",options:[{name:"Highlight",value:"highlight"},{name:"Dark",value:"dark"}]},{component:"checkbox-group",valueType:"string[]",name:"toggles",label:"Checkbox group",options:[{name:"Show title",value:"show-title"},{name:"Show image",value:"show-image"}]},{component:"tab",name:"media",label:"Media & content"},{component:"reference",valueType:"string",name:"image",label:"Image (DAM asset)"},{component:"text",valueType:"string",name:"imageAlt",label:"Image alt"},{component:"aem-content",name:"link",label:"Link (page / URL)"},{component:"aem-content-fragment",name:"contentFragment",label:"Content Fragment"},{component:"aem-experience-fragment",name:"experienceFragment",label:"Experience Fragment"},{component:"aem-tag",valueType:"string",name:"tags",label:"Tags"},{component:"tab",name:"repeatable",label:"Multifield"},{component:"container",name:"items",label:"Items (repeatable)",multi:!0,collapsible:!0,fields:[{component:"text",valueType:"string",name:"itemTitle",label:"Title"},{component:"richtext",valueType:"string",name:"itemText",value:"",label:"Text"},{component:"aem-content",name:"itemLink",label:"Link"}]}]}function Jn(){let e={definitions:[{title:"Field Reference",id:"field-reference",plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:"Field Reference",model:"field-reference"}}}}}],models:[{id:"field-reference",fields:tl()}],filters:[]};return`${JSON.stringify(e,null,2)}
327
- `}function qn(e,t){let n=new Set(e.map(o=>o.id));return[...e,...t.filter(o=>!n.has(o.id))]}function kr(e,t,n){let o=e?.groups?[...e.groups]:[],i=(s,a,l)=>{let c=o.find(d=>d.id===s);c||(c={id:s,title:a,components:[]},o.push(c)),c.components=qn(c.components,l)};return i("default","Default Content",t),i("blocks","Blocks",n),{groups:o}}function ft(e,t){let n=e?[...e]:[],o=n.find(i=>i.id==="section");return o||(o={id:"section",components:["text","image","button","title"]},n.push(o)),o.components=[...new Set([...o.components,...t])],n}var wr,br,yr,vr,Kn=k(()=>{"use strict";f();wr=[{title:"Text",id:"text",plugins:{xwalk:{page:{resourceType:"core/franklin/components/text/v1/text",template:{text:"<p>Text</p>"}}}}},{title:"Image",id:"image",plugins:{xwalk:{page:{resourceType:"core/franklin/components/image/v1/image",template:{image:"",imageAlt:""}}}}},{title:"Button",id:"button",plugins:{xwalk:{page:{resourceType:"core/franklin/components/button/v1/button",template:{text:"Button",href:"",type:""}}}}},{title:"Title",id:"title",plugins:{xwalk:{page:{resourceType:"core/franklin/components/title/v1/title",template:{title:"Title",type:"h2"}}}}}],br=[{id:"title",fields:[{component:"text",valueType:"string",name:"title",label:"Title"},{component:"select",valueType:"string",name:"type",label:"Type",value:"h2",options:[{name:"H1",value:"h1"},{name:"H2",value:"h2"},{name:"H3",value:"h3"},{name:"H4",value:"h4"},{name:"H5",value:"h5"},{name:"H6",value:"h6"}]}]},{id:"image",fields:[{component:"reference",valueType:"string",name:"image",label:"Image",multi:!1},{component:"text",valueType:"string",name:"imageAlt",label:"Alt Text"}]},{id:"button",fields:[{component:"text",valueType:"string",name:"text",label:"Text"},{component:"aem-content",name:"href",label:"Link"},{component:"select",valueType:"string",name:"type",label:"Type",options:[{name:"Default",value:""},{name:"Primary",value:"primary"},{name:"Secondary",value:"secondary"}]}]}];yr=`// Block: field-reference
326
+ }`}],oo=yt.map(e=>e.id)});function _l(){return[{component:"tab",name:"basics",label:"Basics"},{component:"text",valueType:"string",name:"text",label:"Text (single line)"},{component:"textarea",valueType:"string",name:"textarea",label:"Textarea (multi-line)"},{component:"richtext",valueType:"string",name:"richtext",value:"",label:"Rich text"},{component:"number",valueType:"number",name:"number",label:"Number"},{component:"boolean",valueType:"boolean",name:"boolean",value:!1,label:"Boolean"},{component:"date-time",valueType:"date",name:"date",label:"Date / time"},{component:"tab",name:"selection",label:"Selection"},{component:"select",valueType:"string",name:"select",label:"Select",value:"a",options:[{name:"Option A",value:"a"},{name:"Option B",value:"b"}]},{component:"radio-group",valueType:"string",name:"radio",label:"Radio group",value:"x",options:[{name:"X",value:"x"},{name:"Y",value:"y"}]},{component:"multiselect",valueType:"string",name:"classes",label:"Multiselect (CSS classes)",options:[{name:"Highlight",value:"highlight"},{name:"Dark",value:"dark"}]},{component:"checkbox-group",valueType:"string[]",name:"toggles",label:"Checkbox group",options:[{name:"Show title",value:"show-title"},{name:"Show image",value:"show-image"}]},{component:"tab",name:"media",label:"Media & content"},{component:"reference",valueType:"string",name:"image",label:"Image (DAM asset)"},{component:"text",valueType:"string",name:"imageAlt",label:"Image alt"},{component:"aem-content",name:"link",label:"Link (page / URL)"},{component:"aem-content-fragment",name:"contentFragment",label:"Content Fragment"},{component:"aem-experience-fragment",name:"experienceFragment",label:"Experience Fragment"},{component:"aem-tag",valueType:"string",name:"tags",label:"Tags"},{component:"tab",name:"repeatable",label:"Multifield"},{component:"container",name:"items",label:"Items (repeatable)",multi:!0,collapsible:!0,fields:[{component:"text",valueType:"string",name:"itemTitle",label:"Title"},{component:"richtext",valueType:"string",name:"itemText",value:"",label:"Text"},{component:"aem-content",name:"itemLink",label:"Link"}]}]}function io(){let e={definitions:[{title:"Field Reference",id:"field-reference",plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:"Field Reference",model:"field-reference"}}}}}],models:[{id:"field-reference",fields:_l()}],filters:[]};return`${JSON.stringify(e,null,2)}
327
+ `}function ro(e,t){let n=new Set(e.map(o=>o.id));return[...e,...t.filter(o=>!n.has(o.id))]}function Fr(e,t,n){let o=e?.groups?[...e.groups]:[],i=(r,s,l)=>{let c=o.find(d=>d.id===r);c||(c={id:r,title:s,components:[]},o.push(c)),c.components=ro(c.components,l)};return i("default","Default Content",t),i("blocks","Blocks",n),{groups:o}}function vt(e,t){let n=e?[...e]:[],o=n.find(i=>i.id==="section");return o||(o={id:"section",components:["text","image","button","title"]},n.push(o)),o.components=[...new Set([...o.components,...t])],n}var Cr,Tr,Ar,Rr,ao=v(()=>{"use strict";f();Cr=[{title:"Text",id:"text",plugins:{xwalk:{page:{resourceType:"core/franklin/components/text/v1/text",template:{text:"<p>Text</p>"}}}}},{title:"Image",id:"image",plugins:{xwalk:{page:{resourceType:"core/franklin/components/image/v1/image",template:{image:"",imageAlt:""}}}}},{title:"Button",id:"button",plugins:{xwalk:{page:{resourceType:"core/franklin/components/button/v1/button",template:{text:"Button",href:"",type:""}}}}},{title:"Title",id:"title",plugins:{xwalk:{page:{resourceType:"core/franklin/components/title/v1/title",template:{title:"Title",type:"h2"}}}}}],Tr=[{id:"title",fields:[{component:"text",valueType:"string",name:"title",label:"Title"},{component:"select",valueType:"string",name:"type",label:"Type",value:"h2",options:[{name:"H1",value:"h1"},{name:"H2",value:"h2"},{name:"H3",value:"h3"},{name:"H4",value:"h4"},{name:"H5",value:"h5"},{name:"H6",value:"h6"}]}]},{id:"image",fields:[{component:"reference",valueType:"string",name:"image",label:"Image",multi:!1},{component:"text",valueType:"string",name:"imageAlt",label:"Alt Text"}]},{id:"button",fields:[{component:"text",valueType:"string",name:"text",label:"Text"},{component:"aem-content",name:"href",label:"Link"},{component:"select",valueType:"string",name:"type",label:"Type",options:[{name:"Default",value:""},{name:"Primary",value:"primary"},{name:"Secondary",value:"secondary"}]}]}];Ar=`// Block: field-reference
328
328
  // A living reference of every Universal Editor field type (see _field-reference.json).
329
329
  // Authors use it to see what's available; delete it before launch.
330
330
  export default function decorate(block) {
@@ -333,29 +333,31 @@ export default function decorate(block) {
333
333
  // are what you drop and edit.
334
334
  block.classList.add('field-reference');
335
335
  }
336
- `,vr=`/* Block: field-reference */
336
+ `,Rr=`/* Block: field-reference */
337
337
  .field-reference {
338
338
  display: grid;
339
339
  gap: var(--spacing-m, 16px);
340
340
  padding: var(--spacing-l, 32px) 0;
341
341
  }
342
- `});var fe={};O(fe,{scaffoldBlocks:()=>Sr,scaffoldCi:()=>jr,scaffoldEnv:()=>Er,scaffoldHelpers:()=>Pr,scaffoldInteractive:()=>ol,scaffoldUe:()=>on,scaffoldXwalk:()=>Cr});import{existsSync as xr}from"fs";import{mkdir as $r,readFile as nl,writeFile as De}from"fs/promises";import se from"path";async function tn(e){if(!xr(e))return null;try{return JSON.parse(await nl(e,"utf-8"))}catch{return null}}async function nn(e,t){await De(e,`${JSON.stringify(t,null,2)}
343
- `)}async function on(){let e=E();if(!e){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Scaffold - Universal Editor"));let t=[],n=se.join(e,"blocks","field-reference");await $r(n,{recursive:!0}),await De(se.join(n,"field-reference.js"),yr),await De(se.join(n,"field-reference.css"),vr),await De(se.join(n,"_field-reference.json"),Jn()),t.push("blocks/field-reference/ (all 17 fields + multifield)");let o=se.join(e,"component-definition.json"),i=se.join(e,"component-models.json"),s=se.join(e,"component-filters.json"),a=[{title:"Field Reference",id:"field-reference",plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:"Field Reference",model:"field-reference"}}}}}],l=kr(await tn(o),wr,a);await nn(o,l),t.push("component-definition.json (default content + field-reference)");let c=await tn(i)??[],d=JSON.parse(Jn()).models[0],m=qn(c,[...br,d]);await nn(i,m),t.push("component-models.json (title / image / button / field-reference)");let p=ft(await tn(s),["field-reference"]);await nn(s,p),t.push("component-filters.json (section filter)"),r.info(S("Created / merged"));let u=t.map(h=>h.split(" ")[0]),g=U(u);for(let h of t){let[b,...y]=h.split(" ");r.info(j(b,y.join(" ").replace(/^\((.*)\)$/,"$1"),g))}r.info(""),r.info(I(["Universal Editor scaffold ready"]))}async function Sr(e){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Scaffold \u2014 standard blocks"));let n;if(e?.length){n=e.map(d=>Gn(d.trim())).filter(d=>!!d);let c=e.filter(d=>!Gn(d.trim()));c.length&&r.warn(`Unknown block(s): ${c.join(", ")}. Available: ${Fe.map(d=>d.id).join(", ")}`)}else n=Fe;let o=[],i=[];for(let c of n){let d=se.join(t,"blocks",c.id);if(xr(d)){i.push(c.id);continue}await $r(d,{recursive:!0}),await De(se.join(d,`${c.id}.js`),c.js),await De(se.join(d,`${c.id}.css`),c.css),await De(se.join(d,`_${c.id}.json`),c.model),o.push(c.id)}let s=se.join(t,"component-filters.json"),a=ft(await tn(s),n.map(c=>c.id));await nn(s,a),r.info(S("Blocks"));let l=U([...o,...i,"component-filters"]);for(let c of o)r.info(j(c,"created",l));for(let c of i)r.info(R("warn",c,"already exists \u2014 skipped",l));r.info(""),r.info(I([`${o.length} block(s) scaffolded + registered`]))}async function jr(){let e=E();if(!e){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Scaffold - CI workflow"));let t=await Xt(e);r.info(S("GitHub Actions")),t.created?r.info(j(t.path,"doctor + audit loading + audit security + lint/build")):r.info(R("warn",t.path,"already exists - skipped")),r.info(""),r.info(I([t.created?"CI workflow scaffolded - commit it and it runs on every PR":"CI workflow left untouched"]))}async function Pr(e){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Scaffold - helpers"));let n=e?.length?e:void 0;if(!n)if(process.stdout.isTTY){let{checkbox:i}=await Promise.resolve().then(()=>(H(),B));n=await i({message:"Which helpers?",choices:ut.map(s=>({name:s.label,value:s.id,checked:!0}))})}else n=zn;if(!n.length){r.info("Nothing selected.");return}let o=await gr(t,n);r.info(S("Helpers")),o.created?r.info(j(o.path,o.helpers.join(", "))):r.info(R("warn",o.path,"already exists - skipped")),r.info(""),r.info(I([o.created?`${o.helpers.length} helper(s) -> scripts/utils.js`:"Helpers left untouched"]))}async function Er(e={}){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Scaffold - .env"));let n=e.pagesUrl;if(n===void 0)try{let{execa:a}=await import("execa"),l=await a("git",["remote","get-url","origin"],{cwd:t}),c=qe(l.stdout.trim());n=c?`https://${Ke(c.owner,c.repo)}`:""}catch{n=""}let o=e.open??"/",i=e.port??"3007";if(!e.yes&&process.stdout.isTTY){let{input:a}=await Promise.resolve().then(()=>(H(),B));o=await a({message:"AEM_OPEN (path opened on start)",default:o}),i=await a({message:"AEM_PORT",default:String(i)}),n=await a({message:"AEM_PAGES_URL (content origin)",default:n})}let s=await Yt(t,{open:o,port:i,pagesUrl:n});r.info(S(".env")),s.created?r.info(j(s.path,`AEM_OPEN=${o} AEM_PORT=${i}`)):r.info(R("warn",s.path,"already exists - left untouched")),s.gitignoreUpdated&&r.info(j(".gitignore","added .env")),r.info(""),r.info(I([s.created?".env ready for `aem up`":".env left untouched"]))}async function Cr(){let e=E();if(!e){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Scaffold - xwalk.json"));let t=await Zt(e);r.info(S("xwalk.json")),t.created?r.info(j(t.path,"multi-field enabled")):r.info(R("warn",t.path,"already exists - left untouched")),r.info(""),r.info(I([t.created?"xwalk.json ready (UE multi-field)":"xwalk.json left untouched"]))}async function ol(){let{select:e,checkbox:t}=await Promise.resolve().then(()=>(H(),B));r.logoOnce(T("Scaffold"));let n=await e({message:"What do you want to scaffold?",choices:[{name:"Universal Editor config + field-reference (all 17 field types)",value:"ue"},{name:"Standard blocks (hero, cards, columns, accordion, embed)",value:"blocks"},{name:"GitHub Actions CI (doctor + audits + lint/build)",value:"ci"},{name:"Helper functions (scripts/utils.js)",value:"helpers"},{name:"Local-dev .env (aem up: port / open / pages URL)",value:"env"},{name:"xwalk.json (enable Universal Editor multi-field)",value:"xwalk"},{name:"UE config + standard blocks",value:"both"}]});if(n==="env")return Er();if(n==="xwalk")return Cr();if((n==="ue"||n==="both")&&await on(),n==="blocks"||n==="both"){let o=await t({message:"Which blocks?",choices:Fe.map(i=>({name:i.title,value:i.id,checked:!0}))});await Sr(o)}n==="ci"&&await jr(),n==="helpers"&&await Pr()}var me=k(()=>{"use strict";f();D();z();Wn();_n();Un();hr();Kn();Bn();en();_()});var sn={};O(sn,{initProject:()=>cl});import{existsSync as Xn}from"fs";import{readFile as Yn,writeFile as Tr}from"fs/promises";import rn from"path";import Vn from"chalk";async function il(e){try{let{execa:t}=await import("execa"),n=await t("git",["remote","get-url","origin"],{cwd:e}),o=qe(n.stdout.trim());return o?`https://${Ke(o.owner,o.repo)}`:""}catch{return""}}async function rl(e,t){let n=rn.join(e,"package.json");if(!Xn(n))return!1;try{let o=JSON.parse(await Yn(n,"utf-8"));return o.name=t,await Tr(n,`${JSON.stringify(o,null,2)}
344
- `),!0}catch{return!1}}async function sl(e,t){let n=[];for(let o of["README.md","index.html","head.html"]){let i=rn.join(e,o);if(Xn(i))try{let s=await Yn(i,"utf-8"),a=s.replace(/aem-boilerplate/gi,t);a!==s&&(await Tr(i,a),n.push(o))}catch{}}return n}async function al(e){let{confirm:t}=await Promise.resolve().then(()=>(H(),B)),n=[{title:"Install the AEM Code Sync GitHub app",url:"https://github.com/apps/aem-code-sync/installations/new",note:"Connects your repo to the Edge Delivery pipeline (preview/publish)."}];e==="gdrive"&&n.push({title:"Share your content folder",note:"Share the Google Drive folder with the AEM service and set it as the mountpoint."}),e==="sharepoint"&&n.push({title:"Share your content folder",note:"Grant the SharePoint/OneDrive folder to the AEM service account."}),e==="da"&&n.push({title:"Author in DA",url:"https://da.live",note:"Create documents at da.live."}),e==="ue"&&n.push({title:"Open the Universal Editor",url:"https://experience.adobe.com",note:"Author in-context once the repo is connected to AEM."}),n.push({title:"Install the AEM Sidekick extension",url:"https://chromewebstore.google.com/detail/aem-sidekick/igkmdomcgoebiipaifhmpfjhbjccggml",note:"Preview and publish from the browser."}),n.push({title:"Run the local dev server",note:"npm install, then `aem up` (from @adobe/aem-cli)."}),r.info(S("Next steps (outside the repo)"));for(let o=0;o<n.length;o++){let i=n[o];r.info(` ${M.accent(String(o+1))} ${Vn.bold(i.title)}`),i.url&&r.info(` ${Vn.cyan(i.url)}`),r.info(` ${Vn.dim(i.note)}`),await t({message:" Done / skip?",default:!0})}}async function cl(e={}){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found). Clone an EDS boilerplate first, then run this from its root."),process.exitCode=1;return}await r.logoOnceAnimated("Project setup");let{input:n,select:o,confirm:i}=await Promise.resolve().then(()=>(H(),B)),s=!e.yes,a=rn.basename(t),l=rn.join(t,"package.json");if(Xn(l))try{a=JSON.parse(await Yn(l,"utf-8")).name||a}catch{}let c=e.name&&gt(e.name)||gt(await n({message:"1/4 Project name",default:gt(a),validate:b=>!!gt(b)||"Use letters, numbers and dashes"})),d=e.authoring??await o({message:"2/4 Authoring model",choices:[{name:Ae.ue,value:"ue"},{name:Ae.da,value:"da"},{name:Ae.gdrive,value:"gdrive"},{name:Ae.sharepoint,value:"sharepoint"}]}),m=e.mountpoint;if(Qt(d)&&!m)if(d==="da"&&(e.org||s)){let b=e.org??await n({message:" DA org",validate:v=>!!v.trim()||"Required"}),y=e.site??(s?await n({message:" DA site",default:c}):c);m=ir(b.trim(),gt(y))}else d!=="da"&&s&&(m=(await n({message:` ${d==="gdrive"?"Google Drive folder URL":"SharePoint folder URL"}`,validate:y=>/^https?:\/\//.test(y.trim())||"Paste the folder URL"})).trim());let p=e.ci??(s?await i({message:"4/4 Add GitHub Actions CI (audits gatekeeper)?",default:!0}):!0);r.info(S("Summary"));let u=U(["name","authoring","mountpoint","ci"]);if(r.info(j("name",c,u)),r.info(j("authoring",Ae[d],u)),m?r.info(j("mountpoint",m,u)):Qt(d)&&r.info(j("mountpoint","(skipped - set it in fstab.yaml later)",u)),r.info(j("ci",p?"yes":"no",u)),r.info(""),s&&!await i({message:"Apply this setup?",default:!0})){r.info("Cancelled.");return}let g=[];await rl(t,c)&&g.push("package.json (name)");for(let b of await sl(t,c))g.push(`${b} (renamed)`);if(Qt(d)&&m&&g.push(await rr(t,m)),d==="ue"&&(await on(),g.push(await sr(t,c))),p){let b=await Xt(t);g.push(b.created?b.path:`${b.path} (exists, skipped)`)}if(e.env!==!1){let b=await Yt(t,{pagesUrl:await il(t)});g.push(b.created?".env (aem up config)":".env (exists, skipped)")}if(e.xwalk!==!1&&d==="ue"){let b=await Zt(t);g.push(b.created?`${b.path} (UE multi-field)`:`${b.path} (exists, skipped)`)}r.info(S("Configured"));let h=U(g.map(b=>b.split(" ")[0]));for(let b of g){let[y,...v]=b.split(" ");r.info(j(y,v.join(" ").replace(/^\((.*)\)$/,"$1"),h))}r.info(""),s&&await al(d),r.info(I([`"${c}" set up for ${Ae[d]}`]))}var gt,an=k(()=>{"use strict";f();D();z();_n();Un();ar();Bn();en();_();me();gt=e=>e.trim().toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/^-+|-+$/g,"")});var Le={};O(Le,{sandboxList:()=>gl,sandboxLogin:()=>pl,sandboxLogout:()=>ul,sandboxNew:()=>fl,sandboxRm:()=>hl});import ll from"path";import oe from"chalk";async function ge(e,t,n={}){let{execa:o}=await import("execa");return((await o(e,t,n)).stdout??"").toString().trim()}async function Qn(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{await ge(t,[e],{stdio:"ignore"})}catch{}}async function dl(){try{return await ge("gh",["auth","status"]),await ge("gh",["api","user","-q",".login"])}catch{return null}}async function Zn(){let e=await Bi();if(e)try{return{mode:"api",token:e,login:await Jt(e)}}catch{}let t=await dl();return t?{mode:"gh",login:t}:null}async function ml(e,t,n){if(e.mode==="api")return Fi(e.token,t,n);try{return await ge("gh",["repo","view",`${t}/${n}`,"--json","name"]),!0}catch{return!1}}function eo(){r.error("Not authenticated with GitHub."),r.info(" Run `eds sandbox login` to authorize GitHub, or install + `gh auth login`."),process.exitCode=1}async function pl(){await r.logoOnceAnimated("Sandbox - GitHub login");let{input:e}=await Promise.resolve().then(()=>(H(),B));if(qt){let n=await Gi(["repo","delete_repo"]);r.info(S("Authorize GitHub")),r.info(j("code",n.user_code)),r.info(j("open",n.verification_uri)),r.info(""),await Qn(n.verification_uri),r.info(oe.dim(" Waiting for you to authorize in the browser..."));try{let o=await Wi(n.device_code,n.interval,n.expires_in);await Nn(o),r.success(`Authorized as ${await Jt(o)}.`)}catch(o){r.error(`Device flow failed: ${o.message}`),process.exitCode=1}return}r.info(S("Authorize GitHub (least-privilege token)")),r.info(" Create a fine-grained token limited to your sandboxes only:"),r.info(` ${oe.cyan("https://github.com/settings/personal-access-tokens/new")}`),r.info(oe.dim(" - Resource owner: a dedicated sandbox org (recommended) or your account")),r.info(oe.dim(" - Repository access: All repositories in that org (to create new sandboxes),")),r.info(oe.dim(" or Only select repositories to manage existing ones")),r.info(oe.dim(" - Permissions: Administration = Read and write, Contents = Read and write,")),r.info(oe.dim(" Metadata = Read. Set a short expiry.")),r.info(oe.dim(" Tip: `eds sandbox new --org <sandbox-org>` so nothing in your personal account is touched.")),r.info(""),await(await Promise.resolve().then(()=>(H(),B))).confirm({message:"Open the token page?",default:!0})&&await Qn("https://github.com/settings/personal-access-tokens/new");let t=(await e({message:"Paste the token",validate:n=>!!n.trim()||"Required"})).trim();try{let n=await Jt(t);await Nn(t),r.success(`Authorized as ${n}.`)}catch{r.error("That token didn't work (check the scopes)."),process.exitCode=1}}async function ul(){await Hi(),r.success("Signed out (stored GitHub token removed).")}async function fl(e,t={}){let n=await Zn();if(!n)return eo();await r.logoOnceAnimated("Sandbox");let o=!t.yes,{select:i,confirm:s}=await Promise.resolve().then(()=>(H(),B)),a=t.boilerplate;a||(t.ue?a=dt.ue:o?a=await i({message:"Which boilerplate?",choices:[{name:"Document Authoring (adobe/aem-boilerplate)",value:dt.document},{name:"Universal Editor / crosswalk (adobe/aem-boilerplate-xwalk)",value:dt.ue}]}):a=dt.document);let l=t.private??!1;t.private===void 0&&o&&(l=await i({message:"Visibility?",choices:[{name:"Public",value:!1},{name:"Private",value:!0}],default:!1}));let c=t.org??n.login;if(await ml(n,c,e)){r.error(`A repository ${c}/${e} already exists - refusing to touch it.`),r.info(oe.dim(" Pick another name, or remove it first (e.g. `eds sandbox rm` for a sandbox).")),process.exitCode=1;return}r.info(S("Creating sandbox",`${c}/${e} \xB7 ${a}`));try{if(n.mode==="api"){let d=await Di(n.token,a,{owner:c,name:e,private:l});await Li(n.token,c,e,[ze]),r.info(oe.dim(" Cloning...")),await ge("git",["clone",d.cloneUrl,e],{stdio:"inherit"})}else{let d=t.org?`${t.org}/${e}`:e;await ge("gh",Ji(d,{template:a,private:l,clone:!0}),{stdio:"inherit"});try{await ge("gh",["repo","edit",`${c}/${e}`,"--add-topic",ze])}catch{}}}catch(d){r.error(`Create failed: ${d.message}`),process.exitCode=1;return}if(r.info(""),r.info(S("Sandbox ready")),r.info(j("repo",`https://github.com/${c}/${e}`)),r.info(j("preview",On(c,e))),r.info(""),o){if(await s({message:"Open the AEM Code Sync install page now?",default:!0})&&await Qn(Mn()),await s({message:`Configure authoring now (eds init in ./${e})?`,default:!0})){let d=process.cwd();try{process.chdir(ll.join(d,e));let{initProject:m}=await Promise.resolve().then(()=>(an(),sn));await m({})}finally{process.chdir(d)}}}else r.info(oe.dim(` Install AEM Code Sync: ${Mn()}`)),r.info(oe.dim(` Configure authoring: cd ${e} && eds init`));r.info(""),r.info(I([`Sandbox "${e}" ready - tear down with \`eds sandbox rm ${e}\``]))}async function gl(){let e=await Zn();if(!e)return eo();let t=[];try{if(e.mode==="api")t=await Oi(e.token,e.login,ze);else{let o=await ge("gh",["repo","list","--topic",ze,"--limit","100","--json","nameWithOwner","-q",".[].nameWithOwner"]);t=o?o.split(`
345
- `).filter(Boolean):[]}}catch(o){r.error(`List failed: ${o.message}`),process.exitCode=1;return}if(r.info(S("Sandboxes",`${t.length} tagged ${ze}`)),t.length===0){r.info(oe.dim(" None yet. Create one with `eds sandbox new <name>`."));return}let n=U(t);for(let o of t){let[i,s]=o.split("/");r.info(j(o,On(i,s),n))}}async function hl(e,t={}){let n=await Zn();if(!n)return eo();let o=t.org??n.login,i=`${o}/${e}`;if(!t.yes){let{confirm:s}=await Promise.resolve().then(()=>(H(),B));if(!await s({message:`Permanently delete ${i}? This cannot be undone.`,default:!1})){r.info("Cancelled.");return}}try{n.mode==="api"?await Ni(n.token,o,e):await ge("gh",["repo","delete",i,"--yes"])}catch(s){r.error(`Delete failed: ${s.message}`),r.info(oe.dim(" Deleting needs the delete_repo scope (re-run `eds sandbox login`, or `gh auth refresh -s delete_repo`).")),process.exitCode=1;return}r.info(S("Deleted")),r.info(j(i,"removed"))}var Ne=k(()=>{"use strict";f();D();Mi();zi();qi();_()});import{existsSync as wl}from"fs";import{readFile as bl}from"fs/promises";import yl from"path";import{parse as vl}from"yaml";async function Rr(e){let t=yl.join(e,"fstab.yaml");if(wl(t))try{let o=(vl(await bl(t,"utf-8"))??{}).mountpoints?.["/"],i=typeof o=="string"?o:o?.url??"",s=i.match(/content\.da\.live\/([^/]+)\/([^/]+)/);return s?{model:"da",org:s[1],site:s[2],mountpoint:i}:/drive\.google\.com/.test(i)?{model:"gdrive",mountpoint:i}:/sharepoint\.com|-my\.sharepoint/.test(i)?{model:"sharepoint",mountpoint:i}:{model:"document",mountpoint:i}}catch{}return{model:"ue"}}var Ar=k(()=>{"use strict";f()});function kl(e,t,n){let o=n.replace(/^\/+/,"").replace(/\.html$/i,"");return`https://admin.da.live/source/${e}/${t}/${o}.html`}function Fr(e,t,n){let o=n.replace(/^\/+/,"").replace(/\.html$/i,"");return`https://da.live/edit#/${e}/${t}/${o}`}async function Dr(e,t,n,o,i){let s=kl(e,t,n),a=new FormData;a.append("data",new Blob([o],{type:"text/html"}),"content.html");let l={};i&&(l.Authorization=`Bearer ${i}`);let c=await fetch(s,{method:"POST",body:a,headers:l});if(!c.ok)throw new Error(`DA push failed: ${c.status} ${c.statusText}`);return s}var Lr=k(()=>{"use strict";f()});function xl(e){return` <div class="${e}">
342
+ `});var we={};M(we,{scaffoldBlocks:()=>Or,scaffoldCi:()=>Nr,scaffoldEnv:()=>_r,scaffoldHelpers:()=>Mr,scaffoldInteractive:()=>Ul,scaffoldUe:()=>pn,scaffoldXwalk:()=>Ir});import{existsSync as Lr}from"fs";import{mkdir as Dr,readFile as Il,writeFile as _e}from"fs/promises";import se from"path";async function dn(e){if(!Lr(e))return null;try{return JSON.parse(await Il(e,"utf-8"))}catch{return null}}async function mn(e,t){await _e(e,`${JSON.stringify(t,null,2)}
343
+ `)}async function pn(){let e=E();if(!e){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Scaffold - Universal Editor"));let t=[],n=se.join(e,"blocks","field-reference");await Dr(n,{recursive:!0}),await _e(se.join(n,"field-reference.js"),Ar),await _e(se.join(n,"field-reference.css"),Rr),await _e(se.join(n,"_field-reference.json"),io()),t.push("blocks/field-reference/ (all 17 fields + multifield)");let o=se.join(e,"component-definition.json"),i=se.join(e,"component-models.json"),r=se.join(e,"component-filters.json"),s=[{title:"Field Reference",id:"field-reference",plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:"Field Reference",model:"field-reference"}}}}}],l=Fr(await dn(o),Cr,s);await mn(o,l),t.push("component-definition.json (default content + field-reference)");let c=await dn(i)??[],d=JSON.parse(io()).models[0],m=ro(c,[...Tr,d]);await mn(i,m),t.push("component-models.json (title / image / button / field-reference)");let p=vt(await dn(r),["field-reference"]);await mn(r,p),t.push("component-filters.json (section filter)"),a.info(j("Created / merged"));let u=t.map(h=>h.split(" ")[0]),g=I(u);for(let h of t){let[$,...b]=h.split(" ");a.info(P($,b.join(" ").replace(/^\((.*)\)$/,"$1"),g))}a.info(""),a.info(B(["Universal Editor scaffold ready"]))}async function Or(e){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Scaffold \u2014 standard blocks"));let n;if(e?.length){n=e.map(d=>to(d.trim())).filter(d=>!!d);let c=e.filter(d=>!to(d.trim()));c.length&&a.warn(`Unknown block(s): ${c.join(", ")}. Available: ${Me.map(d=>d.id).join(", ")}`)}else n=Me;let o=[],i=[];for(let c of n){let d=se.join(t,"blocks",c.id);if(Lr(d)){i.push(c.id);continue}await Dr(d,{recursive:!0}),await _e(se.join(d,`${c.id}.js`),c.js),await _e(se.join(d,`${c.id}.css`),c.css),await _e(se.join(d,`_${c.id}.json`),c.model),o.push(c.id)}let r=se.join(t,"component-filters.json"),s=vt(await dn(r),n.map(c=>c.id));await mn(r,s),a.info(j("Blocks"));let l=I([...o,...i,"component-filters"]);for(let c of o)a.info(P(c,"created",l));for(let c of i)a.info(R("warn",c,"already exists \u2014 skipped",l));a.info(""),a.info(B([`${o.length} block(s) scaffolded + registered`]))}async function Nr(){let e=E();if(!e){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Scaffold - CI workflow"));let t=await on(e);a.info(j("GitHub Actions")),t.created?a.info(P(t.path,"doctor + audit loading + audit security + lint/build")):a.info(R("warn",t.path,"already exists - skipped")),a.info(""),a.info(B([t.created?"CI workflow scaffolded - commit it and it runs on every PR":"CI workflow left untouched"]))}async function Mr(e){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Scaffold - helpers"));let n=e?.length?e:void 0;if(!n)if(process.stdout.isTTY){let{checkbox:i}=await Promise.resolve().then(()=>(G(),H));n=await i({message:"Which helpers?",choices:yt.map(r=>({name:r.label,value:r.id,checked:!0}))})}else n=oo;if(!n.length){a.info("Nothing selected.");return}let o=await Pr(t,n);a.info(j("Helpers")),o.created?a.info(P(o.path,o.helpers.join(", "))):a.info(R("warn",o.path,"already exists - skipped")),a.info(""),a.info(B([o.created?`${o.helpers.length} helper(s) -> scripts/utils.js`:"Helpers left untouched"]))}async function _r(e={}){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Scaffold - .env"));let n=e.pagesUrl;if(n===void 0)try{let{execa:s}=await import("execa"),l=await s("git",["remote","get-url","origin"],{cwd:t}),c=Qe(l.stdout.trim());n=c?`https://${Ze(c.owner,c.repo)}`:""}catch{n=""}let o=e.open??"/",i=e.port??"3007";if(!e.yes&&process.stdout.isTTY){let{input:s}=await Promise.resolve().then(()=>(G(),H));o=await s({message:"AEM_OPEN (path opened on start)",default:o}),i=await s({message:"AEM_PORT",default:String(i)}),n=await s({message:"AEM_PAGES_URL (content origin)",default:n})}let r=await rn(t,{open:o,port:i,pagesUrl:n});a.info(j(".env")),r.created?a.info(P(r.path,`AEM_OPEN=${o} AEM_PORT=${i}`)):a.info(R("warn",r.path,"already exists - left untouched")),r.gitignoreUpdated&&a.info(P(".gitignore","added .env")),a.info(""),a.info(B([r.created?".env ready for `aem up`":".env left untouched"]))}async function Ir(){let e=E();if(!e){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Scaffold - xwalk.json"));let t=await cn(e);a.info(j("xwalk.json")),t.created?a.info(P(t.path,"multi-field enabled")):a.info(R("warn",t.path,"already exists - left untouched")),a.info(""),a.info(B([t.created?"xwalk.json ready (UE multi-field)":"xwalk.json left untouched"]))}async function Ul(){let{select:e,checkbox:t}=await Promise.resolve().then(()=>(G(),H));a.logoOnce(A("Scaffold"));let n=await e({message:"What do you want to scaffold?",choices:[{name:"Universal Editor config + field-reference (all 17 field types)",value:"ue"},{name:"Standard blocks (hero, cards, columns, accordion, embed)",value:"blocks"},{name:"GitHub Actions CI (doctor + audits + lint/build)",value:"ci"},{name:"Helper functions (scripts/utils.js)",value:"helpers"},{name:"Local-dev .env (aem up: port / open / pages URL)",value:"env"},{name:"xwalk.json (enable Universal Editor multi-field)",value:"xwalk"},{name:"UE config + standard blocks",value:"both"}]});if(n==="env")return _r();if(n==="xwalk")return Ir();if((n==="ue"||n==="both")&&await pn(),n==="blocks"||n==="both"){let o=await t({message:"Which blocks?",choices:Me.map(i=>({name:i.title,value:i.id,checked:!0}))});await Or(o)}n==="ci"&&await Nr(),n==="helpers"&&await Mr()}var ue=v(()=>{"use strict";f();D();J();no();Yn();Qn();Er();ao();Zn();ln();U()});var kt={};M(kt,{initProject:()=>zl});import{existsSync as so}from"fs";import{readFile as co,writeFile as Ur}from"fs/promises";import fn from"path";import un from"chalk";async function Bl(e){try{let{execa:t}=await import("execa"),n=await t("git",["remote","get-url","origin"],{cwd:e}),o=Qe(n.stdout.trim());return o?`https://${Ze(o.owner,o.repo)}`:""}catch{return""}}async function Hl(e,t){let n=fn.join(e,"package.json");if(!so(n))return!1;try{let o=JSON.parse(await co(n,"utf-8"));return o.name=t,await Ur(n,`${JSON.stringify(o,null,2)}
344
+ `),!0}catch{return!1}}async function Gl(e,t){let n=[];for(let o of["README.md","index.html","head.html"]){let i=fn.join(e,o);if(so(i))try{let r=await co(i,"utf-8"),s=r.replace(/aem-boilerplate/gi,t);s!==r&&(await Ur(i,s),n.push(o))}catch{}}return n}async function Wl(e){let{confirm:t}=await Promise.resolve().then(()=>(G(),H)),n=[{title:"Install the AEM Code Sync GitHub app",url:"https://github.com/apps/aem-code-sync/installations/new",note:"Connects your repo to the Edge Delivery pipeline (preview/publish)."}];e==="gdrive"&&n.push({title:"Share your content folder",note:"Share the Google Drive folder with the AEM service and set it as the mountpoint."}),e==="sharepoint"&&n.push({title:"Share your content folder",note:"Grant the SharePoint/OneDrive folder to the AEM service account."}),e==="da"&&n.push({title:"Author in DA",url:"https://da.live",note:"Create documents at da.live."}),e==="ue"&&n.push({title:"Open the Universal Editor",url:"https://experience.adobe.com",note:"Author in-context once the repo is connected to AEM."}),n.push({title:"Install the AEM Sidekick extension",url:"https://chromewebstore.google.com/detail/aem-sidekick/igkmdomcgoebiipaifhmpfjhbjccggml",note:"Preview and publish from the browser."}),n.push({title:"Run the local dev server",note:"npm install, then `aem up` (from @adobe/aem-cli)."}),a.info(j("Next steps (outside the repo)"));for(let o=0;o<n.length;o++){let i=n[o];a.info(` ${N.accent(String(o+1))} ${un.bold(i.title)}`),i.url&&a.info(` ${un.cyan(i.url)}`),a.info(` ${un.dim(i.note)}`),await t({message:" Done / skip?",default:!0})}}async function zl(e={}){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found). Clone an EDS boilerplate first, then run this from its root."),process.exitCode=1;return}await a.logoOnceAnimated("Project setup");let{input:n,select:o,confirm:i}=await Promise.resolve().then(()=>(G(),H)),r=!e.yes,s=fn.basename(t),l=fn.join(t,"package.json");if(so(l))try{let b=JSON.parse(await co(l,"utf-8")).name??"";b&&!/aem-boilerplate/i.test(b)&&(s=b)}catch{}let c=e.name&&et(e.name)||et(r?await n({message:"1/4 Project name",default:et(s),validate:b=>!!et(b)||"Use letters, numbers and dashes"}):s),d=e.authoring?void 0:await wr(t);if(!e.authoring&&!r&&!d){a.error("Couldn't detect the authoring model (no fstab.yaml mountpoint or paths.json). Pass --authoring ue|da|gdrive|sharepoint."),process.exitCode=1;return}d&&a.info(un.dim(` Detected: ${je[d]}`));let m=e.authoring??(r?await o({message:"2/4 Authoring model",default:d,choices:[{name:je.ue,value:"ue"},{name:je.da,value:"da"},{name:je.gdrive,value:"gdrive"},{name:je.sharepoint,value:"sharepoint"}]}):d),p=e.mountpoint;if(sn(m)&&!p)if(m==="da"&&(e.org||r)){let b=e.org??await n({message:" DA org",validate:w=>!!w.trim()||"Required"}),y=e.site??(r?await n({message:" DA site",default:c}):c);p=fr(b.trim(),et(y))}else m!=="da"&&r&&(p=(await n({message:` ${m==="gdrive"?"Google Drive folder URL":"SharePoint folder URL"}`,validate:y=>/^https?:\/\//.test(y.trim())||"Paste the folder URL"})).trim());let u=e.ci??(r?await i({message:"4/4 Add GitHub Actions CI (audits gatekeeper)?",default:!0}):!0);a.info(j("Summary"));let g=I(["name","authoring","mountpoint","ci"]);if(a.info(P("name",c,g)),a.info(P("authoring",je[m],g)),p?a.info(P("mountpoint",p,g)):sn(m)&&a.info(P("mountpoint","(skipped - set it in fstab.yaml later)",g)),a.info(P("ci",u?"yes":"no",g)),a.info(""),r&&!await i({message:"Apply this setup?",default:!0})){a.info("Cancelled.");return}let h=[];await Hl(t,c)&&h.push("package.json (name)");for(let b of await Gl(t,c))h.push(`${b} (renamed)`);if(sn(m)&&p&&h.push(await gr(t,p)),m==="ue"&&(await pn(),h.push(await hr(t,c))),u){let b=await on(t);h.push(b.created?b.path:`${b.path} (exists, skipped)`)}if(e.env!==!1){let b=await rn(t,{pagesUrl:await Bl(t)});h.push(b.created?".env (aem up config)":".env (exists, skipped)")}if(e.xwalk!==!1&&m==="ue"){let b=await cn(t);h.push(b.created?`${b.path} (UE multi-field)`:`${b.path} (exists, skipped)`)}a.info(j("Configured"));let $=I(h.map(b=>b.split(" ")[0]));for(let b of h){let[y,...w]=b.split(" ");a.info(P(y,w.join(" ").replace(/^\((.*)\)$/,"$1"),$))}a.info(""),r&&await Wl(m),a.info(B([`"${c}" set up for ${je[m]}`]))}var et,xt=v(()=>{"use strict";f();D();J();Yn();Qn();br();Zn();ln();U();ue();et=e=>e.trim().toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/^-+|-+$/g,"")});var lo={};M(lo,{newProject:()=>Jl});import Br from"path";import Hr from"chalk";async function Jl(e,t={}){await a.logoOnceAnimated("New project");let n=!t.yes,{input:o,select:i,confirm:r}=await Promise.resolve().then(()=>(G(),H)),s=e?.trim();if(!s){if(!n){a.error("Pass a folder: `eds new <dir>`."),process.exitCode=1;return}s=(await o({message:"Folder for the new project",default:"my-eds-site",validate:g=>!!g.trim()||"Required"})).trim()}let l=t.boilerplate;!l&&!t.ue&&n&&(l=await i({message:"Which boilerplate?",choices:[{name:`Document Authoring / DA (${Q.document})`,value:Q.document},{name:`Universal Editor / crosswalk (${Q.ue})`,value:Q.ue},{name:`Adobe Commerce storefront (${en})`,value:en}]}));let c=er(l,t.ue),d=Br.resolve(s);if(!await tr(d)){a.error(`${s} already exists and isn't empty - refusing to clone into it.`),process.exitCode=1;return}a.info(j("Cloning",`${c.label}${t.ref?`@${t.ref}`:""} \u2192 ${s}`));let m;try{m=await nr(c,d,{ref:t.ref,keepHistory:t.keepHistory,remote:t.remote,stdio:n?"inherit":"pipe"})}catch(g){a.error(g.message),process.exitCode=1;return}let p=I(["folder","source","history","origin"]);if(a.info(j("Project ready")),a.info(P("folder",d,p)),a.info(P("source",`${c.label} @ ${m.commit.slice(0,7)}`,p)),a.info(P("history",t.keepHistory?"boilerplate history kept (remote: upstream)":m.uncommitted?"fresh, files staged (set git user.name / user.email, then commit)":"fresh (one initial commit)",p)),a.info(P("origin",t.remote??"not set (git remote add origin <url>)",p)),a.info(""),t.install??(n?await r({message:"Install dependencies (npm install)?",default:!0}):!1))try{let{execa:g}=await import("execa");await g("npm",["install"],{cwd:d,stdio:n?"inherit":"pipe"}),a.success("Dependencies installed.")}catch(g){a.warn(`npm install failed: ${g.message.split(`
345
+ `)[0]}`)}if(n&&await r({message:`Configure authoring now (eds init in ${s})?`,default:!0})){let g=process.cwd();try{process.chdir(d);let{initProject:h}=await Promise.resolve().then(()=>(xt(),kt));await h({name:Br.basename(d),...c.ue?{authoring:"ue"}:{}})}finally{process.chdir(g)}return}a.info(Hr.dim(` Next: cd ${s} && eds init`)),a.info(Hr.dim(" Then push it to your own GitHub repo and install AEM Code Sync to get a preview URL."))}var mo=v(()=>{"use strict";f();or();D();Zt();U()});function nt(e){return{Authorization:`Bearer ${e}`,Accept:"application/vnd.github+json","X-GitHub-Api-Version":"2022-11-28","User-Agent":"aem-eds-kit","Content-Type":"application/json"}}function ql(e){return`${tt}/repos/${e}/generate`}async function gn(e){let t=await fetch(`${tt}/user`,{headers:nt(e)});if(!t.ok)throw new Error(`GitHub auth failed: ${t.status}`);return(await t.json()).login}async function Gr(e,t,n){let o=await fetch(`${tt}/repos/${t}/${n}`,{headers:nt(e)});if(o.status===404)return!1;if(o.ok)return!0;throw new Error(`existence check failed: ${o.status} ${await o.text()}`)}async function Wr(e,t,n){let o=await fetch(ql(t),{method:"POST",headers:nt(e),body:JSON.stringify({owner:n.owner,name:n.name,private:!!n.private,include_all_branches:!1})});if(!o.ok)throw new Error(`create failed: ${o.status} ${await o.text()}`);let i=await o.json();return{fullName:i.full_name,htmlUrl:i.html_url,cloneUrl:i.clone_url}}async function zr(e,t,n,o){await fetch(`${tt}/repos/${t}/${n}/topics`,{method:"PUT",headers:nt(e),body:JSON.stringify({names:o})})}async function Jr(e,t,n){let o=await fetch(`${tt}/repos/${t}/${n}`,{method:"DELETE",headers:nt(e)});if(!o.ok&&o.status!==204)throw new Error(`delete failed: ${o.status} ${await o.text()}`)}async function qr(e,t,n){let o=encodeURIComponent(`user:${t} topic:${n} fork:true`),i=await fetch(`${tt}/search/repositories?q=${o}&per_page=100`,{headers:nt(e)});if(!i.ok)throw new Error(`search failed: ${i.status}`);return(await i.json()).items.map(s=>s.full_name)}var tt,Kr=v(()=>{"use strict";f();tt="https://api.github.com"});import{existsSync as Xr}from"fs";import{mkdir as Kl,readFile as Xl,rm as Vl,writeFile as Yl}from"fs/promises";import Ql from"os";import Vr from"path";async function Qr(){let e=process.env.GITHUB_TOKEN||process.env.GH_TOKEN;if(e)return e;if(Xr($t))try{return JSON.parse(await Xl($t,"utf-8")).token??null}catch{return null}return null}async function po(e){await Kl(Yr,{recursive:!0,mode:448}),await Yl($t,`${JSON.stringify({token:e},null,2)}
346
+ `,{mode:384})}async function Zr(){Xr($t)&&await Vl($t)}async function ea(e){let t=await fetch("https://github.com/login/device/code",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({client_id:hn,scope:e.join(" ")})});if(!t.ok)throw new Error(`device code request failed: ${t.status}`);return await t.json()}async function ta(e,t,n){let o=Math.max(t,1),i=Date.now()+n*1e3;for(;Date.now()<i;){await new Promise(l=>setTimeout(l,o*1e3));let s=await(await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{Accept:"application/json","Content-Type":"application/json"},body:JSON.stringify({client_id:hn,device_code:e,grant_type:"urn:ietf:params:oauth:grant-type:device_code"})})).json();if(s.access_token)return s.access_token;if(s.error==="slow_down")o+=5;else if(s.error!=="authorization_pending")throw new Error(s.error??"device flow failed")}throw new Error("device flow timed out")}var Yr,$t,hn,na=v(()=>{"use strict";f();Yr=Vr.join(Ql.homedir(),".eds"),$t=Vr.join(Yr,"github.json"),hn=process.env.EDS_GITHUB_CLIENT_ID??""});var Ie={};M(Ie,{sandboxList:()=>rd,sandboxLogin:()=>nd,sandboxLogout:()=>od,sandboxNew:()=>id,sandboxRm:()=>ad});import Zl from"path";import re from"chalk";async function be(e,t,n={}){let{execa:o}=await import("execa");return((await o(e,t,n)).stdout??"").toString().trim()}async function uo(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{await be(t,[e],{stdio:"ignore"})}catch{}}async function ed(){try{return await be("gh",["auth","status"]),await be("gh",["api","user","-q",".login"])}catch{return null}}async function fo(){let e=await Qr();if(e)try{return{mode:"api",token:e,login:await gn(e)}}catch{}let t=await ed();return t?{mode:"gh",login:t}:null}async function td(e,t,n){if(e.mode==="api")return Gr(e.token,t,n);try{return await be("gh",["repo","view",`${t}/${n}`,"--json","name"]),!0}catch{return!1}}function go(){a.error("Not authenticated with GitHub."),a.info(" Run `eds sandbox login` to authorize GitHub, or install + `gh auth login`."),process.exitCode=1}async function nd(){await a.logoOnceAnimated("Sandbox - GitHub login");let{input:e}=await Promise.resolve().then(()=>(G(),H));if(hn){let n=await ea(["repo","delete_repo"]);a.info(j("Authorize GitHub")),a.info(P("code",n.user_code)),a.info(P("open",n.verification_uri)),a.info(""),await uo(n.verification_uri),a.info(re.dim(" Waiting for you to authorize in the browser..."));try{let o=await ta(n.device_code,n.interval,n.expires_in);await po(o),a.success(`Authorized as ${await gn(o)}.`)}catch(o){a.error(`Device flow failed: ${o.message}`),process.exitCode=1}return}a.info(j("Authorize GitHub (least-privilege token)")),a.info(" Create a fine-grained token limited to your sandboxes only:"),a.info(` ${re.cyan("https://github.com/settings/personal-access-tokens/new")}`),a.info(re.dim(" - Resource owner: a dedicated sandbox org (recommended) or your account")),a.info(re.dim(" - Repository access: All repositories in that org (to create new sandboxes),")),a.info(re.dim(" or Only select repositories to manage existing ones")),a.info(re.dim(" - Permissions: Administration = Read and write, Contents = Read and write,")),a.info(re.dim(" Metadata = Read. Set a short expiry.")),a.info(re.dim(" Tip: `eds sandbox new --org <sandbox-org>` so nothing in your personal account is touched.")),a.info(""),await(await Promise.resolve().then(()=>(G(),H))).confirm({message:"Open the token page?",default:!0})&&await uo("https://github.com/settings/personal-access-tokens/new");let t=(await e({message:"Paste the token",validate:n=>!!n.trim()||"Required"})).trim();try{let n=await gn(t);await po(t),a.success(`Authorized as ${n}.`)}catch{a.error("That token didn't work (check the scopes)."),process.exitCode=1}}async function od(){await Zr(),a.success("Signed out (stored GitHub token removed).")}async function id(e,t={}){let n=await fo();if(!n)return go();await a.logoOnceAnimated("Sandbox");let o=!t.yes,{select:i,confirm:r}=await Promise.resolve().then(()=>(G(),H)),s=t.boilerplate;s||(t.ue?s=Q.ue:o?s=await i({message:"Which boilerplate?",choices:[{name:"Document Authoring (adobe/aem-boilerplate)",value:Q.document},{name:"Universal Editor / crosswalk (adobe-rnd/aem-boilerplate-xwalk)",value:Q.ue}]}):s=Q.document);let l=t.private??!1;t.private===void 0&&o&&(l=await i({message:"Visibility?",choices:[{name:"Public",value:!1},{name:"Private",value:!0}],default:!1}));let c=t.org??n.login;if(await td(n,c,e)){a.error(`A repository ${c}/${e} already exists - refusing to touch it.`),a.info(re.dim(" Pick another name, or remove it first (e.g. `eds sandbox rm` for a sandbox).")),process.exitCode=1;return}a.info(j("Creating sandbox",`${c}/${e} \xB7 ${s}`));try{if(n.mode==="api"){let d=await Wr(n.token,s,{owner:c,name:e,private:l});await zr(n.token,c,e,[Ve]),a.info(re.dim(" Cloning...")),await be("git",["clone",d.cloneUrl,e],{stdio:"inherit"})}else{let d=t.org?`${t.org}/${e}`:e;await be("gh",Yi(d,{template:s,private:l,clone:!0}),{stdio:"inherit"});try{await be("gh",["repo","edit",`${c}/${e}`,"--add-topic",Ve])}catch{}}}catch(d){a.error(`Create failed: ${d.message}`),process.exitCode=1;return}if(a.info(""),a.info(j("Sandbox ready")),a.info(P("repo",`https://github.com/${c}/${e}`)),a.info(P("preview",Jn(c,e))),a.info(""),o){if(await r({message:"Open the AEM Code Sync install page now?",default:!0})&&await uo(qn()),await r({message:`Configure authoring now (eds init in ./${e})?`,default:!0})){let d=process.cwd();try{process.chdir(Zl.join(d,e));let{initProject:m}=await Promise.resolve().then(()=>(xt(),kt));await m({})}finally{process.chdir(d)}}}else a.info(re.dim(` Install AEM Code Sync: ${qn()}`)),a.info(re.dim(` Configure authoring: cd ${e} && eds init`));a.info(""),a.info(B([`Sandbox "${e}" ready - tear down with \`eds sandbox rm ${e}\``]))}async function rd(){let e=await fo();if(!e)return go();let t=[];try{if(e.mode==="api")t=await qr(e.token,e.login,Ve);else{let o=await be("gh",["repo","list","--topic",Ve,"--limit","100","--json","nameWithOwner","-q",".[].nameWithOwner"]);t=o?o.split(`
347
+ `).filter(Boolean):[]}}catch(o){a.error(`List failed: ${o.message}`),process.exitCode=1;return}if(a.info(j("Sandboxes",`${t.length} tagged ${Ve}`)),t.length===0){a.info(re.dim(" None yet. Create one with `eds sandbox new <name>`."));return}let n=I(t);for(let o of t){let[i,r]=o.split("/");a.info(P(o,Jn(i,r),n))}}async function ad(e,t={}){let n=await fo();if(!n)return go();let o=t.org??n.login,i=`${o}/${e}`;if(!t.yes){let{confirm:r}=await Promise.resolve().then(()=>(G(),H));if(!await r({message:`Permanently delete ${i}? This cannot be undone.`,default:!1})){a.info("Cancelled.");return}}try{n.mode==="api"?await Jr(n.token,o,e):await be("gh",["repo","delete",i,"--yes"])}catch(r){a.error(`Delete failed: ${r.message}`),a.info(re.dim(" Deleting needs the delete_repo scope (re-run `eds sandbox login`, or `gh auth refresh -s delete_repo`).")),process.exitCode=1;return}a.info(j("Deleted")),a.info(P(i,"removed"))}var Ue=v(()=>{"use strict";f();D();Kr();na();Zt();U()});import{existsSync as sd}from"fs";import{readFile as cd}from"fs/promises";import ld from"path";import{parse as dd}from"yaml";async function oa(e){let t=ld.join(e,"fstab.yaml");if(sd(t))try{let o=(dd(await cd(t,"utf-8"))??{}).mountpoints?.["/"],i=typeof o=="string"?o:o?.url??"",r=i.match(/content\.da\.live\/([^/]+)\/([^/]+)/);return r?{model:"da",org:r[1],site:r[2],mountpoint:i}:/drive\.google\.com/.test(i)?{model:"gdrive",mountpoint:i}:/sharepoint\.com|-my\.sharepoint/.test(i)?{model:"sharepoint",mountpoint:i}:{model:"document",mountpoint:i}}catch{}return{model:"ue"}}var ia=v(()=>{"use strict";f()});function md(e,t,n){let o=n.replace(/^\/+/,"").replace(/\.html$/i,"");return`https://admin.da.live/source/${e}/${t}/${o}.html`}function ra(e,t,n){let o=n.replace(/^\/+/,"").replace(/\.html$/i,"");return`https://da.live/edit#/${e}/${t}/${o}`}async function aa(e,t,n,o,i){let r=md(e,t,n),s=new FormData;s.append("data",new Blob([o],{type:"text/html"}),"content.html");let l={};i&&(l.Authorization=`Bearer ${i}`);let c=await fetch(r,{method:"POST",body:s,headers:l});if(!c.ok)throw new Error(`DA push failed: ${c.status} ${c.statusText}`);return r}var sa=v(()=>{"use strict";f()});function pd(e){return` <div class="${e}">
346
348
  <div>
347
349
  <div>${e} content</div>
348
350
  </div>
349
- </div>`}function $l(e){let t=[` <div><div>Title</div><div>${e.title}</div></div>`,` <div><div>Description</div><div>${e.description??""}</div></div>`];return e.area&&t.push(` <div><div>Template</div><div>${e.area}</div></div>`),` <div class="metadata">
351
+ </div>`}function ud(e){let t=[` <div><div>Title</div><div>${e.title}</div></div>`,` <div><div>Description</div><div>${e.description??""}</div></div>`];return e.area&&t.push(` <div><div>Template</div><div>${e.area}</div></div>`),` <div class="metadata">
350
352
  ${t.join(`
351
353
  `)}
352
- </div>`}function Nr(e){let t=e.blocks??[],n=` <div>
354
+ </div>`}function ca(e){let t=e.blocks??[],n=` <div>
353
355
  <h1>${e.title}</h1>
354
356
  <p>${e.description??"Intro copy goes here."}</p>
355
- </div>`,o=t.map(s=>` <div>
356
- ${xl(s)}
357
+ </div>`,o=t.map(r=>` <div>
358
+ ${pd(r)}
357
359
  </div>`),i=` <div>
358
- ${$l(e)}
360
+ ${ud(e)}
359
361
  </div>`;return`<body>
360
362
  <header></header>
361
363
  <main>
@@ -364,13 +366,13 @@ ${[n,...o,i].join(`
364
366
  </main>
365
367
  <footer></footer>
366
368
  </body>
367
- `}var Or=k(()=>{"use strict";f()});import{existsSync as Sl}from"fs";import{readFile as jl}from"fs/promises";import Pl from"path";function El(e){if(e.value!==void 0)return e.value;switch(e.valueType){case"boolean":return!1;case"number":return 0;case"string[]":return[];default:return""}}async function Cl(e,t){let n=Pl.join(e,"blocks",t,`_${t}.json`);if(!Sl(n))return{};try{let o=JSON.parse(await jl(n,"utf-8")),i=Array.isArray(o.models)?o.models:[],a=(i.find(c=>c.id===t)??i[0])?.fields??[],l={};for(let c of a)c.component!=="tab"&&(l[c.name]=c.component==="container"?[]:El(c));return l}catch{return{}}}async function Mr(e,t){let n=[];for(let i of t.blocks)n.push({name:i,model:i,fields:await Cl(e,i)});let o={title:t.title,template:t.name,components:n};return`${JSON.stringify(o,null,2)}
368
- `}var Ir=k(()=>{"use strict";f()});var oo={};O(oo,{templateNew:()=>Nl});import{existsSync as no}from"fs";import{mkdir as Tl,readFile as _r,readdir as Rl,writeFile as to}from"fs/promises";import ve from"path";import ht from"chalk";async function Fl(e){let t=ve.join(e,"blocks");return no(t)?(await Rl(t,{withFileTypes:!0})).filter(n=>n.isDirectory()).map(n=>n.name):[]}async function Dl(e){let t=ve.join(e,".edsrc.json");if(!no(t))return{};try{return JSON.parse(await _r(t,"utf-8")).admin??{}}catch{return{}}}async function Ll(e,t){if(!t.length)return!1;let n=ve.join(e,"component-filters.json"),o=null;if(no(n))try{o=JSON.parse(await _r(n,"utf-8"))}catch{o=null}let i=ft(o,t);return await to(n,`${JSON.stringify(i,null,2)}
369
- `),!0}async function Nl(e,t={}){let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}await r.logoOnceAnimated("Page template");let{input:o,select:i,confirm:s}=await Promise.resolve().then(()=>(H(),B)),a=!t.yes,l=await Rr(n),c=t.authoring??l.model,d=Al(e),m=t.title??(a?await o({message:"Page title",default:e}):e),p=t.description??(a?await o({message:"Description (optional)"}):""),u=t.path??`/templates/${d}`,g=t.blocks;if(!g&&a){let v=await Fl(n),w=v.length?v:Fe.map(K=>K.id),A=[],X=!0;for(;X;){let K=await i({message:`Add a block in order (${A.length} so far)`,choices:[...w.map(Ce=>({name:Ce,value:Ce})),{name:A.length?"- done -":"- done (empty page) -",value:"__done"}]});K==="__done"?X=!1:A.push(K)}g=A}let h=g??[],b=Nr({title:m,description:p||void 0,blocks:h,area:t.area}),y=ve.join("templates",`${d}.html`);if(await Tl(ve.join(n,"templates"),{recursive:!0}),await to(ve.join(n,y),b),r.info(S("Page template",`${u} \xB7 ${c}`)),r.info(j(y,`${h.length} block(s) + metadata`)),c==="da"){let v=await Dl(n),w=t.org??v.org??l.org,A=t.site??v.site??l.site;if(t.push??(a?await s({message:"Push to DA (da.live)?",default:!0}):!0))if(!w||!A)r.warn("No DA org/site. Pass --org/--site or set admin in .edsrc.json.");else try{await Dr(w,A,u,b,process.env.DA_TOKEN),r.info(j("pushed to DA",Fr(w,A,u)))}catch(K){r.error(`DA push failed: ${K.message}`),r.info(ht.dim(" Open projects allow anonymous writes; others need DA_TOKEN."))}}else if(c==="gdrive"||c==="sharepoint"){let v=c==="gdrive"?"a Google Doc":"a Word doc";r.info(""),r.info(ht.dim(` Document model: import ${y} into ${v} in your mounted folder,`)),r.info(ht.dim(" then preview/publish. (Share the folder + install aem-code-sync first.)"))}else if(c==="ue"){let v=ve.join("templates",`${d}.json`);await to(ve.join(n,v),await Mr(n,{title:m,name:d,blocks:h})),r.info(j(v,`initial content (${h.length} component(s), in order)`)),await Ll(n,h)&&r.info(j("component-filters.json","seeded blocks allowed in Universal Editor")),r.info(""),r.info(ht.dim(" Universal Editor: use the template JSON as the page's initial content, then")),r.info(ht.dim(" author it in the Universal Editor (wire the repo to AEM)."))}r.info(""),r.info(I([`"${d}" template (${c}) - preview with \`eds preview ${u}\``]))}var Al,io=k(()=>{"use strict";f();D();z();Wn();Kn();Ar();Lr();Or();Ir();_();Al=e=>e.trim().toLowerCase().replace(/[^a-z0-9-/]+/g,"-").replace(/^-+|-+$/g,"")});import{existsSync as cn}from"fs";import{readFile as Ur,readdir as Br}from"fs/promises";import Oe from"path";async function Ol(e){let t=[],n=async o=>{for(let i of await Br(o,{withFileTypes:!0})){let s=Oe.join(o,i.name);i.isDirectory()?await n(s):t.push(s)}};return cn(e)&&await n(e),t}async function Hr(e){if(!cn(e))return null;let t=await Br(e,{withFileTypes:!0}),n=t.find(i=>i.isDirectory()&&/clientlib/i.test(i.name));return n?Oe.join(e,n.name):t.some(i=>i.isFile()&&i.name.endsWith(".css"))?e:null}async function Gr(e){let t=await Ol(e),n=t.filter(a=>/\.(less|scss|sass)$/i.test(a)).map(a=>Oe.relative(e,a)),o,i=Oe.join(e,"css.txt");if(cn(i)){let a=(await Ur(i,"utf-8")).split(`
370
- `).map(d=>d.trim()),l=e,c=[];for(let d of a){if(!d)continue;let m=d.match(/^#base\s*=\s*(.+)$/);m?l=Oe.join(e,m[1].trim()):d.startsWith("#")||c.push(d)}o=c.map(d=>Oe.join(l,d)).filter(d=>cn(d)&&d.endsWith(".css"))}else o=t.filter(a=>a.endsWith(".css"));let s=[];for(let a of o)s.push(await Ur(a,"utf-8"));return{css:s.join(`
369
+ `}var la=v(()=>{"use strict";f()});import{existsSync as fd}from"fs";import{readFile as gd}from"fs/promises";import hd from"path";function wd(e){if(e.value!==void 0)return e.value;switch(e.valueType){case"boolean":return!1;case"number":return 0;case"string[]":return[];default:return""}}async function bd(e,t){let n=hd.join(e,"blocks",t,`_${t}.json`);if(!fd(n))return{};try{let o=JSON.parse(await gd(n,"utf-8")),i=Array.isArray(o.models)?o.models:[],s=(i.find(c=>c.id===t)??i[0])?.fields??[],l={};for(let c of s)c.component!=="tab"&&(l[c.name]=c.component==="container"?[]:wd(c));return l}catch{return{}}}async function da(e,t){let n=[];for(let i of t.blocks)n.push({name:i,model:i,fields:await bd(e,i)});let o={title:t.title,template:t.name,components:n};return`${JSON.stringify(o,null,2)}
370
+ `}var ma=v(()=>{"use strict";f()});var bo={};M(bo,{templateNew:()=>jd});import{existsSync as wo}from"fs";import{mkdir as yd,readFile as pa,readdir as vd,writeFile as ho}from"fs/promises";import Pe from"path";import St from"chalk";async function xd(e){let t=Pe.join(e,"blocks");return wo(t)?(await vd(t,{withFileTypes:!0})).filter(n=>n.isDirectory()).map(n=>n.name):[]}async function $d(e){let t=Pe.join(e,".edsrc.json");if(!wo(t))return{};try{return JSON.parse(await pa(t,"utf-8")).admin??{}}catch{return{}}}async function Sd(e,t){if(!t.length)return!1;let n=Pe.join(e,"component-filters.json"),o=null;if(wo(n))try{o=JSON.parse(await pa(n,"utf-8"))}catch{o=null}let i=vt(o,t);return await ho(n,`${JSON.stringify(i,null,2)}
371
+ `),!0}async function jd(e,t={}){let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}await a.logoOnceAnimated("Page template");let{input:o,select:i,confirm:r}=await Promise.resolve().then(()=>(G(),H)),s=!t.yes,l=await oa(n),c=t.authoring??l.model,d=kd(e),m=t.title??(s?await o({message:"Page title",default:e}):e),p=t.description??(s?await o({message:"Description (optional)"}):""),u=t.path??`/templates/${d}`,g=t.blocks;if(!g&&s){let y=await xd(n),w=y.length?y:Me.map(q=>q.id),T=[],K=!0;for(;K;){let q=await i({message:`Add a block in order (${T.length} so far)`,choices:[...w.map(he=>({name:he,value:he})),{name:T.length?"- done -":"- done (empty page) -",value:"__done"}]});q==="__done"?K=!1:T.push(q)}g=T}let h=g??[],$=ca({title:m,description:p||void 0,blocks:h,area:t.area}),b=Pe.join("templates",`${d}.html`);if(await yd(Pe.join(n,"templates"),{recursive:!0}),await ho(Pe.join(n,b),$),a.info(j("Page template",`${u} \xB7 ${c}`)),a.info(P(b,`${h.length} block(s) + metadata`)),c==="da"){let y=await $d(n),w=t.org??y.org??l.org,T=t.site??y.site??l.site;if(t.push??(s?await r({message:"Push to DA (da.live)?",default:!0}):!0))if(!w||!T)a.warn("No DA org/site. Pass --org/--site or set admin in .edsrc.json.");else try{await aa(w,T,u,$,process.env.DA_TOKEN),a.info(P("pushed to DA",ra(w,T,u)))}catch(q){a.error(`DA push failed: ${q.message}`),a.info(St.dim(" Open projects allow anonymous writes; others need DA_TOKEN."))}}else if(c==="gdrive"||c==="sharepoint"){let y=c==="gdrive"?"a Google Doc":"a Word doc";a.info(""),a.info(St.dim(` Document model: import ${b} into ${y} in your mounted folder,`)),a.info(St.dim(" then preview/publish. (Share the folder + install aem-code-sync first.)"))}else if(c==="ue"){let y=Pe.join("templates",`${d}.json`);await ho(Pe.join(n,y),await da(n,{title:m,name:d,blocks:h})),a.info(P(y,`initial content (${h.length} component(s), in order)`)),await Sd(n,h)&&a.info(P("component-filters.json","seeded blocks allowed in Universal Editor")),a.info(""),a.info(St.dim(" Universal Editor: use the template JSON as the page's initial content, then")),a.info(St.dim(" author it in the Universal Editor (wire the repo to AEM)."))}a.info(""),a.info(B([`"${d}" template (${c}) - preview with \`eds preview ${u}\``]))}var kd,yo=v(()=>{"use strict";f();D();J();no();ao();ia();sa();la();ma();U();kd=e=>e.trim().toLowerCase().replace(/[^a-z0-9-/]+/g,"-").replace(/^-+|-+$/g,"")});import{existsSync as wn}from"fs";import{readFile as ua,readdir as fa}from"fs/promises";import Be from"path";async function Pd(e){let t=[],n=async o=>{for(let i of await fa(o,{withFileTypes:!0})){let r=Be.join(o,i.name);i.isDirectory()?await n(r):t.push(r)}};return wn(e)&&await n(e),t}async function ga(e){if(!wn(e))return null;let t=await fa(e,{withFileTypes:!0}),n=t.find(i=>i.isDirectory()&&/clientlib/i.test(i.name));return n?Be.join(e,n.name):t.some(i=>i.isFile()&&i.name.endsWith(".css"))?e:null}async function ha(e){let t=await Pd(e),n=t.filter(s=>/\.(less|scss|sass)$/i.test(s)).map(s=>Be.relative(e,s)),o,i=Be.join(e,"css.txt");if(wn(i)){let s=(await ua(i,"utf-8")).split(`
372
+ `).map(d=>d.trim()),l=e,c=[];for(let d of s){if(!d)continue;let m=d.match(/^#base\s*=\s*(.+)$/);m?l=Be.join(e,m[1].trim()):d.startsWith("#")||c.push(d)}o=c.map(d=>Be.join(l,d)).filter(d=>wn(d)&&d.endsWith(".css"))}else o=t.filter(s=>s.endsWith(".css"));let r=[];for(let s of o)r.push(await ua(s,"utf-8"));return{css:r.join(`
371
373
 
372
- `),files:o.map(a=>Oe.relative(e,a)),preprocessed:n}}var Wr=k(()=>{"use strict";f()});import{XMLParser as Ml}from"fast-xml-parser";function Q(e){return Object.keys(e).find(t=>t!==":@")??""}function V(e){let t=Q(e),n=e[t];return Array.isArray(n)?n:[]}function Il(e){return e[":@"]??{}}function _l(e){return typeof e=="string"?e.replace(/^\{[^}]+\}/,""):e}function C(e,t){return _l(Il(e)[`@_${t}`])}function Ul(e,t){let n=C(t,"multiple")==="true"||C(t,"multiple")==="{Boolean}true";return e.endsWith("/form/pagefield")?"aem-content":e.includes("experience-fragment")||e.endsWith("/xffield")?"aem-experience-fragment":e.endsWith("/cfpicker")?"aem-content-fragment":e.endsWith("/form/textfield")||e.endsWith("/form/colorfield")||e.includes("/autocomplete")?"text":e.endsWith("/form/textarea")?"textarea":e.includes("/richtext")?"richtext":e.endsWith("/form/numberfield")?"number":e.endsWith("/form/checkbox")?"boolean":e.endsWith("/form/radiogroup")?"radio-group":e.endsWith("/form/select")?n?"multiselect":"select":e.endsWith("/form/datepicker")?"date-time":e.endsWith("/form/pathfield")||e.endsWith("/form/pathbrowser")?"aem-content":e.includes("/fileupload")||e.endsWith("/form/fileupload")?"reference":e.includes("tagfield")||e.includes("tagpicker")||e.includes("tagbrowser")?"aem-tag":e.includes("contentfragment")?"aem-content-fragment":e.includes("experiencefragment")?"aem-experience-fragment":null}function Bl(e){return e.endsWith("/form/hidden")||e.endsWith("/foundation/heading")||e.endsWith("/foundation/text")}function Hl(e){return e.includes("/foundation/container")||e.includes("/foundation/fixedcolumns")||e.includes("/foundation/well")||e.includes("/foundation/tabs")||e.includes("/foundation/form/fieldset")||e.includes("/foundation/accordion")}function ro(e){switch(e){case"number":return"number";case"boolean":return"boolean";case"date-time":return"date";case"checkbox-group":return"string[]";case"aem-content":case"aem-content-fragment":case"aem-experience-fragment":return;default:return"string"}}function Me(e,t){return(e??"").replace(/^\.\//,"").trim()||t}function Wl(e){let t=V(e).find(n=>Q(n)==="items");return t?V(t).map(n=>{let o=C(n,"value")??"";return{name:C(n,"text")??C(n,"jcr:title")??o,value:o}}):[]}function wt(e,t,n){let{unmapped:o,counter:i}=n;for(let s of e){let a=C(s,"sling:resourceType")??"";if(a.endsWith("/foundation/include")){let c=n.includeDepth<8?n.resolveInclude?.(C(s,"path")??""):null;c&&wt(c,t,{...n,includeDepth:n.includeDepth+1});continue}if(Bl(a))continue;if(a.endsWith("/foundation/tabs")){let c=V(s).find(d=>Q(d)==="items");for(let d of c?V(c):[]){let m=C(d,"jcr:title");t.push({component:"tab",name:Me(void 0,Q(d)),label:m}),wt(V(d),t,n)}continue}if(a.endsWith("/form/multifield")){let c=[];wt(V(s),c,n);let d=V(s).find(p=>Q(p)==="field"),m=Me(C(s,"name")??(d?C(d,"name"):void 0),`items${i.i++}`);t.push({component:"container",name:m,label:C(s,"fieldLabel")??"Items",multi:!0,collapsible:!0,fields:c});continue}let l=a?Ul(a,s):null;if(l){let c=Me(C(s,"name"),`field${i.i++}`),d={component:l,name:c},m=ro(l);m&&(d.valueType=m);let p=C(s,"fieldLabel")??C(s,"text");if(p&&(d.label=p),l==="select"||l==="radio-group"||l==="multiselect"){let g=Wl(s),h=V(s).find(y=>Q(y)==="datasource"),b=h?C(h,"sling:resourceType")??"":"";g.length?d.options=g:/heading|allowedtypes/i.test(b)?d.options=Gl:(d.component="text",d.valueType="string",n.datasourced.add(c))}let u=l==="boolean"?C(s,"checked"):C(s,"value");u!==void 0&&u!==""&&(d.value=l==="boolean"?u==="true":u),t.push(d);continue}a&&C(s,"name")&&!Hl(a)&&o.add(a),wt(V(s),t,n)}}function so(e){return e.filter((t,n)=>t.component!=="tab"||e[n+1]&&e[n+1].component!=="tab")}function ln(e){let t=new Set,n=[];for(let o of e){if(o.component!=="tab"){if(t.has(o.name))continue;t.add(o.name)}n.push(o.fields?{...o,fields:ln(o.fields)}:o)}return n}function bt(e){return new Ml({ignoreAttributes:!1,attributeNamePrefix:"@_",preserveOrder:!0,removeNSPrefix:!1,trimValues:!0}).parse(e)}function zr(e,t={}){let n=bt(e).find(a=>Q(a)==="jcr:root"),o=[],i=new Set,s=new Set;return n&&wt(V(n),o,{unmapped:i,datasourced:s,counter:{i:1},resolveInclude:t.resolveInclude,includeDepth:0}),{fields:so(ln(o)),unmapped:[...i],datasourced:[...s]}}function Ve(e){let t=0;for(let n of e)n.component!=="tab"&&(t+=1,n.fields&&(t+=Ve(n.fields)));return t}var Gl,dn=k(()=>{"use strict";f();Gl=["h1","h2","h3","h4","h5","h6"].map(e=>({name:e.toUpperCase(),value:e}))});function yt(e){return(C(e,"xtype")??"").toLowerCase()}function vt(e){let t=V(e).find(n=>Q(n)==="items");return t?C(t,"jcr:primaryType")==="cq:WidgetCollection"||!C(t,"xtype")?V(t):[t]:V(e).filter(n=>/^cq:/.test(C(n,"jcr:primaryType")??""))}function Jl(e){let t=V(e).find(n=>Q(n)==="options");return t?V(t).map(n=>{let o=C(n,"value")??"";return{name:C(n,"text")??o,value:o}}):[]}function Jr(e,t,n){let o=C(e,"name")??C(e,"key"),i=null,s,a=Me(o,`field${n.counter.i++}`);switch(t){case"textfield":case"colorfield":case"":i="text";break;case"textarea":i="textarea";break;case"richtext":i="richtext";break;case"numberfield":i="number";break;case"checkbox":i="boolean";break;case"datetime":case"datefield":i="date-time";break;case"pathfield":case"browsefield":i="aem-content";break;case"tags":case"tagsinputfield":i="aem-tag";break;case"smartimage":case"html5smartimage":case"smartfile":case"html5smartfile":case"fileupload":i="reference",a=Me(C(e,"fileReferenceParameter")??o,a);break;case"selection":{let p=(C(e,"type")??"select").toLowerCase();s=Jl(e),p==="checkbox"?i=s.length?"checkbox-group":"boolean":p==="radio"?i="radio-group":i="select",i!=="boolean"&&!s.length&&(i="text",n.datasourced.add(a));break}default:return null}let l={component:i,name:a},c=ro(i);c&&(l.valueType=c);let d=C(e,"fieldLabel")??C(e,"boxLabel")??C(e,"title");d&&(l.label=d),s?.length&&i!=="text"&&(l.options=s);let m=i==="boolean"?C(e,"checked")??C(e,"defaultValue"):C(e,"defaultValue")??C(e,"value");return m!==void 0&&m!==""&&(l.value=i==="boolean"?m==="true":m),l}function Ie(e,t,n){for(let o of e){let i=yt(o);if(zl.has(i))continue;if(Q(o)==="items"||C(o,"jcr:primaryType")==="cq:WidgetCollection"){Ie(V(o),t,n);continue}if(i==="slingscriptinclude"){/^rte\./.test(C(o,"script")??"")?t.push({component:"richtext",name:"text",valueType:"string",label:"Text"}):n.unmapped.add("xtype:slingscriptinclude");continue}if(i==="cqinclude"){let a=(C(o,"path")??"").replace(/\.(infinity|\d+)?\.?json$/,""),l=n.depth<8?n.resolveInclude?.(a):null;l&&Ie(l,t,{...n,depth:n.depth+1});continue}if(i==="tabpanel"){for(let a of vt(o)){if(yt(a)==="cqinclude"){Ie([a],t,n);continue}t.push({component:"tab",name:Q(a),label:C(a,"title")}),Ie(vt(a),t,n)}continue}if(i==="multifield"){let a=V(o).find(d=>Q(d)==="fieldConfig"),l=Me(C(o,"name"),`items${n.counter.i++}`);if(a&&!ao.has(yt(a))&&!C(a,"name")&&!C(a,"key")){let d=Jr(a,yt(a),n);if(d){t.push({...d,name:l,label:C(o,"fieldLabel")??d.label,multi:!0});continue}}let c=[];a&&Ie(ao.has(yt(a))?vt(a):[a],c,n),t.push({component:"container",name:l,label:C(o,"fieldLabel")??"Items",multi:!0,collapsible:!0,fields:c});continue}if(ao.has(i)||C(o,"jcr:primaryType")==="cq:Panel"||!i&&!C(o,"name")&&vt(o).length){Ie(vt(o),t,n);continue}let s=C(o,"name")||C(o,"key")?Jr(o,i,n):null;s?t.push(s):i&&n.unmapped.add(`xtype:${i}`)}}function qr(e){return/jcr:primaryType="cq:(Dialog|TabPanel|Panel|Widget)"/.test(e)||/\sxtype="/.test(e)}function Kr(e,t={}){let n=bt(e).find(s=>Q(s)==="jcr:root"),o=[],i={unmapped:new Set,datasourced:new Set,counter:{i:1},resolveInclude:t.resolveInclude,depth:0};return n&&Ie([n],o,i),{fields:so(ln(o)),unmapped:[...i.unmapped],datasourced:[...i.datasourced]}}var ao,zl,Vr=k(()=>{"use strict";f();dn();ao=new Set(["dialog","panel","dialogfieldset","multifieldpanel","fieldset"]),zl=new Set(["hidden","static","displayfield","label","box","componentstyles"])});import{existsSync as Xe,readFileSync as Xr}from"fs";import{readFile as ql}from"fs/promises";import Z from"path";import{XMLParser as Kl}from"fast-xml-parser";function Vl(e){return[Z.join(e,"_cq_dialog",".content.xml"),Z.join(e,"_cq_dialog.xml"),Z.join(e,"cq:dialog",".content.xml")].find(n=>Xe(n))??null}function Xl(e){return[Z.join(e,"dialog.xml"),Z.join(e,"dialog",".content.xml")].find(n=>Xe(n))??null}function Yr(e,t){let n=Z.join(e,".content.xml");if(Xe(n))try{let s=(new Kl({ignoreAttributes:!1,attributeNamePrefix:"@_"}).parse(Xr(n,"utf-8"))["jcr:root"]??{})[`@_${t}`];return typeof s=="string"?s.replace(/^\{[^}]+\}/,""):void 0}catch{return}}async function Qr(e){return Yr(e,"jcr:title")}function co(e){return Yr(e,"sling:resourceSuperType")}function Yl(e){let t=Z.resolve(e);for(;t!==Z.dirname(t);){if(Z.basename(t)==="jcr_root")return t;t=Z.dirname(t)}return null}function Zr(e,t){let n=e.replace(/^\/mnt\/overlay\//,"/").replace(/^\/(apps|libs)\//,"").replace(/^\//,"").split("/").map(i=>i.replace(/^([a-z]+):/,"_$1_")).join("/"),o=[];for(let i of t)o.push(Z.join(i,"apps",n),Z.join(i,"libs",n),Z.join(i,n));return o}function Ql(e){let t=new Map,n=o=>{if(!t.has(o))try{let i=bt(Xr(o,"utf-8")).find(s=>Q(s)==="jcr:root");t.set(o,i?V(i):null)}catch{t.set(o,null)}return t.get(o)??null};return o=>{if(!o||o.includes("${"))return null;for(let i of Zr(o,e)){let s=i.split(Z.sep);for(let a=s.length;a>1;a--){let l=s.slice(0,a).join(Z.sep),c=Xe(Z.join(l,".content.xml"))?Z.join(l,".content.xml"):Xe(`${l}.xml`)?`${l}.xml`:null;if(!c)continue;let d=n(c);for(let m of s.slice(a)){let p=d?.find(u=>Q(u)===m);d=p?[p]:null}if(d)return d;break}}return null}}async function es(e,t=[]){let n=Yl(e),o=[...n?[n]:[],...t],i=Ql(o),s=e,a,l=null;for(let c=0;c<8;c++){let d=Vl(s),m=d?null:Xl(s),p=d??m;if(p){let h=await ql(p,"utf-8"),b=m&&qr(h)?"classic":"touch",y=b==="classic"?Kr(h,{resolveInclude:i}):zr(h,{resolveInclude:i});if(Ve(y.fields)>0)return{...y,inheritedFrom:a,dialogKind:b};l??={...y,dialogKind:b}}let u=co(s),g=u?Zr(u,o).find(h=>Xe(h)):void 0;if(!u||!g)break;s=g,a=u}return l}function ts(e,t,n){return`${JSON.stringify({definitions:[{title:t,id:e,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:t,model:e}}}}}],models:[{id:e,fields:n}],filters:[]},null,2)}
373
- `}function ns(e,t){let o=t.some(i=>i.component==="container"&&i.multi)?` // This block was migrated from a classic AEM component with a multifield.
374
+ `),files:o.map(s=>Be.relative(e,s)),preprocessed:n}}var wa=v(()=>{"use strict";f()});import{XMLParser as Ed}from"fast-xml-parser";function ee(e){return Object.keys(e).find(t=>t!==":@")??""}function Y(e){let t=ee(e),n=e[t];return Array.isArray(n)?n:[]}function Cd(e){return e[":@"]??{}}function Td(e){return typeof e=="string"?e.replace(/^\{[^}]+\}/,""):e}function C(e,t){return Td(Cd(e)[`@_${t}`])}function Ad(e,t){let n=C(t,"multiple")==="true"||C(t,"multiple")==="{Boolean}true";return e.endsWith("/form/pagefield")?"aem-content":e.includes("experience-fragment")||e.endsWith("/xffield")?"aem-experience-fragment":e.endsWith("/cfpicker")?"aem-content-fragment":e.endsWith("/form/textfield")||e.endsWith("/form/colorfield")||e.includes("/autocomplete")?"text":e.endsWith("/form/textarea")?"textarea":e.includes("/richtext")?"richtext":e.endsWith("/form/numberfield")?"number":e.endsWith("/form/checkbox")?"boolean":e.endsWith("/form/radiogroup")?"radio-group":e.endsWith("/form/select")?n?"multiselect":"select":e.endsWith("/form/datepicker")?"date-time":e.endsWith("/form/pathfield")||e.endsWith("/form/pathbrowser")?"aem-content":e.includes("/fileupload")||e.endsWith("/form/fileupload")?"reference":e.includes("tagfield")||e.includes("tagpicker")||e.includes("tagbrowser")?"aem-tag":e.includes("contentfragment")?"aem-content-fragment":e.includes("experiencefragment")?"aem-experience-fragment":null}function Rd(e){return e.endsWith("/form/hidden")||e.endsWith("/foundation/heading")||e.endsWith("/foundation/text")}function Fd(e){return e.includes("/foundation/container")||e.includes("/foundation/fixedcolumns")||e.includes("/foundation/well")||e.includes("/foundation/tabs")||e.includes("/foundation/form/fieldset")||e.includes("/foundation/accordion")}function vo(e){switch(e){case"number":return"number";case"boolean":return"boolean";case"date-time":return"date";case"checkbox-group":return"string[]";case"aem-content":case"aem-content-fragment":case"aem-experience-fragment":return;default:return"string"}}function He(e,t){return(e??"").replace(/^\.\//,"").trim()||t}function Dd(e){let t=Y(e).find(n=>ee(n)==="items");return t?Y(t).map(n=>{let o=C(n,"value")??"";return{name:C(n,"text")??C(n,"jcr:title")??o,value:o}}):[]}function jt(e,t,n){let{unmapped:o,counter:i}=n;for(let r of e){let s=C(r,"sling:resourceType")??"";if(s.endsWith("/foundation/include")){let c=n.includeDepth<8?n.resolveInclude?.(C(r,"path")??""):null;c&&jt(c,t,{...n,includeDepth:n.includeDepth+1});continue}if(Rd(s))continue;if(s.endsWith("/foundation/tabs")){let c=Y(r).find(d=>ee(d)==="items");for(let d of c?Y(c):[]){let m=C(d,"jcr:title");t.push({component:"tab",name:He(void 0,ee(d)),label:m}),jt(Y(d),t,n)}continue}if(s.endsWith("/form/multifield")){let c=[];jt(Y(r),c,n);let d=Y(r).find(p=>ee(p)==="field"),m=He(C(r,"name")??(d?C(d,"name"):void 0),`items${i.i++}`);t.push({component:"container",name:m,label:C(r,"fieldLabel")??"Items",multi:!0,collapsible:!0,fields:c});continue}let l=s?Ad(s,r):null;if(l){let c=He(C(r,"name"),`field${i.i++}`),d={component:l,name:c},m=vo(l);m&&(d.valueType=m);let p=C(r,"fieldLabel")??C(r,"text");if(p&&(d.label=p),l==="select"||l==="radio-group"||l==="multiselect"){let g=Dd(r),h=Y(r).find(b=>ee(b)==="datasource"),$=h?C(h,"sling:resourceType")??"":"";g.length?d.options=g:/heading|allowedtypes/i.test($)?d.options=Ld:(d.component="text",d.valueType="string",n.datasourced.add(c))}let u=l==="boolean"?C(r,"checked"):C(r,"value");u!==void 0&&u!==""&&(d.value=l==="boolean"?u==="true":u),t.push(d);continue}s&&C(r,"name")&&!Fd(s)&&o.add(s),jt(Y(r),t,n)}}function ko(e){return e.filter((t,n)=>t.component!=="tab"||e[n+1]&&e[n+1].component!=="tab")}function bn(e){let t=new Set,n=[];for(let o of e){if(o.component!=="tab"){if(t.has(o.name))continue;t.add(o.name)}n.push(o.fields?{...o,fields:bn(o.fields)}:o)}return n}function Pt(e){return new Ed({ignoreAttributes:!1,attributeNamePrefix:"@_",preserveOrder:!0,removeNSPrefix:!1,trimValues:!0}).parse(e)}function ba(e,t={}){let n=Pt(e).find(s=>ee(s)==="jcr:root"),o=[],i=new Set,r=new Set;return n&&jt(Y(n),o,{unmapped:i,datasourced:r,counter:{i:1},resolveInclude:t.resolveInclude,includeDepth:0}),{fields:ko(bn(o)),unmapped:[...i],datasourced:[...r]}}function ot(e){let t=0;for(let n of e)n.component!=="tab"&&(t+=1,n.fields&&(t+=ot(n.fields)));return t}var Ld,yn=v(()=>{"use strict";f();Ld=["h1","h2","h3","h4","h5","h6"].map(e=>({name:e.toUpperCase(),value:e}))});function Et(e){return(C(e,"xtype")??"").toLowerCase()}function Ct(e){let t=Y(e).find(n=>ee(n)==="items");return t?C(t,"jcr:primaryType")==="cq:WidgetCollection"||!C(t,"xtype")?Y(t):[t]:Y(e).filter(n=>/^cq:/.test(C(n,"jcr:primaryType")??""))}function Nd(e){let t=Y(e).find(n=>ee(n)==="options");return t?Y(t).map(n=>{let o=C(n,"value")??"";return{name:C(n,"text")??o,value:o}}):[]}function ya(e,t,n){let o=C(e,"name")??C(e,"key"),i=null,r,s=He(o,`field${n.counter.i++}`);switch(t){case"textfield":case"colorfield":case"":i="text";break;case"textarea":i="textarea";break;case"richtext":i="richtext";break;case"numberfield":i="number";break;case"checkbox":i="boolean";break;case"datetime":case"datefield":i="date-time";break;case"pathfield":case"browsefield":i="aem-content";break;case"tags":case"tagsinputfield":i="aem-tag";break;case"smartimage":case"html5smartimage":case"smartfile":case"html5smartfile":case"fileupload":i="reference",s=He(C(e,"fileReferenceParameter")??o,s);break;case"selection":{let p=(C(e,"type")??"select").toLowerCase();r=Nd(e),p==="checkbox"?i=r.length?"checkbox-group":"boolean":p==="radio"?i="radio-group":i="select",i!=="boolean"&&!r.length&&(i="text",n.datasourced.add(s));break}default:return null}let l={component:i,name:s},c=vo(i);c&&(l.valueType=c);let d=C(e,"fieldLabel")??C(e,"boxLabel")??C(e,"title");d&&(l.label=d),r?.length&&i!=="text"&&(l.options=r);let m=i==="boolean"?C(e,"checked")??C(e,"defaultValue"):C(e,"defaultValue")??C(e,"value");return m!==void 0&&m!==""&&(l.value=i==="boolean"?m==="true":m),l}function Ge(e,t,n){for(let o of e){let i=Et(o);if(Od.has(i))continue;if(ee(o)==="items"||C(o,"jcr:primaryType")==="cq:WidgetCollection"){Ge(Y(o),t,n);continue}if(i==="slingscriptinclude"){/^rte\./.test(C(o,"script")??"")?t.push({component:"richtext",name:"text",valueType:"string",label:"Text"}):n.unmapped.add("xtype:slingscriptinclude");continue}if(i==="cqinclude"){let s=(C(o,"path")??"").replace(/\.(infinity|\d+)?\.?json$/,""),l=n.depth<8?n.resolveInclude?.(s):null;l&&Ge(l,t,{...n,depth:n.depth+1});continue}if(i==="tabpanel"){for(let s of Ct(o)){if(Et(s)==="cqinclude"){Ge([s],t,n);continue}t.push({component:"tab",name:ee(s),label:C(s,"title")}),Ge(Ct(s),t,n)}continue}if(i==="multifield"){let s=Y(o).find(d=>ee(d)==="fieldConfig"),l=He(C(o,"name"),`items${n.counter.i++}`);if(s&&!xo.has(Et(s))&&!C(s,"name")&&!C(s,"key")){let d=ya(s,Et(s),n);if(d){t.push({...d,name:l,label:C(o,"fieldLabel")??d.label,multi:!0});continue}}let c=[];s&&Ge(xo.has(Et(s))?Ct(s):[s],c,n),t.push({component:"container",name:l,label:C(o,"fieldLabel")??"Items",multi:!0,collapsible:!0,fields:c});continue}if(xo.has(i)||C(o,"jcr:primaryType")==="cq:Panel"||!i&&!C(o,"name")&&Ct(o).length){Ge(Ct(o),t,n);continue}let r=C(o,"name")||C(o,"key")?ya(o,i,n):null;r?t.push(r):i&&n.unmapped.add(`xtype:${i}`)}}function va(e){return/jcr:primaryType="cq:(Dialog|TabPanel|Panel|Widget)"/.test(e)||/\sxtype="/.test(e)}function ka(e,t={}){let n=Pt(e).find(r=>ee(r)==="jcr:root"),o=[],i={unmapped:new Set,datasourced:new Set,counter:{i:1},resolveInclude:t.resolveInclude,depth:0};return n&&Ge([n],o,i),{fields:ko(bn(o)),unmapped:[...i.unmapped],datasourced:[...i.datasourced]}}var xo,Od,xa=v(()=>{"use strict";f();yn();xo=new Set(["dialog","panel","dialogfieldset","multifieldpanel","fieldset"]),Od=new Set(["hidden","static","displayfield","label","box","componentstyles"])});import{existsSync as it,readFileSync as $a}from"fs";import{readFile as Md}from"fs/promises";import te from"path";import{XMLParser as _d}from"fast-xml-parser";function Id(e){return[te.join(e,"_cq_dialog",".content.xml"),te.join(e,"_cq_dialog.xml"),te.join(e,"cq:dialog",".content.xml")].find(n=>it(n))??null}function Ud(e){return[te.join(e,"dialog.xml"),te.join(e,"dialog",".content.xml")].find(n=>it(n))??null}function Sa(e,t){let n=te.join(e,".content.xml");if(it(n))try{let r=(new _d({ignoreAttributes:!1,attributeNamePrefix:"@_"}).parse($a(n,"utf-8"))["jcr:root"]??{})[`@_${t}`];return typeof r=="string"?r.replace(/^\{[^}]+\}/,""):void 0}catch{return}}async function ja(e){return Sa(e,"jcr:title")}function $o(e){return Sa(e,"sling:resourceSuperType")}function Bd(e){let t=te.resolve(e);for(;t!==te.dirname(t);){if(te.basename(t)==="jcr_root")return t;t=te.dirname(t)}return null}function Pa(e,t){let n=e.replace(/^\/mnt\/overlay\//,"/").replace(/^\/(apps|libs)\//,"").replace(/^\//,"").split("/").map(i=>i.replace(/^([a-z]+):/,"_$1_")).join("/"),o=[];for(let i of t)o.push(te.join(i,"apps",n),te.join(i,"libs",n),te.join(i,n));return o}function Hd(e){let t=new Map,n=o=>{if(!t.has(o))try{let i=Pt($a(o,"utf-8")).find(r=>ee(r)==="jcr:root");t.set(o,i?Y(i):null)}catch{t.set(o,null)}return t.get(o)??null};return o=>{if(!o||o.includes("${"))return null;for(let i of Pa(o,e)){let r=i.split(te.sep);for(let s=r.length;s>1;s--){let l=r.slice(0,s).join(te.sep),c=it(te.join(l,".content.xml"))?te.join(l,".content.xml"):it(`${l}.xml`)?`${l}.xml`:null;if(!c)continue;let d=n(c);for(let m of r.slice(s)){let p=d?.find(u=>ee(u)===m);d=p?[p]:null}if(d)return d;break}}return null}}async function Ea(e,t=[]){let n=Bd(e),o=[...n?[n]:[],...t],i=Hd(o),r=e,s,l=null;for(let c=0;c<8;c++){let d=Id(r),m=d?null:Ud(r),p=d??m;if(p){let h=await Md(p,"utf-8"),$=m&&va(h)?"classic":"touch",b=$==="classic"?ka(h,{resolveInclude:i}):ba(h,{resolveInclude:i});if(ot(b.fields)>0)return{...b,inheritedFrom:s,dialogKind:$};l??={...b,dialogKind:$}}let u=$o(r),g=u?Pa(u,o).find(h=>it(h)):void 0;if(!u||!g)break;r=g,s=u}return l}function Ca(e,t,n){return`${JSON.stringify({definitions:[{title:t,id:e,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:t,model:e}}}}}],models:[{id:e,fields:n}],filters:[]},null,2)}
375
+ `}function Ta(e,t){let o=t.some(i=>i.component==="container"&&i.multi)?` // This block was migrated from a classic AEM component with a multifield.
374
376
  // Each child row is one repeated item - enhance them here.
375
377
  [...block.children].forEach((row) => {
376
378
  row.classList.add('${e}-item');
@@ -382,25 +384,25 @@ export default function decorate(block) {
382
384
  block.classList.add('${e}');
383
385
  ${o}
384
386
  }
385
- `}function os(e){return`/* Block: ${e} */
387
+ `}function Aa(e){return`/* Block: ${e} */
386
388
  /* Migrated from a classic AEM component. Bring the component's styles here */
387
389
  /* (from its clientlib or the rendered page) and keep them scoped to the block. */
388
390
  .${e} {
389
391
  }
390
- `}var is=k(()=>{"use strict";f();Vr();dn()});function Zl(e,t,n){let o=[` // --- ${ss} ---`];return n.click&&o.push(` ${t}.addEventListener('click', (ev) => {`," const el = ev.target.closest('a, button');"," if (!el) return;",` trackEvent({ event: 'block_click', block: '${e}', label: el.dataset.track || el.textContent.trim() });`," });"),n.submit&&o.push(` ${t}.addEventListener('submit', () => {`,` trackEvent({ event: 'form_submit', block: '${e}' });`," });"),o.join(`
391
- `)}function as(e,t,n){if(e.includes(ss))return{js:e,changed:!1,reason:"already instrumented"};if(!n.click&&!n.submit)return{js:e,changed:!1,reason:"no events selected"};let o=e.match(/export default (?:async )?function decorate\s*\(\s*([A-Za-z_$][\w$]*)?[^)]*\)\s*\{/);if(!o||o.index===void 0)return{js:e,changed:!1,reason:"no `export default function decorate(...)` found"};let i=o[1]||"block",s=e;if(!s.includes("scripts/analytics.js")){let d=[...s.matchAll(/^import .*$/gm)];if(d.length){let m=d[d.length-1],p=(m.index??0)+m[0].length;s=`${s.slice(0,p)}
392
- ${rs}${s.slice(p)}`}else s=`${rs}
392
+ `}var Ra=v(()=>{"use strict";f();xa();yn()});function Gd(e,t,n){let o=[` // --- ${La} ---`];return n.click&&o.push(` ${t}.addEventListener('click', (ev) => {`," const el = ev.target.closest('a, button');"," if (!el) return;",` trackEvent({ event: 'block_click', block: '${e}', label: el.dataset.track || el.textContent.trim() });`," });"),n.submit&&o.push(` ${t}.addEventListener('submit', () => {`,` trackEvent({ event: 'form_submit', block: '${e}' });`," });"),o.join(`
393
+ `)}function Da(e,t,n){if(e.includes(La))return{js:e,changed:!1,reason:"already instrumented"};if(!n.click&&!n.submit)return{js:e,changed:!1,reason:"no events selected"};let o=e.match(/export default (?:async )?function decorate\s*\(\s*([A-Za-z_$][\w$]*)?[^)]*\)\s*\{/);if(!o||o.index===void 0)return{js:e,changed:!1,reason:"no `export default function decorate(...)` found"};let i=o[1]||"block",r=e;if(!r.includes("scripts/analytics.js")){let d=[...r.matchAll(/^import .*$/gm)];if(d.length){let m=d[d.length-1],p=(m.index??0)+m[0].length;r=`${r.slice(0,p)}
394
+ ${Fa}${r.slice(p)}`}else r=`${Fa}
393
395
 
394
- ${s}`}let a=s.match(/export default (?:async )?function decorate\s*\(\s*([A-Za-z_$][\w$]*)?[^)]*\)\s*\{/);if(!a||a.index===void 0)return{js:s,changed:!1,reason:"decorate not found"};let l=a.index+a[0].length,c=Zl(t,i,n);return s=`${s.slice(0,l)}
396
+ ${r}`}let s=r.match(/export default (?:async )?function decorate\s*\(\s*([A-Za-z_$][\w$]*)?[^)]*\)\s*\{/);if(!s||s.index===void 0)return{js:r,changed:!1,reason:"decorate not found"};let l=s.index+s[0].length,c=Gd(t,i,n);return r=`${r.slice(0,l)}
395
397
  ${c}
396
- ${s.slice(l)}`,{js:s,changed:!0}}var ss,rs,cs=k(()=>{"use strict";f();ss="analytics (eds track)",rs="import { trackEvent } from '../../scripts/analytics.js';"});var kt={};O(kt,{trackBlock:()=>od});import{existsSync as ls}from"fs";import{readFile as ed,writeFile as td}from"fs/promises";import ds from"path";import nd from"chalk";async function od(e,t={}){let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Track block"));let o=ds.join(n,"blocks",e,`${e}.js`);if(!ls(o)){r.error(`Block "${e}" not found (no blocks/${e}/${e}.js).`),process.exitCode=1;return}let i={click:t.click!==!1,submit:t.submit!==!1},s=as(await ed(o,"utf-8"),e,i);if(!s.changed){r.warn(`Not instrumented: ${s.reason}.`);return}await td(o,s.js),r.info(S("Instrumented"));let a=[i.click?"block_click":null,i.submit?"form_submit":null].filter(Boolean);r.info(j(`blocks/${e}/${e}.js`,a.join(" + "))),ls(ds.join(n,"scripts","analytics.js"))||(r.info(""),r.warn("scripts/analytics.js is missing - run `eds integrate gtm` to create it.")),r.info(""),r.info(nd.dim(" Events push to window.dataLayer via trackEvent - GTM picks them up."))}var xt=k(()=>{"use strict";f();D();z();cs();_()});var po={};O(po,{migrateComponent:()=>sd});import{existsSync as lo}from"fs";import{mkdir as id,writeFile as mo}from"fs/promises";import ke from"path";function rd(e,t,n){return`/* Block: ${e} */
398
+ ${r.slice(l)}`,{js:r,changed:!0}}var La,Fa,Oa=v(()=>{"use strict";f();La="analytics (eds track)",Fa="import { trackEvent } from '../../scripts/analytics.js';"});var Tt={};M(Tt,{trackBlock:()=>qd});import{existsSync as Na}from"fs";import{readFile as Wd,writeFile as zd}from"fs/promises";import Ma from"path";import Jd from"chalk";async function qd(e,t={}){let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Track block"));let o=Ma.join(n,"blocks",e,`${e}.js`);if(!Na(o)){a.error(`Block "${e}" not found (no blocks/${e}/${e}.js).`),process.exitCode=1;return}let i={click:t.click!==!1,submit:t.submit!==!1},r=Da(await Wd(o,"utf-8"),e,i);if(!r.changed){a.warn(`Not instrumented: ${r.reason}.`);return}await zd(o,r.js),a.info(j("Instrumented"));let s=[i.click?"block_click":null,i.submit?"form_submit":null].filter(Boolean);a.info(P(`blocks/${e}/${e}.js`,s.join(" + "))),Na(Ma.join(n,"scripts","analytics.js"))||(a.info(""),a.warn("scripts/analytics.js is missing - run `eds integrate gtm` to create it.")),a.info(""),a.info(Jd.dim(" Events push to window.dataLayer via trackEvent - GTM picks them up."))}var At=v(()=>{"use strict";f();D();J();Oa();U()});var Po={};M(Po,{migrateComponent:()=>Vd});import{existsSync as So}from"fs";import{mkdir as Kd,writeFile as jo}from"fs/promises";import Ee from"path";function Xd(e,t,n){return`/* Block: ${e} */
397
399
  /* Migrated from the component clientlib: ${n.join(", ")}. */
398
400
  /* TODO: review selectors and scope them under .${e} (and port any LESS/SCSS). */
399
401
 
400
402
  ${t.trim()}
401
- `}function ms(e,t=0){let n=[];for(let o of e){let i=" ".repeat(t);if(o.component==="tab")n.push(`${i}${M.blue("\u25B8")} ${o.label??o.name}`);else{let s=o.options?.length?` (${o.options.length} options)`:"",a=o.multi?" \xB7multi":"",l=o.label?`- ${o.label}`:"";n.push(`${i}${M.accent(o.component)}${a} ${o.name}${s} ${l}`),o.fields?.length&&n.push(...ms(o.fields,t+1))}}return n}async function sd(e,t={}){let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}await r.logoOnceAnimated("Migrate component");let{input:o,confirm:i}=await Promise.resolve().then(()=>(H(),B)),s=!t.yes,a=e;if(!a&&s&&(a=await o({message:"Path to the classic component folder",validate:w=>lo(w.trim())||"Folder not found"})),!a){r.error("Provide the path to the classic component folder."),process.exitCode=1;return}a=ke.resolve(a.trim());let l=(t.superRoot??"").split(",").map(w=>w.trim()).filter(Boolean).map(w=>ke.resolve(w)),c=await es(a,l);if(!c){let w=co(a);w?(r.error(`No dialog here: this is a proxy of ${w}, and that component isn't under ${l.length?"the given --super-root":"this jcr_root"}.`),r.info(" Pass --super-root <jcr_root that contains it>, e.g. a checkout of adobe/aem-core-wcm-components (content/src/content/jcr_root).")):r.error(`No Touch UI dialog (_cq_dialog/.content.xml) found in ${a}.`),process.exitCode=1;return}if(Ve(c.fields)===0){r.warn("Dialog found but no mappable fields were detected."),c.unmapped.length&&r.info(`Unmapped resourceTypes: ${c.unmapped.join(", ")}`),process.exitCode=1;return}let d=await Qr(a)??ke.basename(a),m=t.name&&mn(t.name)||mn(s?await o({message:"Block name",default:mn(d)}):d);c.dialogKind==="classic"&&r.info(` ${M.blue("\u21B3")} Classic UI dialog (dialog.xml) - mapped from its xtypes`),c.inheritedFrom&&r.info(` ${M.blue("\u21B3")} Dialog inherited from ${c.inheritedFrom} (proxy component; overlay changes not applied)`),r.info(S("Mapped fields",`${Ve(c.fields)} from dialog`));for(let w of ms(c.fields))r.info(` ${w}`);if(c.unmapped.length&&(r.info(""),r.warn(`Skipped (unrecognised): ${c.unmapped.join(", ")}`)),c.datasourced.length&&r.warn(`Options come from a datasource, migrated as text (add static options if needed): ${c.datasourced.join(", ")}`),r.info(""),s&&!await i({message:`Generate block "${m}"?`,default:!0})){r.info("Cancelled.");return}let p=ke.join(n,"blocks",m);if(lo(p)){r.error(`Block "${m}" already exists at blocks/${m}. Use --name to pick another.`),process.exitCode=1;return}let u=t.clientlib?ke.resolve(t.clientlib.trim()):await Hr(a),g=os(m),h="empty - add styles from clientlib / rendered CSS",b=[];if(u&&lo(u)){let w=await Gr(u);w.css.trim()&&(g=rd(m,w.css,w.files),h=`from clientlib (${w.files.length} file(s)) - review & scope`),b=w.preprocessed}await id(p,{recursive:!0}),await mo(ke.join(p,`${m}.js`),ns(m,c.fields)),await mo(ke.join(p,`${m}.css`),g),await mo(ke.join(p,`_${m}.json`),ts(m,d,c.fields)),r.info(S("Created"));let y=[`${m}.js`,`${m}.css`,`_${m}.json`],v=U(y);if(r.info(j(`${m}.js`,"decorator stub (port HTL logic)",v)),r.info(j(`${m}.css`,h,v)),r.info(j(`_${m}.json`,"Universal Editor model",v)),b.length&&(r.info(""),r.warn(`LESS/SCSS found (needs a build, not copied): ${b.join(", ")}`)),r.info(""),s&&await i({message:"Instrument this block for analytics (dataLayer)?",default:!1})){let{trackBlock:A}=await Promise.resolve().then(()=>(xt(),kt));await A(m,{})}r.info(I([`"${m}" migrated. Next: add CSS, then \`eds block preview ${m}\``]))}var mn,uo=k(()=>{"use strict";f();D();Wr();is();dn();z();_();mn=e=>e.trim().toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/^-+|-+$/g,"")});function te(e,t){return e?e+t.charAt(0).toUpperCase()+t.slice(1):t}var ee,ps=k(()=>{"use strict";f();ee={text:(e,t)=>({component:"text",valueType:"string",name:e,label:t}),textarea:(e,t)=>({component:"textarea",valueType:"string",name:e,label:t}),richtext:(e,t)=>({component:"richtext",valueType:"string",name:e,value:"",label:t}),number:(e,t)=>({component:"number",valueType:"number",name:e,label:t}),boolean:(e,t,n=!1)=>({component:"boolean",valueType:"boolean",name:e,value:n,label:t}),dateTime:(e,t)=>({component:"date-time",valueType:"date",name:e,label:t}),select:(e,t,n,o)=>({component:"select",valueType:"string",name:e,label:t,options:n,...o!==void 0?{value:o}:{}}),multiselect:(e,t,n)=>({component:"multiselect",valueType:"string",name:e,label:t,options:n}),radioGroup:(e,t,n,o)=>({component:"radio-group",valueType:"string",name:e,label:t,options:n,...o!==void 0?{value:o}:{}}),checkboxGroup:(e,t,n)=>({component:"checkbox-group",valueType:"string[]",name:e,label:t,options:n}),reference:(e,t)=>({component:"reference",valueType:"string",name:e,label:t}),aemContent:(e,t)=>({component:"aem-content",name:e,label:t}),aemContentFragment:(e,t)=>({component:"aem-content-fragment",name:e,label:t}),aemExperienceFragment:(e,t)=>({component:"aem-experience-fragment",name:e,label:t}),aemTag:(e,t)=>({component:"aem-tag",valueType:"string",name:e,label:t}),tab:(e,t)=>({component:"tab",name:e,label:t}),container:(e,t,n,o=!0)=>({component:"container",name:e,label:t,multi:!0,collapsible:o,fields:n})}});function wo(e){return Ye.find(t=>t.id===e)}var ad,cd,ld,dd,us,fs,fo,gs,go,ho,md,pd,ud,fd,gd,Ye,bo=k(()=>{"use strict";f();ps();ad=[{name:"H1",value:"h1"},{name:"H2",value:"h2"},{name:"H3",value:"h3"},{name:"H4",value:"h4"},{name:"H5",value:"h5"},{name:"H6",value:"h6"}],cd=[{name:"Same tab",value:"_self"},{name:"New tab",value:"_blank"}],ld=[{name:"Default",value:""},{name:"Primary",value:"primary"},{name:"Secondary",value:"secondary"}],dd=[{name:"Highlight",value:"highlight"},{name:"Dark",value:"dark"},{name:"Centered",value:"centered"},{name:"Full width",value:"full-width"}],us=(e="")=>[ee.text(te(e,"title"),"Title"),ee.select(te(e,"titleType"),"Heading level",ad,"h2")],fs=(e="")=>[ee.text(te(e,"eyebrow"),"Eyebrow")],fo=(e="")=>[ee.reference(te(e,"image"),"Image"),ee.text(te(e,"imageAlt"),"Alt text")],gs=(e="")=>[ee.richtext(te(e,"text"),"Text")],go=(e="")=>[ee.text(te(e,"linkText"),"Link text"),ee.aemContent(te(e,"link"),"Link"),ee.select(te(e,"linkTarget"),"Open in",cd,"_self")],ho=(e="")=>[...go(e),ee.select(te(e,"ctaStyle"),"Style",ld,"")],md=(e="")=>[ee.container(te(e,"ctas")||"ctas","Buttons",ho())],pd=(e="")=>[ee.multiselect(te(e,"classes"),"Styles",dd)],ud=(e="")=>[ee.aemContent(te(e,"url"),"URL (video / embed)")],fd=(e="")=>[...fo(e),...fs(e),...us(e),...gs(e),...ho(e)],gd=(e="")=>[...fo(e),ee.text(te(e,"title"),"Title"),ee.richtext(te(e,"description"),"Description"),...go(e)],Ye=[{id:"heading",label:"Heading (title + level)",build:us},{id:"eyebrow",label:"Eyebrow (kicker line)",build:fs},{id:"image",label:"Image (reference + alt)",build:fo},{id:"richtext",label:"Rich text body",build:gs},{id:"link",label:"Link (text + url + target)",build:go},{id:"cta",label:"CTA (link + style)",build:ho},{id:"cta-group",label:"CTA group (repeatable buttons)",build:md},{id:"classes",label:"Section styles (CSS modifiers)",build:pd},{id:"embed",label:"Embed / video (URL)",build:ud},{id:"teaser",label:"Teaser (image + eyebrow + title + text + CTA)",build:fd},{id:"card",label:"Card (image + title + description + link)",build:gd}]});var ko={};O(ko,{modelAdd:()=>bd});import{existsSync as yo}from"fs";import{readFile as hd,writeFile as wd}from"fs/promises";import vo from"path";async function bd(e,t,n={}){let o=E();if(!o){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Model - add partials"));let{select:i,checkbox:s}=await Promise.resolve().then(()=>(H(),B)),a=!n.yes,l=e;if(!l&&a){let{readdir:w}=await import("fs/promises"),A=vo.join(o,"blocks"),X=yo(A)?(await w(A,{withFileTypes:!0})).filter(K=>K.isDirectory()&&yo(vo.join(A,K.name,`_${K.name}.json`))).map(K=>K.name):[];if(X.length===0){r.error("No block with a _<name>.json model found. Create one with `eds block create`."),process.exitCode=1;return}l=await i({message:"Which block's model?",choices:X.map(K=>({name:K,value:K}))})}if(!l){r.error("Provide a block name."),process.exitCode=1;return}let c=vo.join(o,"blocks",l,`_${l}.json`);if(!yo(c)){r.error(`No model at blocks/${l}/_${l}.json. Create the block first.`),process.exitCode=1;return}let d=t;d.length===0&&a&&(d=await s({message:"Which partials to add?",choices:Ye.map(w=>({name:w.label,value:w.id}))}));let m=d.map(w=>wo(w.trim())).filter(w=>!!w),p=d.filter(w=>!wo(w.trim()));if(p.length&&r.warn(`Unknown partial(s): ${p.join(", ")}. Available: ${Ye.map(w=>w.id).join(", ")}`),m.length===0){r.info("Nothing to add.");return}let u;try{u=JSON.parse(await hd(c,"utf-8"))}catch{r.error(`Could not parse ${c}.`),process.exitCode=1;return}let g=Array.isArray(u.models)?u.models:[],h=g.find(w=>w.id===l)??g[0];if(!h){r.error("Model has no `models[]` entry to add fields to."),process.exitCode=1;return}h.fields=Array.isArray(h.fields)?h.fields:[];let b=new Set(h.fields.map(w=>w.name)),y=[],v=[];for(let w of m)for(let A of w.build()){if(b.has(A.name)){v.push(A.name);continue}b.add(A.name),h.fields.push(A),y.push(A.name)}await wd(c,`${JSON.stringify(u,null,2)}
402
- `),r.info(S("Model updated",`blocks/${l}/_${l}.json`)),r.info(j("partials",m.map(w=>w.id).join(", "))),r.info(j("fields added",y.length?y.join(", "):"(none)")),v.length&&r.info(R("warn","skipped (exists)",v.join(", "))),r.info(""),r.info(I([`${y.length} field(s) added to "${l}"`]))}var xo=k(()=>{"use strict";f();D();bo();z();_()});function ws(e){return pn.find(t=>t.id.toLowerCase()===e.toLowerCase())}function bs(e,t){if(e.includes(hs))return{js:e,changed:!1,reason:"already has JSON-LD"};let n=e.match(/export default (?:async )?function decorate\s*\(\s*([A-Za-z_$][\w$]*)?[^)]*\)\s*\{/);if(!n||n.index===void 0)return{js:e,changed:!1,reason:"no `export default function decorate(...)` found"};let o=n[1]||"block",i=n.index+n[0].length,s=`
403
- // --- ${hs}: ${t.id}) ---
403
+ `}function _a(e,t=0){let n=[];for(let o of e){let i=" ".repeat(t);if(o.component==="tab")n.push(`${i}${N.blue("\u25B8")} ${o.label??o.name}`);else{let r=o.options?.length?` (${o.options.length} options)`:"",s=o.multi?" \xB7multi":"",l=o.label?`- ${o.label}`:"";n.push(`${i}${N.accent(o.component)}${s} ${o.name}${r} ${l}`),o.fields?.length&&n.push(..._a(o.fields,t+1))}}return n}async function Vd(e,t={}){let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}await a.logoOnceAnimated("Migrate component");let{input:o,confirm:i}=await Promise.resolve().then(()=>(G(),H)),r=!t.yes,s=e;if(!s&&r&&(s=await o({message:"Path to the classic component folder",validate:w=>So(w.trim())||"Folder not found"})),!s){a.error("Provide the path to the classic component folder."),process.exitCode=1;return}s=Ee.resolve(s.trim());let l=(t.superRoot??"").split(",").map(w=>w.trim()).filter(Boolean).map(w=>Ee.resolve(w)),c=await Ea(s,l);if(!c){let w=$o(s);w?(a.error(`No dialog here: this is a proxy of ${w}, and that component isn't under ${l.length?"the given --super-root":"this jcr_root"}.`),a.info(" Pass --super-root <jcr_root that contains it>, e.g. a checkout of adobe/aem-core-wcm-components (content/src/content/jcr_root).")):a.error(`No Touch UI dialog (_cq_dialog/.content.xml) found in ${s}.`),process.exitCode=1;return}if(ot(c.fields)===0){a.warn("Dialog found but no mappable fields were detected."),c.unmapped.length&&a.info(`Unmapped resourceTypes: ${c.unmapped.join(", ")}`),process.exitCode=1;return}let d=await ja(s)??Ee.basename(s),m=t.name&&vn(t.name)||vn(r?await o({message:"Block name",default:vn(d)}):d);c.dialogKind==="classic"&&a.info(` ${N.blue("\u21B3")} Classic UI dialog (dialog.xml) - mapped from its xtypes`),c.inheritedFrom&&a.info(` ${N.blue("\u21B3")} Dialog inherited from ${c.inheritedFrom} (proxy component; overlay changes not applied)`),a.info(j("Mapped fields",`${ot(c.fields)} from dialog`));for(let w of _a(c.fields))a.info(` ${w}`);if(c.unmapped.length&&(a.info(""),a.warn(`Skipped (unrecognised): ${c.unmapped.join(", ")}`)),c.datasourced.length&&a.warn(`Options come from a datasource, migrated as text (add static options if needed): ${c.datasourced.join(", ")}`),a.info(""),r&&!await i({message:`Generate block "${m}"?`,default:!0})){a.info("Cancelled.");return}let p=Ee.join(n,"blocks",m);if(So(p)){a.error(`Block "${m}" already exists at blocks/${m}. Use --name to pick another.`),process.exitCode=1;return}let u=t.clientlib?Ee.resolve(t.clientlib.trim()):await ga(s),g=Aa(m),h="empty - add styles from clientlib / rendered CSS",$=[];if(u&&So(u)){let w=await ha(u);w.css.trim()&&(g=Xd(m,w.css,w.files),h=`from clientlib (${w.files.length} file(s)) - review & scope`),$=w.preprocessed}await Kd(p,{recursive:!0}),await jo(Ee.join(p,`${m}.js`),Ta(m,c.fields)),await jo(Ee.join(p,`${m}.css`),g),await jo(Ee.join(p,`_${m}.json`),Ca(m,d,c.fields)),a.info(j("Created"));let b=[`${m}.js`,`${m}.css`,`_${m}.json`],y=I(b);if(a.info(P(`${m}.js`,"decorator stub (port HTL logic)",y)),a.info(P(`${m}.css`,h,y)),a.info(P(`_${m}.json`,"Universal Editor model",y)),$.length&&(a.info(""),a.warn(`LESS/SCSS found (needs a build, not copied): ${$.join(", ")}`)),a.info(""),r&&await i({message:"Instrument this block for analytics (dataLayer)?",default:!1})){let{trackBlock:T}=await Promise.resolve().then(()=>(At(),Tt));await T(m,{})}a.info(B([`"${m}" migrated. Next: add CSS, then \`eds block preview ${m}\``]))}var vn,Eo=v(()=>{"use strict";f();D();wa();Ra();yn();J();U();vn=e=>e.trim().toLowerCase().replace(/[^a-z0-9-]+/g,"-").replace(/^-+|-+$/g,"")});function oe(e,t){return e?e+t.charAt(0).toUpperCase()+t.slice(1):t}var ne,Ia=v(()=>{"use strict";f();ne={text:(e,t)=>({component:"text",valueType:"string",name:e,label:t}),textarea:(e,t)=>({component:"textarea",valueType:"string",name:e,label:t}),richtext:(e,t)=>({component:"richtext",valueType:"string",name:e,value:"",label:t}),number:(e,t)=>({component:"number",valueType:"number",name:e,label:t}),boolean:(e,t,n=!1)=>({component:"boolean",valueType:"boolean",name:e,value:n,label:t}),dateTime:(e,t)=>({component:"date-time",valueType:"date",name:e,label:t}),select:(e,t,n,o)=>({component:"select",valueType:"string",name:e,label:t,options:n,...o!==void 0?{value:o}:{}}),multiselect:(e,t,n)=>({component:"multiselect",valueType:"string",name:e,label:t,options:n}),radioGroup:(e,t,n,o)=>({component:"radio-group",valueType:"string",name:e,label:t,options:n,...o!==void 0?{value:o}:{}}),checkboxGroup:(e,t,n)=>({component:"checkbox-group",valueType:"string[]",name:e,label:t,options:n}),reference:(e,t)=>({component:"reference",valueType:"string",name:e,label:t}),aemContent:(e,t)=>({component:"aem-content",name:e,label:t}),aemContentFragment:(e,t)=>({component:"aem-content-fragment",name:e,label:t}),aemExperienceFragment:(e,t)=>({component:"aem-experience-fragment",name:e,label:t}),aemTag:(e,t)=>({component:"aem-tag",valueType:"string",name:e,label:t}),tab:(e,t)=>({component:"tab",name:e,label:t}),container:(e,t,n,o=!0)=>({component:"container",name:e,label:t,multi:!0,collapsible:o,fields:n})}});function Ro(e){return rt.find(t=>t.id===e)}var Yd,Qd,Zd,em,Ua,Ba,Co,Ha,To,Ao,tm,nm,om,im,rm,rt,Fo=v(()=>{"use strict";f();Ia();Yd=[{name:"H1",value:"h1"},{name:"H2",value:"h2"},{name:"H3",value:"h3"},{name:"H4",value:"h4"},{name:"H5",value:"h5"},{name:"H6",value:"h6"}],Qd=[{name:"Same tab",value:"_self"},{name:"New tab",value:"_blank"}],Zd=[{name:"Default",value:""},{name:"Primary",value:"primary"},{name:"Secondary",value:"secondary"}],em=[{name:"Highlight",value:"highlight"},{name:"Dark",value:"dark"},{name:"Centered",value:"centered"},{name:"Full width",value:"full-width"}],Ua=(e="")=>[ne.text(oe(e,"title"),"Title"),ne.select(oe(e,"titleType"),"Heading level",Yd,"h2")],Ba=(e="")=>[ne.text(oe(e,"eyebrow"),"Eyebrow")],Co=(e="")=>[ne.reference(oe(e,"image"),"Image"),ne.text(oe(e,"imageAlt"),"Alt text")],Ha=(e="")=>[ne.richtext(oe(e,"text"),"Text")],To=(e="")=>[ne.text(oe(e,"linkText"),"Link text"),ne.aemContent(oe(e,"link"),"Link"),ne.select(oe(e,"linkTarget"),"Open in",Qd,"_self")],Ao=(e="")=>[...To(e),ne.select(oe(e,"ctaStyle"),"Style",Zd,"")],tm=(e="")=>[ne.container(oe(e,"ctas")||"ctas","Buttons",Ao())],nm=(e="")=>[ne.multiselect(oe(e,"classes"),"Styles",em)],om=(e="")=>[ne.aemContent(oe(e,"url"),"URL (video / embed)")],im=(e="")=>[...Co(e),...Ba(e),...Ua(e),...Ha(e),...Ao(e)],rm=(e="")=>[...Co(e),ne.text(oe(e,"title"),"Title"),ne.richtext(oe(e,"description"),"Description"),...To(e)],rt=[{id:"heading",label:"Heading (title + level)",build:Ua},{id:"eyebrow",label:"Eyebrow (kicker line)",build:Ba},{id:"image",label:"Image (reference + alt)",build:Co},{id:"richtext",label:"Rich text body",build:Ha},{id:"link",label:"Link (text + url + target)",build:To},{id:"cta",label:"CTA (link + style)",build:Ao},{id:"cta-group",label:"CTA group (repeatable buttons)",build:tm},{id:"classes",label:"Section styles (CSS modifiers)",build:nm},{id:"embed",label:"Embed / video (URL)",build:om},{id:"teaser",label:"Teaser (image + eyebrow + title + text + CTA)",build:im},{id:"card",label:"Card (image + title + description + link)",build:rm}]});var Oo={};M(Oo,{modelAdd:()=>cm});import{existsSync as Lo}from"fs";import{readFile as am,writeFile as sm}from"fs/promises";import Do from"path";async function cm(e,t,n={}){let o=E();if(!o){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Model - add partials"));let{select:i,checkbox:r}=await Promise.resolve().then(()=>(G(),H)),s=!n.yes,l=e;if(!l&&s){let{readdir:w}=await import("fs/promises"),T=Do.join(o,"blocks"),K=Lo(T)?(await w(T,{withFileTypes:!0})).filter(q=>q.isDirectory()&&Lo(Do.join(T,q.name,`_${q.name}.json`))).map(q=>q.name):[];if(K.length===0){a.error("No block with a _<name>.json model found. Create one with `eds block create`."),process.exitCode=1;return}l=await i({message:"Which block's model?",choices:K.map(q=>({name:q,value:q}))})}if(!l){a.error("Provide a block name."),process.exitCode=1;return}let c=Do.join(o,"blocks",l,`_${l}.json`);if(!Lo(c)){a.error(`No model at blocks/${l}/_${l}.json. Create the block first.`),process.exitCode=1;return}let d=t;d.length===0&&s&&(d=await r({message:"Which partials to add?",choices:rt.map(w=>({name:w.label,value:w.id}))}));let m=d.map(w=>Ro(w.trim())).filter(w=>!!w),p=d.filter(w=>!Ro(w.trim()));if(p.length&&a.warn(`Unknown partial(s): ${p.join(", ")}. Available: ${rt.map(w=>w.id).join(", ")}`),m.length===0){a.info("Nothing to add.");return}let u;try{u=JSON.parse(await am(c,"utf-8"))}catch{a.error(`Could not parse ${c}.`),process.exitCode=1;return}let g=Array.isArray(u.models)?u.models:[],h=g.find(w=>w.id===l)??g[0];if(!h){a.error("Model has no `models[]` entry to add fields to."),process.exitCode=1;return}h.fields=Array.isArray(h.fields)?h.fields:[];let $=new Set(h.fields.map(w=>w.name)),b=[],y=[];for(let w of m)for(let T of w.build()){if($.has(T.name)){y.push(T.name);continue}$.add(T.name),h.fields.push(T),b.push(T.name)}await sm(c,`${JSON.stringify(u,null,2)}
404
+ `),a.info(j("Model updated",`blocks/${l}/_${l}.json`)),a.info(P("partials",m.map(w=>w.id).join(", "))),a.info(P("fields added",b.length?b.join(", "):"(none)")),y.length&&a.info(R("warn","skipped (exists)",y.join(", "))),a.info(""),a.info(B([`${b.length} field(s) added to "${l}"`]))}var No=v(()=>{"use strict";f();D();Fo();J();U()});function Wa(e){return kn.find(t=>t.id.toLowerCase()===e.toLowerCase())}function za(e,t){if(e.includes(Ga))return{js:e,changed:!1,reason:"already has JSON-LD"};let n=e.match(/export default (?:async )?function decorate\s*\(\s*([A-Za-z_$][\w$]*)?[^)]*\)\s*\{/);if(!n||n.index===void 0)return{js:e,changed:!1,reason:"no `export default function decorate(...)` found"};let o=n[1]||"block",i=n.index+n[0].length,r=`
405
+ // --- ${Ga}: ${t.id}) ---
404
406
  {
405
407
  const root = ${o};
406
408
  const ld = ${t.object};
@@ -409,7 +411,7 @@ ${t.trim()}
409
411
  ldScript.textContent = JSON.stringify(ld);
410
412
  document.head.append(ldScript);
411
413
  }
412
- `;return{js:`${e.slice(0,i)}${s}${e.slice(i)}`,changed:!0}}var hs,pn,ys=k(()=>{"use strict";f();hs="json-ld (eds schema",pn=[{id:"Article",label:"Article / BlogPosting",object:`{
414
+ `;return{js:`${e.slice(0,i)}${r}${e.slice(i)}`,changed:!0}}var Ga,kn,Ja=v(()=>{"use strict";f();Ga="json-ld (eds schema",kn=[{id:"Article",label:"Article / BlogPosting",object:`{
413
415
  '@context': 'https://schema.org',
414
416
  '@type': 'Article',
415
417
  headline: root.querySelector('h1, h2, h3')?.textContent?.trim() || document.title,
@@ -488,17 +490,51 @@ ${t.trim()}
488
490
  position: i + 1,
489
491
  text: li.textContent?.trim(),
490
492
  })),
491
- }`}]});var $o={};O($o,{schemaBlock:()=>Sd});import{existsSync as yd}from"fs";import{readFile as vd,writeFile as kd}from"fs/promises";import xd from"path";import $d from"chalk";async function Sd(e,t={}){let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Schema - JSON-LD"));let o=xd.join(n,"blocks",e,`${e}.js`);if(!yd(o)){r.error(`Block "${e}" not found (no blocks/${e}/${e}.js).`),process.exitCode=1;return}let i=t.type;if(!i&&!t.yes){let{select:l}=await Promise.resolve().then(()=>(H(),B));i=await l({message:"Which schema.org type?",choices:pn.map(c=>({name:`${c.id} - ${c.label}`,value:c.id}))})}let s=i?ws(i):void 0;if(!s){r.error(`Unknown schema type "${i}". Options: ${pn.map(l=>l.id).join(", ")}`),process.exitCode=1;return}let a=bs(await vd(o,"utf-8"),s);if(!a.changed){r.warn(`Not added: ${a.reason}.`);return}await kd(o,a.js),r.info(S("JSON-LD added")),r.info(j(`blocks/${e}/${e}.js`,`${s.id} (${s.label})`)),r.info(""),r.info($d.dim(" Review the generated object - some fields are heuristic or TODO. Validate at search.google.com/test/rich-results."))}var So=k(()=>{"use strict";f();D();z();ys();_()});function Pd(e,t){for(let n of e.match(/<meta\b[^>]*>/gi)??[])if(n.match(/\bname=["']([^"']+)["']/i)?.[1]===t)return n.match(/\bcontent=["']([^"']*)["']/i)?.[1]??"";return null}function vs(e){return Pd(e,jd)!==null}function ks(e){return Array.isArray(e)?e.map(t=>t&&typeof t=="object"?t.id:void 0).filter(t=>typeof t=="string"):[]}function xs(e){let t=!!e.configPresent["component-definition.json"]&&!!e.configPresent["component-models.json"],n=new Set(e.modelIds),o=e.blocks.map(i=>{let s=i.hasModelFile||n.has(i.name);return{name:i.name,editable:s,reason:s?void 0:"no UE model (_<name>.json or component-models entry)"}});return{isUeProject:t,blocks:o}}var jo,jd,$s=k(()=>{"use strict";f();jo=["component-definition.json","component-models.json","component-filters.json"],jd="urn:adobe:aue:system:aemconnection"});var jt={};O(jt,{ueCheck:()=>Fd,ueOpen:()=>Dd});import{existsSync as St}from"fs";import{readFile as Ss,readdir as Ed}from"fs/promises";import $t from"path";import un from"chalk";async function Cd(e){if(!St(e))return null;try{return JSON.parse(await Ss(e,"utf-8"))}catch{return null}}async function Td(e){let t=$t.join(e,"blocks");return St(t)?(await Ed(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>({name:o.name,hasModelFile:St($t.join(t,o.name,`_${o.name}.json`))})):[]}async function Rd(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{let{execa:n}=await import("execa");await n(t,[e],{stdio:"ignore"})}catch{}}async function Ad(e){try{let{execa:t}=await import("execa");return(await t("git",["remote","get-url","origin"],{cwd:e})).stdout.trim()||null}catch{return null}}async function Fd(){let e=E();if(!e){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Universal Editor - readiness"));let t={};for(let p of jo)t[p]=St($t.join(e,p));let n=await Cd($t.join(e,"component-models.json")),o=await Td(e),{isUeProject:i,blocks:s}=xs({configPresent:t,blocks:o,modelIds:ks(n)});r.info(S("Universal Editor config"));let a=[...jo],l=U(a);for(let p of a)r.info(R(t[p]?"pass":"fail",p,void 0,l));if(!i){r.info(""),r.warn("This doesn't look like a Universal Editor (crosswalk) project - run `eds scaffold ue` first."),process.exitCode=1;return}let c=$t.join(e,"head.html");if(St(c)){let p=vs(await Ss(c,"utf-8"));r.info(R(p?"pass":"info","head.html",p?"aemconnection present":"no aemconnection (fine for cloud author)"))}if(r.info(S("Blocks",`${s.length} found`)),s.length===0)r.info(un.dim(" No blocks yet."));else{let p=U(s.map(u=>u.name));for(let u of s)r.info(R(u.editable?"pass":"warn",u.name,u.reason,p))}let d=s.filter(p=>p.editable).length,m=s.length-d;r.info(""),r.info(be({pass:d,warn:m})),r.info(un.dim(" Open a page in the editor with `eds ue open <path>`."))}async function Dd(e,t={}){let n=E()??process.cwd(),o=e??t.path??"/",i=t.url;if(!i){let a=await Ad(n),l=a?qe(a):null;if(!l){r.error("Couldn't determine the preview host from git."),r.info(un.dim(" Pass it explicitly: `eds ue open <path> --url main--<repo>--<owner>.aem.page`")),process.exitCode=1;return}i=Ke(l.owner,l.repo,t.ref??"main")}let s=cr({host:i,path:o,org:t.org});r.info(S("Universal Editor")),r.info(j("page",`${i}${o.startsWith("/")?"":"/"}${o}`)),r.info(j("open",s)),t.open!==!1?await Rd(s):r.info(un.dim(" (use without --no-open to launch the browser)"))}var Pt=k(()=>{"use strict";f();D();z();$s();en();_()});var Eo={};O(Eo,{createBlock:()=>Md,ueModelFor:()=>Ps});import{existsSync as Ld}from"fs";import{mkdir as Nd,writeFile as Po}from"fs/promises";import Et from"path";import js from"chalk";function Od(e){return e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function Ps(e){let t=Od(e);return`${JSON.stringify({definitions:[{title:t,id:e,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:t,model:e}}}}}],models:[{id:e,fields:[{component:"text",name:"title",label:"Title",valueType:"string"},{component:"select",name:"titleType",label:"Title Type",valueType:"string",value:"h2",options:[{name:"H1",value:"h1"},{name:"H2",value:"h2"},{name:"H3",value:"h3"},{name:"H4",value:"h4"}]},{component:"richtext",name:"text",value:"",label:"Text",valueType:"string"}]}],filters:[]},null,2)}
492
- `}async function Md(e,t={}){if(!Re.test(e)){r.error(`Invalid block name "${e}". Use kebab-case (e.g., "hero-banner", "card-list").`),process.exitCode=1;return}let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found). Run this from your project root."),process.exitCode=1;return}let o=Et.join(n,"blocks",e);if(Ld(o)){r.error(`Block "${e}" already exists at ${o}`),process.exitCode=1;return}await Nd(o,{recursive:!0});let i=`export default function decorate(block) {
493
+ }`}]});var Mo={};M(Mo,{schemaBlock:()=>fm});import{existsSync as lm}from"fs";import{readFile as dm,writeFile as mm}from"fs/promises";import pm from"path";import um from"chalk";async function fm(e,t={}){let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Schema - JSON-LD"));let o=pm.join(n,"blocks",e,`${e}.js`);if(!lm(o)){a.error(`Block "${e}" not found (no blocks/${e}/${e}.js).`),process.exitCode=1;return}let i=t.type;if(!i&&!t.yes){let{select:l}=await Promise.resolve().then(()=>(G(),H));i=await l({message:"Which schema.org type?",choices:kn.map(c=>({name:`${c.id} - ${c.label}`,value:c.id}))})}let r=i?Wa(i):void 0;if(!r){a.error(`Unknown schema type "${i}". Options: ${kn.map(l=>l.id).join(", ")}`),process.exitCode=1;return}let s=za(await dm(o,"utf-8"),r);if(!s.changed){a.warn(`Not added: ${s.reason}.`);return}await mm(o,s.js),a.info(j("JSON-LD added")),a.info(P(`blocks/${e}/${e}.js`,`${r.id} (${r.label})`)),a.info(""),a.info(um.dim(" Review the generated object - some fields are heuristic or TODO. Validate at search.google.com/test/rich-results."))}var _o=v(()=>{"use strict";f();D();J();Ja();U()});function hm(e,t){for(let n of e.match(/<meta\b[^>]*>/gi)??[])if(n.match(/\bname=["']([^"']+)["']/i)?.[1]===t)return n.match(/\bcontent=["']([^"']*)["']/i)?.[1]??"";return null}function qa(e){return hm(e,gm)!==null}function Ka(e){return Array.isArray(e)?e.map(t=>t&&typeof t=="object"?t.id:void 0).filter(t=>typeof t=="string"):[]}function Xa(e){let t=!!e.configPresent["component-definition.json"]&&!!e.configPresent["component-models.json"],n=new Set(e.modelIds),o=e.blocks.map(i=>{let r=i.hasModelFile||n.has(i.name);return{name:i.name,editable:r,reason:r?void 0:"no UE model (_<name>.json or component-models entry)"}});return{isUeProject:t,blocks:o}}var Io,gm,Va=v(()=>{"use strict";f();Io=["component-definition.json","component-models.json","component-filters.json"],gm="urn:adobe:aue:system:aemconnection"});var Lt={};M(Lt,{ueCheck:()=>xm,ueOpen:()=>$m});import{existsSync as Ft}from"fs";import{readFile as Ya,readdir as wm}from"fs/promises";import Rt from"path";import xn from"chalk";async function bm(e){if(!Ft(e))return null;try{return JSON.parse(await Ya(e,"utf-8"))}catch{return null}}async function ym(e){let t=Rt.join(e,"blocks");return Ft(t)?(await wm(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>({name:o.name,hasModelFile:Ft(Rt.join(t,o.name,`_${o.name}.json`))})):[]}async function vm(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{let{execa:n}=await import("execa");await n(t,[e],{stdio:"ignore"})}catch{}}async function km(e){try{let{execa:t}=await import("execa");return(await t("git",["remote","get-url","origin"],{cwd:e})).stdout.trim()||null}catch{return null}}async function xm(){let e=E();if(!e){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Universal Editor - readiness"));let t={};for(let p of Io)t[p]=Ft(Rt.join(e,p));let n=await bm(Rt.join(e,"component-models.json")),o=await ym(e),{isUeProject:i,blocks:r}=Xa({configPresent:t,blocks:o,modelIds:Ka(n)});a.info(j("Universal Editor config"));let s=[...Io],l=I(s);for(let p of s)a.info(R(t[p]?"pass":"fail",p,void 0,l));if(!i){a.info(""),a.warn("This doesn't look like a Universal Editor (crosswalk) project - run `eds scaffold ue` first."),process.exitCode=1;return}let c=Rt.join(e,"head.html");if(Ft(c)){let p=qa(await Ya(c,"utf-8"));a.info(R(p?"pass":"info","head.html",p?"aemconnection present":"no aemconnection (fine for cloud author)"))}if(a.info(j("Blocks",`${r.length} found`)),r.length===0)a.info(xn.dim(" No blocks yet."));else{let p=I(r.map(u=>u.name));for(let u of r)a.info(R(u.editable?"pass":"warn",u.name,u.reason,p))}let d=r.filter(p=>p.editable).length,m=r.length-d;a.info(""),a.info($e({pass:d,warn:m})),a.info(xn.dim(" Open a page in the editor with `eds ue open <path>`."))}async function $m(e,t={}){let n=E()??process.cwd(),o=e??t.path??"/",i=t.url;if(!i){let s=await km(n),l=s?Qe(s):null;if(!l){a.error("Couldn't determine the preview host from git."),a.info(xn.dim(" Pass it explicitly: `eds ue open <path> --url main--<repo>--<owner>.aem.page`")),process.exitCode=1;return}i=Ze(l.owner,l.repo,t.ref??"main")}let r=yr({host:i,path:o,org:t.org});a.info(j("Universal Editor")),a.info(P("page",`${i}${o.startsWith("/")?"":"/"}${o}`)),a.info(P("open",r)),t.open!==!1?await vm(r):a.info(xn.dim(" (use without --no-open to launch the browser)"))}var Dt=v(()=>{"use strict";f();D();J();Va();ln();U()});var Bo={};M(Bo,{createBlock:()=>Em,ueModelFor:()=>Za});import{existsSync as Sm}from"fs";import{mkdir as jm,writeFile as Uo}from"fs/promises";import Ot from"path";import Qa from"chalk";function Pm(e){return e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function Za(e){let t=Pm(e);return`${JSON.stringify({definitions:[{title:t,id:e,plugins:{xwalk:{page:{resourceType:"core/franklin/components/block/v1/block",template:{name:t,model:e}}}}}],models:[{id:e,fields:[{component:"text",name:"title",label:"Title",valueType:"string"},{component:"select",name:"titleType",label:"Title Type",valueType:"string",value:"h2",options:[{name:"H1",value:"h1"},{name:"H2",value:"h2"},{name:"H3",value:"h3"},{name:"H4",value:"h4"}]},{component:"richtext",name:"text",value:"",label:"Text",valueType:"string"}]}],filters:[]},null,2)}
494
+ `}async function Em(e,t={}){if(!Ne.test(e)){a.error(`Invalid block name "${e}". Use kebab-case (e.g., "hero-banner", "card-list").`),process.exitCode=1;return}let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found). Run this from your project root."),process.exitCode=1;return}let o=Ot.join(n,"blocks",e);if(Sm(o)){a.error(`Block "${e}" already exists at ${o}`),process.exitCode=1;return}await jm(o,{recursive:!0});let i=`export default function decorate(block) {
493
495
  // TODO: implement ${e} block
494
496
  }
495
- `,s=`.${e} {
497
+ `,r=`.${e} {
496
498
  /* TODO: style ${e} block */
497
499
  }
498
- `;await Po(Et.join(o,`${e}.js`),i),await Po(Et.join(o,`${e}.css`),s);let a=t.ueModel!==!1;a&&await Po(Et.join(o,`_${e}.json`),Ps(e)),r.success(`Block "${e}" created at ${js.cyan(Et.relative(n,o))}${a?js.dim(" (+ Universal Editor model)"):""}`)}var Co=k(()=>{"use strict";f();D();z();Je()});import{existsSync as fn}from"fs";import{readFile as Id}from"fs/promises";import{homedir as Qe}from"os";import Ze from"path";async function Ro(e){let{execaCommand:t}=await import("execa");try{return(await t(`which ${e}`)).stdout.trim()||void 0}catch{return}}function Es(e){if(!e||typeof e!="object")return;let t=e,n=t.mcpServers;if(n&&typeof n=="object"){for(let o of Object.keys(n))if(o.toLowerCase().includes("figma"))return o}for(let o of Object.values(t)){let i=Es(o);if(i)return i}}async function Ao(e){for(let t of e)try{if(!fn(t))continue;let n=await Id(t,"utf-8");try{let o=Es(JSON.parse(n));if(o)return o}catch{}if(n.toLowerCase().includes("figma"))return"figma"}catch{}}async function Cs(e){if(e){let t=To.find(n=>n.type===e);if(t){let n=await Ro(t.binary);if(n){let o=await Ao(t.mcpConfigPaths);return{type:t.type,path:n,configDir:fn(t.configDir)?t.configDir:void 0,hasFigmaMcp:!!o,figmaMcpServerName:o}}r.warn(`Preferred agent "${e}" not found in PATH`)}}for(let t of To){let n=await Ro(t.binary);if(n){let o=await Ao(t.mcpConfigPaths);return{type:t.type,path:n,configDir:fn(t.configDir)?t.configDir:void 0,hasFigmaMcp:!!o,figmaMcpServerName:o}}}}async function gn(){let e=[];for(let t of To){let n=await Ro(t.binary);if(n){let o=await Ao(t.mcpConfigPaths);e.push({type:t.type,path:n,configDir:fn(t.configDir)?t.configDir:void 0,hasFigmaMcp:!!o,figmaMcpServerName:o})}}return e}var To,Fo=k(()=>{"use strict";f();D();To=[{type:"claude",binary:"claude",configDir:Ze.join(Qe(),".claude"),mcpConfigPaths:[Ze.join(Qe(),".claude","plugins.json"),Ze.join(Qe(),".claude.json")]},{type:"cursor",binary:"cursor",configDir:Ze.join(Qe(),".cursor"),mcpConfigPaths:[Ze.join(Qe(),".cursor","mcp.json")]},{type:"codex",binary:"codex",configDir:Ze.join(Qe(),".codex"),mcpConfigPaths:[]}]});import{mkdir as _d,readFile as Ud,writeFile as Bd}from"fs/promises";import{tmpdir as Hd}from"os";import Ct from"path";import Gd from"readline";import ie from"chalk";async function Do(e,t){let n=t?Ct.join(t,"tmp"):Hd(),o=Ct.join(n,"eds-cli");await _d(o,{recursive:!0});let i=`from-design-${Date.now()}.md`,s=Ct.join(o,i);return await Bd(s,e,"utf-8"),s}function Ts(e,t){return Buffer.byteLength(e,"utf-8")<=Wd?e:`Your full task is in the file ${t}. Read that whole file first and follow its instructions exactly - it replaces this message.`}async function Lo(e,t,n,o){let{execa:i}=await import("execa"),s=await Ud(t,"utf-8");try{switch(e.type){case"claude":{r.info(`Running Claude Code ${ie.dim("- live log:")}`);let a=[...e.figmaMcpServerName?[e.figmaMcpServerName]:[],"figma-sse","figma-desktop","figma","Figma","plugin_figma_figma"],l=[...new Set(a.map(m=>`mcp__${m}`)),"Edit","Write","Read"].join(","),d=i("claude",["-p","--model",o??"haiku","--output-format","stream-json","--verbose","--allowedTools",l],{cwd:n,buffer:!1,input:s,stdio:["pipe","pipe","inherit"]});await Jd(d,n);break}case"cursor":{r.info("Running Cursor agent..."),await i("cursor",["--prompt",Ts(s,t)],{cwd:n,stdio:"inherit"});break}case"codex":{r.info("Running Codex..."),await i("codex",[Ts(s,t)],{cwd:n,stdio:"inherit"});break}}return!0}catch(a){let l=(a instanceof Error?a.message:String(a)).split(`
499
- `)[0].slice(0,300);return r.error(`Agent ${e.type} failed: ${l}`),!1}}function zd(e){return e.includes("figma")?e.split("__").pop()??e:e.toLowerCase()}async function Jd(e,t){let n=(await import("ora")).default,o=Date.now(),i=()=>`${Math.round((Date.now()-o)/1e3)}s`,s=n({text:`thinking ${ie.dim(i())}`,color:"yellow"}).start(),a="thinking",l=setInterval(()=>{s.text=`${a} ${ie.dim(i())}`},300),c=new Map,d=p=>{s.stop(),r.info(` ${p}`),s.start()},m;try{if(e.stdout){let p=Gd.createInterface({input:e.stdout});for await(let u of p){let g=u.trim();if(!g)continue;let h;try{h=JSON.parse(g)}catch{continue}let b=Array.isArray(h.message?.content)?h.message.content:[];if(h.type==="assistant"){for(let y of b)if(y.type==="text"&&"text"in y){let v=y.text.trim().split(`
500
- `)[0].slice(0,100);v&&d(ie.dim(v))}else if(y.type==="tool_use"&&"name"in y){let v="id"in y&&y.id?y.id:`${Math.random()}`;c.set(v,{label:qd(y.name,y.input,t),start:Date.now()}),a=zd(y.name)}}else if(h.type==="user"){for(let y of b)if(y.type==="tool_result"&&"tool_use_id"in y&&y.tool_use_id){let v=c.get(y.tool_use_id);if(v){let w=`${((Date.now()-v.start)/1e3).toFixed(1)}s`,A="is_error"in y&&y.is_error?` ${ie.red("failed")}`:"";d(`${v.label} ${ie.dim(w)}${A}`),c.delete(y.tool_use_id)}}}else if(h.type==="result"){let y=typeof h.duration_ms=="number"?`${(h.duration_ms/1e3).toFixed(1)}s`:"",v=typeof h.total_cost_usd=="number"?`$${h.total_cost_usd.toFixed(3)}`:"";m=[y,v].filter(Boolean).join(" \xB7 ")||"done"}}}for(let p of c.values())d(`${p.label} ${ie.dim("\u2026")}`);clearInterval(l),m?s.succeed(`${M.accent("agent finished")} ${ie.dim(m)}`):s.stop()}catch(p){throw clearInterval(l),s.stop(),p}await e}function qd(e,t,n){let o=i=>{let s=t?.[i];return typeof s!="string"?"":s.startsWith(n)?Ct.relative(n,s):Ct.basename(s)};if(e.includes("figma")){let i=e.split("__").pop()??e;return`${J.figma} ${ie.bold(i)} ${ie.dim("Figma MCP")}`}switch(e){case"Write":case"Edit":case"NotebookEdit":return`${M.accent("\u270E")} ${ie.cyan(o("file_path"))}`;case"Read":return ie.dim(`\xB7 read ${o("file_path")}`);case"Bash":{let i=typeof t?.command=="string"?t.command.split(`
501
- `)[0].slice(0,70):"";return ie.dim(`$ ${i}`)}default:return`${M.blue("\u2192")} ${e}`}}var Wd,Rs=k(()=>{"use strict";f();D();_();Wd=96*1024});import{existsSync as Kd}from"fs";import{readFile as Vd}from"fs/promises";import{homedir as Xd}from"os";import No from"path";async function As(e){try{let t=await Vd(e,"utf-8");return JSON.parse(t)}catch{return}}async function pe(e){let t=await As(Oo),n=e?await As(No.join(e,Yd)):void 0,o={...typeof t=="object"&&t!==null?t:{},...typeof n=="object"&&n!==null?n:{}},i=In.safeParse(o);return i.success?i.data:(r.debug("Config validation issues:",i.error.flatten()),In.parse({}))}function Ds(){return Fs}function Mo(){return Oo}function Io(){return Kd(Oo)}var Fs,Oo,Yd,xe=k(()=>{"use strict";f();D();Je();Fs=No.join(Xd(),".eds"),Oo=No.join(Fs,"config.json"),Yd=".edsrc.json"});function Ls(e){return e<=480?`${e} mobile`:e<=1024?`${e} tablet`:`${e} desktop`}function Qd(e,t="figma"){return e?e.split(",").map(n=>Number.parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0).map(n=>({width:n,label:Ls(n),source:t})):[]}function Ns(e,t){let n=Qd(e,"figma");return n.length?n:Zd(t)}function Zd(e){if(!Array.isArray(e))return[];let t=new Set,n=[];for(let o of e){let i=Number(o?.width);if(!Number.isFinite(i)||i<=0||t.has(i))continue;t.add(i);let s=o.source,a=s==="figma"||s==="scrape"?s:"default";n.push({width:i,label:Ls(i),source:a})}return n}var Os=k(()=>{"use strict";f()});import{existsSync as em}from"fs";import{createRequire as tm}from"module";import nm from"path";import{pathToFileURL as Ms}from"url";async function Is(e){try{return(await import("playwright")).chromium}catch{}let t=[e,process.cwd()].filter(n=>!!n);if(t.length)try{let o=tm(Ms(nm.join(t[0],"package.json")).href).resolve("playwright",{paths:t});return(await import(Ms(o).href)).chromium}catch{}throw new Error("Scraping needs Playwright. Install it in your project (`npm i -D playwright`) or globally (`npm i -g playwright`), then `npx playwright install chromium`.")}async function _s(e){let t=e.width??1440,n=await Is(e.projectRoot),o;try{o=await n.launch({headless:!0})}catch(i){let s=i instanceof Error?i.message:String(i);throw/Executable doesn't exist|install/i.test(s)?new Error("Chromium isn't installed for Playwright. Run `npx playwright install chromium`."):i}try{let i=e.storageStatePath&&em(e.storageStatePath),a=await(await o.newContext({viewport:{width:t,height:900},deviceScaleFactor:1,...i?{storageState:e.storageStatePath}:{}})).newPage();await a.goto(e.url,{waitUntil:"networkidle",timeout:45e3}),await a.waitForTimeout(700);let l=await a.evaluate(om,{maxNodes:320,maxDepth:14,textCap:200}),c={source:`scrape:${e.provider}`,url:e.url,viewport:t,authenticated:!!i,title:l.title,root:l.root,nodeCount:l.nodeCount,truncated:l.truncated};return JSON.stringify(c,null,2)}finally{await o.close()}}async function Us(e){let n=await(await Is(e.projectRoot)).launch({headless:!1});try{let o=await n.newContext();await(await o.newPage()).goto(e.loginUrl,{waitUntil:"domcontentloaded",timeout:6e4}),await e.waitForUser(),await o.storageState({path:e.statePath})}finally{await n.close()}}function om(e){let t=new Set(["SCRIPT","STYLE","NOSCRIPT","LINK","META","HEAD","BR","TEMPLATE"]),n=0,o=!1,i=d=>!d||d==="none"||d==="normal"||d==="auto"||d==="0px"||d==="rgba(0, 0, 0, 0)"||d==="transparent";function s(d){let m="";for(let p of Array.from(d.childNodes))p.nodeType===3&&(m+=p.textContent??"");return m=m.replace(/\s+/g," ").trim(),m.length>e.textCap?`${m.slice(0,e.textCap)}\u2026`:m}function a(d){let m=getComputedStyle(d),p={},u=(g,h)=>{i(h)||(p[g]=h)};return u("display",m.display),(m.display.includes("flex")||m.display.includes("grid"))&&(u("flexDirection",m.flexDirection),u("justifyContent",m.justifyContent),u("alignItems",m.alignItems),u("gap",m.gap)),u("padding",m.padding),u("margin",m.margin),u("color",m.color),u("background",m.backgroundColor),m.backgroundImage&&m.backgroundImage!=="none"&&(p.backgroundImage=m.backgroundImage.slice(0,160)),u("fontFamily",m.fontFamily),u("fontSize",m.fontSize),u("fontWeight",m.fontWeight),u("lineHeight",m.lineHeight),u("letterSpacing",m.letterSpacing),u("textAlign",m.textAlign),u("border",m.border),u("borderRadius",m.borderRadius),u("boxShadow",m.boxShadow),m.opacity&&m.opacity!=="1"&&(p.opacity=m.opacity),m.position&&m.position!=="static"&&(p.position=m.position),p}function l(d,m){if(n>=e.maxNodes)return o=!0,null;if(t.has(d.tagName))return null;let p=d.getBoundingClientRect(),u=getComputedStyle(d);if(u.display==="none"||u.visibility==="hidden"||u.opacity==="0"||p.width<1||p.height<1)return null;n++;let h={tag:d.tagName.toLowerCase(),rect:{x:Math.round(p.x),y:Math.round(p.y),w:Math.round(p.width),h:Math.round(p.height)}},b=(d.getAttribute("class")||"").trim().split(/\s+/).filter(Boolean).slice(0,3);b.length&&(h.class=b.join(" "));let y=a(d);if(Object.keys(y).length&&(h.style=y),d.tagName==="IMG"){let w=d;h.img={src:(w.currentSrc||w.src||"").slice(0,200),alt:w.alt||"",w:w.naturalWidth,h:w.naturalHeight}}let v=s(d);if(v&&(h.text=v),m<e.maxDepth){let w=[];for(let A of Array.from(d.children)){let X=l(A,m+1);X&&w.push(X)}w.length&&(h.children=w)}return h}let c=l(document.body,0);return{title:document.title,root:c,nodeCount:n,truncated:o}}var _o=k(()=>{"use strict";f()});import{mkdir as Bs,readFile as im,rm as Hs,stat as rm,writeFile as sm}from"fs/promises";import Ws from"path";function hn(e){return Ws.join(e,"tmp","eds-cli","figma-rest-calls.json")}async function cm(e,t,n){let o=`${e}.lock`;for(await Bs(Ws.dirname(e),{recursive:!0});;)try{await Bs(o);break}catch{await rm(o).then(s=>t()-s.mtimeMs,()=>0)>am?await Hs(o,{recursive:!0,force:!0}):await new Promise(s=>setTimeout(s,25))}try{return await n()}finally{await Hs(o,{recursive:!0,force:!0})}}async function lm(e){try{let t=JSON.parse(await im(e,"utf-8"));return Array.isArray(t)?t.filter(n=>typeof n=="number"):[]}catch{return[]}}async function wn(e){let t=Math.max(1,e.perMinute??Uo),n=e.now??Date.now,o=e.sleep??(i=>new Promise(s=>setTimeout(s,i)));for(;;){let i=await cm(e.logPath,n,async()=>{let s=n(),a=(await lm(e.logPath)).filter(l=>s-l<Gs);return a.length<t?(a.push(s),await sm(e.logPath,JSON.stringify(a)),0):Math.min(...a)+Gs-s+50});if(i<=0)return;e.onWait?.(i),await o(i)}}var Uo,Gs,am,bn=k(()=>{"use strict";f();Uo=10,Gs=6e4,am=1e4});function dm(e){let t=Math.max(0,Math.round(e));if(t<60)return`${t} s`;if(t<3600)return`${Math.round(t/60)} min`;if(t<86400){let o=Math.round(t%3600/60);return`${Math.floor(t/3600)} h${o?` ${o} min`:""}`}let n=Math.round(t%86400/3600);return`${Math.floor(t/86400)} d${n?` ${n} h`:""}`}async function Go(e,t,n,o=!1){await n?.();let i=await fetch(e,{headers:{"X-Figma-Token":t}});if(i.status!==429)return i;let s=c=>i.headers.get(c)??void 0,a=s("retry-after"),l=a!==void 0&&/^\d+$/.test(a)?Number(a):void 0;if(!o&&l!==void 0&&l<=60)return await mm.sleep(l*1e3),Go(e,t,n,!0);throw new Tt(l,s("x-figma-plan-tier"),s("x-figma-rate-limit-type"),s("x-figma-upgrade-link"))}async function qs(e){let{fileKey:t,nodeId:n,token:o}=e,i=n?`${Bo}/files/${t}/nodes?ids=${encodeURIComponent(n)}`:`${Bo}/files/${t}`,s=await Go(i,o,e.pace);if(!s.ok){let a=await s.text().catch(()=>""),l=s.status===403?" (check the token scope: it needs file_content:read, and access to this file)":s.status===404?" (file or node not found \u2014 check the URL)":"";throw new Error(`Figma REST ${s.status} ${s.statusText}${l}${a?` \u2014 ${a.slice(0,200)}`:""}`)}return s.json()}async function Ks(e){let{fileKey:t,nodeId:n,token:o,scale:i=1}=e;if(!n)throw new Error("A node id is required to render a Figma image.");let s=`${Bo}/images/${t}?ids=${encodeURIComponent(n)}&format=png&scale=${i}`,a=await Go(s,o,e.pace);if(!a.ok){let m=await a.text().catch(()=>"");throw new Error(`Figma images ${a.status} ${a.statusText}${m?` \u2014 ${m.slice(0,200)}`:""}`)}let l=await a.json();if(l.err)throw new Error(`Figma images: ${l.err}`);let c=l.images?.[n]??Object.values(l.images??{}).find(Boolean);if(!c)throw new Error("Figma returned no image URL for that node.");let d=await fetch(c);if(!d.ok)throw new Error(`Fetching the rendered image failed: ${d.status} ${d.statusText}`);return Buffer.from(await d.arrayBuffer())}function Ho(e){if(!e)return;let t=o=>Math.round(Math.max(0,Math.min(1,o))*255).toString(16).padStart(2,"0"),n=`#${t(e.r)}${t(e.g)}${t(e.b)}`;return e.a!==void 0&&e.a<1?`${n}${t(e.a)}`:n}function Js(e){let t=e?.find(n=>n.visible!==!1);if(t){if(t.type==="SOLID")return Ho(t.color);if(t.type?.startsWith("GRADIENT")){let n=(t.gradientStops??[]).map(o=>Ho(o.color)).filter(Boolean);return n.length?`gradient(${n.join(" \u2192 ")})`:"gradient"}return t.type==="IMAGE"?"image(placeholder)":t.type?.toLowerCase()}}function Vs(e,t){if(!e||typeof e!="object")return null;let n={name:e.name,type:e.type};if(e.absoluteBoundingBox){let{width:a,height:l}=e.absoluteBoundingBox;a!=null&&l!=null&&(n.size={w:Math.round(a),h:Math.round(l)})}e.layoutMode&&e.layoutMode!=="NONE"&&(n.layout={direction:e.layoutMode==="HORIZONTAL"?"row":"column",gap:e.itemSpacing,padding:[e.paddingTop,e.paddingRight,e.paddingBottom,e.paddingLeft],align:[e.primaryAxisAlignItems,e.counterAxisAlignItems].filter(Boolean).join("/")});let o=Js(e.fills);o&&(n.fill=o);let i=Js(e.strokes);i&&(n.stroke={color:i,weight:e.strokeWeight}),e.cornerRadius&&(n.radius=e.cornerRadius);let s=(e.effects??[]).filter(a=>a.visible!==!1&&(a.type==="DROP_SHADOW"||a.type==="INNER_SHADOW")).map(a=>`${a.type==="INNER_SHADOW"?"inset ":""}${a.offset?.x??0} ${a.offset?.y??0} ${a.radius??0} ${Ho(a.color)??""}`.trim());if(s.length&&(n.shadows=s),e.type==="TEXT"&&e.characters!==void 0){n.text=e.characters;let a=e.style??{};n.font={family:a.fontFamily,size:a.fontSize,weight:a.fontWeight,lineHeight:a.lineHeightPx,letterSpacing:a.letterSpacing,align:a.textAlignHorizontal}}if(e.children?.length&&t<pm){let a=e.children.slice(0,zs).map(l=>Vs(l,t+1)).filter(Boolean);a.length&&(n.children=a),e.children.length>zs&&(n.childrenTruncated=e.children.length)}return n}function Xs(e,t){let n=e,o;if(t&&n.nodes){let s=Object.keys(n.nodes)[0];o=s?n.nodes[s]?.document:void 0}if(o??=n.document,!o)throw new Error("Figma REST response had no document node to serialize.");let i={source:"figma-rest",file:n.name,root:Vs(o,0)};return JSON.stringify(i,null,2)}var Bo,Tt,mm,pm,zs,Wo=k(()=>{"use strict";f();Bo="https://api.figma.com/v1",Tt=class extends Error{constructor(n,o,i,s){let a=[o&&`plan tier: ${o}`,i&&`limit type: ${i}`].filter(Boolean).join(", ");super(`Figma REST rate limit reached${a?` (${a})`:""}${n!==void 0?`; resets in ${dm(n)}`:""}`);this.retryAfterSeconds=n;this.planTier=o;this.limitType=i;this.upgradeLink=s;this.name="FigmaRateLimitError"}retryAfterSeconds;planTier;limitType;upgradeLink};mm={sleep:e=>new Promise(t=>setTimeout(t,e))};pm=12,zs=60});import{existsSync as um}from"fs";import{mkdir as fm,readFile as gm,writeFile as hm}from"fs/promises";import Rt from"path";function wm(e,t,n){let o=s=>s.replace(/[^a-z0-9._-]/gi,"-"),i=`${o(t)}__${o(n??"file")}.json`;return Rt.join(e,"tmp","eds-cli","design-cache",i)}function bm(e,t){let n=`scrape__${t.replace(/[^a-z0-9._-]/gi,"-").slice(0,120)}.json`;return Rt.join(e,"tmp","eds-cli","design-cache",n)}function zo(e){return e==="framer"||e==="stitch"}async function Ys(e){if(!um(e))return null;try{return await gm(e,"utf-8")}catch{return null}}async function Qs(e,t){await fm(Rt.dirname(e),{recursive:!0}),await hm(e,t,"utf-8")}async function Zs(e){let{figma:t,projectRoot:n}=e;if(e.localFile)return{design:{mode:"file",filePath:e.localFile},summary:`local file ${e.localFile}`};if(zo(e.provider)&&e.designUrl){let s=bm(n,e.designUrl),a=Rt.relative(n,s);if(e.dryRun)return{design:{mode:"scrape",spec:`{ "note": "dry run \u2014 the live ${e.provider} page is scraped at generate time", "url": "${e.designUrl}" }`,cachePath:a},summary:`scrape (dry run) ${e.designUrl}`};if(!e.refresh){let l=await Ys(s);if(l)return{design:{mode:"scrape",spec:l,cachePath:a},summary:`cache ${a}`}}try{let l=await _s({url:e.designUrl,provider:e.provider,projectRoot:n,storageStatePath:e.storageStatePath});return await Qs(s,l),{design:{mode:"scrape",spec:l,cachePath:a},summary:`scrape \u2192 ${a}`}}catch(l){return{summary:"scrape failed",scrapeError:l instanceof Error?l.message:String(l)}}}if(!t?.fileKey)return{summary:"no design source"};let o=wm(n,t.fileKey,t.nodeId),i=Rt.relative(n,o);if(!e.refresh){let s=await Ys(o);if(s)return{design:{mode:"spec",spec:s,cachePath:i},summary:`cache ${i}`}}if(e.token&&!e.preferMcp)try{let s=await qs({fileKey:t.fileKey,nodeId:t.nodeId,token:e.token,pace:()=>wn({logPath:hn(n),perMinute:e.restPerMinute,onWait:e.onRestWait})}),a=Xs(s,t.nodeId);return await Qs(o,a),{design:{mode:"spec",spec:a,cachePath:i},summary:`REST \u2192 ${i}`}}catch(s){return s instanceof Tt?{summary:"REST rate-limited",restError:s.message,rateLimit:s}:{design:{mode:"mcp",cachePath:i},summary:"MCP (REST failed \u2014 1 call)",restError:s instanceof Error?s.message:String(s)}}return{design:{mode:"mcp",cachePath:i},summary:"MCP (1 call, cached)"}}var ea=k(()=>{"use strict";f();_o();bn();Wo()});function yn(e){if(/^\d+[-:]\d+$/.test(e.trim()))throw new Error(`Input "${e}" looks like a node-id but not a full URL. Provide a Figma URL or use --file-key.`);let t;try{t=new URL(e.trim())}catch{throw new Error(`Invalid Figma URL: "${e}"`)}if(!t.hostname.endsWith("figma.com"))throw new Error(`Not a Figma URL: "${e}"`);let n=t.pathname.split("/").filter(Boolean);if(n.length<2)throw new Error(`Cannot extract fileKey from URL: "${e}"`);let o=n[0];if(!ym.has(o))throw new Error(`Not a Figma file URL: "${e}". Use a design link (figma.com/design/<file>/\u2026?node-id=\u2026).`);let i,s;n[2]==="branch"&&n[3]?(i=n[3],s=n[4]?decodeURIComponent(n[4]):void 0):(i=n[1],s=n[2]?decodeURIComponent(n[2]):void 0);let a=t.searchParams.get("node-id"),l=a?vm(a):void 0;return{fileKey:i,nodeId:l,fileName:s}}function vm(e){return decodeURIComponent(e).replace(/-/g,":")}var ym,ta=k(()=>{"use strict";f();ym=new Set(["design","file","board","make","slides","proto"])});import{existsSync as km}from"fs";import{readFile as xm}from"fs/promises";import $m from"path";function na(e){try{return JSON.stringify(JSON.parse(e))}catch{return e}}function Sm(e,t,n){if(!e||e==="document"||e==="ue")return"";let o=t?` (model / persisted query: \`${t}\`)`:"",i="`${window.location.origin}/graphql/execute.json/<project>/<query>;path=<cfPath>`";return e==="cf"?`
500
+ `;await Uo(Ot.join(o,`${e}.js`),i),await Uo(Ot.join(o,`${e}.css`),r);let s=t.ueModel!==!1;s&&await Uo(Ot.join(o,`_${e}.json`),Za(e)),a.success(`Block "${e}" created at ${Qa.cyan(Ot.relative(n,o))}${s?Qa.dim(" (+ Universal Editor model)"):""}`)}var Ho=v(()=>{"use strict";f();D();J();Ye()});import{existsSync as Cm}from"fs";import{readFile as Tm}from"fs/promises";import{homedir as Am}from"os";import Go from"path";async function es(e){try{let t=await Tm(e,"utf-8");return JSON.parse(t)}catch{return}}async function ce(e){let t=await es(Wo),n=e?await es(Go.join(e,Rm)):void 0,o={...typeof t=="object"&&t!==null?t:{},...typeof n=="object"&&n!==null?n:{}},i=Vn.safeParse(o);return i.success?i.data:(a.debug("Config validation issues:",i.error.flatten()),Vn.parse({}))}function ns(){return ts}function zo(){return Wo}function Jo(){return Cm(Wo)}var ts,Wo,Rm,ye=v(()=>{"use strict";f();D();Ye();ts=Go.join(Am(),".eds"),Wo=Go.join(ts,"config.json"),Rm=".edsrc.json"});import{existsSync as Fm}from"fs";import{mkdir as Lm,readFile as Dm,readdir as Om,writeFile as Nm}from"fs/promises";import We from"path";function ze(e){return $n.includes(e)}async function is(e,t=Nt[e],n=1500){let o=e==="ollama"?`${qo(t)}/api/tags`:`${qo(t)}/models`;try{let i=await fetch(o,{signal:AbortSignal.timeout(n)});if(!i.ok)return null;let r=await i.json();return(e==="ollama"?(r.models??[]).map(l=>l.name??l.model??""):(r.data??[]).map(l=>l.id??"")).filter(Boolean)}catch{return null}}function rs(e){let t=[/coder/i,/codestral|devstral/i,/code/i,/qwen/i,/deepseek/i,/llama/i];for(let n of t){let o=e.find(i=>n.test(i));if(o)return o}return e[0]}function as(e){return Math.ceil(e.length/3.5)}async function*Mm(e){let t=e.getReader(),n=new TextDecoder,o="";for(;;){let{value:i,done:r}=await t.read();if(r)break;o+=n.decode(i,{stream:!0});let s=o.indexOf(`
501
+ `);for(;s>=0;)yield o.slice(0,s),o=o.slice(s+1),s=o.indexOf(`
502
+ `)}o.trim()&&(yield o)}async function ss(e){let t=qo(e.baseUrl),n={"content-type":"application/json"};e.apiKey&&(n.authorization=`Bearer ${e.apiKey}`);let o,i;if(e.type==="ollama")o=`${t}/api/chat`,i={model:e.model,stream:!0,messages:[{role:"user",content:e.prompt,...e.images?.length?{images:e.images.map(c=>c.data.toString("base64"))}:{}}],options:{num_ctx:e.contextTokens??Ko,temperature:.2}};else{o=`${t}/chat/completions`;let c=e.images?.length?[{type:"text",text:e.prompt},...e.images.map(d=>({type:"image_url",image_url:{url:`data:${d.mime};base64,${d.data.toString("base64")}`}}))]:e.prompt;i={model:e.model,stream:!0,temperature:.2,messages:[{role:"user",content:c}]}}let r=await fetch(o,{method:"POST",headers:n,body:JSON.stringify(i),signal:e.signal});if(!r.ok||!r.body){let c=await r.text().catch(()=>"");throw new Error(`${Ce[e.type]} ${r.status} ${r.statusText}${c?` \u2014 ${c.slice(0,200)}`:""}`)}let s="",l={text:""};for await(let c of Mm(r.body)){let d=c.trim();if(d)if(e.type==="ollama"){let m=JSON.parse(d);if(m.error)throw new Error(`Ollama: ${m.error}`);let p=m.message?.content??"";p&&(s+=p,e.onToken?.(p)),m.done&&(l.promptTokens=m.prompt_eval_count,l.outputTokens=m.eval_count)}else{if(!d.startsWith("data:"))continue;let m=d.slice(5).trim();if(m==="[DONE]")break;let p=JSON.parse(m);if(p.error)throw new Error(`${Ce[e.type]}: ${p.error.message}`);let u=p.choices?.[0]?.delta?.content??"";u&&(s+=u,e.onToken?.(u)),p.usage&&(l.promptTokens=p.usage.prompt_tokens,l.outputTokens=p.usage.completion_tokens)}}return l.text=s,l}function cs(e){let t=`blocks/${e}`;return`
503
+
504
+ ## Output format for this run (local model, no tools) \u2014 this overrides the instructions above
505
+ You cannot read files, run commands, call MCP or use editing tools: everything you need is in this message. Ignore any instruction above to read a file, fetch the design or call a tool.
506
+ Reply with **every file you create, complete**, each wrapped exactly like this (no other markdown around it):
507
+
508
+ === FILE: ${t}/${e}.js ===
509
+ ...the whole file...
510
+ === END FILE ===
511
+
512
+ Write \`${t}/${e}.js\`, \`${t}/${e}.css\`, the Universal Editor model \`${t}/_${e}.json\` (unless told to skip it), the preview mock \`${t}/_${e}.preview.html\` and \`${t}/.eds-meta.json\`. Only paths under \`${t}/\` are saved. After the files, at most 3 lines of summary.`}function ls(e){let t=[],n=e.split(/\r?\n/),o=null;for(let r of n){let s=r.match(_m);if(s&&!os.test(r)){o&&t.push({path:o.path,content:o.body.join(`
513
+ `)}),o={path:s[1].replace(/^`|`$/g,""),body:[]};continue}if(o&&os.test(r)){t.push({path:o.path,content:o.body.join(`
514
+ `)}),o=null;continue}o&&o.body.push(r)}if(o&&t.push({path:o.path,content:o.body.join(`
515
+ `)}),t.length)return t.map(Im);let i=/(?:^|\n)(?:[#*`\s]*([\w./-]+\.(?:js|css|json|html))[`*:\s]*\n)?```[\w-]*[ \t]*([\w./-]+\.(?:js|css|json|html))?[^\n]*\n([\s\S]*?)\n```/g;for(let r of e.matchAll(i)){let s=r[2]??r[1];s&&t.push({path:s,content:r[3]})}return t}function Im(e){let t=e.content.match(/^\s*```[\w-]*\n([\s\S]*?)\n```\s*$/);return t?{...e,content:t[1]}:e}async function ds(e,t,n){let o=We.join(e,"blocks",t),i={written:[],rejected:[]};for(let r of n){let s=r.path.trim().replace(/^\.?\//,""),l=s.includes("/")?We.resolve(e,s):We.join(o,s);if(We.dirname(l)!==o){i.rejected.push(r.path);continue}await Lm(o,{recursive:!0}),await Nm(l,r.content.endsWith(`
516
+ `)?r.content:`${r.content}
517
+ `),i.written.push(We.relative(e,l))}return i}async function ms(e,t){let n=We.join(e,"blocks",t);if(!Fm(n))return"";let o=[];for(let i of(await Om(n)).sort()){if(!/\.(js|css|json|html)$/.test(i))continue;let r=await Dm(We.join(n,i),"utf-8");o.push(`=== FILE: blocks/${t}/${i} ===
518
+ ${r.trimEnd()}
519
+ === END FILE ===`)}return o.join(`
520
+
521
+ `)}var $n,Nt,Ce,Ko,qo,_m,os,Sn=v(()=>{"use strict";f();$n=["ollama","omlx","local"],Nt={ollama:"http://127.0.0.1:11434",omlx:"http://127.0.0.1:8000/v1",local:"http://127.0.0.1:8080/v1"},Ce={ollama:"Ollama",omlx:"oMLX",local:"local OpenAI-compatible server"},Ko=32768;qo=e=>e.replace(/\/+$/,"");_m=/^=+\s*FILE:\s*(.+?)\s*=+\s*$/,os=/^=+\s*END FILE\s*=+\s*$/});import{existsSync as jn}from"fs";import{readFile as Um}from"fs/promises";import{homedir as at}from"os";import st from"path";async function Vo(e){let{execaCommand:t}=await import("execa");try{return(await t(`which ${e}`)).stdout.trim()||void 0}catch{return}}function ps(e){if(!e||typeof e!="object")return;let t=e,n=t.mcpServers;if(n&&typeof n=="object"){for(let o of Object.keys(n))if(o.toLowerCase().includes("figma"))return o}for(let o of Object.values(t)){let i=ps(o);if(i)return i}}async function Yo(e){for(let t of e)try{if(!jn(t))continue;let n=await Um(t,"utf-8");try{let o=ps(JSON.parse(n));if(o)return o}catch{}if(n.toLowerCase().includes("figma"))return"figma"}catch{}}async function Qo(e){let t=E()??void 0,n=(await ce(t)).local,o=n?.baseUrl??Nt[e],i=await is(e,o);if(!i)return;let r=n?.model??rs(i);if(!r){a.warn(`${Ce[e]} at ${o} has no models - pull one first (e.g. \`ollama pull qwen2.5-coder:14b\`).`);return}return{type:e,path:o,baseUrl:o,model:r,hasFigmaMcp:!1}}async function us(e){if(e&&ze(e)){let t=await Qo(e);if(t)return t;a.warn(`${Ce[e]} isn't reachable - is it running?`);return}if(e){let t=Xo.find(n=>n.type===e);if(t){let n=await Vo(t.binary);if(n){let o=await Yo(t.mcpConfigPaths);return{type:t.type,path:n,configDir:jn(t.configDir)?t.configDir:void 0,hasFigmaMcp:!!o,figmaMcpServerName:o}}a.warn(`Preferred agent "${e}" not found in PATH`)}}for(let t of Xo){let n=await Vo(t.binary);if(n){let o=await Yo(t.mcpConfigPaths);return{type:t.type,path:n,configDir:jn(t.configDir)?t.configDir:void 0,hasFigmaMcp:!!o,figmaMcpServerName:o}}}for(let t of $n.filter(n=>n!=="local")){let n=await Qo(t);if(n)return n}}async function Pn(){let e=[];for(let t of Xo){let n=await Vo(t.binary);if(n){let o=await Yo(t.mcpConfigPaths);e.push({type:t.type,path:n,configDir:jn(t.configDir)?t.configDir:void 0,hasFigmaMcp:!!o,figmaMcpServerName:o})}}for(let t of $n.filter(n=>n!=="local")){let n=await Qo(t);n&&e.push(n)}return e}var Xo,Zo=v(()=>{"use strict";f();ye();D();J();Sn();Xo=[{type:"claude",binary:"claude",configDir:st.join(at(),".claude"),mcpConfigPaths:[st.join(at(),".claude","plugins.json"),st.join(at(),".claude.json")]},{type:"cursor",binary:"cursor",configDir:st.join(at(),".cursor"),mcpConfigPaths:[st.join(at(),".cursor","mcp.json")]},{type:"codex",binary:"codex",configDir:st.join(at(),".codex"),mcpConfigPaths:[]}]});import{mkdir as hs,readFile as ei,writeFile as ws}from"fs/promises";import{tmpdir as Bm}from"os";import fe from"path";import Hm from"readline";import Z from"chalk";async function ti(e,t){let n=t?fe.join(t,"tmp"):Bm(),o=fe.join(n,"eds-cli");await hs(o,{recursive:!0});let i=`from-design-${Date.now()}.md`,r=fe.join(o,i);return await ws(r,e,"utf-8"),r}function fs(e,t){return Buffer.byteLength(e,"utf-8")<=Gm?e:`Your full task is in the file ${t}. Read that whole file first and follow its instructions exactly - it replaces this message.`}async function ni(e,t,n,o,i){let{execa:r}=await import("execa"),s=await ei(t,"utf-8");try{if(ze(e.type))return await Wm(e,s,n,o,i);switch(e.type){case"claude":{a.info(`Running Claude Code ${Z.dim("- live log:")}`);let l=[...e.figmaMcpServerName?[e.figmaMcpServerName]:[],"figma-sse","figma-desktop","figma","Figma","plugin_figma_figma"],c=[...new Set(l.map(p=>`mcp__${p}`)),"Edit","Write","Read"].join(","),m=r("claude",["-p","--model",o??"haiku","--output-format","stream-json","--verbose","--allowedTools",c],{cwd:n,buffer:!1,input:s,stdio:["pipe","pipe","inherit"]});await Jm(m,n);break}case"cursor":{a.info("Running Cursor agent..."),await r("cursor",["--prompt",fs(s,t)],{cwd:n,stdio:"inherit"});break}case"codex":{a.info("Running Codex..."),await r("codex",[fs(s,t)],{cwd:n,stdio:"inherit"});break}}return!0}catch(l){let c=(l instanceof Error?l.message:String(l)).split(`
522
+ `)[0].slice(0,300);return a.error(`Agent ${e.type} failed: ${c}`),!1}}async function Wm(e,t,n,o,i){let r=e.type,s=i?.blockName;if(!s)throw new Error("A local model needs the block name to save its files.");let l=o??e.model;if(!l)throw new Error(`No model chosen for ${Ce[r]} - set local.model in config.`);let c=t,d=[];if(i?.designFile){let L=fe.resolve(n,i.designFile),xe=fe.extname(L).toLowerCase();xe===".svg"?c+=`
523
+
524
+ ## The design (${i.designFile})
525
+ \`\`\`svg
526
+ ${await ei(L,"utf-8")}
527
+ \`\`\``:gs[xe]&&(d.push({data:await ei(L),mime:gs[xe]}),c+=`
528
+
529
+ ## The design
530
+ The design (${i.designFile}) is attached as an image. A model without vision can't see it - use a vision model (e.g. qwen2.5vl, llama3.2-vision).`)}i?.refine&&(c+=`
531
+
532
+ ## The block as it is now
533
+ Change these files; reply with every file you change, complete.
534
+
535
+ ${await ms(n,s)}`),c+=cs(s);let m=i?.contextTokens??Ko,p=as(c)+d.length*1500+6e3;p>m&&a.warn(`The prompt needs about ${p} tokens of context but ${m} are configured - raise local.contextTokens${r==="ollama"?"":" and the server's own context length"}, or use a smaller design.`);let u=(await import("ora")).default,g=Date.now(),h=()=>`${Math.round((Date.now()-g)/1e3)}s`;a.info(`Running ${Ce[r]} ${Z.dim(`${l} \xB7 ${e.baseUrl}`)}`);let $=u({text:`waiting for the model ${Z.dim(h())}`,color:"yellow"}).start(),b=0,y=setInterval(()=>{$.text=`${b?`writing \xB7 ${b} chars`:"reading the prompt"} ${Z.dim(h())}`},300),w;try{w=await ss({type:r,baseUrl:e.baseUrl??Nt[r],model:l,prompt:c,images:d,apiKey:i?.apiKey,contextTokens:Math.max(m,r==="ollama"?p:0),onToken:L=>{b+=L.length}})}finally{clearInterval(y),$.stop()}let T=fe.join(n,"tmp","eds-cli",`local-reply-${Date.now()}.md`);await hs(fe.dirname(T),{recursive:!0}),await ws(T,w.text,"utf-8");let K=ls(w.text),{written:q,rejected:he}=await ds(n,s,K),De=[h(),w.outputTokens?`${w.outputTokens} tokens out`:`${w.text.length} chars`].join(" \xB7 ");for(let L of q)a.info(` ${N.accent("\u270E")} ${Z.cyan(L)}`);for(let L of he)a.warn(`Ignored a file outside blocks/${s}/: ${L}`);return q.length?a.info(`${N.accent("\u2713")} ${N.accent("model finished")} ${Z.dim(De)}`):a.warn(`The model replied but no files could be read from it (${De}). Raw reply: ${fe.relative(n,T)}`),!0}function zm(e){return e.includes("figma")?e.split("__").pop()??e:e.toLowerCase()}async function Jm(e,t){let n=(await import("ora")).default,o=Date.now(),i=()=>`${Math.round((Date.now()-o)/1e3)}s`,r=n({text:`thinking ${Z.dim(i())}`,color:"yellow"}).start(),s="thinking",l=setInterval(()=>{r.text=`${s} ${Z.dim(i())}`},300),c=new Map,d=p=>{r.stop(),a.info(` ${p}`),r.start()},m;try{if(e.stdout){let p=Hm.createInterface({input:e.stdout});for await(let u of p){let g=u.trim();if(!g)continue;let h;try{h=JSON.parse(g)}catch{continue}let $=Array.isArray(h.message?.content)?h.message.content:[];if(h.type==="assistant"){for(let b of $)if(b.type==="text"&&"text"in b){let y=b.text.trim().split(`
536
+ `)[0].slice(0,100);y&&d(Z.dim(y))}else if(b.type==="tool_use"&&"name"in b){let y="id"in b&&b.id?b.id:`${Math.random()}`;c.set(y,{label:qm(b.name,b.input,t),start:Date.now()}),s=zm(b.name)}}else if(h.type==="user"){for(let b of $)if(b.type==="tool_result"&&"tool_use_id"in b&&b.tool_use_id){let y=c.get(b.tool_use_id);if(y){let w=`${((Date.now()-y.start)/1e3).toFixed(1)}s`,T="is_error"in b&&b.is_error?` ${Z.red("failed")}`:"";d(`${y.label} ${Z.dim(w)}${T}`),c.delete(b.tool_use_id)}}}else if(h.type==="result"){let b=typeof h.duration_ms=="number"?`${(h.duration_ms/1e3).toFixed(1)}s`:"",y=typeof h.total_cost_usd=="number"?`$${h.total_cost_usd.toFixed(3)}`:"";m=[b,y].filter(Boolean).join(" \xB7 ")||"done"}}}for(let p of c.values())d(`${p.label} ${Z.dim("\u2026")}`);clearInterval(l),m?r.succeed(`${N.accent("agent finished")} ${Z.dim(m)}`):r.stop()}catch(p){throw clearInterval(l),r.stop(),p}await e}function qm(e,t,n){let o=i=>{let r=t?.[i];return typeof r!="string"?"":r.startsWith(n)?fe.relative(n,r):fe.basename(r)};if(e.includes("figma")){let i=e.split("__").pop()??e;return`${X.figma} ${Z.bold(i)} ${Z.dim("Figma MCP")}`}switch(e){case"Write":case"Edit":case"NotebookEdit":return`${N.accent("\u270E")} ${Z.cyan(o("file_path"))}`;case"Read":return Z.dim(`\xB7 read ${o("file_path")}`);case"Bash":{let i=typeof t?.command=="string"?t.command.split(`
537
+ `)[0].slice(0,70):"";return Z.dim(`$ ${i}`)}default:return`${N.blue("\u2192")} ${e}`}}var Gm,gs,bs=v(()=>{"use strict";f();D();U();Sn();Gm=96*1024;gs={".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp"}});function ys(e){return e<=480?`${e} mobile`:e<=1024?`${e} tablet`:`${e} desktop`}function Km(e,t="figma"){return e?e.split(",").map(n=>Number.parseInt(n.trim(),10)).filter(n=>Number.isFinite(n)&&n>0).map(n=>({width:n,label:ys(n),source:t})):[]}function vs(e,t){let n=Km(e,"figma");return n.length?n:Xm(t)}function Xm(e){if(!Array.isArray(e))return[];let t=new Set,n=[];for(let o of e){let i=Number(o?.width);if(!Number.isFinite(i)||i<=0||t.has(i))continue;t.add(i);let r=o.source,s=r==="figma"||r==="scrape"?r:"default";n.push({width:i,label:ys(i),source:s})}return n}var ks=v(()=>{"use strict";f()});import{existsSync as Vm}from"fs";import{createRequire as Ym}from"module";import Qm from"path";import{pathToFileURL as xs}from"url";async function $s(e){try{return(await import("playwright")).chromium}catch{}let t=[e,process.cwd()].filter(n=>!!n);if(t.length)try{let o=Ym(xs(Qm.join(t[0],"package.json")).href).resolve("playwright",{paths:t});return(await import(xs(o).href)).chromium}catch{}throw new Error("Scraping needs Playwright. Install it in your project (`npm i -D playwright`) or globally (`npm i -g playwright`), then `npx playwright install chromium`.")}async function Ss(e){let t=e.width??1440,n=await $s(e.projectRoot),o;try{o=await n.launch({headless:!0})}catch(i){let r=i instanceof Error?i.message:String(i);throw/Executable doesn't exist|install/i.test(r)?new Error("Chromium isn't installed for Playwright. Run `npx playwright install chromium`."):i}try{let i=e.storageStatePath&&Vm(e.storageStatePath),s=await(await o.newContext({viewport:{width:t,height:900},deviceScaleFactor:1,...i?{storageState:e.storageStatePath}:{}})).newPage();await s.goto(e.url,{waitUntil:"networkidle",timeout:45e3}),await s.waitForTimeout(700);let l=await s.evaluate(Zm,{maxNodes:320,maxDepth:14,textCap:200}),c={source:`scrape:${e.provider}`,url:e.url,viewport:t,authenticated:!!i,title:l.title,root:l.root,nodeCount:l.nodeCount,truncated:l.truncated};return JSON.stringify(c,null,2)}finally{await o.close()}}async function js(e){let n=await(await $s(e.projectRoot)).launch({headless:!1});try{let o=await n.newContext();await(await o.newPage()).goto(e.loginUrl,{waitUntil:"domcontentloaded",timeout:6e4}),await e.waitForUser(),await o.storageState({path:e.statePath})}finally{await n.close()}}function Zm(e){let t=new Set(["SCRIPT","STYLE","NOSCRIPT","LINK","META","HEAD","BR","TEMPLATE"]),n=0,o=!1,i=d=>!d||d==="none"||d==="normal"||d==="auto"||d==="0px"||d==="rgba(0, 0, 0, 0)"||d==="transparent";function r(d){let m="";for(let p of Array.from(d.childNodes))p.nodeType===3&&(m+=p.textContent??"");return m=m.replace(/\s+/g," ").trim(),m.length>e.textCap?`${m.slice(0,e.textCap)}\u2026`:m}function s(d){let m=getComputedStyle(d),p={},u=(g,h)=>{i(h)||(p[g]=h)};return u("display",m.display),(m.display.includes("flex")||m.display.includes("grid"))&&(u("flexDirection",m.flexDirection),u("justifyContent",m.justifyContent),u("alignItems",m.alignItems),u("gap",m.gap)),u("padding",m.padding),u("margin",m.margin),u("color",m.color),u("background",m.backgroundColor),m.backgroundImage&&m.backgroundImage!=="none"&&(p.backgroundImage=m.backgroundImage.slice(0,160)),u("fontFamily",m.fontFamily),u("fontSize",m.fontSize),u("fontWeight",m.fontWeight),u("lineHeight",m.lineHeight),u("letterSpacing",m.letterSpacing),u("textAlign",m.textAlign),u("border",m.border),u("borderRadius",m.borderRadius),u("boxShadow",m.boxShadow),m.opacity&&m.opacity!=="1"&&(p.opacity=m.opacity),m.position&&m.position!=="static"&&(p.position=m.position),p}function l(d,m){if(n>=e.maxNodes)return o=!0,null;if(t.has(d.tagName))return null;let p=d.getBoundingClientRect(),u=getComputedStyle(d);if(u.display==="none"||u.visibility==="hidden"||u.opacity==="0"||p.width<1||p.height<1)return null;n++;let h={tag:d.tagName.toLowerCase(),rect:{x:Math.round(p.x),y:Math.round(p.y),w:Math.round(p.width),h:Math.round(p.height)}},$=(d.getAttribute("class")||"").trim().split(/\s+/).filter(Boolean).slice(0,3);$.length&&(h.class=$.join(" "));let b=s(d);if(Object.keys(b).length&&(h.style=b),d.tagName==="IMG"){let w=d;h.img={src:(w.currentSrc||w.src||"").slice(0,200),alt:w.alt||"",w:w.naturalWidth,h:w.naturalHeight}}let y=r(d);if(y&&(h.text=y),m<e.maxDepth){let w=[];for(let T of Array.from(d.children)){let K=l(T,m+1);K&&w.push(K)}w.length&&(h.children=w)}return h}let c=l(document.body,0);return{title:document.title,root:c,nodeCount:n,truncated:o}}var oi=v(()=>{"use strict";f()});import{mkdir as Ps,readFile as ep,rm as Es,stat as tp,writeFile as np}from"fs/promises";import Ts from"path";function En(e){return Ts.join(e,"tmp","eds-cli","figma-rest-calls.json")}async function ip(e,t,n){let o=`${e}.lock`;for(await Ps(Ts.dirname(e),{recursive:!0});;)try{await Ps(o);break}catch{await tp(o).then(r=>t()-r.mtimeMs,()=>0)>op?await Es(o,{recursive:!0,force:!0}):await new Promise(r=>setTimeout(r,25))}try{return await n()}finally{await Es(o,{recursive:!0,force:!0})}}async function rp(e){try{let t=JSON.parse(await ep(e,"utf-8"));return Array.isArray(t)?t.filter(n=>typeof n=="number"):[]}catch{return[]}}async function Cn(e){let t=Math.max(1,e.perMinute??ii),n=e.now??Date.now,o=e.sleep??(i=>new Promise(r=>setTimeout(r,i)));for(;;){let i=await ip(e.logPath,n,async()=>{let r=n(),s=(await rp(e.logPath)).filter(l=>r-l<Cs);return s.length<t?(s.push(r),await np(e.logPath,JSON.stringify(s)),0):Math.min(...s)+Cs-r+50});if(i<=0)return;e.onWait?.(i),await o(i)}}var ii,Cs,op,Tn=v(()=>{"use strict";f();ii=10,Cs=6e4,op=1e4});function ap(e){let t=Math.max(0,Math.round(e));if(t<60)return`${t} s`;if(t<3600)return`${Math.round(t/60)} min`;if(t<86400){let o=Math.round(t%3600/60);return`${Math.floor(t/3600)} h${o?` ${o} min`:""}`}let n=Math.round(t%86400/3600);return`${Math.floor(t/86400)} d${n?` ${n} h`:""}`}async function si(e,t,n,o=!1){await n?.();let i=await fetch(e,{headers:{"X-Figma-Token":t}});if(i.status!==429)return i;let r=c=>i.headers.get(c)??void 0,s=r("retry-after"),l=s!==void 0&&/^\d+$/.test(s)?Number(s):void 0;if(!o&&l!==void 0&&l<=60)return await sp.sleep(l*1e3),si(e,t,n,!0);throw new Mt(l,r("x-figma-plan-tier"),r("x-figma-rate-limit-type"),r("x-figma-upgrade-link"))}async function Fs(e){let{fileKey:t,nodeId:n,token:o}=e,i=n?`${ri}/files/${t}/nodes?ids=${encodeURIComponent(n)}`:`${ri}/files/${t}`,r=await si(i,o,e.pace);if(!r.ok){let s=await r.text().catch(()=>""),l=r.status===403?" (check the token scope: it needs file_content:read, and access to this file)":r.status===404?" (file or node not found \u2014 check the URL)":"";throw new Error(`Figma REST ${r.status} ${r.statusText}${l}${s?` \u2014 ${s.slice(0,200)}`:""}`)}return r.json()}async function Ls(e){let{fileKey:t,nodeId:n,token:o,scale:i=1}=e;if(!n)throw new Error("A node id is required to render a Figma image.");let r=`${ri}/images/${t}?ids=${encodeURIComponent(n)}&format=png&scale=${i}`,s=await si(r,o,e.pace);if(!s.ok){let m=await s.text().catch(()=>"");throw new Error(`Figma images ${s.status} ${s.statusText}${m?` \u2014 ${m.slice(0,200)}`:""}`)}let l=await s.json();if(l.err)throw new Error(`Figma images: ${l.err}`);let c=l.images?.[n]??Object.values(l.images??{}).find(Boolean);if(!c)throw new Error("Figma returned no image URL for that node.");let d=await fetch(c);if(!d.ok)throw new Error(`Fetching the rendered image failed: ${d.status} ${d.statusText}`);return Buffer.from(await d.arrayBuffer())}function ai(e){if(!e)return;let t=o=>Math.round(Math.max(0,Math.min(1,o))*255).toString(16).padStart(2,"0"),n=`#${t(e.r)}${t(e.g)}${t(e.b)}`;return e.a!==void 0&&e.a<1?`${n}${t(e.a)}`:n}function Rs(e){let t=e?.find(n=>n.visible!==!1);if(t){if(t.type==="SOLID")return ai(t.color);if(t.type?.startsWith("GRADIENT")){let n=(t.gradientStops??[]).map(o=>ai(o.color)).filter(Boolean);return n.length?`gradient(${n.join(" \u2192 ")})`:"gradient"}return t.type==="IMAGE"?"image(placeholder)":t.type?.toLowerCase()}}function Ds(e,t){if(!e||typeof e!="object")return null;let n={name:e.name,type:e.type};if(e.absoluteBoundingBox){let{width:s,height:l}=e.absoluteBoundingBox;s!=null&&l!=null&&(n.size={w:Math.round(s),h:Math.round(l)})}e.layoutMode&&e.layoutMode!=="NONE"&&(n.layout={direction:e.layoutMode==="HORIZONTAL"?"row":"column",gap:e.itemSpacing,padding:[e.paddingTop,e.paddingRight,e.paddingBottom,e.paddingLeft],align:[e.primaryAxisAlignItems,e.counterAxisAlignItems].filter(Boolean).join("/")});let o=Rs(e.fills);o&&(n.fill=o);let i=Rs(e.strokes);i&&(n.stroke={color:i,weight:e.strokeWeight}),e.cornerRadius&&(n.radius=e.cornerRadius);let r=(e.effects??[]).filter(s=>s.visible!==!1&&(s.type==="DROP_SHADOW"||s.type==="INNER_SHADOW")).map(s=>`${s.type==="INNER_SHADOW"?"inset ":""}${s.offset?.x??0} ${s.offset?.y??0} ${s.radius??0} ${ai(s.color)??""}`.trim());if(r.length&&(n.shadows=r),e.type==="TEXT"&&e.characters!==void 0){n.text=e.characters;let s=e.style??{};n.font={family:s.fontFamily,size:s.fontSize,weight:s.fontWeight,lineHeight:s.lineHeightPx,letterSpacing:s.letterSpacing,align:s.textAlignHorizontal}}if(e.children?.length&&t<cp){let s=e.children.slice(0,As).map(l=>Ds(l,t+1)).filter(Boolean);s.length&&(n.children=s),e.children.length>As&&(n.childrenTruncated=e.children.length)}return n}function Os(e,t){let n=e,o;if(t&&n.nodes){let r=Object.keys(n.nodes)[0];o=r?n.nodes[r]?.document:void 0}if(o??=n.document,!o)throw new Error("Figma REST response had no document node to serialize.");let i={source:"figma-rest",file:n.name,root:Ds(o,0)};return JSON.stringify(i,null,2)}var ri,Mt,sp,cp,As,ci=v(()=>{"use strict";f();ri="https://api.figma.com/v1",Mt=class extends Error{constructor(n,o,i,r){let s=[o&&`plan tier: ${o}`,i&&`limit type: ${i}`].filter(Boolean).join(", ");super(`Figma REST rate limit reached${s?` (${s})`:""}${n!==void 0?`; resets in ${ap(n)}`:""}`);this.retryAfterSeconds=n;this.planTier=o;this.limitType=i;this.upgradeLink=r;this.name="FigmaRateLimitError"}retryAfterSeconds;planTier;limitType;upgradeLink};sp={sleep:e=>new Promise(t=>setTimeout(t,e))};cp=12,As=60});import{existsSync as lp}from"fs";import{mkdir as dp,readFile as mp,writeFile as pp}from"fs/promises";import _t from"path";function up(e,t,n){let o=r=>r.replace(/[^a-z0-9._-]/gi,"-"),i=`${o(t)}__${o(n??"file")}.json`;return _t.join(e,"tmp","eds-cli","design-cache",i)}function fp(e,t){let n=`scrape__${t.replace(/[^a-z0-9._-]/gi,"-").slice(0,120)}.json`;return _t.join(e,"tmp","eds-cli","design-cache",n)}function li(e){return e==="framer"||e==="stitch"}async function Ns(e){if(!lp(e))return null;try{return await mp(e,"utf-8")}catch{return null}}async function Ms(e,t){await dp(_t.dirname(e),{recursive:!0}),await pp(e,t,"utf-8")}async function _s(e){let{figma:t,projectRoot:n}=e;if(e.localFile)return{design:{mode:"file",filePath:e.localFile},summary:`local file ${e.localFile}`};if(li(e.provider)&&e.designUrl){let r=fp(n,e.designUrl),s=_t.relative(n,r);if(e.dryRun)return{design:{mode:"scrape",spec:`{ "note": "dry run \u2014 the live ${e.provider} page is scraped at generate time", "url": "${e.designUrl}" }`,cachePath:s},summary:`scrape (dry run) ${e.designUrl}`};if(!e.refresh){let l=await Ns(r);if(l)return{design:{mode:"scrape",spec:l,cachePath:s},summary:`cache ${s}`}}try{let l=await Ss({url:e.designUrl,provider:e.provider,projectRoot:n,storageStatePath:e.storageStatePath});return await Ms(r,l),{design:{mode:"scrape",spec:l,cachePath:s},summary:`scrape \u2192 ${s}`}}catch(l){return{summary:"scrape failed",scrapeError:l instanceof Error?l.message:String(l)}}}if(!t?.fileKey)return{summary:"no design source"};let o=up(n,t.fileKey,t.nodeId),i=_t.relative(n,o);if(!e.refresh){let r=await Ns(o);if(r)return{design:{mode:"spec",spec:r,cachePath:i},summary:`cache ${i}`}}if(e.token&&!e.preferMcp)try{let r=await Fs({fileKey:t.fileKey,nodeId:t.nodeId,token:e.token,pace:()=>Cn({logPath:En(n),perMinute:e.restPerMinute,onWait:e.onRestWait})}),s=Os(r,t.nodeId);return await Ms(o,s),{design:{mode:"spec",spec:s,cachePath:i},summary:`REST \u2192 ${i}`}}catch(r){return r instanceof Mt?{summary:"REST rate-limited",restError:r.message,rateLimit:r}:{design:{mode:"mcp",cachePath:i},summary:"MCP (REST failed \u2014 1 call)",restError:r instanceof Error?r.message:String(r)}}return{design:{mode:"mcp",cachePath:i},summary:"MCP (1 call, cached)"}}var Is=v(()=>{"use strict";f();oi();Tn();ci()});function An(e){if(/^\d+[-:]\d+$/.test(e.trim()))throw new Error(`Input "${e}" looks like a node-id but not a full URL. Provide a Figma URL or use --file-key.`);let t;try{t=new URL(e.trim())}catch{throw new Error(`Invalid Figma URL: "${e}"`)}if(!t.hostname.endsWith("figma.com"))throw new Error(`Not a Figma URL: "${e}"`);let n=t.pathname.split("/").filter(Boolean);if(n.length<2)throw new Error(`Cannot extract fileKey from URL: "${e}"`);let o=n[0];if(!gp.has(o))throw new Error(`Not a Figma file URL: "${e}". Use a design link (figma.com/design/<file>/\u2026?node-id=\u2026).`);let i,r;n[2]==="branch"&&n[3]?(i=n[3],r=n[4]?decodeURIComponent(n[4]):void 0):(i=n[1],r=n[2]?decodeURIComponent(n[2]):void 0);let s=t.searchParams.get("node-id"),l=s?hp(s):void 0;return{fileKey:i,nodeId:l,fileName:r}}function hp(e){return decodeURIComponent(e).replace(/-/g,":")}var gp,Us=v(()=>{"use strict";f();gp=new Set(["design","file","board","make","slides","proto"])});import{existsSync as wp}from"fs";import{readFile as bp}from"fs/promises";import yp from"path";function Bs(e){try{return JSON.stringify(JSON.parse(e))}catch{return e}}function vp(e,t,n){if(!e||e==="document"||e==="ue")return"";let o=t?` (model / persisted query: \`${t}\`)`:"",i="`${window.location.origin}/graphql/execute.json/<project>/<query>;path=<cfPath>`";return e==="cf"?`
502
538
  ## Content source: Content Fragment
503
539
  This block renders an AEM **Content Fragment**${o} - not inline-authored copy.
504
540
  - UE model: use an \`aem-content-fragment\` field (e.g. \`name: "fragment"\`) for the CF reference.
@@ -511,38 +547,38 @@ This block mixes **two sources in one model and one \`decorate(block)\`**:
511
547
  - **Inline (UE-authored)** parts \u2192 normal fields (text / richtext / image / select) read straight from the authored DOM cells, with semantic collapsing.
512
548
  - **Content Fragment** part${o} \u2192 an \`aem-content-fragment\` field; \`decorate()\` is **async** and also fetches that CF via a GraphQL persisted query (${i}) and renders its fields.
513
549
  - Field order in the model = cell order in the authored DOM. Read the inline cells by position; detect the CF reference by its \`/content/dam/\` link. Merge both into the final markup, and handle the CF loading/empty/error states.
514
- `}async function oa(e){let t=await jm(e.projectRoot),n=Sm(e.contentSource,e.cfHint,e.blockName),o=e.screenshot===!0,i=e.provider??"figma",s=et[i],a=e.design,l=a?.mode==="file"?/\.(png|jpe?g|webp)$/i.test(a.filePath):!1,d=`## Step 5 \u2014 One Verification Pass (single pass, then stop)
550
+ `}async function Hs(e){let t=await kp(e.projectRoot),n=vp(e.contentSource,e.cfHint,e.blockName),o=e.screenshot===!0,i=e.provider??"figma",r=ct[i],s=e.design,l=s?.mode==="file"?/\.(png|jpe?g|webp)$/i.test(s.filePath):!1,d=`## Step 5 \u2014 One Verification Pass (single pass, then stop)
515
551
  Do **exactly one** self-check \u2014 do **not** loop:
516
- 1. Compare your implementation to ${a?.mode==="spec"?"the exact values in the embedded design data from Step 1":a?.mode==="scrape"?"the exact values in the scraped design data from Step 1":a?.mode==="file"?l?"the local design image":"the exact values in the local SVG":a?.mode==="mcp"?"the exact values from the `get_design_context` you cached":o?"the `get_screenshot` image":"the exact values from `get_design_context`"} once, across: spacing, fonts, colors, radius, shadows, alignment and proportions.
552
+ 1. Compare your implementation to ${s?.mode==="spec"?"the exact values in the embedded design data from Step 1":s?.mode==="scrape"?"the exact values in the scraped design data from Step 1":s?.mode==="file"?l?"the local design image":"the exact values in the local SVG":s?.mode==="mcp"?"the exact values from the `get_design_context` you cached":o?"the `get_screenshot` image":"the exact values from `get_design_context`"} once, across: spacing, fonts, colors, radius, shadows, alignment and proportions.
517
553
  2. Apply **one** round of corrections, then **stop** \u2014 don't iterate to "pixel perfect". The author reviews the result in the live preview (\`eds block preview\`) and will request another pass with specific feedback if needed.
518
- 3. Briefly state what you checked and any value you had to infer.`,m=`Target: fileKey \`${e.figma?.fileKey}\`${e.figma?.nodeId?`, node \`${e.figma.nodeId}\``:" (no node selected \u2014 use the full page)"}.`,p;a?.mode==="spec"?p=`## Step 1 \u2014 Use the Provided Design Data (no MCP)
554
+ 3. Briefly state what you checked and any value you had to infer.`,m=`Target: fileKey \`${e.figma?.fileKey}\`${e.figma?.nodeId?`, node \`${e.figma.nodeId}\``:" (no node selected \u2014 use the full page)"}.`,p;s?.mode==="spec"?p=`## Step 1 \u2014 Use the Provided Design Data (no MCP)
519
555
  The design was already fetched for you and is embedded below \u2014 **do not call any Figma MCP tool** (\`get_design_context\`, \`get_variable_defs\`, \`get_screenshot\`). Parse it for the exact structure, layout, spacing, colors, typography, radius and effects.
520
556
 
521
557
  \`\`\`json
522
- ${na(a.spec)}
558
+ ${Bs(s.spec)}
523
559
  \`\`\`
524
560
 
525
- Image fills are placeholders (the data references assets, not pixels) \u2014 render a placeholder at the right aspect-ratio per the Placeholders section; authors supply the real image.`:a?.mode==="scrape"?p=`## Step 1 \u2014 Use the Scraped Design Data (no MCP)
526
- The design was scraped from the live **${s}** page (${e.designRef??"the URL"}) with headless Chromium and is embedded below \u2014 **do not call any MCP tool** and **do not fetch the URL yourself**. The tree holds **computed** values: geometry (\`rect\` x/y/w/h, px), layout (\`display\`/\`flexDirection\`/\`gap\`/\`padding\`), colours, typography, radius and shadows. Use them verbatim (convert px\u2192rem where appropriate) and regroup the flattened DOM into semantic structure yourself (Step 3).
561
+ Image fills are placeholders (the data references assets, not pixels) \u2014 render a placeholder at the right aspect-ratio per the Placeholders section; authors supply the real image.`:s?.mode==="scrape"?p=`## Step 1 \u2014 Use the Scraped Design Data (no MCP)
562
+ The design was scraped from the live **${r}** page (${e.designRef??"the URL"}) with headless Chromium and is embedded below \u2014 **do not call any MCP tool** and **do not fetch the URL yourself**. The tree holds **computed** values: geometry (\`rect\` x/y/w/h, px), layout (\`display\`/\`flexDirection\`/\`gap\`/\`padding\`), colours, typography, radius and shadows. Use them verbatim (convert px\u2192rem where appropriate) and regroup the flattened DOM into semantic structure yourself (Step 3).
527
563
 
528
564
  \`\`\`json
529
- ${na(a.spec)}
565
+ ${Bs(s.spec)}
530
566
  \`\`\`
531
567
 
532
568
  If the page holds several sections, build **only** the one for \`${e.blockName}\` (the element whose class or \`data-block\` matches the block name) and read the rest only for shared tokens.
533
569
 
534
- The scraped **text and images are reference content**, not authored copy \u2014 reproduce the layout/styling exactly, but read real content from the authored DOM at runtime and fall back to placeholders (see the Placeholders section). Do **not** hardcode the scraped copy or ship the scraped image URLs.`:a?.mode==="file"?p=`## Step 1 \u2014 Read the Local Design Export (no MCP)
535
- Read \`${a.filePath}\` with your **Read** tool. Do **not** call any Figma MCP tool.
570
+ The scraped **text and images are reference content**, not authored copy \u2014 reproduce the layout/styling exactly, but read real content from the authored DOM at runtime and fall back to placeholders (see the Placeholders section). Do **not** hardcode the scraped copy or ship the scraped image URLs.`:s?.mode==="file"?p=`## Step 1 \u2014 Read the Local Design Export (no MCP)
571
+ Read \`${s.filePath}\` with your **Read** tool. Do **not** call any Figma MCP tool.
536
572
 
537
- ${l?"It's a raster image (PNG/JPG) \u2014 open it and reproduce it visually: infer spacing, colors, typography, radius, shadows and layout as precisely as you can from the pixels.":"It's an **SVG** \u2014 read it as text and parse the **exact** values: geometry and positions (x/y/width/height, `viewBox`), text and typography (font-family / font-size / font-weight on `<text>`/`<tspan>`), fills and gradients, strokes, and effects. Use the numbers verbatim, converting px\u2192rem where appropriate. The SVG is flattened \u2014 regroup into semantic structure yourself (Step 3), don't mirror raw `<g>`/`<path>` nesting."}`:a?.mode==="mcp"?p=`## Step 1 \u2014 Fetch the Design Once, Then Cache It (single MCP call)
573
+ ${l?"It's a raster image (PNG/JPG) \u2014 open it and reproduce it visually: infer spacing, colors, typography, radius, shadows and layout as precisely as you can from the pixels.":"It's an **SVG** \u2014 read it as text and parse the **exact** values: geometry and positions (x/y/width/height, `viewBox`), text and typography (font-family / font-size / font-weight on `<text>`/`<tspan>`), fills and gradients, strokes, and effects. Use the numbers verbatim, converting px\u2192rem where appropriate. The SVG is flattened \u2014 regroup into semantic structure yourself (Step 3), don't mirror raw `<g>`/`<path>` nesting."}`:s?.mode==="mcp"?p=`## Step 1 \u2014 Fetch the Design Once, Then Cache It (single MCP call)
538
574
  Call **\`get_design_context\` exactly once** for the target node. Do **not** call \`get_variable_defs\` or \`get_screenshot\` \u2014 each extra MCP call burns the Figma plan's scarce tool-call budget; derive colors and tokens from the context you already got.
539
- **Immediately after**, \`Write\` the raw design data you received to \`${a.cachePath}\` (pretty JSON) so re-runs and refine passes reuse it without another MCP call. Then generate from it.
575
+ **Immediately after**, \`Write\` the raw design data you received to \`${s.cachePath}\` (pretty JSON) so re-runs and refine passes reuse it without another MCP call. Then generate from it.
540
576
 
541
577
  ${m}`:i==="figma"?p=`## Step 1 \u2014 Fetch the Design (single MCP call)
542
578
  Call **\`get_design_context\` exactly once** for the target node \u2014 it returns structure, layout, measurements, text and the colors/tokens you need. Do **not** call \`get_variable_defs\`${o?"":" or `get_screenshot`"} \u2014 each extra MCP call burns the Figma plan's scarce budget.${o?" You may call `get_screenshot` once (`maxDimension: 1024`) for the Step 5 check.":""}
543
579
 
544
580
  ${m}`:p=`## Step 1 \u2014 Read the Design
545
- Open the live **${s}** page at \`${e.designRef??"(the design URL)"}\` and read its rendered layout, typography, colours, spacing, radius and effects. Extract the **exact** values \u2014 do not approximate.`;let u=e.withUeModel?`
581
+ Open the live **${r}** page at \`${e.designRef??"(the design URL)"}\` and read its rendered layout, typography, colours, spacing, radius and effects. Extract the **exact** values \u2014 do not approximate.`;let u=e.withUeModel?`
546
582
  ## Step 4b \u2014 Universal Editor Authoring (REQUIRED, not optional)
547
583
  Authors must be able to drop and edit this block in the Universal Editor, so generate its UE configuration **in the same pass** as the code.
548
584
 
@@ -617,9 +653,9 @@ Rules:
617
653
  If the project uses a **single aggregated model file** (\`component-definition.json\` + \`component-models.json\` + \`component-filters.json\`) instead of per-block \`_${e.blockName}.json\`, detect that convention and add the block's definition/model/filter to those files instead (and register the block in the \`section\` filter). Prefer the per-block \`_${e.blockName}.json\` when neither exists. Full field reference and a repeatable-cards round-trip example: \`docs/universal-editor-fields.md\`.
618
654
 
619
655
  **Reusable field groups (partials):** when the design shows one of these common shapes, reuse the standard group instead of inventing fields \u2014 same groups \`eds model add\` uses, so the model stays consistent across the project:
620
- ${Ye.map(b=>`- \`${b.id}\` \u2014 ${b.label}`).join(`
656
+ ${rt.map($=>`- \`${$.id}\` \u2014 ${$.label}`).join(`
621
657
  `)}
622
- `:"",g=a?.mode==="file"?"a design export":s,h=a?.mode==="file"?"design":`${s} design`;return`# Pixel-Perfect EDS Block from ${g}
658
+ `:"",g=s?.mode==="file"?"a design export":r,h=s?.mode==="file"?"design":`${r} design`;return`# Pixel-Perfect EDS Block from ${g}
623
659
 
624
660
  ## Task
625
661
  Generate an AEM Edge Delivery Services block named **\`${e.blockName}\`** that reproduces the ${h} **1:1 \u2014 pixel perfect**. Exact spacing, colors, typography, and layout. Not "close enough" \u2014 identical.
@@ -698,11 +734,11 @@ ${t}
698
734
  5. Mobile-first CSS with breakpoints at 600px and 900px
699
735
  6. Prefer existing project tokens over new hardcoded values${e.withUeModel?"\n7. UE model field `name`s must match what `decorate()` reads, and every Figma variant must appear as a select option wired to a CSS modifier":""}${e.contentSource==="cf"||e.contentSource==="mixed"?"\n8. **Content Fragment (hard requirement - the CLI checks it):** the model has an `aem-content-fragment` field, and `decorate(block)` is `async` and `fetch()`es that fragment's data (GraphQL persisted query) before building the DOM. A block that only reads inline cells fails verification.":""}
700
736
 
701
- Finally, record the design's frame width(s) you read in Step 1 into \`blocks/${e.blockName}/.eds-meta.json\` as \`{ "breakpoints": [{ "width": <px>, "source": "${a?.mode==="scrape"?"scrape":i}" }] }\` (one entry per distinct frame width). The CLI merges this so \`eds block preview\` shows the block at the **real design widths**, not a fixed device set.
737
+ Finally, record the design's frame width(s) you read in Step 1 into \`blocks/${e.blockName}/.eds-meta.json\` as \`{ "breakpoints": [{ "width": <px>, "source": "${s?.mode==="scrape"?"scrape":i}" }] }\` (one entry per distinct frame width). The CLI merges this so \`eds block preview\` shows the block at the **real design widths**, not a fixed device set.
702
738
 
703
739
  ---
704
- *Prompt version: ${At}*
705
- `}function ia(e){let t=e.provider??"figma",n=t==="figma"&&e.figma?.fileKey?`If the change needs design values, re-read **only what you need** from Figma (fileKey \`${e.figma.fileKey}\`${e.figma.nodeId?`, node \`${e.figma.nodeId}\``:""}) \u2014 don't re-fetch the whole design.`:"Use the values already in the files (and the cached design snapshot under `tmp/eds-cli/design-cache/` if present); infer sensibly if the request is purely stylistic.";return`# Refine the \`${e.blockName}\` EDS block
740
+ *Prompt version: ${It}*
741
+ `}function Gs(e){let t=e.provider??"figma",n=t==="figma"&&e.figma?.fileKey?`If the change needs design values, re-read **only what you need** from Figma (fileKey \`${e.figma.fileKey}\`${e.figma.nodeId?`, node \`${e.figma.nodeId}\``:""}) \u2014 don't re-fetch the whole design.`:"Use the values already in the files (and the cached design snapshot under `tmp/eds-cli/design-cache/` if present); infer sensibly if the request is purely stylistic.";return`# Refine the \`${e.blockName}\` EDS block
706
742
 
707
743
  The block already exists in \`blocks/${e.blockName}/\` and the author reviewed it in the live preview. Apply **this change** and nothing else:
708
744
 
@@ -721,9 +757,9 @@ The block already exists in \`blocks/${e.blockName}/\` and the author reviewed i
721
757
  - **No shell access:** only read/write files${t==="figma"?" and call the Figma MCP":""}. Do **not** run \`eslint\`, \`stylelint\`, \`npm\`, \`npx\`, \`tsc\`, a build, or any Bash command \u2014 they aren't granted and just fail.
722
758
  - **Minimise chat output:** edit files directly, don't paste code back. End with a **\u22642-line** summary of what changed.
723
759
 
724
- *Prompt version: ${At}*
725
- `}async function jm(e){let t=$m.join(e,"styles","styles.css");if(!km(t))return"";try{let o=(await xm(t,"utf-8")).match(/:root\s*\{([^}]+)\}/);if(!o)return"";let i=o[1].split(`
726
- `).filter(s=>s.trim().startsWith("--")).map(s=>s.trim()).join(`
760
+ *Prompt version: ${It}*
761
+ `}async function kp(e){let t=yp.join(e,"styles","styles.css");if(!wp(t))return"";try{let o=(await bp(t,"utf-8")).match(/:root\s*\{([^}]+)\}/);if(!o)return"";let i=o[1].split(`
762
+ `).filter(r=>r.trim().startsWith("--")).map(r=>r.trim()).join(`
727
763
  `);return i?`
728
764
  ## Existing Project Tokens
729
765
  The project already defines these CSS custom properties in \`styles/styles.css\`.
@@ -734,7 +770,7 @@ Reuse them instead of hardcoding values:
734
770
  ${i}
735
771
  }
736
772
  \`\`\`
737
- `:""}catch{return""}}var At,et,ra=k(()=>{"use strict";f();bo();At="0.7.1",et={figma:"Figma",framer:"Framer",stitch:"Google Stitch"}});import{existsSync as Pm}from"fs";import{chmod as Em,mkdir as Cm}from"fs/promises";import{homedir as Tm}from"os";import sa from"path";function Jo(e){return sa.join(Tm(),".eds","auth",`${e}.json`)}function aa(e){return Pm(Jo(e))}async function ca(e){await Cm(sa.dirname(e),{recursive:!0,mode:448})}async function la(e){try{await Em(e,384)}catch{}}var da=k(()=>{"use strict";f()});import{emitKeypressEvents as Rm}from"readline";async function Ft(e){let t=process.stdin,n=vn.menu&&t.isTTY;await new Promise(o=>{let i=!1,s=async c=>{i||(i=!0,process.off("SIGINT",a),process.off("SIGTERM",a),n&&(t.off("keypress",l),t.setRawMode(!1),t.pause()),await e(),c&&process.exit(0),o())},a=()=>{s(!0)},l=(c,d)=>{d?.ctrl&&d.name==="c"?s(!0):(d?.name==="escape"||d?.name==="return")&&s(!1)};process.on("SIGINT",a),process.on("SIGTERM",a),n&&(Rm(t),t.setRawMode(!0),t.resume(),t.on("keypress",l))})}function Dt(){return vn.menu&&process.stdin.isTTY?"Press Esc or Enter to stop and go back to the menu (Ctrl+C quits).":"Press Ctrl+C to stop."}var vn,kn=k(()=>{"use strict";f();vn={menu:!1}});function ue(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Am(e){let t=e,n=t.match(/<body[^>]*>([\s\S]*?)<\/body>/i);return n&&(t=n[1]),t.replace(/<!DOCTYPE[^>]*>/gi,"").replace(/<\/?(?:html|head|body)[^>]*>/gi,"").replace(/<link\b[^>]*>/gi,"").replace(/<style[\s\S]*?<\/style>/gi,"").replace(/<script[\s\S]*?<\/script>/gi,"").replace(/<!--[\s\S]*?-->/g,"").trim()}function xn(e){let{blockName:t}=e,n=Am(e.sampleContent);return`<!DOCTYPE html>
773
+ `:""}catch{return""}}var It,ct,Ws=v(()=>{"use strict";f();Fo();It="0.7.1",ct={figma:"Figma",framer:"Framer",stitch:"Google Stitch"}});import{existsSync as xp}from"fs";import{chmod as $p,mkdir as Sp}from"fs/promises";import{homedir as jp}from"os";import zs from"path";function di(e){return zs.join(jp(),".eds","auth",`${e}.json`)}function Js(e){return xp(di(e))}async function qs(e){await Sp(zs.dirname(e),{recursive:!0,mode:448})}async function Ks(e){try{await $p(e,384)}catch{}}var Xs=v(()=>{"use strict";f()});import{emitKeypressEvents as Pp}from"readline";async function Ut(e){let t=process.stdin,n=Rn.menu&&t.isTTY;await new Promise(o=>{let i=!1,r=async c=>{i||(i=!0,process.off("SIGINT",s),process.off("SIGTERM",s),n&&(t.off("keypress",l),t.setRawMode(!1),t.pause()),await e(),c&&process.exit(0),o())},s=()=>{r(!0)},l=(c,d)=>{d?.ctrl&&d.name==="c"?r(!0):(d?.name==="escape"||d?.name==="return")&&r(!1)};process.on("SIGINT",s),process.on("SIGTERM",s),n&&(Pp(t),t.setRawMode(!0),t.resume(),t.on("keypress",l))})}function Bt(){return Rn.menu&&process.stdin.isTTY?"Press Esc or Enter to stop and go back to the menu (Ctrl+C quits).":"Press Ctrl+C to stop."}var Rn,Fn=v(()=>{"use strict";f();Rn={menu:!1}});function ge(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function Ep(e){let t=e,n=t.match(/<body[^>]*>([\s\S]*?)<\/body>/i);return n&&(t=n[1]),t.replace(/<!DOCTYPE[^>]*>/gi,"").replace(/<\/?(?:html|head|body)[^>]*>/gi,"").replace(/<link\b[^>]*>/gi,"").replace(/<style[\s\S]*?<\/style>/gi,"").replace(/<script[\s\S]*?<\/script>/gi,"").replace(/<!--[\s\S]*?-->/g,"").trim()}function Ln(e){let{blockName:t}=e,n=Ep(e.sampleContent);return`<!DOCTYPE html>
738
774
  <html lang="en">
739
775
  <head>
740
776
  <meta charset="utf-8" />
@@ -764,19 +800,19 @@ ${n}
764
800
  try { new EventSource('/__eds_events').onmessage = () => location.reload(); } catch (e) { /* no SSE */ }
765
801
  </script>
766
802
  </body>
767
- </html>`}function Fm(e){let t=e.filter(n=>n.figma);return(t.length?t:e).reduce((n,o)=>o.width>n.width?o:n,e[0])}function ma(e){let t=e.map((o,i)=>{let s=Fm(o.breakpoints),a=o.breakpoints.map(d=>`<option value="${d.width}"${d.width===s.width?" selected":""}>${ue(d.label)}</option>`).join(""),l=o.figmaUrl?`<a class="figma-link" href="${ue(o.figmaUrl)}" target="_blank" rel="noopener">Figma \u2197</a>`:"",c=o.placeholder?'<span class="hint">placeholder content</span>':"";return`<section class="card">
803
+ </html>`}function Cp(e){let t=e.filter(n=>n.figma);return(t.length?t:e).reduce((n,o)=>o.width>n.width?o:n,e[0])}function Vs(e){let t=e.map((o,i)=>{let r=Cp(o.breakpoints),s=o.breakpoints.map(d=>`<option value="${d.width}"${d.width===r.width?" selected":""}>${ge(d.label)}</option>`).join(""),l=o.figmaUrl?`<a class="figma-link" href="${ge(o.figmaUrl)}" target="_blank" rel="noopener">Figma \u2197</a>`:"",c=o.placeholder?'<span class="hint">placeholder content</span>':"";return`<section class="card">
768
804
  <div class="cardbar">
769
- <span class="block">${ue(o.blockName)}</span>
805
+ <span class="block">${ge(o.blockName)}</span>
770
806
  <select class="bp" data-i="${i}">
771
- ${a}
807
+ ${s}
772
808
  <option value="full">Full</option>
773
809
  </select>
774
810
  ${c}
775
811
  ${l}
776
812
  </div>
777
813
  <div class="stage">
778
- <div class="device" data-i="${i}" data-w="${s.width}" style="width:${s.width}px">
779
- <iframe src="${ue(o.frameRoute)}" title="${ue(o.blockName)} preview" loading="lazy"></iframe>
814
+ <div class="device" data-i="${i}" data-w="${r.width}" style="width:${r.width}px">
815
+ <iframe src="${ge(o.frameRoute)}" title="${ge(o.blockName)} preview" loading="lazy"></iframe>
780
816
  </div>
781
817
  </div>
782
818
  </section>`}).join(`
@@ -825,16 +861,16 @@ ${n}
825
861
  try { new EventSource('/__eds_events').onmessage = () => location.reload(); } catch (e) { /* no SSE */ }
826
862
  </script>
827
863
  </body>
828
- </html>`}function pa(e){let{blockName:t,breakpoints:n,figmaUrl:o,frameRoute:i,placeholder:s}=e,a=n.filter(p=>p.figma),l=(a.length?a:n).reduce((p,u)=>u.width>p.width?u:p,n[0]),c=n.map(p=>`<option value="${p.width}"${p.width===l.width?" selected":""}>${ue(p.label)}</option>`).join(`
829
- `),d=o?`<a class="figma-link" href="${ue(o)}" target="_blank" rel="noopener">
864
+ </html>`}function Ys(e){let{blockName:t,breakpoints:n,figmaUrl:o,frameRoute:i,placeholder:r}=e,s=n.filter(p=>p.figma),l=(s.length?s:n).reduce((p,u)=>u.width>p.width?u:p,n[0]),c=n.map(p=>`<option value="${p.width}"${p.width===l.width?" selected":""}>${ge(p.label)}</option>`).join(`
865
+ `),d=o?`<a class="figma-link" href="${ge(o)}" target="_blank" rel="noopener">
830
866
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 3h6v6"/><path d="M10 14 21 3"/><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/></svg>
831
867
  Open in Figma
832
- </a>`:"",m=s?`<span class="hint">placeholder content \u2014 add <code>blocks/${t}/_${t}.preview.html</code></span>`:"";return`<!DOCTYPE html>
868
+ </a>`:"",m=r?`<span class="hint">placeholder content \u2014 add <code>blocks/${t}/_${t}.preview.html</code></span>`:"";return`<!DOCTYPE html>
833
869
  <html lang="en">
834
870
  <head>
835
871
  <meta charset="utf-8" />
836
872
  <meta name="viewport" content="width=device-width, initial-scale=1" />
837
- <title>eds preview \u2014 ${ue(t)}</title>
873
+ <title>eds preview \u2014 ${ge(t)}</title>
838
874
  <style>
839
875
  *{box-sizing:border-box}
840
876
  html,body{margin:0;padding:0;background:#1f1f1f;color:#eaeaea;font-family:ui-sans-serif,-apple-system,"Segoe UI",sans-serif}
@@ -856,7 +892,7 @@ ${n}
856
892
  </head>
857
893
  <body>
858
894
  <div class="bar">
859
- <span class="label">Block</span><span class="block">${ue(t)}</span>
895
+ <span class="label">Block</span><span class="block">${ge(t)}</span>
860
896
  <label class="label" for="bp" style="margin-left:8px">Breakpoint</label>
861
897
  <select id="bp">
862
898
  ${c}
@@ -867,7 +903,7 @@ ${n}
867
903
  </div>
868
904
  <div class="stage">
869
905
  <div class="device" id="device" data-w="${l.width}" style="width:${l.width}px">
870
- <iframe id="frame" src="${i}" title="${ue(t)} preview"></iframe>
906
+ <iframe id="frame" src="${i}" title="${ge(t)} preview"></iframe>
871
907
  </div>
872
908
  </div>
873
909
  <script>
@@ -881,24 +917,24 @@ ${n}
881
917
  setWidth(Number(bp.value));
882
918
  </script>
883
919
  </body>
884
- </html>`}var ua=k(()=>{"use strict";f()});import{createReadStream as Dm,existsSync as Lm,statSync as Nm}from"fs";import Om from"http";import qo from"path";function $n(e,t,n,o="127.0.0.1",i){let s=qo.resolve(e),a=new Set,l=Om.createServer(async(c,d)=>{let m=decodeURIComponent((c.url??"/").split("?")[0]);if(m===Im){d.writeHead(200,{"content-type":"application/json"}),d.end(JSON.stringify({eds:!0}));return}if(m===_m){d.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"}),d.write(`: connected
920
+ </html>`}var Qs=v(()=>{"use strict";f()});import{createReadStream as Tp,existsSync as Ap,statSync as Rp}from"fs";import Fp from"http";import mi from"path";function Dn(e,t,n,o="127.0.0.1",i){let r=mi.resolve(e),s=new Set,l=Fp.createServer(async(c,d)=>{let m=decodeURIComponent((c.url??"/").split("?")[0]);if(m===Dp){d.writeHead(200,{"content-type":"application/json"}),d.end(JSON.stringify({eds:!0}));return}if(m===Op){d.writeHead(200,{"content-type":"text/event-stream","cache-control":"no-cache",connection:"keep-alive"}),d.write(`: connected
885
921
 
886
- `),a.add(d),c.on("close",()=>a.delete(d));return}let p=t[m];if(p){d.writeHead(200,{"content-type":p.type}),d.end(p.body);return}if(i)try{let g=await i(m);if(g){d.writeHead(200,{"content-type":g.type}),d.end(g.body);return}}catch(g){d.writeHead(500,{"content-type":"text/plain"}),d.end(`Preview error: ${g instanceof Error?g.message:String(g)}`);return}let u=qo.join(s,m);if(!u.startsWith(s)){d.writeHead(403),d.end("Forbidden");return}if(!Lm(u)||!Nm(u).isFile()){d.writeHead(404,{"content-type":"text/plain"}),d.end(`Not found: ${m}`);return}d.writeHead(200,{"content-type":Mm[qo.extname(u).toLowerCase()]??"application/octet-stream"}),Dm(u).pipe(d)});return new Promise((c,d)=>{let m=0,p=u=>{l.once("error",g=>{g.code==="EADDRINUSE"&&m<10?(m++,p(u+1)):d(g)}),l.listen(u,o,()=>{c({url:`http://${o}:${u}/`,port:u,reload:()=>{for(let g of a)g.write(`data: reload
922
+ `),s.add(d),c.on("close",()=>s.delete(d));return}let p=t[m];if(p){d.writeHead(200,{"content-type":p.type}),d.end(p.body);return}if(i)try{let g=await i(m);if(g){d.writeHead(200,{"content-type":g.type}),d.end(g.body);return}}catch(g){d.writeHead(500,{"content-type":"text/plain"}),d.end(`Preview error: ${g instanceof Error?g.message:String(g)}`);return}let u=mi.join(r,m);if(!u.startsWith(r)){d.writeHead(403),d.end("Forbidden");return}if(!Ap(u)||!Rp(u).isFile()){d.writeHead(404,{"content-type":"text/plain"}),d.end(`Not found: ${m}`);return}d.writeHead(200,{"content-type":Lp[mi.extname(u).toLowerCase()]??"application/octet-stream"}),Tp(u).pipe(d)});return new Promise((c,d)=>{let m=0,p=u=>{l.once("error",g=>{g.code==="EADDRINUSE"&&m<10?(m++,p(u+1)):d(g)}),l.listen(u,o,()=>{c({url:`http://${o}:${u}/`,port:u,reload:()=>{for(let g of s)g.write(`data: reload
887
923
 
888
- `)},close:()=>new Promise(g=>{for(let h of a)h.end();l.close(()=>g())})})})};p(n)})}var Mm,Im,_m,fa=k(()=>{"use strict";f();Mm={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".mjs":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".avif":"image/avif",".woff":"font/woff",".woff2":"font/woff2",".ico":"image/x-icon"},Im="/__eds_ping",_m="/__eds_events"});var Lt={};O(Lt,{FRAME_PREFIX:()=>Se,galleryPreview:()=>Wm,listPreviewableBlocks:()=>_e,loadBlockForPreview:()=>he,previewBlock:()=>Gm,startFrameServer:()=>tt,startPreview:()=>va});import{existsSync as ae,watch as ga}from"fs";import{readFile as Sn,readdir as Um}from"fs/promises";import ne from"path";import $e from"chalk";function Ko(e){return e<=480?`${e} mobile`:e<=1024?`${e} tablet`:`${e} desktop`}function ha(e,t){if(e){let o=e.split(",").map(i=>Number.parseInt(i.trim(),10)).filter(i=>Number.isFinite(i)&&i>0);if(o.length)return o.map(i=>({width:i,label:Ko(i),figma:!1}))}let n=t?.breakpoints;return Array.isArray(n)&&n.length?n.map(o=>({width:Number(o.width),label:typeof o.label=="string"?o.label:Ko(Number(o.width)),figma:o.source==="figma"||o.source==="scrape"})).filter(o=>Number.isFinite(o.width)&&o.width>0):Hm.map(o=>({width:o,label:Ko(o),figma:!1}))}function wa(e){if(!e?.figmaFileKey||typeof e.figmaFileKey!="string")return;let t=typeof e.figmaNodeId=="string"?e.figmaNodeId.replace(":","-"):void 0,n=`https://www.figma.com/design/${e.figmaFileKey}/preview`;return t?`${n}?node-id=${t}`:n}function ba(e){return`<div class="${e} block">
924
+ `)},close:()=>new Promise(g=>{for(let h of s)h.end();l.close(()=>g())})})})};p(n)})}var Lp,Dp,Op,Zs=v(()=>{"use strict";f();Lp={".html":"text/html; charset=utf-8",".js":"text/javascript; charset=utf-8",".mjs":"text/javascript; charset=utf-8",".css":"text/css; charset=utf-8",".json":"application/json; charset=utf-8",".svg":"image/svg+xml",".png":"image/png",".jpg":"image/jpeg",".jpeg":"image/jpeg",".webp":"image/webp",".gif":"image/gif",".avif":"image/avif",".woff":"font/woff",".woff2":"font/woff2",".ico":"image/x-icon"},Dp="/__eds_ping",Op="/__eds_events"});var Ht={};M(Ht,{FRAME_PREFIX:()=>Ae,galleryPreview:()=>Up,listPreviewableBlocks:()=>Je,loadBlockForPreview:()=>ve,previewBlock:()=>Ip,startFrameServer:()=>lt,startPreview:()=>rc});import{existsSync as le,watch as ec}from"fs";import{readFile as On,readdir as Np}from"fs/promises";import ie from"path";import Te from"chalk";function pi(e){return e<=480?`${e} mobile`:e<=1024?`${e} tablet`:`${e} desktop`}function tc(e,t){if(e){let o=e.split(",").map(i=>Number.parseInt(i.trim(),10)).filter(i=>Number.isFinite(i)&&i>0);if(o.length)return o.map(i=>({width:i,label:pi(i),figma:!1}))}let n=t?.breakpoints;return Array.isArray(n)&&n.length?n.map(o=>({width:Number(o.width),label:typeof o.label=="string"?o.label:pi(Number(o.width)),figma:o.source==="figma"||o.source==="scrape"})).filter(o=>Number.isFinite(o.width)&&o.width>0):_p.map(o=>({width:o,label:pi(o),figma:!1}))}function nc(e){if(!e?.figmaFileKey||typeof e.figmaFileKey!="string")return;let t=typeof e.figmaNodeId=="string"?e.figmaNodeId.replace(":","-"):void 0,n=`https://www.figma.com/design/${e.figmaFileKey}/preview`;return t?`${n}?node-id=${t}`:n}function oc(e){return`<div class="${e} block">
889
925
  <div><div>
890
926
  <h2>${e} heading</h2>
891
927
  <p>Sample body copy for the preview. Replace with real authored content.</p>
892
928
  <p><a href="#">Primary action</a></p>
893
929
  <p><a href="#">Secondary action</a></p>
894
930
  </div></div>
895
- </div>`}async function he(e,t,n){let o=ne.join(e,"blocks",t);if(!ae(ne.join(o,`${t}.css`))&&!ae(ne.join(o,`${t}.js`)))return null;let i=null,s=ne.join(o,".eds-meta.json");if(ae(s))try{i=JSON.parse(await Sn(s,"utf-8"))}catch{}let a=ne.join(o,`_${t}.preview.html`),l,c=!1;return ae(a)?l=await Sn(a,"utf-8"):(l=ba(t),c=!0),{name:t,sampleContent:l,breakpoints:ha(n,i),figmaUrl:wa(i),placeholder:c}}async function tt(e,t,n){return $n(e,{},n,"127.0.0.1",async i=>{if(!i.startsWith(Se))return;let s=i.slice(Se.length);if(!/^[a-z0-9-]+$/i.test(s))return;let a=await he(e,s,t);if(a)return{body:xn({blockName:s,breakpoints:a.breakpoints,sampleContent:a.sampleContent,frameRoute:Se+s}),type:"text/html; charset=utf-8"}})}async function _e(e){let t=ne.join(e,"blocks");if(!ae(t))return[];let n=await Um(t,{withFileTypes:!0}),o=[];for(let i of n){if(!i.isDirectory()||Bm.has(i.name))continue;let s=ne.join(t,i.name);(ae(ne.join(s,`${i.name}.css`))||ae(ne.join(s,`${i.name}.js`)))&&o.push(i.name)}return o.sort()}async function ya(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{let{execa:n}=await import("execa");await n(t,[e],{stdio:"ignore",shell:process.platform==="win32"})}catch{}}async function va(e,t={}){let n=E();if(!n)return r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1,null;let o=ne.join(n,"blocks",e);if(!ae(o))return r.error(`Block "${e}" not found at blocks/${e}/.`),process.exitCode=1,null;if(!ae(ne.join(o,`${e}.css`))&&!ae(ne.join(o,`${e}.js`)))return r.error(`Block "${e}" has no ${e}.css / ${e}.js to preview.`),process.exitCode=1,null;(e==="header"||e==="footer")&&(r.warn(`"${e}" is page chrome, not a content block \u2014 it won't render standalone here.`),r.info($e.dim(` It fetches the ${e==="header"?"nav":"footer"} fragment and needs the full page runtime.`)),r.info($e.dim(" Preview a content block instead (e.g. a block generated from a design).")));let i=null,s=ne.join(o,".eds-meta.json");if(ae(s))try{i=JSON.parse(await Sn(s,"utf-8"))}catch{}let a=ne.join(o,`_${e}.preview.html`),l,c=!1;ae(a)?l=await Sn(a,"utf-8"):(l=ba(e),c=!0);let d=ha(t.widths,i),m=wa(i),p="/__eds_preview_frame",u=xn({blockName:e,breakpoints:d,sampleContent:l,frameRoute:p}),g=pa({blockName:e,breakpoints:d,sampleContent:l,figmaUrl:m,frameRoute:p,placeholder:c}),h=Number.parseInt(t.port??"8777",10),b=await $n(n,{"/":{body:g,type:"text/html; charset=utf-8"},[p]:{body:u,type:"text/html; charset=utf-8"}},Number.isFinite(h)?h:8777);r.logoOnce(T(`Preview \u2014 ${e}`)),r.info(S("Live preview",b.url)),r.info(R("pass","breakpoints",`${d.map(w=>`${w.width}${w.figma?"\u2713":""}`).join(", ")}, Full`)),c&&r.info(R("warn","content",`placeholder \u2014 add blocks/${e}/_${e}.preview.html for real content`));let y,v=ga(o,{recursive:!0},()=>{clearTimeout(y),y=setTimeout(()=>b.reload(),150)});return r.info(""),r.info(` ${$e.bold("\u279C")} ${$e.cyan(b.url)}`),r.info(R("pass","live reload","edits to the block refresh the browser")),t.open!==!1&&await ya(b.url),{url:b.url,close:async()=>{v.close(),await b.close()}}}async function Gm(e,t={}){let n=await va(e,t);n&&(r.info($e.dim(` ${Dt()}
896
- `)),await Ft(n.close))}async function Wm(e={}){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n="/__eds_frame/",o=async d=>{if(d==="/"){let m=await _e(t),p=[];for(let u of m){let g=await he(t,u,e.widths);g&&p.push({blockName:u,breakpoints:g.breakpoints,frameRoute:n+u,figmaUrl:g.figmaUrl,placeholder:g.placeholder})}return{body:ma(p),type:"text/html; charset=utf-8"}}if(d.startsWith(n)){let m=d.slice(n.length);if(!/^[a-z0-9-]+$/i.test(m))return;let p=await he(t,m,e.widths);return p?{body:xn({blockName:m,breakpoints:p.breakpoints,sampleContent:p.sampleContent,frameRoute:n+m}),type:"text/html; charset=utf-8"}:void 0}},i=Number.parseInt(e.port??"8777",10),s=await $n(t,{},Number.isFinite(i)?i:8777,"127.0.0.1",o),a=await _e(t);r.logoOnce(T("Preview \u2014 gallery")),r.info(S("Live gallery",s.url)),r.info(R(a.length?"pass":"warn","blocks",a.length?a.join(", "):"none yet \u2014 generate one with eds block from-design"));let l,c=ga(ne.join(t,"blocks"),{recursive:!0},()=>{clearTimeout(l),l=setTimeout(()=>s.reload(),150)});r.info(""),r.info(` ${$e.bold("\u279C")} ${$e.cyan(s.url)}`),r.info(R("pass","live reload","new & edited blocks refresh the browser")),r.info($e.dim(` ${Dt()}
897
- `)),e.open!==!1&&await ya(s.url),await Ft(async()=>{c.close(),await s.close()})}var Bm,Hm,Se,Ue=k(()=>{"use strict";f();D();ua();fa();z();kn();_();Bm=new Set(["header","footer"]),Hm=[375,768,1280];Se="/__eds_frame/"});var Xo={};O(Xo,{blockFromDesign:()=>ep});import{existsSync as ce}from"fs";import{readFile as je,writeFile as zm}from"fs/promises";import q from"path";import{fileURLToPath as Jm}from"url";import P from"chalk";import jn from"ora";function qm(){let e=q.dirname(Jm(import.meta.url));return[q.resolve(e,"../../samples/hero.svg"),q.resolve(e,"../../../samples/hero.svg")].find(n=>ce(n))??null}async function Km(e=8777){try{let t=new AbortController,n=setTimeout(()=>t.abort(),400),o=await fetch(`http://127.0.0.1:${e}/__eds_ping`,{signal:t.signal});return clearTimeout(n),o.ok?(await o.json())?.eds===!0:!1}catch{return!1}}async function Vm(e){let{input:t,select:n,confirm:o}=await Promise.resolve().then(()=>(H(),B)),i=await n({message:"1/7 Design source",choices:[{name:"Figma (REST / MCP / local)",value:"figma"},{name:"Framer (scraped, headless Chromium)",value:"framer"},{name:"Google Stitch (scraped, headless Chromium)",value:"stitch"}],default:"figma"}),s=await t({message:"2/7 Component name",validate:w=>Re.test(w.trim())||"Use kebab-case, e.g. hero-banner"}),a=e??await t({message:`3/7 ${et[i]} link`,validate:w=>{if(!w.trim())return"Paste the design link";if(i!=="figma")return/^https?:\/\//i.test(w.trim())||"Paste a public http(s) URL to the page";try{return yn(w.trim()),!0}catch(A){return A.message}}}),l=await n({message:"4/7 Where does the content come from?",choices:[{name:"Document authoring (default EDS)",value:"document"},{name:"Universal Editor",value:"ue"},{name:"Content Fragment",value:"cf"},{name:"Mixed - Universal Editor + Content Fragment",value:"mixed"}],default:"document"}),c;(l==="cf"||l==="mixed")&&(c=(await t({message:" CF model / GraphQL persisted-query name (optional)"})).trim()||void 0);let d=await o({message:"5/7 Generate the Universal Editor model?",default:!0}),m=await o({message:"6/7 Add a screenshot MCP call for a pixel check? (off = one fewer MCP call)",default:!1}),p=await gn(),u=await n({message:"7/7 Run with",choices:[...p.map(w=>({name:`${w.type}${i==="figma"&&!w.hasFigmaMcp?" (Figma MCP not detected)":""}`,value:`agent:${w.type}`})),{name:"Preview the prompt only (--dry-run)",value:"dry-run"},{name:"Save the prompt, run it later (--agent none)",value:"none"}],default:p[0]?`agent:${p[0].type}`:"dry-run"}),g=et[i].toLowerCase();r.info(S("Summary"));let h=U(["component",g,"content","ue model","screenshot","run"]);r.info(j("component",s,h));let b=i==="figma"?(()=>{let w=yn(a.trim());return w.nodeId?`node ${w.nodeId}`:w.fileKey})():a.trim();if(r.info(j(g,b,h)),r.info(j("content",l+(c?` (${c})`:""),h)),r.info(j("ue model",d?"yes":"no",h)),r.info(j("screenshot",m?"yes":"no (token-lean)",h)),r.info(j("run",u.replace("agent:",""),h)),r.info(""),!await o({message:"Generate this block?",default:!0}))return null;let v={figmaUrl:a.trim(),name:s,provider:i,source:l,cfHint:c,ueModel:d,screenshot:m};return u==="dry-run"?v.dryRun=!0:u==="none"?v.agent="none":(v.agent=u.replace("agent:",""),v.yes=!0),v}function Vo(e){return e&&e.replace(/[-_\s]+/g,"-").replace(/[^a-z0-9-]/gi,"").toLowerCase().replace(/^-+|-+$/g,"")||"design-block"}function Xm(e){try{let t=new URL(e);return t.pathname.split("/").filter(Boolean).pop()||t.hostname.split(".")[0]}catch{return""}}function Ym(e){if(e)try{let t=new URL(e).hostname.toLowerCase();if(t.includes("figma.com"))return"figma";if(t.includes("framer"))return"framer";if(t.includes("stitch"))return"stitch"}catch{}}function Zm(e){if(/^[a-z][a-z0-9+.-]*:\/\//i.test(e))return null;let t=q.isAbsolute(e)?e:q.resolve(process.cwd(),e);return!ce(t)||!Qm.has(q.extname(t).toLowerCase())?null:t}async function ep(e,t){let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found). Run this from your project root."),process.exitCode=1;return}await r.logoOnceAnimated("Design \u2192 EDS block");let o=e,i=t;if(!o&&i.sample){let L=qm();if(!L){r.error("Bundled sample design not found (samples/hero.svg)."),process.exitCode=1;return}o=L,i={name:"hero",provider:"figma",...i},r.info(` ${J.pass} Sample design ${P.dim("Kiri Bloom hero")} ${P.dim("(bundled \xB7 no token \xB7 no MCP)")}`)}if(!o){let L=await Vm(o);if(!L){r.info("Cancelled.");return}o=L.figmaUrl,i={...i,...L}}let s=i.provider;if(s&&!(s in et)){r.error(`Unknown --provider "${s}". Use: figma, framer or stitch.`),process.exitCode=1;return}if(i.source&&!ka.includes(i.source)){r.error(`Unknown --source "${i.source}". Use: ${ka.join(", ")}.`),process.exitCode=1;return}let a=s??Ym(o)??"figma",l=et[a],c=Zm(o),d=c?c.startsWith(n+q.sep)?q.relative(n,c):c:void 0,m=null,p=d??o;if(c)r.info(` ${J.pass} Local design file ${P.dim(d)} ${P.dim("(no Figma MCP)")}`);else if(a==="figma"){let L=jn("Parsing Figma URL...").start();try{m=yn(o),L.succeed(`Parsed Figma URL ${P.dim(m.nodeId?`node ${m.nodeId}`:`file ${m.fileKey}`)}`)}catch(le){L.fail(le.message),process.exitCode=1;return}}else r.info(` ${J.pass} ${l} design ${P.dim(p)}`);let u=i.name||(c?Vo(q.basename(c,q.extname(c))):m?Vo(m.fileName):o?Vo(Xm(o)):"");if(!Re.test(u)){r.error(`Invalid block name "${u}". Use --name with a kebab-case name (e.g., --name hero-banner).`),process.exitCode=1;return}!i.name&&m?.nodeId&&(r.warn(`Block name "${u}" came from the Figma file name, not the selected frame.`),r.info(P.dim(` Pass ${P.cyan("--name <kebab-case>")} for a cleaner block name.`)));let g=await pe(n),h=g.figma?.token??process.env.FIGMA_TOKEN??process.env.FIGMA_PAT,b;if(zo(a)&&!c&&!i.dryRun&&(i.auth||i.authRefresh))if(b=Jo(a),i.authRefresh||!aa(a)){let L=(()=>{try{return new URL(o).origin}catch{return o}})();r.info(` ${P.dim("\u2192")} Opening ${P.cyan(l)} \u2014 click ${P.cyan("Sign In")} and log in, then come back here.`);let{input:le}=await Promise.resolve().then(()=>(H(),B));try{await ca(b),await Us({loginUrl:L,statePath:b,projectRoot:n,waitForUser:async()=>{await le({message:"Press Enter once you're signed in (you don't need to open the design)"})}}),await la(b),r.info(` ${J.pass} Session saved ${P.dim(b)}`)}catch(re){r.error(`Could not capture the ${l} session: ${re instanceof Error?re.message:String(re)}`),process.exitCode=1;return}}else r.info(` ${J.pass} Using saved ${l} session ${P.dim(b)} ${P.dim("(--auth-refresh to re-login)")}`);let y=jn("Resolving design source...").start(),v=await Zs({figma:m,localFile:d,token:h,projectRoot:n,preferMcp:i.mcp,refresh:i.refresh,provider:a,designUrl:c?void 0:o,storageStatePath:b,dryRun:i.dryRun,restPerMinute:g.figma?.restPerMinute,onRestWait:L=>{y.text=`Resolving design source... waiting ${Math.ceil(L/1e3)} s for a Figma REST slot (${g.figma?.restPerMinute??Uo}/min)`}});if(v.scrapeError){y.fail(`Scrape failed: ${v.scrapeError}`),r.info(P.dim(` Check the URL is a public ${l} page, and that Chromium is installed (${P.cyan("npx playwright install chromium")}).`)),process.exitCode=1;return}if(v.rateLimit){y.fail(v.rateLimit.message),r.info(P.dim(" The limit follows the plan that owns the file: 20 calls/month on Starter or with a View/Collab seat, 10-20/min with a Dev/Full seat on a paid plan.")),r.info(P.dim(` Not falling back to Figma MCP (its budget is the same or smaller). Re-run after the reset, pass ${P.cyan("--mcp")} to spend an MCP call instead, or export the frame as PNG/SVG (no quota).`)),v.rateLimit.upgradeLink&&r.info(P.dim(` Plan details: ${v.rateLimit.upgradeLink}`)),process.exitCode=1;return}if(y.succeed(`Design source ${P.dim(v.summary)}`),v.restError&&r.warn(`Figma REST fetch failed, using MCP fallback: ${v.restError}`),v.design?.mode==="scrape"&&!i.dryRun)try{let L=JSON.parse(v.design.spec),le=(L.title??"").toLowerCase(),re=v.design.spec.toLowerCase(),Ht=/isn'?t shared|doesn'?t exist|page not found|\b404\b/;(Ht.test(le)||Ht.test(re)||/\bsign[ -]?in\b|\blog[ -]?in\b/.test(le)||(L.nodeCount??0)<8)&&(r.warn(`The scraped page looks like a login / error shell${L.title?` ("${L.title}")`:""} \u2014 the design may be gated or the URL wrong.`),r.info(P.dim(` Use ${P.cyan("--auth")} to log in once (or ${P.cyan("--auth-refresh")} to re-login), and confirm the URL opens the design when you're signed in.`)))}catch{}let w=jn("Reading design tokens & building prompt...").start(),A=await oa({provider:a,figma:m,designRef:p,blockName:u,projectRoot:n,withUeModel:i.ueModel!==!1,contentSource:i.source??"document",cfHint:i.cfHint,screenshot:i.screenshot===!0,design:v.design}),X=await Do(A,n),K=ce(q.join(n,"styles","styles.css"));if(w.succeed(K?`Loaded design tokens ${P.dim("styles/styles.css")}`:`Built prompt ${P.dim("no project tokens found")}`),r.info(P.dim(` prompt \u2192 ${X}`)),i.dryRun){r.info(""),r.info(P.yellow("Dry run mode \u2014 prompt generated but agent not invoked.")),r.info(`Prompt file: ${P.cyan(X)}`),r.info(`Block name: ${P.cyan(u)}`),r.info(`Prompt version: ${At}`),r.info(""),r.info("Preview:"),r.info(P.dim("\u2500".repeat(60))),console.log(A);return}let Ce=i.agent||g.agent;if(i.agent==="none"){r.info("Agent skipped (--agent none). Use the prompt file manually:"),r.info(` ${P.cyan(X)}`);return}let Bt=jn("Detecting AI agent...").start(),Y=await Cs(Ce);if(!Y){Bt.fail("No AI agent found (claude, cursor, or codex)."),r.info(`Install Claude Code: ${P.cyan("npm install -g @anthropic-ai/claude-code")}`),r.info(`Or use the prompt file manually: ${P.cyan(X)}`),process.exitCode=1;return}if(Bt.succeed(`Agent ready ${P.cyan(Y.type)} ${P.dim(Y.path)}`),(v.design?.mode==="mcp"||!v.design&&a==="figma")&&a==="figma"&&!Y.hasFigmaMcp&&(r.warn(`Figma MCP may not be configured for ${Y.type}.`),r.info(`Run ${P.cyan("eds figma setup")} to configure it, or set a Figma token for REST.`)),!i.yes){let{confirm:L}=await Promise.resolve().then(()=>(H(),B));if(!await L({message:`Run ${Y.type} with the generated prompt?`,default:!0})){r.info(`Prompt saved to: ${P.cyan(X)}`);return}}let ic=v.design?.mode==="spec"?"embedded design (no MCP)":v.design?.mode==="scrape"?`scraped ${l} page (no MCP)`:v.design?.mode==="file"?`reading ${d}`:v.design?.mode==="mcp"?`via ${l} MCP (1 call, cached)`:`via ${l} MCP`;r.info(` ${P.dim("\u2192")} Handing off to ${P.cyan(Y.type)} ${P.dim(ic)}`),v.design?.mode==="mcp"&&r.info(P.dim(" get_design_context \xD71 \u2192 cache"));let rc=i.source==="cf"||i.source==="mixed",Dn=g.model??(rc&&Y.type==="claude"?"sonnet":void 0);if(Dn&&!g.model&&r.info(P.dim(` Model: ${Dn} (Content Fragment source)`)),!await Lo(Y,X,n,Dn)){process.exitCode=1;return}let at=q.join(n,"blocks",u);if(!(ce(q.join(at,`${u}.js`))||ce(q.join(at,`${u}.css`)))){r.warn(`No block files were written to blocks/${u}/ \u2014 nothing to preview.`),v.design?.mode==="mcp"&&!Y.hasFigmaMcp?(r.info(P.dim(` The agent couldn't read the design: no ${l} MCP is configured for ${Y.type}.`)),r.info(P.dim(` Run ${P.cyan("eds figma setup")}, or set a Figma token (FIGMA_TOKEN) to use REST, then re-run.`))):v.design?.mode==="mcp"?(r.info(P.dim(" The agent couldn't read the design, so it generated nothing. Common cause: the")),r.info(P.dim(` ${l} MCP tool-call limit (e.g. Figma Starter plan). See the log above.`)),r.info(P.dim(" Wait for the limit to reset or upgrade the plan, then re-run the same command."))):r.info(P.dim(" The agent generated nothing \u2014 see the log above for why.")),process.exitCode=1;return}let sc=await np(at,u,i.ueModel!==!1,i.source??"document");if(ce(at)){let L=q.join(at,".eds-meta.json"),le;if(ce(L))try{le=JSON.parse(await je(L,"utf-8")).breakpoints}catch{}let re=Ns(i.widths,le),Ht={provider:a,designRef:p,figmaFileKey:m?.fileKey??null,figmaNodeId:m?.nodeId??null,lastSyncedAt:new Date().toISOString(),promptVersion:At,agentUsed:Y.type,...re.length?{breakpoints:re}:{}};await zm(L,`${JSON.stringify(Ht,null,2)}
898
- `),re.length&&r.info(P.dim(` Preview breakpoints: ${re.map($i=>$i.width).join(" \xB7 ")}`))}if(!sc){r.warn(`Block "${u}" generated with issues \u2014 review the output above before publishing.`),process.exitCode=1;return}if(r.success(`Block "${u}" generation complete.`),!i.yes){let{confirm:L}=await Promise.resolve().then(()=>(H(),B));if(await L({message:"Instrument this block for analytics (dataLayer)?",default:!1})){let{trackBlock:re}=await Promise.resolve().then(()=>(xt(),kt));await re(u,{})}}if(!i.yes)await tp({blockName:u,projectRoot:n,agent:Y,model:g.model,provider:a,figma:m,designRef:p});else if(i.serve){let{previewBlock:L}=await Promise.resolve().then(()=>(Ue(),Lt));await L(u,{})}else r.info(` ${P.dim("\u2192")} Next: ${P.cyan(`eds block preview ${u}`)}`)}async function tp(e){let{select:t,input:n}=await Promise.resolve().then(()=>(H(),B)),{startPreview:o}=await Promise.resolve().then(()=>(Ue(),Lt)),i=null;for(r.info("");;){let s=await t({message:"Block ready \u2014 what next?",choices:[{name:"Refine \u2014 describe a change",value:"refine"},{name:i?`Preview open at ${i.url} (reloads on change)`:"Open live preview",value:"preview",disabled:i?"running":!1},{name:"Finish",value:"done"}],default:"refine"});if(s==="done")break;if(s==="preview"){await Km()?r.info(P.dim(" A preview server is already running at http://127.0.0.1:8777.")):i=await o(e.blockName,{});continue}let a=(await n({message:"Describe the change:"})).trim();if(!a)continue;let l=ia({blockName:e.blockName,feedback:a,provider:e.provider,figma:e.figma,designRef:e.designRef}),c=await Do(l,e.projectRoot);r.info(` ${P.dim("\u2192")} Applying your change with ${P.cyan(e.agent.type)}\u2026`),await Lo(e.agent,c,e.projectRoot,e.model)}if(i){let s=i;r.info(P.dim(` Preview still live at ${s.url}. ${Dt()}
899
- `)),await Ft(s.close)}}async function np(e,t,n,o="document"){let i=[],s=q.join(e,`${t}.js`),a=q.join(e,`${t}.css`),l=ce(s),c=ce(a);if(i.push({status:l?"pass":"fail",name:`${t}.js`,message:l?"created":"missing \u2014 agent did not write the JS file"}),i.push({status:c?"pass":"fail",name:`${t}.css`,message:c?"created":"missing \u2014 agent did not write the CSS file"}),l){let m=await je(s,"utf-8");i.push({status:/export\s+default/.test(m)?"pass":"fail",name:"decorate export",message:/export\s+default/.test(m)?"found":"no default export \u2014 block won't load"}),m.includes("console.log")&&i.push({status:"warn",name:"no console.log",message:"found console.log \u2014 remove before production"})}if(c){let m=await je(a,"utf-8");i.push({status:m.includes(`.${t}`)?"pass":"warn",name:"scoped CSS",message:m.includes(`.${t}`)?`scoped to .${t}`:`no .${t} selector \u2014 styles may leak`})}if(n){let m=ce(q.join(e,`_${t}.json`)),p=q.join(e,"..","..","component-models.json"),u=!1;if(!m&&ce(p))try{u=(await je(p,"utf-8")).includes(`"${t}"`)}catch{}let g=m||u;if(i.push({status:g?"pass":"warn",name:"Universal Editor model",message:g?m?`_${t}.json created`:"added to component-models.json":`missing \u2014 no _${t}.json (run with default UE generation, or --no-ue-model to skip)`}),m&&l)try{let h=await je(q.join(e,`_${t}.json`),"utf-8"),b=await je(s,"utf-8"),y=/"resourceType"\s*:\s*"[^"]*\/item"/.test(h)||/"filter"\s*:/.test(h)||/"multi"\s*:\s*true/.test(h),v=/\.children/.test(b)||/\bfor\s*\(/.test(b)||/\.forEach\s*\(/.test(b);y&&i.push({status:v?"pass":"warn",name:"multifield wired",message:v?"decorate() iterates items":"repeatable model but decorate() never iterates block.children \u2014 only one item will render"})}catch{}}if((o==="cf"||o==="mixed")&&l){let m=await je(s,"utf-8"),p=q.join(e,`_${t}.json`),g=(ce(p)?await je(p,"utf-8"):"").includes("aem-content-fragment"),h=/\bfetch\s*\(/.test(m);i.push({status:g&&h?"pass":"warn",name:"content fragment",message:g&&h?"CF field in the model, fetched in decorate()":[!g&&"no aem-content-fragment field in the model",!h&&"decorate() never fetches the fragment"].filter(Boolean).join("; ")})}r.info(S("Verification"));let d=U(i.map(m=>m.name));for(let m of i)r.info(R(m.status,m.name,m.message,d));return r.info(""),!i.some(m=>m.status==="fail")}var ka,Qm,Yo=k(()=>{"use strict";f();Fo();Rs();xe();Os();ea();ta();bn();ra();D();z();Je();da();_o();kn();_();ka=["document","ue","cf","mixed"],Qm=new Set([".svg",".png",".jpg",".jpeg",".webp"])});var xa={};O(xa,{listBlocks:()=>rp});import{existsSync as Nt}from"fs";import{readFile as op,readdir as ip}from"fs/promises";import nt from"path";import ot from"chalk";async function rp(e={}){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n=nt.join(t,"blocks");if(!Nt(n)){r.info("No blocks/ directory found.");return}let o=await ip(n,{withFileTypes:!0}),i=[];for(let a of o){if(!a.isDirectory())continue;let l=a.name,c=nt.join(n,l),d={name:l,hasJs:Nt(nt.join(c,`${l}.js`)),hasCss:Nt(nt.join(c,`${l}.css`)),hasUeModel:Nt(nt.join(c,`_${l}.json`))},m=nt.join(c,".eds-meta.json");if(Nt(m))try{let p=JSON.parse(await op(m,"utf-8"));d.figmaSource={fileKey:p.figmaFileKey,nodeId:p.figmaNodeId,lastSyncedAt:p.lastSyncedAt}}catch{}i.push(d)}if(e.json){console.log(JSON.stringify(i,null,2));return}if(i.length===0){r.info("No blocks found.");return}r.info(S("Blocks",`${i.length} in project`));let s=U(i.map(a=>a.name));for(let a of i){let l=[a.hasJs?M.ok("js"):ot.dim.strikethrough("js"),a.hasCss?M.ok("css"):ot.dim.strikethrough("css")];a.hasUeModel&&l.push(M.blue("ue-model")),a.figmaSource&&l.push(`${J.figma} ${M.dotPurple("figma")}`);let c=ct(ot.bold(a.name),s);if(r.info(` ${c} ${ot.dim("[")}${l.join(" ")}${ot.dim("]")}`),a.figmaSource){let d=new Date(a.figmaSource.lastSyncedAt).toLocaleDateString();r.info(` ${" ".repeat(s)} ${J.arrow} ${ot.dim(`figma:${a.figmaSource.fileKey} \xB7 synced ${d}`)}`)}}r.info("")}var $a=k(()=>{"use strict";f();D();z();_()});import Sa from"path";function Qo(e,t){return Sa.join(e,"blocks",t,"__snapshots__")}function Pa(e,t,n){return Sa.join(Qo(e,t),`${t}-${n}.png`)}function Ot(e){return`${(e*100).toFixed(2)}%`}async function Zo(e,t,n,o=900){let i;try{({chromium:i}=await import("playwright"))}catch{throw new Error(ja)}let s=await i.launch();try{let a=await s.newPage({viewport:{width:t,height:o}});await a.goto(e,{waitUntil:"networkidle"}),await a.waitForTimeout(300);let l=n?a.locator(n).first():null;return l&&await l.count()?await l.screenshot():await a.screenshot({fullPage:!0})}finally{await s.close()}}async function Ea(){try{let e="pngjs",t="pixelmatch",{PNG:n}=await import(e),o=(await import(t)).default;return{PNG:n,pixelmatch:o}}catch{throw new Error(ja)}}async function Ca(e,t){let{PNG:n,pixelmatch:o}=await Ea(),i=n.sync.read(e),s=n.sync.read(t);if(i.width!==s.width||i.height!==s.height)return{diffPixels:-1,totalPixels:0,ratio:1,sizeMismatch:!0,width:i.width,height:i.height,otherWidth:s.width,otherHeight:s.height};let{width:a,height:l}=i,c=new n({width:a,height:l}),d=o(i.data,s.data,c.data,a,l,{threshold:.1}),m=a*l;return{diffPixels:d,totalPixels:m,ratio:m?d/m:0,width:a,height:l,diffPng:n.sync.write(c)}}async function Ta(e,t){let{PNG:n,pixelmatch:o}=await Ea(),i=n.sync.read(e),s=n.sync.read(t),a=Math.min(i.width,s.width),l=Math.min(i.height,s.height),c=new n({width:a,height:l}),d=new n({width:a,height:l});n.bitblt(i,c,0,0,a,l,0,0),n.bitblt(s,d,0,0,a,l,0,0);let m=new n({width:a,height:l}),p=o(c.data,d.data,m.data,a,l,{threshold:.1}),u=a*l;return{diffPixels:p,totalPixels:u,ratio:u?p/u:0,width:a,height:l,diffPng:n.sync.write(m)}}var ja,Ra=k(()=>{"use strict";f();ja=`Visual testing needs extra tools. Install them with:
900
- npm i -D playwright pixelmatch pngjs && npx playwright install chromium`});var Na={};O(Na,{visualTest:()=>ap});import{existsSync as Aa}from"fs";import{mkdir as ei,readFile as Fa,writeFile as Mt}from"fs/promises";import we from"path";import ti from"chalk";async function ap(e,t={}){let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}if(t.design){await cp(n,e,t);return}let o=e?[e]:await _e(n);if(!o.length){r.warn("No previewable blocks to test.");return}let i=Number.parseInt(t.port??"8788",10),s=await tt(n,t.widths,Number.isFinite(i)?i:8788),a=Number.parseFloat(t.threshold??"0.01"),l=we.join(n,"tmp","eds-cli","visual-diff");r.logoOnce(T("Visual test"));let c=0,d=0,m=0,p=0;try{for(let u of o){let g=await he(n,u,t.widths);if(g){r.info(S(u));for(let h of g.breakpoints){let b=await Zo(Da(s.url,u),h.width,La(u)),y=Pa(n,u,h.width),v=Aa(y);if(t.update||!v){await ei(Qo(n,u),{recursive:!0}),await Mt(y,b),v?(p++,r.info(R("pass",`${h.width}px`,"baseline updated"))):(m++,r.info(R("pass",`${h.width}px`,"baseline created")));continue}let w=await Ca(await Fa(y),b);if(w.sizeMismatch){d++;let A=w.height===sp&&(w.otherHeight??0)<w.height;r.info(R("fail",`${h.width}px`,A?`baseline is an older full-page shot (${w.width}\xD7${w.height}) \u2014 re-run with --update`:`size changed ${w.width}\xD7${w.height} \u2192 ${w.otherWidth}\xD7${w.otherHeight}`));continue}if(w.ratio>a){d++,await ei(l,{recursive:!0});let A=we.join(l,`${u}-${h.width}.diff.png`);w.diffPng&&await Mt(A,w.diffPng),r.info(R("fail",`${h.width}px`,`${Ot(w.ratio)} changed \u2192 ${we.relative(n,A)}`))}else c++,r.info(R("pass",`${h.width}px`,w.ratio>0?`${Ot(w.ratio)} (within ${Ot(a)})`:"identical"))}}}}catch(u){r.error(u instanceof Error?u.message:String(u)),process.exitCode=1;return}finally{await s.close()}r.info(""),r.info(`${ti.green(`${c} passed`)} \xB7 ${ti.yellow(`${d} changed`)} \xB7 ${m} new \xB7 ${p} updated`),d>0&&(r.warn(`${d} visual change(s). Review the diff PNGs in tmp/eds-cli/visual-diff/, then re-run with --update to accept.`),process.exitCode=1)}async function cp(e,t,n){if(!t){r.error("Design diff needs a block name: eds block test <name> --design"),process.exitCode=1;return}let o=await he(e,t,n.widths);if(!o){r.error(`Block "${t}" has no css/js to render.`),process.exitCode=1;return}let i,s,a=we.join(e,"blocks",t,".eds-meta.json");if(Aa(a))try{let g=JSON.parse(await Fa(a,"utf-8"));i=g.figmaFileKey??void 0,s=g.figmaNodeId??void 0}catch{}if(!i||!s){r.error(`"${t}" has no Figma source in .eds-meta.json \u2014 can't fetch the design image.`),process.exitCode=1;return}let l=await pe(e),c=l.figma?.token??process.env.FIGMA_TOKEN??process.env.FIGMA_PAT;if(!c){r.error("Design diff needs a Figma token (FIGMA_TOKEN or figma.token) to render the node."),process.exitCode=1;return}let d=o.breakpoints.filter(g=>g.figma),m=(d.length?d:o.breakpoints).reduce((g,h)=>h.width>g.width?h:g,o.breakpoints[0]).width,p=Number.parseInt(n.port??"8788",10),u=await tt(e,n.widths,Number.isFinite(p)?p:8788);r.logoOnce(T("Design \u2194 render")),r.info(S(t,`${m}px`));try{let g=await Zo(Da(u.url,t),m,La(t));r.info(R("pass","render","block screenshot captured"));let h=await Ks({fileKey:i,nodeId:s,token:c,scale:1,pace:()=>wn({logPath:hn(e),perMinute:l.figma?.restPerMinute,onWait:v=>r.info(R("warn","design",`waiting ${Math.ceil(v/1e3)} s for a Figma REST slot`))})});r.info(R("pass","design","Figma image fetched (REST)"));let b=await Ta(h,g),y=we.join(e,"tmp","eds-cli","visual-diff");await ei(y,{recursive:!0}),await Mt(we.join(y,`${t}-design.png`),h),await Mt(we.join(y,`${t}-render.png`),g),b.diffPng&&await Mt(we.join(y,`${t}-design-diff.png`),b.diffPng),r.info(R("warn","diff",`~${Ot(b.ratio)} different over ${b.width}\xD7${b.height} (approximate)`)),r.info(""),r.info(ti.dim(` Saved design / render / diff to ${we.relative(e,y)}/${t}-*.png \u2014 compare side by side.`))}catch(g){r.error(g instanceof Error?g.message:String(g)),process.exitCode=1}finally{await u.close()}}var Da,La,sp,Oa=k(()=>{"use strict";f();xe();bn();Wo();D();Ra();z();_();Ue();Da=(e,t)=>`${e}${Se.slice(1)}${t}`,La=e=>`body > .${e}`,sp=900});async function Ma(e,t,n){let o;try{({chromium:o}=await import("playwright"))}catch{throw new Error(lp)}let i=await o.launch();try{let s=await i.newPage({viewport:{width:t,height:900}});await s.goto(e,{waitUntil:"networkidle"}),await s.waitForTimeout(200);let a=await s.evaluate(dp);return n&&a.push(...await s.evaluate(`(${mp})(${JSON.stringify(n)})`)),a}finally{await i.close()}}var lp,dp,mp,Ia=k(()=>{"use strict";f();lp=`Content checks need Playwright. Install it with:
901
- npm i -D playwright && npx playwright install chromium`,dp=`(() => {
931
+ </div>`}async function ve(e,t,n){let o=ie.join(e,"blocks",t);if(!le(ie.join(o,`${t}.css`))&&!le(ie.join(o,`${t}.js`)))return null;let i=null,r=ie.join(o,".eds-meta.json");if(le(r))try{i=JSON.parse(await On(r,"utf-8"))}catch{}let s=ie.join(o,`_${t}.preview.html`),l,c=!1;return le(s)?l=await On(s,"utf-8"):(l=oc(t),c=!0),{name:t,sampleContent:l,breakpoints:tc(n,i),figmaUrl:nc(i),placeholder:c}}async function lt(e,t,n){return Dn(e,{},n,"127.0.0.1",async i=>{if(!i.startsWith(Ae))return;let r=i.slice(Ae.length);if(!/^[a-z0-9-]+$/i.test(r))return;let s=await ve(e,r,t);if(s)return{body:Ln({blockName:r,breakpoints:s.breakpoints,sampleContent:s.sampleContent,frameRoute:Ae+r}),type:"text/html; charset=utf-8"}})}async function Je(e){let t=ie.join(e,"blocks");if(!le(t))return[];let n=await Np(t,{withFileTypes:!0}),o=[];for(let i of n){if(!i.isDirectory()||Mp.has(i.name))continue;let r=ie.join(t,i.name);(le(ie.join(r,`${i.name}.css`))||le(ie.join(r,`${i.name}.js`)))&&o.push(i.name)}return o.sort()}async function ic(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{let{execa:n}=await import("execa");await n(t,[e],{stdio:"ignore",shell:process.platform==="win32"})}catch{}}async function rc(e,t={}){let n=E();if(!n)return a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1,null;let o=ie.join(n,"blocks",e);if(!le(o))return a.error(`Block "${e}" not found at blocks/${e}/.`),process.exitCode=1,null;if(!le(ie.join(o,`${e}.css`))&&!le(ie.join(o,`${e}.js`)))return a.error(`Block "${e}" has no ${e}.css / ${e}.js to preview.`),process.exitCode=1,null;(e==="header"||e==="footer")&&(a.warn(`"${e}" is page chrome, not a content block \u2014 it won't render standalone here.`),a.info(Te.dim(` It fetches the ${e==="header"?"nav":"footer"} fragment and needs the full page runtime.`)),a.info(Te.dim(" Preview a content block instead (e.g. a block generated from a design).")));let i=null,r=ie.join(o,".eds-meta.json");if(le(r))try{i=JSON.parse(await On(r,"utf-8"))}catch{}let s=ie.join(o,`_${e}.preview.html`),l,c=!1;le(s)?l=await On(s,"utf-8"):(l=oc(e),c=!0);let d=tc(t.widths,i),m=nc(i),p="/__eds_preview_frame",u=Ln({blockName:e,breakpoints:d,sampleContent:l,frameRoute:p}),g=Ys({blockName:e,breakpoints:d,sampleContent:l,figmaUrl:m,frameRoute:p,placeholder:c}),h=Number.parseInt(t.port??"8777",10),$=await Dn(n,{"/":{body:g,type:"text/html; charset=utf-8"},[p]:{body:u,type:"text/html; charset=utf-8"}},Number.isFinite(h)?h:8777);a.logoOnce(A(`Preview \u2014 ${e}`)),a.info(j("Live preview",$.url)),a.info(R("pass","breakpoints",`${d.map(w=>`${w.width}${w.figma?"\u2713":""}`).join(", ")}, Full`)),c&&a.info(R("warn","content",`placeholder \u2014 add blocks/${e}/_${e}.preview.html for real content`));let b,y=ec(o,{recursive:!0},()=>{clearTimeout(b),b=setTimeout(()=>$.reload(),150)});return a.info(""),a.info(` ${Te.bold("\u279C")} ${Te.cyan($.url)}`),a.info(R("pass","live reload","edits to the block refresh the browser")),t.open!==!1&&await ic($.url),{url:$.url,close:async()=>{y.close(),await $.close()}}}async function Ip(e,t={}){let n=await rc(e,t);n&&(a.info(Te.dim(` ${Bt()}
932
+ `)),await Ut(n.close))}async function Up(e={}){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n="/__eds_frame/",o=async d=>{if(d==="/"){let m=await Je(t),p=[];for(let u of m){let g=await ve(t,u,e.widths);g&&p.push({blockName:u,breakpoints:g.breakpoints,frameRoute:n+u,figmaUrl:g.figmaUrl,placeholder:g.placeholder})}return{body:Vs(p),type:"text/html; charset=utf-8"}}if(d.startsWith(n)){let m=d.slice(n.length);if(!/^[a-z0-9-]+$/i.test(m))return;let p=await ve(t,m,e.widths);return p?{body:Ln({blockName:m,breakpoints:p.breakpoints,sampleContent:p.sampleContent,frameRoute:n+m}),type:"text/html; charset=utf-8"}:void 0}},i=Number.parseInt(e.port??"8777",10),r=await Dn(t,{},Number.isFinite(i)?i:8777,"127.0.0.1",o),s=await Je(t);a.logoOnce(A("Preview \u2014 gallery")),a.info(j("Live gallery",r.url)),a.info(R(s.length?"pass":"warn","blocks",s.length?s.join(", "):"none yet \u2014 generate one with eds block from-design"));let l,c=ec(ie.join(t,"blocks"),{recursive:!0},()=>{clearTimeout(l),l=setTimeout(()=>r.reload(),150)});a.info(""),a.info(` ${Te.bold("\u279C")} ${Te.cyan(r.url)}`),a.info(R("pass","live reload","new & edited blocks refresh the browser")),a.info(Te.dim(` ${Bt()}
933
+ `)),e.open!==!1&&await ic(r.url),await Ut(async()=>{c.close(),await r.close()})}var Mp,_p,Ae,qe=v(()=>{"use strict";f();D();Qs();Zs();J();Fn();U();Mp=new Set(["header","footer"]),_p=[375,768,1280];Ae="/__eds_frame/"});var fi={};M(fi,{blockFromDesign:()=>Vp});import{existsSync as de}from"fs";import{readFile as Re,writeFile as Bp}from"fs/promises";import V from"path";import{fileURLToPath as Hp}from"url";import S from"chalk";import Nn from"ora";function Gp(){let e=V.dirname(Hp(import.meta.url));return[V.resolve(e,"../../samples/hero.svg"),V.resolve(e,"../../../samples/hero.svg")].find(n=>de(n))??null}async function Wp(e=8777){try{let t=new AbortController,n=setTimeout(()=>t.abort(),400),o=await fetch(`http://127.0.0.1:${e}/__eds_ping`,{signal:t.signal});return clearTimeout(n),o.ok?(await o.json())?.eds===!0:!1}catch{return!1}}async function zp(e){let{input:t,select:n,confirm:o}=await Promise.resolve().then(()=>(G(),H)),i=await n({message:"1/7 Design source",choices:[{name:"Figma (REST / MCP / local)",value:"figma"},{name:"Framer (scraped, headless Chromium)",value:"framer"},{name:"Google Stitch (scraped, headless Chromium)",value:"stitch"}],default:"figma"}),r=await t({message:"2/7 Component name",validate:w=>Ne.test(w.trim())||"Use kebab-case, e.g. hero-banner"}),s=e??await t({message:`3/7 ${ct[i]} link`,validate:w=>{if(!w.trim())return"Paste the design link";if(i!=="figma")return/^https?:\/\//i.test(w.trim())||"Paste a public http(s) URL to the page";try{return An(w.trim()),!0}catch(T){return T.message}}}),l=await n({message:"4/7 Where does the content come from?",choices:[{name:"Document authoring (default EDS)",value:"document"},{name:"Universal Editor",value:"ue"},{name:"Content Fragment",value:"cf"},{name:"Mixed - Universal Editor + Content Fragment",value:"mixed"}],default:"document"}),c;(l==="cf"||l==="mixed")&&(c=(await t({message:" CF model / GraphQL persisted-query name (optional)"})).trim()||void 0);let d=await o({message:"5/7 Generate the Universal Editor model?",default:!0}),m=await o({message:"6/7 Add a screenshot MCP call for a pixel check? (off = one fewer MCP call)",default:!1}),p=await Pn(),u=await n({message:"7/7 Run with",choices:[...p.map(w=>({name:w.model?`${w.type} \xB7 ${w.model} (local)`:`${w.type}${i==="figma"&&!w.hasFigmaMcp?" (Figma MCP not detected)":""}`,value:`agent:${w.type}`})),{name:"Preview the prompt only (--dry-run)",value:"dry-run"},{name:"Save the prompt, run it later (--agent none)",value:"none"}],default:p[0]?`agent:${p[0].type}`:"dry-run"}),g=ct[i].toLowerCase();a.info(j("Summary"));let h=I(["component",g,"content","ue model","screenshot","run"]);a.info(P("component",r,h));let $=i==="figma"?(()=>{let w=An(s.trim());return w.nodeId?`node ${w.nodeId}`:w.fileKey})():s.trim();if(a.info(P(g,$,h)),a.info(P("content",l+(c?` (${c})`:""),h)),a.info(P("ue model",d?"yes":"no",h)),a.info(P("screenshot",m?"yes":"no (token-lean)",h)),a.info(P("run",u.replace("agent:",""),h)),a.info(""),!await o({message:"Generate this block?",default:!0}))return null;let y={figmaUrl:s.trim(),name:r,provider:i,source:l,cfHint:c,ueModel:d,screenshot:m};return u==="dry-run"?y.dryRun=!0:u==="none"?y.agent="none":(y.agent=u.replace("agent:",""),y.yes=!0),y}function ui(e){return e&&e.replace(/[-_\s]+/g,"-").replace(/[^a-z0-9-]/gi,"").toLowerCase().replace(/^-+|-+$/g,"")||"design-block"}function Jp(e){try{let t=new URL(e);return t.pathname.split("/").filter(Boolean).pop()||t.hostname.split(".")[0]}catch{return""}}function qp(e){if(e)try{let t=new URL(e).hostname.toLowerCase();if(t.includes("figma.com"))return"figma";if(t.includes("framer"))return"framer";if(t.includes("stitch"))return"stitch"}catch{}}function Xp(e){if(/^[a-z][a-z0-9+.-]*:\/\//i.test(e))return null;let t=V.isAbsolute(e)?e:V.resolve(process.cwd(),e);return!de(t)||!Kp.has(V.extname(t).toLowerCase())?null:t}async function Vp(e,t){let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found). Run this from your project root."),process.exitCode=1;return}await a.logoOnceAnimated("Design \u2192 EDS block");let o=e,i=t;if(!o&&i.sample){let O=Gp();if(!O){a.error("Bundled sample design not found (samples/hero.svg)."),process.exitCode=1;return}o=O,i={name:"hero",provider:"figma",...i},a.info(` ${X.pass} Sample design ${S.dim("Kiri Bloom hero")} ${S.dim("(bundled \xB7 no token \xB7 no MCP)")}`)}if(!o){let O=await zp(o);if(!O){a.info("Cancelled.");return}o=O.figmaUrl,i={...i,...O}}let r=i.provider;if(r&&!(r in ct)){a.error(`Unknown --provider "${r}". Use: figma, framer or stitch.`),process.exitCode=1;return}if(i.source&&!ac.includes(i.source)){a.error(`Unknown --source "${i.source}". Use: ${ac.join(", ")}.`),process.exitCode=1;return}let s=r??qp(o)??"figma",l=ct[s],c=Xp(o),d=c?c.startsWith(n+V.sep)?V.relative(n,c):c:void 0,m=null,p=d??o;if(c)a.info(` ${X.pass} Local design file ${S.dim(d)} ${S.dim("(no Figma MCP)")}`);else if(s==="figma"){let O=Nn("Parsing Figma URL...").start();try{m=An(o),O.succeed(`Parsed Figma URL ${S.dim(m.nodeId?`node ${m.nodeId}`:`file ${m.fileKey}`)}`)}catch(me){O.fail(me.message),process.exitCode=1;return}}else a.info(` ${X.pass} ${l} design ${S.dim(p)}`);let u=i.name||(c?ui(V.basename(c,V.extname(c))):m?ui(m.fileName):o?ui(Jp(o)):"");if(!Ne.test(u)){a.error(`Invalid block name "${u}". Use --name with a kebab-case name (e.g., --name hero-banner).`),process.exitCode=1;return}!i.name&&m?.nodeId&&(a.warn(`Block name "${u}" came from the Figma file name, not the selected frame.`),a.info(S.dim(` Pass ${S.cyan("--name <kebab-case>")} for a cleaner block name.`)));let g=await ce(n),h=g.figma?.token??process.env.FIGMA_TOKEN??process.env.FIGMA_PAT,$;if(li(s)&&!c&&!i.dryRun&&(i.auth||i.authRefresh))if($=di(s),i.authRefresh||!Js(s)){let O=(()=>{try{return new URL(o).origin}catch{return o}})();a.info(` ${S.dim("\u2192")} Opening ${S.cyan(l)} \u2014 click ${S.cyan("Sign In")} and log in, then come back here.`);let{input:me}=await Promise.resolve().then(()=>(G(),H));try{await qs($),await js({loginUrl:O,statePath:$,projectRoot:n,waitForUser:async()=>{await me({message:"Press Enter once you're signed in (you don't need to open the design)"})}}),await Ks($),a.info(` ${X.pass} Session saved ${S.dim($)}`)}catch(ae){a.error(`Could not capture the ${l} session: ${ae instanceof Error?ae.message:String(ae)}`),process.exitCode=1;return}}else a.info(` ${X.pass} Using saved ${l} session ${S.dim($)} ${S.dim("(--auth-refresh to re-login)")}`);let b=Nn("Resolving design source...").start(),y=await _s({figma:m,localFile:d,token:h,projectRoot:n,preferMcp:i.mcp,refresh:i.refresh,provider:s,designUrl:c?void 0:o,storageStatePath:$,dryRun:i.dryRun,restPerMinute:g.figma?.restPerMinute,onRestWait:O=>{b.text=`Resolving design source... waiting ${Math.ceil(O/1e3)} s for a Figma REST slot (${g.figma?.restPerMinute??ii}/min)`}});if(y.scrapeError){b.fail(`Scrape failed: ${y.scrapeError}`),a.info(S.dim(` Check the URL is a public ${l} page, and that Chromium is installed (${S.cyan("npx playwright install chromium")}).`)),process.exitCode=1;return}if(y.rateLimit){b.fail(y.rateLimit.message),a.info(S.dim(" The limit follows the plan that owns the file: 20 calls/month on Starter or with a View/Collab seat, 10-20/min with a Dev/Full seat on a paid plan.")),a.info(S.dim(` Not falling back to Figma MCP (its budget is the same or smaller). Re-run after the reset, pass ${S.cyan("--mcp")} to spend an MCP call instead, or export the frame as PNG/SVG (no quota).`)),y.rateLimit.upgradeLink&&a.info(S.dim(` Plan details: ${y.rateLimit.upgradeLink}`)),process.exitCode=1;return}if(b.succeed(`Design source ${S.dim(y.summary)}`),y.restError&&a.warn(`Figma REST fetch failed, using MCP fallback: ${y.restError}`),y.design?.mode==="scrape"&&!i.dryRun)try{let O=JSON.parse(y.design.spec),me=(O.title??"").toLowerCase(),ae=y.design.spec.toLowerCase(),Xt=/isn'?t shared|doesn'?t exist|page not found|\b404\b/;(Xt.test(me)||Xt.test(ae)||/\bsign[ -]?in\b|\blog[ -]?in\b/.test(me)||(O.nodeCount??0)<8)&&(a.warn(`The scraped page looks like a login / error shell${O.title?` ("${O.title}")`:""} \u2014 the design may be gated or the URL wrong.`),a.info(S.dim(` Use ${S.cyan("--auth")} to log in once (or ${S.cyan("--auth-refresh")} to re-login), and confirm the URL opens the design when you're signed in.`)))}catch{}let w=Nn("Reading design tokens & building prompt...").start(),T=await Hs({provider:s,figma:m,designRef:p,blockName:u,projectRoot:n,withUeModel:i.ueModel!==!1,contentSource:i.source??"document",cfHint:i.cfHint,screenshot:i.screenshot===!0,design:y.design}),K=await ti(T,n),q=de(V.join(n,"styles","styles.css"));if(w.succeed(q?`Loaded design tokens ${S.dim("styles/styles.css")}`:`Built prompt ${S.dim("no project tokens found")}`),a.info(S.dim(` prompt \u2192 ${K}`)),i.dryRun){a.info(""),a.info(S.yellow("Dry run mode \u2014 prompt generated but agent not invoked.")),a.info(`Prompt file: ${S.cyan(K)}`),a.info(`Block name: ${S.cyan(u)}`),a.info(`Prompt version: ${It}`),a.info(""),a.info("Preview:"),a.info(S.dim("\u2500".repeat(60))),console.log(T);return}let he=i.agent||g.agent;if(i.agent==="none"){a.info("Agent skipped (--agent none). Use the prompt file manually:"),a.info(` ${S.cyan(K)}`);return}let De=Nn("Detecting AI agent...").start(),L=await us(he);if(!L){De.fail("No AI agent found (claude, cursor, codex, or a local Ollama / oMLX server)."),a.info(`Install Claude Code: ${S.cyan("npm install -g @anthropic-ai/claude-code")}`),a.info(`Or run a local model: ${S.cyan("ollama serve")} / ${S.cyan("omlx start")}, then ${S.cyan("--agent ollama")} or ${S.cyan("--agent omlx")}.`),a.info(`Or use the prompt file manually: ${S.cyan(K)}`),process.exitCode=1;return}let xe=ze(L.type);De.succeed(`Agent ready ${S.cyan(L.type)} ${S.dim(xe?`${i.model??L.model} \xB7 ${L.path}`:L.path)}`);let Bi=y.design?.mode==="mcp"||!y.design&&s==="figma";if(xe&&Bi){a.error("A local model can't read a Figma design through MCP."),a.info(S.dim(` Set a Figma token (${S.cyan("FIGMA_TOKEN")}) so eds fetches it over REST, export the frame as PNG/SVG, or scrape a Framer / Stitch page. Prompt saved: ${K}`)),process.exitCode=1;return}if(Bi&&s==="figma"&&!L.hasFigmaMcp&&(a.warn(`Figma MCP may not be configured for ${L.type}.`),a.info(`Run ${S.cyan("eds figma setup")} to configure it, or set a Figma token for REST.`)),!i.yes){let{confirm:O}=await Promise.resolve().then(()=>(G(),H));if(!await O({message:`Run ${L.type} with the generated prompt?`,default:!0})){a.info(`Prompt saved to: ${S.cyan(K)}`);return}}let Gc=y.design?.mode==="spec"?"embedded design (no MCP)":y.design?.mode==="scrape"?`scraped ${l} page (no MCP)`:y.design?.mode==="file"?`reading ${d}`:y.design?.mode==="mcp"?`via ${l} MCP (1 call, cached)`:`via ${l} MCP`;a.info(` ${S.dim("\u2192")} Handing off to ${S.cyan(L.type)} ${S.dim(Gc)}`),y.design?.mode==="mcp"&&a.info(S.dim(" get_design_context \xD71 \u2192 cache"));let Wc=i.source==="cf"||i.source==="mixed",Wn=xe?i.model??L.model:i.model??g.model??(Wc&&L.type==="claude"?"sonnet":void 0);Wn&&!xe&&!i.model&&!g.model&&a.info(S.dim(` Model: ${Wn} (Content Fragment source)`));let zc={blockName:u,designFile:y.design?.mode==="file"?d:void 0,contextTokens:g.local?.contextTokens,apiKey:g.local?.apiKey};if(!await ni(L,K,n,Wn,zc)){process.exitCode=1;return}let gt=V.join(n,"blocks",u);if(!(de(V.join(gt,`${u}.js`))||de(V.join(gt,`${u}.css`)))){a.warn(`No block files were written to blocks/${u}/ \u2014 nothing to preview.`),y.design?.mode==="mcp"&&!L.hasFigmaMcp?(a.info(S.dim(` The agent couldn't read the design: no ${l} MCP is configured for ${L.type}.`)),a.info(S.dim(` Run ${S.cyan("eds figma setup")}, or set a Figma token (FIGMA_TOKEN) to use REST, then re-run.`))):y.design?.mode==="mcp"?(a.info(S.dim(" The agent couldn't read the design, so it generated nothing. Common cause: the")),a.info(S.dim(` ${l} MCP tool-call limit (e.g. Figma Starter plan). See the log above.`)),a.info(S.dim(" Wait for the limit to reset or upgrade the plan, then re-run the same command."))):a.info(S.dim(" The agent generated nothing \u2014 see the log above for why.")),process.exitCode=1;return}let Jc=await Qp(gt,u,i.ueModel!==!1,i.source??"document");if(de(gt)){let O=V.join(gt,".eds-meta.json"),me;if(de(O))try{me=JSON.parse(await Re(O,"utf-8")).breakpoints}catch{}let ae=vs(i.widths,me),Xt={provider:s,designRef:p,figmaFileKey:m?.fileKey??null,figmaNodeId:m?.nodeId??null,lastSyncedAt:new Date().toISOString(),promptVersion:It,agentUsed:L.type,...ae.length?{breakpoints:ae}:{}};await Bp(O,`${JSON.stringify(Xt,null,2)}
934
+ `),ae.length&&a.info(S.dim(` Preview breakpoints: ${ae.map(Hi=>Hi.width).join(" \xB7 ")}`))}if(!Jc){a.warn(`Block "${u}" generated with issues \u2014 review the output above before publishing.`),process.exitCode=1;return}if(a.success(`Block "${u}" generation complete.`),!i.yes){let{confirm:O}=await Promise.resolve().then(()=>(G(),H));if(await O({message:"Instrument this block for analytics (dataLayer)?",default:!1})){let{trackBlock:ae}=await Promise.resolve().then(()=>(At(),Tt));await ae(u,{})}}if(!i.yes)await Yp({blockName:u,projectRoot:n,agent:L,model:ze(L.type)?i.model??L.model:i.model??g.model,contextTokens:g.local?.contextTokens,apiKey:g.local?.apiKey,provider:s,figma:m,designRef:p});else if(i.serve){let{previewBlock:O}=await Promise.resolve().then(()=>(qe(),Ht));await O(u,{})}else a.info(` ${S.dim("\u2192")} Next: ${S.cyan(`eds block preview ${u}`)}`)}async function Yp(e){let{select:t,input:n}=await Promise.resolve().then(()=>(G(),H)),{startPreview:o}=await Promise.resolve().then(()=>(qe(),Ht)),i=null;for(a.info("");;){let r=await t({message:"Block ready \u2014 what next?",choices:[{name:"Refine \u2014 describe a change",value:"refine"},{name:i?`Preview open at ${i.url} (reloads on change)`:"Open live preview",value:"preview",disabled:i?"running":!1},{name:"Finish",value:"done"}],default:"refine"});if(r==="done")break;if(r==="preview"){await Wp()?a.info(S.dim(" A preview server is already running at http://127.0.0.1:8777.")):i=await o(e.blockName,{});continue}let s=(await n({message:"Describe the change:"})).trim();if(!s)continue;let l=Gs({blockName:e.blockName,feedback:s,provider:e.provider,figma:e.figma,designRef:e.designRef}),c=await ti(l,e.projectRoot);a.info(` ${S.dim("\u2192")} Applying your change with ${S.cyan(e.agent.type)}\u2026`),await ni(e.agent,c,e.projectRoot,e.model,{blockName:e.blockName,refine:!0,contextTokens:e.contextTokens,apiKey:e.apiKey})}if(i){let r=i;a.info(S.dim(` Preview still live at ${r.url}. ${Bt()}
935
+ `)),await Ut(r.close)}}async function Qp(e,t,n,o="document"){let i=[],r=V.join(e,`${t}.js`),s=V.join(e,`${t}.css`),l=de(r),c=de(s);if(i.push({status:l?"pass":"fail",name:`${t}.js`,message:l?"created":"missing \u2014 agent did not write the JS file"}),i.push({status:c?"pass":"fail",name:`${t}.css`,message:c?"created":"missing \u2014 agent did not write the CSS file"}),l){let m=await Re(r,"utf-8");i.push({status:/export\s+default/.test(m)?"pass":"fail",name:"decorate export",message:/export\s+default/.test(m)?"found":"no default export \u2014 block won't load"}),m.includes("console.log")&&i.push({status:"warn",name:"no console.log",message:"found console.log \u2014 remove before production"})}if(c){let m=await Re(s,"utf-8");i.push({status:m.includes(`.${t}`)?"pass":"warn",name:"scoped CSS",message:m.includes(`.${t}`)?`scoped to .${t}`:`no .${t} selector \u2014 styles may leak`})}if(n){let m=de(V.join(e,`_${t}.json`)),p=V.join(e,"..","..","component-models.json"),u=!1;if(!m&&de(p))try{u=(await Re(p,"utf-8")).includes(`"${t}"`)}catch{}let g=m||u;if(i.push({status:g?"pass":"warn",name:"Universal Editor model",message:g?m?`_${t}.json created`:"added to component-models.json":`missing \u2014 no _${t}.json (run with default UE generation, or --no-ue-model to skip)`}),m&&l)try{let h=await Re(V.join(e,`_${t}.json`),"utf-8"),$=await Re(r,"utf-8"),b=/"resourceType"\s*:\s*"[^"]*\/item"/.test(h)||/"filter"\s*:/.test(h)||/"multi"\s*:\s*true/.test(h),y=/\.children/.test($)||/\bfor\s*\(/.test($)||/\.forEach\s*\(/.test($);b&&i.push({status:y?"pass":"warn",name:"multifield wired",message:y?"decorate() iterates items":"repeatable model but decorate() never iterates block.children \u2014 only one item will render"})}catch{}}if((o==="cf"||o==="mixed")&&l){let m=await Re(r,"utf-8"),p=V.join(e,`_${t}.json`),g=(de(p)?await Re(p,"utf-8"):"").includes("aem-content-fragment"),h=/\bfetch\s*\(/.test(m);i.push({status:g&&h?"pass":"warn",name:"content fragment",message:g&&h?"CF field in the model, fetched in decorate()":[!g&&"no aem-content-fragment field in the model",!h&&"decorate() never fetches the fragment"].filter(Boolean).join("; ")})}a.info(j("Verification"));let d=I(i.map(m=>m.name));for(let m of i)a.info(R(m.status,m.name,m.message,d));return a.info(""),!i.some(m=>m.status==="fail")}var ac,Kp,gi=v(()=>{"use strict";f();Zo();bs();Sn();ye();ks();Is();Us();Tn();Ws();D();J();Ye();Xs();oi();Fn();U();ac=["document","ue","cf","mixed"],Kp=new Set([".svg",".png",".jpg",".jpeg",".webp"])});var sc={};M(sc,{listBlocks:()=>tu});import{existsSync as Gt}from"fs";import{readFile as Zp,readdir as eu}from"fs/promises";import dt from"path";import mt from"chalk";async function tu(e={}){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n=dt.join(t,"blocks");if(!Gt(n)){a.info("No blocks/ directory found.");return}let o=await eu(n,{withFileTypes:!0}),i=[];for(let s of o){if(!s.isDirectory())continue;let l=s.name,c=dt.join(n,l),d={name:l,hasJs:Gt(dt.join(c,`${l}.js`)),hasCss:Gt(dt.join(c,`${l}.css`)),hasUeModel:Gt(dt.join(c,`_${l}.json`))},m=dt.join(c,".eds-meta.json");if(Gt(m))try{let p=JSON.parse(await Zp(m,"utf-8"));d.figmaSource={fileKey:p.figmaFileKey,nodeId:p.figmaNodeId,lastSyncedAt:p.lastSyncedAt}}catch{}i.push(d)}if(e.json){console.log(JSON.stringify(i,null,2));return}if(i.length===0){a.info("No blocks found.");return}a.info(j("Blocks",`${i.length} in project`));let r=I(i.map(s=>s.name));for(let s of i){let l=[s.hasJs?N.ok("js"):mt.dim.strikethrough("js"),s.hasCss?N.ok("css"):mt.dim.strikethrough("css")];s.hasUeModel&&l.push(N.blue("ue-model")),s.figmaSource&&l.push(`${X.figma} ${N.dotPurple("figma")}`);let c=ht(mt.bold(s.name),r);if(a.info(` ${c} ${mt.dim("[")}${l.join(" ")}${mt.dim("]")}`),s.figmaSource){let d=new Date(s.figmaSource.lastSyncedAt).toLocaleDateString();a.info(` ${" ".repeat(r)} ${X.arrow} ${mt.dim(`figma:${s.figmaSource.fileKey} \xB7 synced ${d}`)}`)}}a.info("")}var cc=v(()=>{"use strict";f();D();J();U()});import lc from"path";function hi(e,t){return lc.join(e,"blocks",t,"__snapshots__")}function mc(e,t,n){return lc.join(hi(e,t),`${t}-${n}.png`)}function Wt(e){return`${(e*100).toFixed(2)}%`}async function wi(e,t,n,o=900){let i;try{({chromium:i}=await import("playwright"))}catch{throw new Error(dc)}let r=await i.launch();try{let s=await r.newPage({viewport:{width:t,height:o}});await s.goto(e,{waitUntil:"networkidle"}),await s.waitForTimeout(300);let l=n?s.locator(n).first():null;return l&&await l.count()?await l.screenshot():await s.screenshot({fullPage:!0})}finally{await r.close()}}async function pc(){try{let e="pngjs",t="pixelmatch",{PNG:n}=await import(e),o=(await import(t)).default;return{PNG:n,pixelmatch:o}}catch{throw new Error(dc)}}async function uc(e,t){let{PNG:n,pixelmatch:o}=await pc(),i=n.sync.read(e),r=n.sync.read(t);if(i.width!==r.width||i.height!==r.height)return{diffPixels:-1,totalPixels:0,ratio:1,sizeMismatch:!0,width:i.width,height:i.height,otherWidth:r.width,otherHeight:r.height};let{width:s,height:l}=i,c=new n({width:s,height:l}),d=o(i.data,r.data,c.data,s,l,{threshold:.1}),m=s*l;return{diffPixels:d,totalPixels:m,ratio:m?d/m:0,width:s,height:l,diffPng:n.sync.write(c)}}async function fc(e,t){let{PNG:n,pixelmatch:o}=await pc(),i=n.sync.read(e),r=n.sync.read(t),s=Math.min(i.width,r.width),l=Math.min(i.height,r.height),c=new n({width:s,height:l}),d=new n({width:s,height:l});n.bitblt(i,c,0,0,s,l,0,0),n.bitblt(r,d,0,0,s,l,0,0);let m=new n({width:s,height:l}),p=o(c.data,d.data,m.data,s,l,{threshold:.1}),u=s*l;return{diffPixels:p,totalPixels:u,ratio:u?p/u:0,width:s,height:l,diffPng:n.sync.write(m)}}var dc,gc=v(()=>{"use strict";f();dc=`Visual testing needs extra tools. Install them with:
936
+ npm i -D playwright pixelmatch pngjs && npx playwright install chromium`});var vc={};M(vc,{visualTest:()=>ou});import{existsSync as hc}from"fs";import{mkdir as bi,readFile as wc,writeFile as zt}from"fs/promises";import ke from"path";import yi from"chalk";async function ou(e,t={}){let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}if(t.design){await iu(n,e,t);return}let o=e?[e]:await Je(n);if(!o.length){a.warn("No previewable blocks to test.");return}let i=Number.parseInt(t.port??"8788",10),r=await lt(n,t.widths,Number.isFinite(i)?i:8788),s=Number.parseFloat(t.threshold??"0.01"),l=ke.join(n,"tmp","eds-cli","visual-diff");a.logoOnce(A("Visual test"));let c=0,d=0,m=0,p=0;try{for(let u of o){let g=await ve(n,u,t.widths);if(g){a.info(j(u));for(let h of g.breakpoints){let $=await wi(bc(r.url,u),h.width,yc(u)),b=mc(n,u,h.width),y=hc(b);if(t.update||!y){await bi(hi(n,u),{recursive:!0}),await zt(b,$),y?(p++,a.info(R("pass",`${h.width}px`,"baseline updated"))):(m++,a.info(R("pass",`${h.width}px`,"baseline created")));continue}let w=await uc(await wc(b),$);if(w.sizeMismatch){d++;let T=w.height===nu&&(w.otherHeight??0)<w.height;a.info(R("fail",`${h.width}px`,T?`baseline is an older full-page shot (${w.width}\xD7${w.height}) \u2014 re-run with --update`:`size changed ${w.width}\xD7${w.height} \u2192 ${w.otherWidth}\xD7${w.otherHeight}`));continue}if(w.ratio>s){d++,await bi(l,{recursive:!0});let T=ke.join(l,`${u}-${h.width}.diff.png`);w.diffPng&&await zt(T,w.diffPng),a.info(R("fail",`${h.width}px`,`${Wt(w.ratio)} changed \u2192 ${ke.relative(n,T)}`))}else c++,a.info(R("pass",`${h.width}px`,w.ratio>0?`${Wt(w.ratio)} (within ${Wt(s)})`:"identical"))}}}}catch(u){a.error(u instanceof Error?u.message:String(u)),process.exitCode=1;return}finally{await r.close()}a.info(""),a.info(`${yi.green(`${c} passed`)} \xB7 ${yi.yellow(`${d} changed`)} \xB7 ${m} new \xB7 ${p} updated`),d>0&&(a.warn(`${d} visual change(s). Review the diff PNGs in tmp/eds-cli/visual-diff/, then re-run with --update to accept.`),process.exitCode=1)}async function iu(e,t,n){if(!t){a.error("Design diff needs a block name: eds block test <name> --design"),process.exitCode=1;return}let o=await ve(e,t,n.widths);if(!o){a.error(`Block "${t}" has no css/js to render.`),process.exitCode=1;return}let i,r,s=ke.join(e,"blocks",t,".eds-meta.json");if(hc(s))try{let g=JSON.parse(await wc(s,"utf-8"));i=g.figmaFileKey??void 0,r=g.figmaNodeId??void 0}catch{}if(!i||!r){a.error(`"${t}" has no Figma source in .eds-meta.json \u2014 can't fetch the design image.`),process.exitCode=1;return}let l=await ce(e),c=l.figma?.token??process.env.FIGMA_TOKEN??process.env.FIGMA_PAT;if(!c){a.error("Design diff needs a Figma token (FIGMA_TOKEN or figma.token) to render the node."),process.exitCode=1;return}let d=o.breakpoints.filter(g=>g.figma),m=(d.length?d:o.breakpoints).reduce((g,h)=>h.width>g.width?h:g,o.breakpoints[0]).width,p=Number.parseInt(n.port??"8788",10),u=await lt(e,n.widths,Number.isFinite(p)?p:8788);a.logoOnce(A("Design \u2194 render")),a.info(j(t,`${m}px`));try{let g=await wi(bc(u.url,t),m,yc(t));a.info(R("pass","render","block screenshot captured"));let h=await Ls({fileKey:i,nodeId:r,token:c,scale:1,pace:()=>Cn({logPath:En(e),perMinute:l.figma?.restPerMinute,onWait:y=>a.info(R("warn","design",`waiting ${Math.ceil(y/1e3)} s for a Figma REST slot`))})});a.info(R("pass","design","Figma image fetched (REST)"));let $=await fc(h,g),b=ke.join(e,"tmp","eds-cli","visual-diff");await bi(b,{recursive:!0}),await zt(ke.join(b,`${t}-design.png`),h),await zt(ke.join(b,`${t}-render.png`),g),$.diffPng&&await zt(ke.join(b,`${t}-design-diff.png`),$.diffPng),a.info(R("warn","diff",`~${Wt($.ratio)} different over ${$.width}\xD7${$.height} (approximate)`)),a.info(""),a.info(yi.dim(` Saved design / render / diff to ${ke.relative(e,b)}/${t}-*.png \u2014 compare side by side.`))}catch(g){a.error(g instanceof Error?g.message:String(g)),process.exitCode=1}finally{await u.close()}}var bc,yc,nu,kc=v(()=>{"use strict";f();ye();Tn();ci();D();gc();J();U();qe();bc=(e,t)=>`${e}${Ae.slice(1)}${t}`,yc=e=>`body > .${e}`,nu=900});async function xc(e,t,n){let o;try{({chromium:o}=await import("playwright"))}catch{throw new Error(ru)}let i=await o.launch();try{let r=await i.newPage({viewport:{width:t,height:900}});await r.goto(e,{waitUntil:"networkidle"}),await r.waitForTimeout(200);let s=await r.evaluate(au);return n&&s.push(...await r.evaluate(`(${su})(${JSON.stringify(n)})`)),s}finally{await i.close()}}var ru,au,su,$c=v(()=>{"use strict";f();ru=`Content checks need Playwright. Install it with:
937
+ npm i -D playwright && npx playwright install chromium`,au=`(() => {
902
938
  const out = [];
903
939
  const root = document.querySelector('[class$="block"]') || document.body;
904
940
  const trunc = (s) => (s || '').slice(0, 60);
@@ -944,7 +980,7 @@ ${n}
944
980
  }
945
981
  }
946
982
  return out;
947
- })()`,mp=`(html) => {
983
+ })()`,su=`(html) => {
948
984
  const doc = new DOMParser().parseFromString(html, 'text/html');
949
985
  const root = doc.querySelector('.block') || doc.body.firstElementChild;
950
986
  if (!root) return [];
@@ -958,14 +994,14 @@ ${n}
958
994
  }
959
995
  }
960
996
  return wrapped ? [{ level: 'warn', rule: 'mock-nesting', detail: wrapped + ' of ' + cells + ' cells in the preview mock wrap their content in an extra <div>; EDS delivers row > cell > content' }] : [];
961
- }`});var _a={};O(_a,{blockCheck:()=>pp});import ni from"chalk";async function pp(e,t={}){let n=E();if(!n){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let o=e?[e]:await _e(n);if(!o.length){r.warn("No previewable blocks to check.");return}let i=Number.parseInt(t.port??"8789",10),s=await tt(n,t.widths,Number.isFinite(i)?i:8789);r.logoOnce(T("Content check"));let a=0,l=0,c=0;try{for(let d of o){let m=await he(n,d,t.widths);if(!m)continue;let p=m.breakpoints.reduce((g,h)=>h.width>g.width?h:g,m.breakpoints[0]).width,u=await Ma(`${s.url}${Se.slice(1)}${d}`,p,m.placeholder?void 0:m.sampleContent);if(r.info(S(d,`${p}px`)),!u.length){c++,r.info(R("pass","clean","no issues"));continue}for(let g of u)g.level==="error"?a++:l++,r.info(R(g.level==="error"?"fail":"warn",g.rule,g.detail))}}catch(d){r.error(d instanceof Error?d.message:String(d)),process.exitCode=1;return}finally{await s.close()}r.info(""),r.info(`${ni.green(`${c} clean`)} \xB7 ${ni.red(`${a} error(s)`)} \xB7 ${ni.yellow(`${l} warning(s)`)}`),(a>0||t.strict&&l>0)&&(process.exitCode=1)}var Ua=k(()=>{"use strict";f();D();Ia();z();_();Ue()});function Ba(e){return Pn.find(t=>t.id===e)}function Ha(e,t){return`
997
+ }`});var Sc={};M(Sc,{blockCheck:()=>cu});import vi from"chalk";async function cu(e,t={}){let n=E();if(!n){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let o=e?[e]:await Je(n);if(!o.length){a.warn("No previewable blocks to check.");return}let i=Number.parseInt(t.port??"8789",10),r=await lt(n,t.widths,Number.isFinite(i)?i:8789);a.logoOnce(A("Content check"));let s=0,l=0,c=0;try{for(let d of o){let m=await ve(n,d,t.widths);if(!m)continue;let p=m.breakpoints.reduce((g,h)=>h.width>g.width?h:g,m.breakpoints[0]).width,u=await xc(`${r.url}${Ae.slice(1)}${d}`,p,m.placeholder?void 0:m.sampleContent);if(a.info(j(d,`${p}px`)),!u.length){c++,a.info(R("pass","clean","no issues"));continue}for(let g of u)g.level==="error"?s++:l++,a.info(R(g.level==="error"?"fail":"warn",g.rule,g.detail))}}catch(d){a.error(d instanceof Error?d.message:String(d)),process.exitCode=1;return}finally{await r.close()}a.info(""),a.info(`${vi.green(`${c} clean`)} \xB7 ${vi.red(`${s} error(s)`)} \xB7 ${vi.yellow(`${l} warning(s)`)}`),(s>0||t.strict&&l>0)&&(process.exitCode=1)}var jc=v(()=>{"use strict";f();D();$c();J();U();qe()});function Pc(e){return Mn.find(t=>t.id===e)}function Ec(e,t){return`
962
998
  // \u2500\u2500 ${e} (eds integrate) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
963
999
  {
964
1000
  ${t.split(`
965
1001
  `).map(n=>n&&` ${n}`).join(`
966
1002
  `)}
967
1003
  }
968
- `}var Pn,Ga=k(()=>{"use strict";f();Pn=[{id:"gtm",name:"Google Tag Manager",fields:[{name:"id",message:"GTM container ID",placeholder:"GTM-XXXXXXX"}],code:()=>`// Google Tag Manager - loaded from ./analytics.js (delayed phase, after LCP).
1004
+ `}var Mn,Cc=v(()=>{"use strict";f();Mn=[{id:"gtm",name:"Google Tag Manager",fields:[{name:"id",message:"GTM container ID",placeholder:"GTM-XXXXXXX"}],code:()=>`// Google Tag Manager - loaded from ./analytics.js (delayed phase, after LCP).
969
1005
  import { loadGTM } from './analytics.js';
970
1006
  import pageMetaPush from './page-meta.js';
971
1007
 
@@ -1056,19 +1092,19 @@ document.head.appendChild(cb);`},{id:"custom",name:"Custom third-party script",f
1056
1092
  const s = document.createElement('script');
1057
1093
  s.async = true;
1058
1094
  s.src = ${JSON.stringify(e.url||"")};
1059
- document.head.appendChild(s);`}]});var ii={};O(ii,{integrate:()=>hp});import{existsSync as up}from"fs";import{mkdir as Wa,readFile as fp,writeFile as za}from"fs/promises";import En from"path";import oi from"chalk";async function hp(e){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Integrate - third-party service"));let{select:n,input:o}=await Promise.resolve().then(()=>(H(),B)),i=e||await n({message:"Which service do you want to add?",choices:Pn.map(p=>({name:p.name,value:p.id}))}),s=Ba(i);if(!s){r.error(`Unknown integration "${i}". Options: ${Pn.map(p=>p.id).join(", ")}`),process.exitCode=1;return}let a={};for(let p of s.fields){let u=await o({message:` ${p.message}`,default:p.placeholder});a[p.name]=u.trim()}let l=[];if(s.module)for(let p of s.module(a)){let u=En.join(t,p.file);await Wa(En.dirname(u),{recursive:!0}),await za(u,p.content),l.push(p.file)}let c=s.module?`
1060
- // ${s.name} (eds integrate)
1061
- ${s.code(a)}
1062
- `:Ha(s.name,s.code(a)),d=En.join(t,"scripts","delayed.js");await Wa(En.dirname(d),{recursive:!0});let m=up(d)?await fp(d,"utf-8"):gp;await za(d,`${m.replace(/\s*$/,"")}
1063
- ${c}`),r.info(S("Added"));for(let p of l)r.info(j(s.name,`wrote ${p}`));r.info(j(s.name,"wired into scripts/delayed.js")),r.info(""),r.info(oi.dim(" Loads after LCP (delayed phase) - zero impact on your Core Web Vitals.")),(s.id==="gtm"||s.id==="ga4")&&r.info(oi.dim(" Tip: gate analytics behind user consent (add the Cookiebot integration).")),s.id==="chat"&&r.info(oi.dim(" The widget loads only when the visitor clicks the button (facade pattern).")),r.info(""),r.info(I(["Integration added"]))}var gp,ri=k(()=>{"use strict";f();Ga();D();z();_();gp=`// delayed.js - third-party / non-critical scripts.
1095
+ document.head.appendChild(s);`}]});var xi={};M(xi,{integrate:()=>pu});import{existsSync as lu}from"fs";import{mkdir as Tc,readFile as du,writeFile as Ac}from"fs/promises";import _n from"path";import ki from"chalk";async function pu(e){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Integrate - third-party service"));let{select:n,input:o}=await Promise.resolve().then(()=>(G(),H)),i=e||await n({message:"Which service do you want to add?",choices:Mn.map(p=>({name:p.name,value:p.id}))}),r=Pc(i);if(!r){a.error(`Unknown integration "${i}". Options: ${Mn.map(p=>p.id).join(", ")}`),process.exitCode=1;return}let s={};for(let p of r.fields){let u=await o({message:` ${p.message}`,default:p.placeholder});s[p.name]=u.trim()}let l=[];if(r.module)for(let p of r.module(s)){let u=_n.join(t,p.file);await Tc(_n.dirname(u),{recursive:!0}),await Ac(u,p.content),l.push(p.file)}let c=r.module?`
1096
+ // ${r.name} (eds integrate)
1097
+ ${r.code(s)}
1098
+ `:Ec(r.name,r.code(s)),d=_n.join(t,"scripts","delayed.js");await Tc(_n.dirname(d),{recursive:!0});let m=lu(d)?await du(d,"utf-8"):mu;await Ac(d,`${m.replace(/\s*$/,"")}
1099
+ ${c}`),a.info(j("Added"));for(let p of l)a.info(P(r.name,`wrote ${p}`));a.info(P(r.name,"wired into scripts/delayed.js")),a.info(""),a.info(ki.dim(" Loads after LCP (delayed phase) - zero impact on your Core Web Vitals.")),(r.id==="gtm"||r.id==="ga4")&&a.info(ki.dim(" Tip: gate analytics behind user consent (add the Cookiebot integration).")),r.id==="chat"&&a.info(ki.dim(" The widget loads only when the visitor clicks the button (facade pattern).")),a.info(""),a.info(B(["Integration added"]))}var mu,$i=v(()=>{"use strict";f();Cc();D();J();U();mu=`// delayed.js - third-party / non-critical scripts.
1064
1100
  // Loaded in the EDS delayed phase (after LCP), so nothing here blocks the page.
1065
- `});var si={};O(si,{figmaSetup:()=>vp});import{existsSync as wp}from"fs";import{mkdir as bp,writeFile as yp}from"fs/promises";import de from"chalk";async function vp(){let{select:e,confirm:t}=await Promise.resolve().then(()=>(H(),B));r.logoOnce(T()),r.info(S("Figma MCP Setup Wizard")),r.info("Detecting installed AI agents...");let n=await gn(),o;if(n.length===0?(r.warn("No AI agents found (claude, cursor, codex)."),r.info(`Install Claude Code: ${de.cyan("npm install -g @anthropic-ai/claude-code")}`),o="none"):(r.success(`Found: ${n.map(s=>de.cyan(s.type)).join(", ")}`),o=await e({message:"Which agent do you want to use with eds-cli?",choices:[...n.map(s=>({name:`${s.type}${s.hasFigmaMcp?de.green(" (Figma MCP detected)"):""}`,value:s.type})),{name:"None (manual mode)",value:"none"}]})),o!=="none"){let s=n.find(a=>a.type===o);if(s&&!s.hasFigmaMcp){switch(r.warn(`Figma MCP is not configured for ${o}.
1066
- `),r.info(`Install it with one of these methods:
1067
- `),o){case"claude":r.info(` ${de.cyan("claude mcp add --transport sse figma-sse https://mcp.figma.com/sse")}`),r.info(" or for Figma Desktop app:"),r.info(` ${de.cyan("claude mcp add --transport http figma-desktop http://127.0.0.1:3845/mcp")}`);break;case"cursor":r.info(` Add to ${de.cyan("~/.cursor/mcp.json")}:`),r.info(de.dim(JSON.stringify({mcpServers:{figma:{url:"https://mcp.figma.com/sse"}}},null,2)));break;case"codex":r.info(" See Figma MCP docs: https://help.figma.com/hc/en-us/articles/32132100833559");break}r.info("")}else s?.hasFigmaMcp&&r.success(`Figma MCP is already configured for ${o}!`)}if(r.info(de.dim(`
1068
- Note: Figma MCP requires a Figma seat (Dev or Full on paid plans for desktop server).`)),await t({message:"Save preferences to ~/.eds/config.json?",default:!0})){let s=Ds();wp(s)||await bp(s,{recursive:!0});let a={};o!=="none"&&(a.agent=o),await yp(Mo(),`${JSON.stringify(a,null,2)}
1069
- `,{mode:384}),r.success(`Config saved to ${de.cyan(Mo())}`)}r.info(de.bold(`
1070
- Setup complete!`)),o!=="none"&&r.info(`Try: ${de.cyan('eds block from-design "<figma-url>" --dry-run')}`)}var ai=k(()=>{"use strict";f();Fo();xe();D();_()});var ci={};O(ci,{doctor:()=>xp});import{existsSync as It}from"fs";import{readFile as _t,readdir as kp}from"fs/promises";import Be from"path";import{parse as Ja}from"yaml";async function xp(e={}){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n=Xi(t);e.json||(r.logoOnce(T("Doctor")),r.info(S("Doctor",t)));let o=[];if(o.push({name:"fstab.yaml exists",status:n.hasFstab?"pass":"warn",message:n.hasFstab?"Found":"Missing - fine for Universal Editor / DA; required for document-mounted setups"}),n.hasFstab)try{let p=await _t(Be.join(t,"fstab.yaml"),"utf-8");Ja(p),o.push({name:"fstab.yaml valid YAML",status:"pass",message:"Valid"})}catch{o.push({name:"fstab.yaml valid YAML",status:"fail",message:"Invalid YAML syntax"})}if(o.push({name:"head.html exists",status:n.hasHeadHtml?"pass":"warn",message:n.hasHeadHtml?"Found":"Missing - recommended for metadata/scripts"}),o.push({name:"blocks/ directory",status:n.hasBlocks?"pass":"warn",message:n.hasBlocks?"Found":"Missing - no blocks yet"}),n.hasBlocks){let p=Be.join(t,"blocks"),u=await kp(p,{withFileTypes:!0}),g="",h=Be.join(t,"component-models.json");if(It(h))try{g=await _t(h,"utf-8")}catch{}for(let b of u){if(!b.isDirectory())continue;let y=b.name,v=Be.join(p,y,`${y}.js`),w=It(v);o.push({name:`blocks/${y} has JS`,status:w?"pass":"warn",message:w?"Found":`Missing ${y}.js`}),w&&(await _t(v,"utf-8")).includes("console.log")&&o.push({name:`blocks/${y} no console.log`,status:"warn",message:"Found console.log - remove before production"});let A=It(Be.join(p,y,`_${y}.json`)),X=g.includes(`"${y}"`);o.push({name:`blocks/${y} UE model`,status:A||X?"pass":"warn",message:A||X?A?`_${y}.json`:"in component-models.json":"no Universal Editor model - authors can't edit this block in UE"});let K=Be.join(p,y,".eds-meta.json");if(It(K))try{let Ce=JSON.parse(await _t(K,"utf-8")),Bt=new Date(Ce.lastSyncedAt),Y=Math.floor((Date.now()-Bt.getTime())/(1e3*60*60*24));o.push({name:`blocks/${y} Figma sync`,status:Y>30?"warn":"pass",message:Y>30?`Last synced ${Y} days ago - design may have changed`:`Synced ${Y} days ago`})}catch{o.push({name:`blocks/${y} .eds-meta.json`,status:"warn",message:"Invalid metadata file"})}}}let i=Be.join(t,"helix-query.yaml");if(It(i))try{let p=await _t(i,"utf-8");Ja(p),o.push({name:"helix-query.yaml valid",status:"pass",message:"Valid YAML"})}catch{o.push({name:"helix-query.yaml valid",status:"fail",message:"Invalid YAML syntax"})}o.push({name:"~/.eds/config.json",status:Io()?"pass":"warn",message:Io()?"Found":'Missing - run "eds figma setup" to configure'});let s=o.filter(p=>p.status==="fail"),a=o.filter(p=>p.status==="warn");if(e.json){let p={pass:o.filter(u=>u.status==="pass").length,warn:a.length,fail:s.length};console.log(JSON.stringify({projectRoot:t,results:o,summary:p},null,2)),s.length>0&&(process.exitCode=1);return}let l=U(o.map(p=>p.name));for(let p of o)r.info(R(p.status,p.name,p.message,l));let c=o.filter(p=>p.status==="fail"),d=o.filter(p=>p.status==="warn"),m=o.filter(p=>p.status==="pass");r.info(""),r.info(I([be({pass:m.length,warn:d.length,fail:c.length})])),c.length>0&&(process.exitCode=1)}var li=k(()=>{"use strict";f();xe();D();z();_()});var mi={};O(mi,{auditLoading:()=>Sp});import{existsSync as Pe}from"fs";import{readFile as it,readdir as $p,stat as qa}from"fs/promises";import Ee from"path";import di from"chalk";async function Sp(e={}){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}e.json||(r.logoOnce(T("Loading Audit")),r.info(S("Loading Order Audit",t)));let n=[];if(await jp(t,n),await Pp(t,n),await Ep(t,n),await Cp(t,n),await Tp(t,n),await Rp(t,n),e.json){let o={pass:n.filter(i=>i.status==="pass").length,warn:n.filter(i=>i.status==="warn").length,fail:n.filter(i=>i.status==="fail").length,info:n.filter(i=>i.status==="info").length};console.log(JSON.stringify({projectRoot:t,results:n,summary:o},null,2)),o.fail>0&&(process.exitCode=1);return}Fp(n)}async function jp(e,t){let n=Ee.join(e,"head.html");if(!Pe(n)){t.push({rule:"head.html exists",status:"warn",message:"Missing head.html"});return}let o=await it(n,"utf-8"),i=o.split(`
1071
- `);for(let c=0;c<i.length;c++){let d=i[c];/<script\b/i.test(d)&&!/type\s*=\s*["']module["']/i.test(d)&&!/<\/script>/.test(d)&&t.push({rule:"No render-blocking scripts in head.html",status:"fail",message:'Script without type="module" blocks rendering',file:"head.html",line:c+1})}let a=(o.match(/<link[^>]+rel=["']stylesheet["'][^>]*>/gi)||[]).filter(c=>!c.includes("styles/styles.css")&&!c.includes("styles.css"));a.length>0&&t.push({rule:"No extra stylesheets in head.html",status:"warn",message:`${a.length} extra stylesheet(s) \u2014 each competes with LCP budget`,file:"head.html"}),/<link[^>]+rel=["'](preload|preconnect)["']/i.test(o)&&t.push({rule:"No preload/preconnect in head.html",status:"warn",message:"preload/preconnect can hurt EDS LCP \u2014 resources compete with the 100KB budget",file:"head.html"}),/<script\b[^>]*>[\s\S]*?[^\s<][\s\S]*?<\/script>/i.test(o)&&t.push({rule:"No inline scripts in head.html",status:"warn",message:"Inline scripts block rendering \u2014 move to delayed.js",file:"head.html"});let l=/(?:src|href)=["'](https?:\/\/(?!(?:localhost|127\.0\.0\.1))[^"']+)["']/gi;for(let c of o.matchAll(l)){let d=c[1];d.includes("fonts.googleapis.com")||t.push({rule:"No third-party resources in head.html",status:"warn",message:`Third-party resource: ${d} \u2014 move to delayed.js`,file:"head.html"})}/<link[^>]+as=["']font["']/i.test(o)&&t.push({rule:"No font preloads in head.html",status:"warn",message:"Font preloads consume LCP bandwidth budget \u2014 let loadFonts() handle them",file:"head.html"}),t.some(c=>c.file==="head.html")||t.push({rule:"head.html is clean",status:"pass",message:"No render-blocking issues found",file:"head.html"})}async function Pp(e,t){let n=Ee.join(e,"scripts","scripts.js");if(!Pe(n)){t.push({rule:"scripts/scripts.js exists",status:"warn",message:"Missing scripts.js \u2014 cannot audit loading phases"});return}let o=await it(n,"utf-8"),i=o.split(`
1072
- `),s=/function\s+loadEager|loadEager\s*=/i.test(o),a=/function\s+loadLazy|loadLazy\s*=/i.test(o),l=/function\s+loadDelayed|loadDelayed\s*=/i.test(o);t.push({rule:"loadEager phase exists",status:s?"pass":"fail",message:s?"Found":"Missing loadEager \u2014 LCP optimization depends on it",file:"scripts/scripts.js"}),t.push({rule:"loadLazy phase exists",status:a?"pass":"fail",message:a?"Found":"Missing loadLazy \u2014 below-fold content won't load properly",file:"scripts/scripts.js"}),t.push({rule:"loadDelayed phase exists",status:l?"pass":"warn",message:l?"Found":"Missing loadDelayed \u2014 third-party scripts may block LCP",file:"scripts/scripts.js"});let c=o.match(/setTimeout\s*\([^,]+,\s*(\d+)\s*\)/);if(l&&c){let d=Number.parseInt(c[1],10);d<3e3?t.push({rule:"Delayed phase waits >= 3s",status:"warn",message:`delayed.js loads after ${d}ms \u2014 should be >= 3000ms for LCP safety`,file:"scripts/scripts.js"}):t.push({rule:"Delayed phase waits >= 3s",status:"pass",message:`${d}ms delay before loading delayed.js`,file:"scripts/scripts.js"})}if(s){let d=o.match(/loadEager[\s\S]*?(?=function\s|const\s+load|$)/)?.[0]||"";/loadSections\s*\(/.test(d)&&t.push({rule:"loadEager loads only first section",status:"fail",message:"loadEager calls loadSections() \u2014 should only load first section for fast LCP",file:"scripts/scripts.js"})}for(let d=0;d<i.length;d++){let m=i[d];/import\s.*from\s+['"]https?:\/\//i.test(m)&&t.push({rule:"No third-party imports at top level",status:"warn",message:`Third-party import at line ${d+1} \u2014 move to delayed.js if not critical`,file:"scripts/scripts.js",line:d+1})}if(s){let d=Ap(o,"loadEager");d&&/loadHeader|loadFooter/.test(d)&&t.push({rule:"Header/footer not in loadEager",status:"warn",message:"Header/footer in loadEager delays LCP \u2014 move to loadLazy",file:"scripts/scripts.js"})}}async function Ep(e,t){let n=Ee.join(e,"styles","styles.css");if(!Pe(n))return;let i=(await qa(n)).size/1024;t.push({rule:"styles.css size within LCP budget",status:i>40?"warn":"pass",message:`${i.toFixed(1)} KB${i>40?" \u2014 large CSS competes with 100KB LCP budget":""}`,file:"styles/styles.css"});let s=await it(n,"utf-8");/@import\s/.test(s)&&t.push({rule:"No @import in styles.css",status:"warn",message:"@import creates a request chain \u2014 inline the CSS or use lazy-styles.css",file:"styles/styles.css"})}async function Cp(e,t){let n=Ee.join(e,"scripts","delayed.js");if(!Pe(n)){t.push({rule:"scripts/delayed.js exists",status:"info",message:"No delayed.js \u2014 third-party scripts should go here"});return}(await it(n,"utf-8")).replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").trim()||t.push({rule:"delayed.js has content",status:"info",message:"delayed.js is empty \u2014 add analytics/martech here",file:"scripts/delayed.js"})}async function Tp(e,t){let n=Ee.join(e,"blocks");if(!Pe(n))return;let o=await $p(n,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let s=i.name,a=Ee.join(n,s,`${s}.js`);if(!Pe(a))continue;let l=await it(a,"utf-8"),c=l.split(`
1073
- `),d=["jquery","lodash","moment","rxjs","d3","three","gsap","anime","chart.js","swiper"];for(let u=0;u<c.length;u++){let g=c[u].toLowerCase();for(let h of d)g.includes("from")&&g.includes(h)&&/import\s/.test(g)&&t.push({rule:"No heavy imports in blocks",status:"warn",message:`Imports "${h}" \u2014 heavy library delays section loading`,file:`blocks/${s}/${s}.js`,line:u+1})}/document\.write/i.test(l)&&t.push({rule:"No document.write in blocks",status:"fail",message:"document.write blocks parsing and can break the page",file:`blocks/${s}/${s}.js`});let p=(await qa(a)).size/1024;p>20&&t.push({rule:"Block JS size reasonable",status:"warn",message:`${p.toFixed(1)} KB \u2014 consider splitting or lazy-loading parts`,file:`blocks/${s}/${s}.js`})}for(let i of o){if(!i.isDirectory())continue;let s=i.name,a=Ee.join(n,s,`${s}.css`);if(!Pe(a))continue;let l=await it(a,"utf-8"),c=/^([a-z][a-z0-9-]*)\s*\{/gm;for(let d of l.matchAll(c)){let m=d[1];["body","html","main"].includes(m)||t.push({rule:"Block CSS is scoped",status:"warn",message:`Bare element selector "${m}" \u2014 may leak styles and cause CLS. Use .${s} prefix`,file:`blocks/${s}/${s}.css`})}}}async function Rp(e,t){let n=Ee.join(e,"scripts","aem.js");if(!Pe(n)){t.push({rule:"scripts/aem.js exists",status:"warn",message:"Missing aem.js (or lib-franklin.js) \u2014 the EDS framework library"});return}t.push({rule:"aem.js present",status:"pass",message:"Found \u2014 remember: never modify this file",file:"scripts/aem.js"})}function Ap(e,t){let o=new RegExp(`(?:async\\s+)?function\\s+${t}\\s*\\([^)]*\\)\\s*\\{`).exec(e);if(!o)return null;let i=1,s=o.index+o[0].length,a=s;for(;s<e.length&&i>0;)e[s]==="{"?i++:e[s]==="}"&&i--,s++;return e.slice(a,s-1)}function Fp(e){let t=new Map;for(let o of e){let i=o.file||"general",s=t.get(i)??[];s.push(o),t.set(i,s)}for(let[o,i]of t){r.info(` ${J.bullet} ${di.underline(o)}`);for(let s of i){let a=s.line?di.dim(`:${s.line}`):"";r.info(` ${Gt(s.status)} ${s.rule}${a}`),s.status!=="pass"&&r.info(di.dim(` ${s.message}`))}r.info("")}let n={pass:e.filter(o=>o.status==="pass").length,warn:e.filter(o=>o.status==="warn").length,fail:e.filter(o=>o.status==="fail").length,info:e.filter(o=>o.status==="info").length};r.info(I([be(n)])),n.fail>0&&(process.exitCode=1)}var pi=k(()=>{"use strict";f();D();z();_()});var fi={};O(fi,{auditSecurity:()=>Bp});import{existsSync as Cn}from"fs";import{readFile as Dp,readdir as Lp}from"fs/promises";import He from"path";import ui from"chalk";async function*Va(e){let t=await Lp(e,{withFileTypes:!0});for(let n of t){let o=He.join(e,n.name);if(n.isDirectory()){if(Mp.has(n.name))continue;yield*Va(o)}else n.isFile()&&(yield o)}}function _p(e,t,n){let o=[],i=e.split(`
1074
- `);for(let s=0;s<i.length;s++){let a=i[s],l=!1;for(let c of Np)c.ext.includes(n)&&(c.id==="innerhtml-static"&&l||c.re.test(a)&&(c.extra&&!c.extra(a)||(c.id==="innerhtml-dynamic"&&(l=!0),o.push({severity:c.severity,rule:c.id,message:c.message,file:t,line:s+1,snippet:a.trim().slice(0,100)}))))}return o}async function Up(e){if(!Cn(He.join(e,"package.json")))return{status:"skipped",note:"no package.json"};if(!(Cn(He.join(e,"package-lock.json"))||Cn(He.join(e,"npm-shrinkwrap.json")))&&!Cn(He.join(e,"node_modules")))return{status:"skipped",note:"no package-lock.json / node_modules \u2014 run npm install"};try{let{execa:n}=await import("execa"),{stdout:o}=await n("npm",["audit","--json"],{cwd:e,reject:!1}),s=JSON.parse(o)?.metadata?.vulnerabilities??{},a={critical:s.critical??0,high:s.high??0,moderate:s.moderate??0,low:s.low??0};return{status:a.critical+a.high+a.moderate+a.low>0?"vulnerable":"ok",counts:a}}catch(n){return{status:"skipped",note:`npm audit failed: ${n.message}`}}}async function Bp(e={}){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n=[];for await(let c of Va(t)){let d=He.extname(c).slice(1).toLowerCase();if(!Ip.has(d))continue;let m=He.relative(t,c);if(m.endsWith("aem.js")||m.endsWith("lib-franklin.js"))continue;let p=await Dp(c,"utf-8");n.push(..._p(p,m,d))}let o=await Up(t),i=c=>n.filter(d=>d.severity===c),s={critical:i("critical").length,high:i("high").length,moderate:i("moderate").length,low:i("low").length},a=s.critical>0||s.high>0||(o.counts?.critical??0)>0||(o.counts?.high??0)>0;if(e.json){console.log(JSON.stringify({projectRoot:t,dependencies:o,findings:n,summary:{code:s}},null,2)),a&&(process.exitCode=1);return}if(r.logoOnce(T("Security Audit")),r.info(S("Dependencies","npm audit")),o.status==="skipped")r.info(R("info","npm audit",o.note??"skipped"));else if(o.status==="ok")r.info(R("pass","npm audit","no known vulnerabilities"));else{let c=o.counts??{critical:0,high:0,moderate:0,low:0};r.info(R(c.critical+c.high>0?"fail":"warn","npm audit",`${c.critical} critical, ${c.high} high, ${c.moderate} moderate, ${c.low} low \u2014 run \`npm audit fix\``))}if(r.info(S("Exploit scan","XSS \xB7 secrets \xB7 injection \xB7 tabnabbing")),n.length===0)r.info(R("pass","code","no risky patterns found"));else{let c=[...n].sort((d,m)=>Ka.indexOf(d.severity)-Ka.indexOf(m.severity));for(let d of c){let m=Op[d.severity],p=ui.dim(`${d.file}:${d.line}`);r.info(` ${Gt(m.status)} ${ui.bold(m.label)} ${d.message} ${p}`),r.info(ui.dim(` ${d.snippet}`))}}let l=be({fail:s.critical+s.high+(o.counts?.critical??0)+(o.counts?.high??0),warn:s.moderate+(o.counts?.moderate??0),info:s.low+(o.counts?.low??0)});r.info(""),r.info(I([l||`${J.pass} no vulnerabilities or risky patterns found`])),a&&(process.exitCode=1)}var Np,Ka,Op,Mp,Ip,gi=k(()=>{"use strict";f();D();z();_();Np=[{id:"eval",severity:"critical",re:/\beval\s*\(/,message:"eval() executes arbitrary code \u2014 prime XSS / RCE vector",ext:["js","mjs","html"]},{id:"aws-key",severity:"critical",re:/\bAKIA[0-9A-Z]{16}\b/,message:"Hardcoded AWS access key id",ext:["js","mjs","html","json"]},{id:"private-key",severity:"critical",re:/-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/,message:"Embedded private key material",ext:["js","mjs","html","json","pem","txt"]},{id:"new-function",severity:"high",re:/\bnew\s+Function\s*\(/,message:"new Function() runs strings as code",ext:["js","mjs","html"]},{id:"document-write",severity:"high",re:/document\.write(?:ln)?\s*\(/,message:"document.write() enables XSS and blocks parsing",ext:["js","mjs","html"]},{id:"innerhtml-dynamic",severity:"high",re:/\.(?:inner|outer)HTML\s*=\s*[^;\n]*(?:\$\{|\+|concat)/,message:"Dynamic innerHTML assignment \u2014 sanitize or use textContent / DOM APIs",ext:["js","mjs"]},{id:"insert-adjacent-html",severity:"high",re:/insertAdjacentHTML\s*\(/,message:"insertAdjacentHTML with untrusted data is an XSS vector",ext:["js","mjs"]},{id:"js-url",severity:"high",re:/(?:href|src)\s*=\s*["']?\s*javascript:/i,message:"javascript: URL \u2014 XSS vector",ext:["js","mjs","html"]},{id:"secret",severity:"high",re:/(?:api[_-]?key|secret|access[_-]?token|auth[_-]?token|client[_-]?secret|passwd|password)\s*[:=]\s*["'][^"']{8,}["']/i,message:"Possible hardcoded secret / credential",ext:["js","mjs","html","json"],extra:e=>!/(example|placeholder|your[-_]|changeme|xxxx|<[^>]+>|\$\{)/i.test(e)},{id:"bearer-token",severity:"high",re:/Bearer\s+[A-Za-z0-9\-._~+/]{20,}/,message:"Hardcoded bearer token",ext:["js","mjs","html","json"]},{id:"innerhtml-static",severity:"moderate",re:/\.(?:inner|outer)HTML\s*=/,message:"innerHTML assignment \u2014 confirm the content is trusted / sanitized",ext:["js","mjs"]},{id:"insecure-url",severity:"moderate",re:/(?:href|src)\s*=\s*["']http:\/\/(?!localhost|127\.0\.0\.1)/i,message:"Insecure http:// resource \u2014 mixed content, use https://",ext:["html","js","mjs"]},{id:"target-blank",severity:"moderate",re:/target\s*=\s*["']_blank["']/,message:'target="_blank" without rel="noopener" \u2014 reverse tabnabbing',ext:["html","js","mjs"],extra:e=>!/rel\s*=\s*["'][^"']*noopener/i.test(e)},{id:"postmessage-wildcard",severity:"moderate",re:/postMessage\s*\([^,]+,\s*["']\*["']\s*\)/,message:"postMessage to '*' origin \u2014 restrict the target origin",ext:["js","mjs"]},{id:"inline-handler",severity:"low",re:/\son[a-z]+\s*=\s*["']/i,message:"Inline event handler \u2014 move to addEventListener (CSP-unfriendly)",ext:["html"]},{id:"console-log",severity:"low",re:/console\.(?:log|debug)\s*\(/,message:"console.log / debug left in code \u2014 potential info leak",ext:["js","mjs"]}],Ka=["critical","high","moderate","low"],Op={critical:{status:"fail",label:"CRIT"},high:{status:"fail",label:"HIGH"},moderate:{status:"warn",label:"MOD "},low:{status:"info",label:"LOW "}},Mp=new Set(["node_modules",".git","dist","build",".vscode","coverage"]),Ip=new Set(["js","mjs","html","json","pem","txt"])});async function Xa(e,t,n){let o=t.ref||"main",i=n.startsWith("/")?n:`/${n}`,s=`${Hp}/${e}/${t.org}/${t.site}/${o}${i}`;r.debug(`POST ${s}`);let a=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json"}}),l=await a.json().catch(()=>({})),c=l;return a.ok?{ok:!0,status:a.status,path:i,previewUrl:c.preview?.url,liveUrl:c.live?.url}:{ok:!1,status:a.status,path:i,message:l.message||`HTTP ${a.status}`}}async function hi(e,t){return Xa("preview",e,t)}async function wi(e,t){return Xa("live",e,t)}async function Ya(e,t){return Promise.all(t.map(n=>hi(e,n)))}async function Qa(e,t){return Promise.all(t.map(n=>wi(e,n)))}var Hp,bi=k(()=>{"use strict";f();D();Hp="https://admin.hlx.page"});var yi={};O(yi,{preview:()=>Wp,resolveAdminConfig:()=>Tn});import Za from"chalk";import Gp from"ora";async function Wp(e,t){let n=E(),o=await pe(n),i=Tn(o,t);if(!i)return;let s=Gp(`Previewing ${e.length} path(s)...`).start(),a=e.length===1?[await hi(i,e[0])]:await Ya(i,e);s.stop();let l=!1;for(let c of a)c.ok?r.success(`${c.path} \u2192 ${Za.cyan(c.previewUrl||"preview updated")}`):(r.error(`${c.path} \u2014 ${c.message}`),l=!0);l&&(process.exitCode=1)}function Tn(e,t){let n=t.org||e.admin?.org,o=t.site||e.admin?.site,i=t.ref||e.admin?.ref||"main";if(!n||!o){r.error("Missing --org and --site. Set them via flags or in .edsrc.json:"),r.info(Za.dim(' { "admin": { "org": "my-org", "site": "my-site" } }')),process.exitCode=1;return}return{org:n,site:o,ref:i}}var Rn=k(()=>{"use strict";f();bi();xe();D();z()});var vi={};O(vi,{publish:()=>qp});import zp from"chalk";import Jp from"ora";async function qp(e,t){let n=E(),o=await pe(n),i=Tn(o,t);if(!i)return;let s=Jp(`Publishing ${e.length} path(s)...`).start(),a=e.length===1?[await wi(i,e[0])]:await Qa(i,e);s.stop();let l=!1;for(let c of a)c.ok?r.success(`${c.path} \u2192 ${zp.cyan(c.liveUrl||"published")}`):(r.error(`${c.path} \u2014 ${c.message}`),l=!0);l&&(process.exitCode=1)}var ki=k(()=>{"use strict";f();bi();xe();D();z();Rn()});var An={};O(An,{adminWizard:()=>Kp});async function Kp(e){let t=E();if(!t){r.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}r.logoOnce(T("Admin API \u2014 preview / publish"));let{select:n,input:o,confirm:i}=await Promise.resolve().then(()=>(H(),B)),a=(await pe(t)).admin??{},l=e??await n({message:"What do you want to do?",choices:[{name:"Preview pages (staging)",value:"preview"},{name:"Publish pages (go live)",value:"publish"}]}),c=(await o({message:"GitHub org / owner",default:a.org})).trim(),d=(await o({message:"Repository / site",default:a.site})).trim(),m=(await o({message:"Git ref",default:a.ref||"main"})).trim(),u=(await o({message:"Paths (space- or comma-separated)",default:"/"})).split(/[\s,]+/).filter(Boolean);if(!c||!d||u.length===0){r.error("org, site and at least one path are required."),process.exitCode=1;return}r.info(S("Summary"));let g=U(["operation","org","site","ref","paths"]);if(r.info(j("operation",l,g)),r.info(j("org",c,g)),r.info(j("site",d,g)),r.info(j("ref",m,g)),r.info(j("paths",u.join(", "),g)),r.info(""),l==="publish"&&!await i({message:`Publish ${u.length} path(s) to LIVE?`,default:!1})){r.info("Cancelled.");return}let h={org:c,site:d,ref:m};if(l==="preview"){let{preview:b}=await Promise.resolve().then(()=>(Rn(),yi));await b(u,h)}else{let{publish:b}=await Promise.resolve().then(()=>(ki(),vi));await b(u,h)}}var Fn=k(()=>{"use strict";f();xe();D();z();_()});var ec={};O(ec,{mainMenu:()=>eu});import{existsSync as Vp}from"fs";import{readdir as Xp}from"fs/promises";import Yp from"path";import Qp from"chalk";async function xi(e){let t=Yp.join(e,"blocks");return Vp(t)?(await Xp(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>o.name):[]}async function eu(){let{select:e,isEscape:t,isExit:n}=await Promise.resolve().then(()=>(H(),B));vn.menu=!0,await r.logoOnceAnimated("");let o;for(;;){r.info(Qp.dim(" Esc quits here \xB7 goes back to this menu from any step"));let i;try{i=await e({message:"Choose an action",choices:Zp,default:o})}catch(s){if(t(s)||n(s))return;throw s}if(i==="exit")return;o=i;try{await tu(i)}catch(s){if(n(s))return;t(s)||r.error(s instanceof Error?s.message:String(s))}process.exitCode=void 0,r.info("")}}async function tu(e){let{select:t,input:n}=await Promise.resolve().then(()=>(H(),B));switch(e){case"init":{let{initProject:o}=await Promise.resolve().then(()=>(an(),sn));await o({});return}case"template":{let o=await n({message:"Template name",validate:s=>!!s.trim()||"Required"}),{templateNew:i}=await Promise.resolve().then(()=>(io(),oo));await i(o.trim(),{});return}case"sandbox":{let o=await n({message:"Sandbox repo name",validate:s=>/^[a-z0-9][a-z0-9._-]*$/i.test(s.trim())||"Use a valid repo name"}),{sandboxNew:i}=await Promise.resolve().then(()=>(Ne(),Le));await i(o.trim(),{});return}case"from-design":{let{blockFromDesign:o}=await Promise.resolve().then(()=>(Yo(),Xo));await o(void 0,{});return}case"migrate":{let{migrateComponent:o}=await Promise.resolve().then(()=>(uo(),po));await o(void 0,{});return}case"scaffold":{let{scaffoldInteractive:o}=await Promise.resolve().then(()=>(me(),fe));await o();return}case"create":{let o=await n({message:"Block name",validate:s=>Re.test(s.trim())||"Use kebab-case, e.g. hero-banner"}),{createBlock:i}=await Promise.resolve().then(()=>(Co(),Eo));await i(o.trim(),{});return}case"integrate":{let{integrate:o}=await Promise.resolve().then(()=>(ri(),ii));await o(void 0);return}case"preview-block":{let o=E();if(!o){r.error("Not inside an EDS project (no EDS project markers found).");return}let i=await xi(o);if(i.length===0){r.warn("No blocks found in blocks/.");return}let s=await t({message:"Which block?",choices:i.map(l=>({name:l,value:l}))}),{previewBlock:a}=await Promise.resolve().then(()=>(Ue(),Lt));await a(s,{});return}case"model":{let{modelAdd:o}=await Promise.resolve().then(()=>(xo(),ko));await o(void 0,[],{});return}case"track":{let o=E();if(!o){r.error("Not inside an EDS project (no EDS project markers found).");return}let i=await xi(o);if(i.length===0){r.warn("No blocks found in blocks/.");return}let s=await t({message:"Which block to instrument?",choices:i.map(l=>({name:l,value:l}))}),{trackBlock:a}=await Promise.resolve().then(()=>(xt(),kt));await a(s,{});return}case"schema":{let o=E();if(!o){r.error("Not inside an EDS project (no EDS project markers found).");return}let i=await xi(o);if(i.length===0){r.warn("No blocks found in blocks/.");return}let s=await t({message:"Which block?",choices:i.map(l=>({name:l,value:l}))}),{schemaBlock:a}=await Promise.resolve().then(()=>(So(),$o));await a(s,{});return}case"ue":{if(await t({message:"Universal Editor:",choices:[{name:"Check readiness (which blocks are editable)",value:"check"},{name:"Open a page in the editor",value:"open"}]})==="check"){let{ueCheck:i}=await Promise.resolve().then(()=>(Pt(),jt));await i()}else{let i=await n({message:"Page path",default:"/"}),{ueOpen:s}=await Promise.resolve().then(()=>(Pt(),jt));await s(i.trim()||"/",{})}return}case"admin":{let{adminWizard:o}=await Promise.resolve().then(()=>(Fn(),An));await o();return}case"audit":{let o=await t({message:"Which audit?",choices:[{name:"Doctor \u2014 overall project health",value:"doctor"},{name:"Loading \u2014 three-phase / LCP budget",value:"loading"},{name:"Security \u2014 vulnerabilities & exploit patterns",value:"security"}]});if(o==="doctor"){let{doctor:i}=await Promise.resolve().then(()=>(li(),ci));await i({})}else if(o==="loading"){let{auditLoading:i}=await Promise.resolve().then(()=>(pi(),mi));await i({})}else{let{auditSecurity:i}=await Promise.resolve().then(()=>(gi(),fi));await i({})}return}case"figma-setup":{let{figmaSetup:o}=await Promise.resolve().then(()=>(ai(),si));await o();return}}}var Zp,tc=k(()=>{"use strict";f();D();z();Je();kn();Zp=[{name:"Set up project",value:"init",description:"Authoring model, CI, naming"},{name:"Page template",value:"template",description:"Generate initial content"},{name:"Sandbox repo",value:"sandbox",description:"Disposable GitHub repo"},{name:"Block from design",value:"from-design",description:"Figma, Framer or Google Stitch"},{name:"Migrate component",value:"migrate",description:"Classic AEM component \u2192 EDS"},{name:"Scaffold UE",value:"scaffold",description:"Universal Editor components"},{name:"Empty block",value:"create",description:"Create a bare block"},{name:"Integration",value:"integrate",description:"GTM, chat, consent\u2026"},{name:"Model fields",value:"model",description:"Add fields to a block model (partials)"},{name:"Analytics",value:"track",description:"Instrument a block (dataLayer)"},{name:"Structured data",value:"schema",description:"Add JSON-LD to a block"},{name:"Universal Editor",value:"ue",description:"Check readiness / open the editor"},{name:"Preview block",value:"preview-block",description:"Live preview in the browser"},{name:"Pages",value:"admin",description:"Preview / publish (Admin API)"},{name:"Audit",value:"audit",description:"Doctor / loading / security"},{name:"Figma MCP",value:"figma-setup",description:"Configure the connection"},{name:"Exit",value:"exit",description:"Quit eds (or press Esc)"}]});f();import nu from"chalk";import{Command as ou}from"commander";var Si={name:"aem-eds-kit",version:"0.4.48",description:"CLI for AEM Edge Delivery Services: blocks from Figma, Framer or Google Stitch designs, AEM component migration (AEMaaCS and 6.5), Universal Editor models and QA",type:"module",engines:{node:">=20"},bin:{eds:"dist/bin/eds.js"},files:["dist","samples","CHANGELOG.md"],scripts:{dev:"tsx src/bin/eds.ts",build:"tsup",test:"vitest run","test:watch":"vitest",lint:"biome check src/ tests/","lint:fix":"biome check --write src/ tests/",typecheck:"tsc --noEmit",prepare:"git config core.hooksPath .githooks || true",prepublishOnly:"npm run build"},keywords:["aem","edge-delivery-services","helix","figma","mcp","cli","adobe","aem-edge-delivery","universal-editor","aemaacs","aem-migration","framer","google-stitch","design-to-code","claude-code"],author:"Piotr Godycki <piotrgodycki@yahoo.com>",license:"MIT",repository:{type:"git",url:"git+https://github.com/piotrgodycki/aem-eds-kit.git"},homepage:"https://piotrgodycki.github.io/aem-eds-kit/",bugs:{url:"https://github.com/piotrgodycki/aem-eds-kit/issues"},dependencies:{"@inquirer/prompts":"^7.0.0",chalk:"^5.4.0",commander:"^13.0.0",execa:"^9.5.0","fast-xml-parser":"^5.11.2",ora:"^8.1.0",yaml:"^2.6.0",zod:"^3.24.0"},devDependencies:{"@biomejs/biome":"^1.9.0","@types/node":"^22.0.0",tsup:"^8.3.0",tsx:"^4.19.0",typescript:"^5.7.0",vitest:"^2.1.0"},optionalDependencies:{"@modelcontextprotocol/sdk":"^1.29.0",pixelmatch:"^6.0.0",playwright:"^1.64.0",pngjs:"^7.0.0"}};D();_();var G=new ou;G.name("eds").description("CLI for AEM Edge Delivery Services with Figma integration").version(Si.version).option("--verbose","Enable verbose output").option("--quiet","Suppress non-error output").option("--json","Output in JSON format").option("--no-color","Disable color output").showHelpAfterError("(add --help for usage)").hook("preAction",e=>{let t=e.opts();t.verbose&&r.setLevel("debug"),t.quiet&&r.setQuiet(!0),t.color===!1&&(nu.level=0)});G.addHelpText("beforeAll",()=>T());var Ut=G.command("sandbox").description("Disposable EDS sandbox repos on GitHub");Ut.command("new <name>").description("Create a disposable EDS repo from a boilerplate (GitHub auth, no gh required)").option("--org <org>","Create under a GitHub org (else your account)").option("--boilerplate <repo>","Template repo (default adobe/aem-boilerplate)").option("--ue","Use the crosswalk / Universal Editor boilerplate").option("--private","Create a private repo").option("--yes","Skip the guided prompts (use flags/defaults)").action(async(e,t)=>{let{sandboxNew:n}=await Promise.resolve().then(()=>(Ne(),Le));await n(e,t)});Ut.command("login").description("Authorize GitHub (OAuth device flow or a token) - no gh needed").action(async()=>{let{sandboxLogin:e}=await Promise.resolve().then(()=>(Ne(),Le));await e()});Ut.command("logout").description("Remove the stored GitHub token").action(async()=>{let{sandboxLogout:e}=await Promise.resolve().then(()=>(Ne(),Le));await e()});Ut.command("list").description("List your EDS sandboxes (repos tagged eds-sandbox)").action(async()=>{let{sandboxList:e}=await Promise.resolve().then(()=>(Ne(),Le));await e()});Ut.command("rm <name>").description("Delete a sandbox repo (destructive)").option("--org <org>","Owner org (else your account)").option("--yes","Skip the confirmation").action(async(e,t)=>{let{sandboxRm:n}=await Promise.resolve().then(()=>(Ne(),Le));await n(e,t)});var iu=G.command("template").description("Generate page templates / initial content");iu.command("new <name>").description("Generate EDS page initial content (sections + blocks + metadata), DA push optional").option("--path <path>","Content path (default: /templates/<name>)").option("--title <title>","Page title").option("--description <text>","Page description").option("--blocks <list>","Comma-separated block ids to seed",e=>e.split(",").map(t=>t.trim())).option("--area <area>","Site area / template label (stored in metadata)").option("--authoring <model>","Force authoring model: da | gdrive | sharepoint | ue").option("--push","Push the page to DA (da.live)").option("--org <org>","DA org (else from .edsrc.json)").option("--site <site>","DA site (else from .edsrc.json)").option("--yes","Skip prompts").action(async(e,t)=>{let{templateNew:n}=await Promise.resolve().then(()=>(io(),oo));await n(e,t)});G.command("init").description("Set up a freshly cloned EDS boilerplate for your authoring model (interactive)").option("--name <name>","Project name (kebab-case)").option("--authoring <model>","Authoring model: ue | da | gdrive | sharepoint").option("--mountpoint <url>","Content source URL (document models)").option("--org <org>","DA org (authoring=da)").option("--site <site>","DA site (authoring=da)").option("--no-ci","Skip the GitHub Actions CI workflow").option("--no-env","Skip the local-dev .env (aem up config)").option("--no-xwalk","Skip xwalk.json (UE multi-field)").option("--yes","Skip prompts; apply with flags/defaults").action(async e=>{let{initProject:t}=await Promise.resolve().then(()=>(an(),sn));await t(e)});var ru=G.command("migrate").description("Migrate from classic AEM to EDS");ru.command("component [dir]").description("Migrate a classic AEM component's dialog into an EDS block + UE model").option("--name <name>","Block name (otherwise inferred from the component)").option("--clientlib <dir>","Path to the component's clientlib (otherwise auto-detected)").option("--super-root <dirs>","jcr_root folder(s), comma-separated, holding a proxy component's super type (e.g. a Core Components checkout)").option("--yes","Skip confirmation prompts").action(async(e,t)=>{let{migrateComponent:n}=await Promise.resolve().then(()=>(uo(),po));await n(e,t)});var su=G.command("model").description("Compose Universal Editor models");su.command("add <block> [partials...]").description("Add reusable field groups (partials) to a block's UE model").option("--yes","Skip prompts").action(async(e,t,n)=>{let{modelAdd:o}=await Promise.resolve().then(()=>(xo(),ko));await o(e,t,n)});var au=G.command("schema").description("Structured data (JSON-LD) for blocks");au.command("block <name>").description("Inject a JSON-LD (schema.org) builder into a block's decorate()").option("--type <type>","schema.org type (Article, FAQPage, Product, ...)").option("--yes","Skip prompts").action(async(e,t)=>{let{schemaBlock:n}=await Promise.resolve().then(()=>(So(),$o));await n(e,t)});var cu=G.command("track").description("Instrument blocks for analytics");cu.command("block <name>").description("Add dataLayer tracking (click + form submit) to a block's decorate()").option("--no-click","Skip click tracking").option("--no-submit","Skip form-submit tracking").action(async(e,t)=>{let{trackBlock:n}=await Promise.resolve().then(()=>(xt(),kt));await n(e,t)});var nc=G.command("ue").description("Universal Editor - readiness check + editor deep link");nc.command("check").description("Check whether blocks are Universal-Editor-ready (offline)").action(async()=>{let{ueCheck:e}=await Promise.resolve().then(()=>(Pt(),jt));await e()});nc.command("open [path]").description("Open a page in the hosted Universal Editor (preview host from git)").option("--org <slug>","IMS org slug (skips the org picker)").option("--ref <branch>","Branch/ref for the preview host (default: main)").option("--url <host>","Override the delivery host (e.g. main--repo--owner.aem.page)").option("--no-open","Print the link without opening the browser").action(async(e,t)=>{let{ueOpen:n}=await Promise.resolve().then(()=>(Pt(),jt));await n(e,t)});var rt=G.command("block").description("Manage EDS blocks");rt.command("create <name>").description("Scaffold a new EDS block (with Universal Editor model by default)").option("--no-ue-model","Skip the Universal Editor model (generated by default)").action(async(e,t)=>{let{createBlock:n}=await Promise.resolve().then(()=>(Co(),Eo));await n(e,t)});rt.command("from-design [design]").description("Generate an EDS block from a design: a Figma URL, a Framer/Stitch page (scraped with headless Chromium), or a local SVG/PNG export (quota-free, no MCP). Interactive wizard when run with no argument.").option("--name <name>","Override the inferred block name").option("--provider <type>","Design source: figma | framer | stitch (else detected from the URL)").option("--agent <type>","Force agent type (claude|cursor|codex|none)").option("--dry-run","Generate prompt only, do not invoke agent").option("--source <type>","Content source: document|ue|cf|mixed (default: document)").option("--widths <list>","Design frame widths for preview breakpoints (e.g. 390,768,1440)").option("--no-ue-model","Skip the Universal Editor model (generated by default)").option("--screenshot","Add a screenshot MCP call for pixel verification (opt-in; costs a call)").option("--mcp","Force the Figma MCP adapter even when a REST token is set").option("--refresh","Ignore the cached design snapshot and re-fetch").option("--auth","Scrape with a logged-in session (Framer/Stitch) \u2014 login captured once, then reused").option("--auth-refresh","Force a fresh scrape login even if a session is saved").option("--sample","Use the bundled sample design (Kiri Bloom hero) \u2014 no URL, no token, no MCP").option("--serve","Auto-start the live preview after generating (non-interactive runs only)").option("--yes","Skip confirmation prompts").action(async(e,t)=>{let{blockFromDesign:n}=await Promise.resolve().then(()=>(Yo(),Xo));await n(e,t)});rt.command("list").description("List all blocks in the project").action(async e=>{let{listBlocks:t}=await Promise.resolve().then(()=>($a(),xa));await t({...e,json:G.opts().json})});rt.command("preview [name]").description("Serve a live, breakpoint-switchable preview of a block \u2014 or a gallery of all blocks when no name is given").option("--port <port>","Port to serve on (default: 8777, falls back if taken)").option("--widths <list>","Comma-separated breakpoint widths (e.g. 375,768,1280)").option("--no-open","Do not open the browser automatically").action(async(e,t)=>{let n=await Promise.resolve().then(()=>(Ue(),Lt));e?await n.previewBlock(e,t):await n.galleryPreview(t)});rt.command("test [name]").description("Visual-regression test a block (or all blocks) against committed baselines").option("--update","(Re)write the baseline screenshots instead of comparing").option("--threshold <ratio>","Max changed-pixel ratio before failing (default 0.01 = 1%)").option("--design","Compare the rendered block against its Figma design image (needs a token)").option("--widths <list>","Comma-separated breakpoint widths (e.g. 375,768,1280)").option("--port <port>","Port for the internal preview server (default: 8788)").action(async(e,t)=>{let{visualTest:n}=await Promise.resolve().then(()=>(Oa(),Na));await n(e,t)});rt.command("check [name]").description("Content, link and a11y check on a block's rendered DOM (or all blocks)").option("--strict","Fail on warnings too, not just errors").option("--widths <list>","Comma-separated breakpoint widths (uses the widest)").option("--port <port>","Port for the internal preview server (default: 8789)").action(async(e,t)=>{let{blockCheck:n}=await Promise.resolve().then(()=>(Ua(),_a));await n(e,t)});var st=G.command("scaffold").description("Scaffold standard UE components and blocks").action(async()=>{let{scaffoldInteractive:e}=await Promise.resolve().then(()=>(me(),fe));await e()});st.command("ue").description("Scaffold default-content UE components + a field-reference block (all 17 fields)").action(async()=>{let{scaffoldUe:e}=await Promise.resolve().then(()=>(me(),fe));await e()});st.command("blocks [names...]").description("Scaffold standard blocks (hero, cards, columns, accordion, embed) with UE models").action(async e=>{let{scaffoldBlocks:t}=await Promise.resolve().then(()=>(me(),fe));await t(e)});st.command("ci").description("Scaffold a GitHub Actions workflow (doctor + audits + project lint/build)").action(async()=>{let{scaffoldCi:e}=await Promise.resolve().then(()=>(me(),fe));await e()});st.command("helpers [names...]").description("Scaffold scripts/utils.js with chosen EDS helpers (interactive picker)").action(async e=>{let{scaffoldHelpers:t}=await Promise.resolve().then(()=>(me(),fe));await t(e)});st.command("env").description("Write a local-dev .env for `aem up` (AEM_OPEN / AEM_PORT / AEM_PAGES_URL)").option("--open <path>","AEM_OPEN - path opened on start (default: /)").option("--port <port>","AEM_PORT - proxy port (default: 3007)").option("--pages-url <url>","AEM_PAGES_URL - content origin (default: from git remote)").option("--yes","Skip prompts; use flags/defaults").action(async e=>{let{scaffoldEnv:t}=await Promise.resolve().then(()=>(me(),fe));await t(e)});st.command("xwalk").description("Write xwalk.json enabling Universal Editor multi-field support").action(async()=>{let{scaffoldXwalk:e}=await Promise.resolve().then(()=>(me(),fe));await e()});G.command("integrate [type]").description("Add a third-party service (GTM, GA4, chat, consent) to scripts/delayed.js").action(async e=>{let{integrate:t}=await Promise.resolve().then(()=>(ri(),ii));await t(e)});var lu=G.command("figma").description("Figma MCP integration");lu.command("setup").description("Configure Figma MCP for your AI agent").action(async()=>{let{figmaSetup:e}=await Promise.resolve().then(()=>(ai(),si));await e()});G.command("doctor").description("Audit your EDS project for common issues").action(async()=>{let{doctor:e}=await Promise.resolve().then(()=>(li(),ci));await e({json:G.opts().json})});var oc=G.command("audit").description("Run project audits");oc.command("loading").description("Check loading order (eager/lazy/delayed phases, LCP budget)").action(async()=>{let{auditLoading:e}=await Promise.resolve().then(()=>(pi(),mi));await e({json:G.opts().json})});oc.command("security").description("Scan for vulnerabilities (npm audit) and exploit patterns (XSS, secrets, tabnabbing)").action(async()=>{let{auditSecurity:e}=await Promise.resolve().then(()=>(gi(),fi));await e({json:G.opts().json})});G.command("preview [paths...]").description("Preview pages via Admin API (interactive wizard when run with no paths)").option("--org <org>","GitHub org/owner").option("--site <site>","Repository name").option("--ref <ref>","Git ref (default: main)").action(async(e,t)=>{if(!e||e.length===0){let{adminWizard:o}=await Promise.resolve().then(()=>(Fn(),An));await o("preview");return}let{preview:n}=await Promise.resolve().then(()=>(Rn(),yi));await n(e,t)});G.command("publish [paths...]").description("Publish pages to live via Admin API (interactive wizard when run with no paths)").option("--org <org>","GitHub org/owner").option("--site <site>","Repository name").option("--ref <ref>","Git ref (default: main)").action(async(e,t)=>{if(!e||e.length===0){let{adminWizard:o}=await Promise.resolve().then(()=>(Fn(),An));await o("publish");return}let{publish:n}=await Promise.resolve().then(()=>(ki(),vi));await n(e,t)});(async()=>{try{if(process.argv.slice(2).length===0)if(process.stdout.isTTY){let{mainMenu:e}=await Promise.resolve().then(()=>(tc(),ec));await e()}else G.outputHelp();else await G.parseAsync()}catch(e){r.error(e instanceof Error?e.message:String(e)),process.exitCode=1}})();
1101
+ `});var Si={};M(Si,{figmaSetup:()=>hu});import{existsSync as uu}from"fs";import{mkdir as fu,writeFile as gu}from"fs/promises";import pe from"chalk";async function hu(){let{select:e,confirm:t}=await Promise.resolve().then(()=>(G(),H));a.logoOnce(A()),a.info(j("Figma MCP Setup Wizard")),a.info("Detecting installed AI agents...");let n=await Pn(),o;if(n.length===0?(a.warn("No AI agents found (claude, cursor, codex)."),a.info(`Install Claude Code: ${pe.cyan("npm install -g @anthropic-ai/claude-code")}`),o="none"):(a.success(`Found: ${n.map(r=>pe.cyan(r.type)).join(", ")}`),o=await e({message:"Which agent do you want to use with eds-cli?",choices:[...n.map(r=>({name:`${r.type}${r.hasFigmaMcp?pe.green(" (Figma MCP detected)"):""}`,value:r.type})),{name:"None (manual mode)",value:"none"}]})),o!=="none"){let r=n.find(s=>s.type===o);if(r&&!r.hasFigmaMcp){switch(a.warn(`Figma MCP is not configured for ${o}.
1102
+ `),a.info(`Install it with one of these methods:
1103
+ `),o){case"claude":a.info(` ${pe.cyan("claude mcp add --transport sse figma-sse https://mcp.figma.com/sse")}`),a.info(" or for Figma Desktop app:"),a.info(` ${pe.cyan("claude mcp add --transport http figma-desktop http://127.0.0.1:3845/mcp")}`);break;case"cursor":a.info(` Add to ${pe.cyan("~/.cursor/mcp.json")}:`),a.info(pe.dim(JSON.stringify({mcpServers:{figma:{url:"https://mcp.figma.com/sse"}}},null,2)));break;case"codex":a.info(" See Figma MCP docs: https://help.figma.com/hc/en-us/articles/32132100833559");break}a.info("")}else r?.hasFigmaMcp&&a.success(`Figma MCP is already configured for ${o}!`)}if(a.info(pe.dim(`
1104
+ Note: Figma MCP requires a Figma seat (Dev or Full on paid plans for desktop server).`)),await t({message:"Save preferences to ~/.eds/config.json?",default:!0})){let r=ns();uu(r)||await fu(r,{recursive:!0});let s={};o!=="none"&&(s.agent=o),await gu(zo(),`${JSON.stringify(s,null,2)}
1105
+ `,{mode:384}),a.success(`Config saved to ${pe.cyan(zo())}`)}a.info(pe.bold(`
1106
+ Setup complete!`)),o!=="none"&&a.info(`Try: ${pe.cyan('eds block from-design "<figma-url>" --dry-run')}`)}var ji=v(()=>{"use strict";f();Zo();ye();D();U()});var Pi={};M(Pi,{doctor:()=>bu});import{existsSync as Jt}from"fs";import{readFile as qt,readdir as wu}from"fs/promises";import Ke from"path";import{parse as Rc}from"yaml";async function bu(e={}){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n=ar(t);e.json||(a.logoOnce(A("Doctor")),a.info(j("Doctor",t)));let o=[];if(o.push({name:"fstab.yaml exists",status:n.hasFstab?"pass":"warn",message:n.hasFstab?"Found":"Missing - fine for Universal Editor / DA; required for document-mounted setups"}),n.hasFstab)try{let p=await qt(Ke.join(t,"fstab.yaml"),"utf-8");Rc(p),o.push({name:"fstab.yaml valid YAML",status:"pass",message:"Valid"})}catch{o.push({name:"fstab.yaml valid YAML",status:"fail",message:"Invalid YAML syntax"})}if(o.push({name:"head.html exists",status:n.hasHeadHtml?"pass":"warn",message:n.hasHeadHtml?"Found":"Missing - recommended for metadata/scripts"}),o.push({name:"blocks/ directory",status:n.hasBlocks?"pass":"warn",message:n.hasBlocks?"Found":"Missing - no blocks yet"}),n.hasBlocks){let p=Ke.join(t,"blocks"),u=await wu(p,{withFileTypes:!0}),g="",h=Ke.join(t,"component-models.json");if(Jt(h))try{g=await qt(h,"utf-8")}catch{}for(let $ of u){if(!$.isDirectory())continue;let b=$.name,y=Ke.join(p,b,`${b}.js`),w=Jt(y);o.push({name:`blocks/${b} has JS`,status:w?"pass":"warn",message:w?"Found":`Missing ${b}.js`}),w&&(await qt(y,"utf-8")).includes("console.log")&&o.push({name:`blocks/${b} no console.log`,status:"warn",message:"Found console.log - remove before production"});let T=Jt(Ke.join(p,b,`_${b}.json`)),K=g.includes(`"${b}"`);o.push({name:`blocks/${b} UE model`,status:T||K?"pass":"warn",message:T||K?T?`_${b}.json`:"in component-models.json":"no Universal Editor model - authors can't edit this block in UE"});let q=Ke.join(p,b,".eds-meta.json");if(Jt(q))try{let he=JSON.parse(await qt(q,"utf-8")),De=new Date(he.lastSyncedAt),L=Math.floor((Date.now()-De.getTime())/(1e3*60*60*24));o.push({name:`blocks/${b} Figma sync`,status:L>30?"warn":"pass",message:L>30?`Last synced ${L} days ago - design may have changed`:`Synced ${L} days ago`})}catch{o.push({name:`blocks/${b} .eds-meta.json`,status:"warn",message:"Invalid metadata file"})}}}let i=Ke.join(t,"helix-query.yaml");if(Jt(i))try{let p=await qt(i,"utf-8");Rc(p),o.push({name:"helix-query.yaml valid",status:"pass",message:"Valid YAML"})}catch{o.push({name:"helix-query.yaml valid",status:"fail",message:"Invalid YAML syntax"})}o.push({name:"~/.eds/config.json",status:Jo()?"pass":"warn",message:Jo()?"Found":'Missing - run "eds figma setup" to configure'});let r=o.filter(p=>p.status==="fail"),s=o.filter(p=>p.status==="warn");if(e.json){let p={pass:o.filter(u=>u.status==="pass").length,warn:s.length,fail:r.length};console.log(JSON.stringify({projectRoot:t,results:o,summary:p},null,2)),r.length>0&&(process.exitCode=1);return}let l=I(o.map(p=>p.name));for(let p of o)a.info(R(p.status,p.name,p.message,l));let c=o.filter(p=>p.status==="fail"),d=o.filter(p=>p.status==="warn"),m=o.filter(p=>p.status==="pass");a.info(""),a.info(B([$e({pass:m.length,warn:d.length,fail:c.length})])),c.length>0&&(process.exitCode=1)}var Ei=v(()=>{"use strict";f();ye();D();J();U()});var Ti={};M(Ti,{auditLoading:()=>vu});import{existsSync as Fe}from"fs";import{readFile as pt,readdir as yu,stat as Fc}from"fs/promises";import Le from"path";import Ci from"chalk";async function vu(e={}){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}e.json||(a.logoOnce(A("Loading Audit")),a.info(j("Loading Order Audit",t)));let n=[];if(await ku(t,n),await xu(t,n),await $u(t,n),await Su(t,n),await ju(t,n),await Pu(t,n),e.json){let o={pass:n.filter(i=>i.status==="pass").length,warn:n.filter(i=>i.status==="warn").length,fail:n.filter(i=>i.status==="fail").length,info:n.filter(i=>i.status==="info").length};console.log(JSON.stringify({projectRoot:t,results:n,summary:o},null,2)),o.fail>0&&(process.exitCode=1);return}Cu(n)}async function ku(e,t){let n=Le.join(e,"head.html");if(!Fe(n)){t.push({rule:"head.html exists",status:"warn",message:"Missing head.html"});return}let o=await pt(n,"utf-8"),i=o.split(`
1107
+ `);for(let c=0;c<i.length;c++){let d=i[c];/<script\b/i.test(d)&&!/type\s*=\s*["']module["']/i.test(d)&&!/<\/script>/.test(d)&&t.push({rule:"No render-blocking scripts in head.html",status:"fail",message:'Script without type="module" blocks rendering',file:"head.html",line:c+1})}let s=(o.match(/<link[^>]+rel=["']stylesheet["'][^>]*>/gi)||[]).filter(c=>!c.includes("styles/styles.css")&&!c.includes("styles.css"));s.length>0&&t.push({rule:"No extra stylesheets in head.html",status:"warn",message:`${s.length} extra stylesheet(s) \u2014 each competes with LCP budget`,file:"head.html"}),/<link[^>]+rel=["'](preload|preconnect)["']/i.test(o)&&t.push({rule:"No preload/preconnect in head.html",status:"warn",message:"preload/preconnect can hurt EDS LCP \u2014 resources compete with the 100KB budget",file:"head.html"}),/<script\b[^>]*>[\s\S]*?[^\s<][\s\S]*?<\/script>/i.test(o)&&t.push({rule:"No inline scripts in head.html",status:"warn",message:"Inline scripts block rendering \u2014 move to delayed.js",file:"head.html"});let l=/(?:src|href)=["'](https?:\/\/(?!(?:localhost|127\.0\.0\.1))[^"']+)["']/gi;for(let c of o.matchAll(l)){let d=c[1];d.includes("fonts.googleapis.com")||t.push({rule:"No third-party resources in head.html",status:"warn",message:`Third-party resource: ${d} \u2014 move to delayed.js`,file:"head.html"})}/<link[^>]+as=["']font["']/i.test(o)&&t.push({rule:"No font preloads in head.html",status:"warn",message:"Font preloads consume LCP bandwidth budget \u2014 let loadFonts() handle them",file:"head.html"}),t.some(c=>c.file==="head.html")||t.push({rule:"head.html is clean",status:"pass",message:"No render-blocking issues found",file:"head.html"})}async function xu(e,t){let n=Le.join(e,"scripts","scripts.js");if(!Fe(n)){t.push({rule:"scripts/scripts.js exists",status:"warn",message:"Missing scripts.js \u2014 cannot audit loading phases"});return}let o=await pt(n,"utf-8"),i=o.split(`
1108
+ `),r=/function\s+loadEager|loadEager\s*=/i.test(o),s=/function\s+loadLazy|loadLazy\s*=/i.test(o),l=/function\s+loadDelayed|loadDelayed\s*=/i.test(o);t.push({rule:"loadEager phase exists",status:r?"pass":"fail",message:r?"Found":"Missing loadEager \u2014 LCP optimization depends on it",file:"scripts/scripts.js"}),t.push({rule:"loadLazy phase exists",status:s?"pass":"fail",message:s?"Found":"Missing loadLazy \u2014 below-fold content won't load properly",file:"scripts/scripts.js"}),t.push({rule:"loadDelayed phase exists",status:l?"pass":"warn",message:l?"Found":"Missing loadDelayed \u2014 third-party scripts may block LCP",file:"scripts/scripts.js"});let c=o.match(/setTimeout\s*\([^,]+,\s*(\d+)\s*\)/);if(l&&c){let d=Number.parseInt(c[1],10);d<3e3?t.push({rule:"Delayed phase waits >= 3s",status:"warn",message:`delayed.js loads after ${d}ms \u2014 should be >= 3000ms for LCP safety`,file:"scripts/scripts.js"}):t.push({rule:"Delayed phase waits >= 3s",status:"pass",message:`${d}ms delay before loading delayed.js`,file:"scripts/scripts.js"})}if(r){let d=o.match(/loadEager[\s\S]*?(?=function\s|const\s+load|$)/)?.[0]||"";/loadSections\s*\(/.test(d)&&t.push({rule:"loadEager loads only first section",status:"fail",message:"loadEager calls loadSections() \u2014 should only load first section for fast LCP",file:"scripts/scripts.js"})}for(let d=0;d<i.length;d++){let m=i[d];/import\s.*from\s+['"]https?:\/\//i.test(m)&&t.push({rule:"No third-party imports at top level",status:"warn",message:`Third-party import at line ${d+1} \u2014 move to delayed.js if not critical`,file:"scripts/scripts.js",line:d+1})}if(r){let d=Eu(o,"loadEager");d&&/loadHeader|loadFooter/.test(d)&&t.push({rule:"Header/footer not in loadEager",status:"warn",message:"Header/footer in loadEager delays LCP \u2014 move to loadLazy",file:"scripts/scripts.js"})}}async function $u(e,t){let n=Le.join(e,"styles","styles.css");if(!Fe(n))return;let i=(await Fc(n)).size/1024;t.push({rule:"styles.css size within LCP budget",status:i>40?"warn":"pass",message:`${i.toFixed(1)} KB${i>40?" \u2014 large CSS competes with 100KB LCP budget":""}`,file:"styles/styles.css"});let r=await pt(n,"utf-8");/@import\s/.test(r)&&t.push({rule:"No @import in styles.css",status:"warn",message:"@import creates a request chain \u2014 inline the CSS or use lazy-styles.css",file:"styles/styles.css"})}async function Su(e,t){let n=Le.join(e,"scripts","delayed.js");if(!Fe(n)){t.push({rule:"scripts/delayed.js exists",status:"info",message:"No delayed.js \u2014 third-party scripts should go here"});return}(await pt(n,"utf-8")).replace(/\/\/.*$/gm,"").replace(/\/\*[\s\S]*?\*\//g,"").trim()||t.push({rule:"delayed.js has content",status:"info",message:"delayed.js is empty \u2014 add analytics/martech here",file:"scripts/delayed.js"})}async function ju(e,t){let n=Le.join(e,"blocks");if(!Fe(n))return;let o=await yu(n,{withFileTypes:!0});for(let i of o){if(!i.isDirectory())continue;let r=i.name,s=Le.join(n,r,`${r}.js`);if(!Fe(s))continue;let l=await pt(s,"utf-8"),c=l.split(`
1109
+ `),d=["jquery","lodash","moment","rxjs","d3","three","gsap","anime","chart.js","swiper"];for(let u=0;u<c.length;u++){let g=c[u].toLowerCase();for(let h of d)g.includes("from")&&g.includes(h)&&/import\s/.test(g)&&t.push({rule:"No heavy imports in blocks",status:"warn",message:`Imports "${h}" \u2014 heavy library delays section loading`,file:`blocks/${r}/${r}.js`,line:u+1})}/document\.write/i.test(l)&&t.push({rule:"No document.write in blocks",status:"fail",message:"document.write blocks parsing and can break the page",file:`blocks/${r}/${r}.js`});let p=(await Fc(s)).size/1024;p>20&&t.push({rule:"Block JS size reasonable",status:"warn",message:`${p.toFixed(1)} KB \u2014 consider splitting or lazy-loading parts`,file:`blocks/${r}/${r}.js`})}for(let i of o){if(!i.isDirectory())continue;let r=i.name,s=Le.join(n,r,`${r}.css`);if(!Fe(s))continue;let l=await pt(s,"utf-8"),c=/^([a-z][a-z0-9-]*)\s*\{/gm;for(let d of l.matchAll(c)){let m=d[1];["body","html","main"].includes(m)||t.push({rule:"Block CSS is scoped",status:"warn",message:`Bare element selector "${m}" \u2014 may leak styles and cause CLS. Use .${r} prefix`,file:`blocks/${r}/${r}.css`})}}}async function Pu(e,t){let n=Le.join(e,"scripts","aem.js");if(!Fe(n)){t.push({rule:"scripts/aem.js exists",status:"warn",message:"Missing aem.js (or lib-franklin.js) \u2014 the EDS framework library"});return}t.push({rule:"aem.js present",status:"pass",message:"Found \u2014 remember: never modify this file",file:"scripts/aem.js"})}function Eu(e,t){let o=new RegExp(`(?:async\\s+)?function\\s+${t}\\s*\\([^)]*\\)\\s*\\{`).exec(e);if(!o)return null;let i=1,r=o.index+o[0].length,s=r;for(;r<e.length&&i>0;)e[r]==="{"?i++:e[r]==="}"&&i--,r++;return e.slice(s,r-1)}function Cu(e){let t=new Map;for(let o of e){let i=o.file||"general",r=t.get(i)??[];r.push(o),t.set(i,r)}for(let[o,i]of t){a.info(` ${X.bullet} ${Ci.underline(o)}`);for(let r of i){let s=r.line?Ci.dim(`:${r.line}`):"";a.info(` ${Vt(r.status)} ${r.rule}${s}`),r.status!=="pass"&&a.info(Ci.dim(` ${r.message}`))}a.info("")}let n={pass:e.filter(o=>o.status==="pass").length,warn:e.filter(o=>o.status==="warn").length,fail:e.filter(o=>o.status==="fail").length,info:e.filter(o=>o.status==="info").length};a.info(B([$e(n)])),n.fail>0&&(process.exitCode=1)}var Ai=v(()=>{"use strict";f();D();J();U()});var Fi={};M(Fi,{auditSecurity:()=>Mu});import{existsSync as In}from"fs";import{readFile as Tu,readdir as Au}from"fs/promises";import Xe from"path";import Ri from"chalk";async function*Dc(e){let t=await Au(e,{withFileTypes:!0});for(let n of t){let o=Xe.join(e,n.name);if(n.isDirectory()){if(Lu.has(n.name))continue;yield*Dc(o)}else n.isFile()&&(yield o)}}function Ou(e,t,n){let o=[],i=e.split(`
1110
+ `);for(let r=0;r<i.length;r++){let s=i[r],l=!1;for(let c of Ru)c.ext.includes(n)&&(c.id==="innerhtml-static"&&l||c.re.test(s)&&(c.extra&&!c.extra(s)||(c.id==="innerhtml-dynamic"&&(l=!0),o.push({severity:c.severity,rule:c.id,message:c.message,file:t,line:r+1,snippet:s.trim().slice(0,100)}))))}return o}async function Nu(e){if(!In(Xe.join(e,"package.json")))return{status:"skipped",note:"no package.json"};if(!(In(Xe.join(e,"package-lock.json"))||In(Xe.join(e,"npm-shrinkwrap.json")))&&!In(Xe.join(e,"node_modules")))return{status:"skipped",note:"no package-lock.json / node_modules \u2014 run npm install"};try{let{execa:n}=await import("execa"),{stdout:o}=await n("npm",["audit","--json"],{cwd:e,reject:!1}),r=JSON.parse(o)?.metadata?.vulnerabilities??{},s={critical:r.critical??0,high:r.high??0,moderate:r.moderate??0,low:r.low??0};return{status:s.critical+s.high+s.moderate+s.low>0?"vulnerable":"ok",counts:s}}catch(n){return{status:"skipped",note:`npm audit failed: ${n.message}`}}}async function Mu(e={}){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}let n=[];for await(let c of Dc(t)){let d=Xe.extname(c).slice(1).toLowerCase();if(!Du.has(d))continue;let m=Xe.relative(t,c);if(m.endsWith("aem.js")||m.endsWith("lib-franklin.js"))continue;let p=await Tu(c,"utf-8");n.push(...Ou(p,m,d))}let o=await Nu(t),i=c=>n.filter(d=>d.severity===c),r={critical:i("critical").length,high:i("high").length,moderate:i("moderate").length,low:i("low").length},s=r.critical>0||r.high>0||(o.counts?.critical??0)>0||(o.counts?.high??0)>0;if(e.json){console.log(JSON.stringify({projectRoot:t,dependencies:o,findings:n,summary:{code:r}},null,2)),s&&(process.exitCode=1);return}if(a.logoOnce(A("Security Audit")),a.info(j("Dependencies","npm audit")),o.status==="skipped")a.info(R("info","npm audit",o.note??"skipped"));else if(o.status==="ok")a.info(R("pass","npm audit","no known vulnerabilities"));else{let c=o.counts??{critical:0,high:0,moderate:0,low:0};a.info(R(c.critical+c.high>0?"fail":"warn","npm audit",`${c.critical} critical, ${c.high} high, ${c.moderate} moderate, ${c.low} low \u2014 run \`npm audit fix\``))}if(a.info(j("Exploit scan","XSS \xB7 secrets \xB7 injection \xB7 tabnabbing")),n.length===0)a.info(R("pass","code","no risky patterns found"));else{let c=[...n].sort((d,m)=>Lc.indexOf(d.severity)-Lc.indexOf(m.severity));for(let d of c){let m=Fu[d.severity],p=Ri.dim(`${d.file}:${d.line}`);a.info(` ${Vt(m.status)} ${Ri.bold(m.label)} ${d.message} ${p}`),a.info(Ri.dim(` ${d.snippet}`))}}let l=$e({fail:r.critical+r.high+(o.counts?.critical??0)+(o.counts?.high??0),warn:r.moderate+(o.counts?.moderate??0),info:r.low+(o.counts?.low??0)});a.info(""),a.info(B([l||`${X.pass} no vulnerabilities or risky patterns found`])),s&&(process.exitCode=1)}var Ru,Lc,Fu,Lu,Du,Li=v(()=>{"use strict";f();D();J();U();Ru=[{id:"eval",severity:"critical",re:/\beval\s*\(/,message:"eval() executes arbitrary code \u2014 prime XSS / RCE vector",ext:["js","mjs","html"]},{id:"aws-key",severity:"critical",re:/\bAKIA[0-9A-Z]{16}\b/,message:"Hardcoded AWS access key id",ext:["js","mjs","html","json"]},{id:"private-key",severity:"critical",re:/-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----/,message:"Embedded private key material",ext:["js","mjs","html","json","pem","txt"]},{id:"new-function",severity:"high",re:/\bnew\s+Function\s*\(/,message:"new Function() runs strings as code",ext:["js","mjs","html"]},{id:"document-write",severity:"high",re:/document\.write(?:ln)?\s*\(/,message:"document.write() enables XSS and blocks parsing",ext:["js","mjs","html"]},{id:"innerhtml-dynamic",severity:"high",re:/\.(?:inner|outer)HTML\s*=\s*[^;\n]*(?:\$\{|\+|concat)/,message:"Dynamic innerHTML assignment \u2014 sanitize or use textContent / DOM APIs",ext:["js","mjs"]},{id:"insert-adjacent-html",severity:"high",re:/insertAdjacentHTML\s*\(/,message:"insertAdjacentHTML with untrusted data is an XSS vector",ext:["js","mjs"]},{id:"js-url",severity:"high",re:/(?:href|src)\s*=\s*["']?\s*javascript:/i,message:"javascript: URL \u2014 XSS vector",ext:["js","mjs","html"]},{id:"secret",severity:"high",re:/(?:api[_-]?key|secret|access[_-]?token|auth[_-]?token|client[_-]?secret|passwd|password)\s*[:=]\s*["'][^"']{8,}["']/i,message:"Possible hardcoded secret / credential",ext:["js","mjs","html","json"],extra:e=>!/(example|placeholder|your[-_]|changeme|xxxx|<[^>]+>|\$\{)/i.test(e)},{id:"bearer-token",severity:"high",re:/Bearer\s+[A-Za-z0-9\-._~+/]{20,}/,message:"Hardcoded bearer token",ext:["js","mjs","html","json"]},{id:"innerhtml-static",severity:"moderate",re:/\.(?:inner|outer)HTML\s*=/,message:"innerHTML assignment \u2014 confirm the content is trusted / sanitized",ext:["js","mjs"]},{id:"insecure-url",severity:"moderate",re:/(?:href|src)\s*=\s*["']http:\/\/(?!localhost|127\.0\.0\.1)/i,message:"Insecure http:// resource \u2014 mixed content, use https://",ext:["html","js","mjs"]},{id:"target-blank",severity:"moderate",re:/target\s*=\s*["']_blank["']/,message:'target="_blank" without rel="noopener" \u2014 reverse tabnabbing',ext:["html","js","mjs"],extra:e=>!/rel\s*=\s*["'][^"']*noopener/i.test(e)},{id:"postmessage-wildcard",severity:"moderate",re:/postMessage\s*\([^,]+,\s*["']\*["']\s*\)/,message:"postMessage to '*' origin \u2014 restrict the target origin",ext:["js","mjs"]},{id:"inline-handler",severity:"low",re:/\son[a-z]+\s*=\s*["']/i,message:"Inline event handler \u2014 move to addEventListener (CSP-unfriendly)",ext:["html"]},{id:"console-log",severity:"low",re:/console\.(?:log|debug)\s*\(/,message:"console.log / debug left in code \u2014 potential info leak",ext:["js","mjs"]}],Lc=["critical","high","moderate","low"],Fu={critical:{status:"fail",label:"CRIT"},high:{status:"fail",label:"HIGH"},moderate:{status:"warn",label:"MOD "},low:{status:"info",label:"LOW "}},Lu=new Set(["node_modules",".git","dist","build",".vscode","coverage"]),Du=new Set(["js","mjs","html","json","pem","txt"])});async function Oc(e,t,n){let o=t.ref||"main",i=n.startsWith("/")?n:`/${n}`,r=`${_u}/${e}/${t.org}/${t.site}/${o}${i}`;a.debug(`POST ${r}`);let s=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"}}),l=await s.json().catch(()=>({})),c=l;return s.ok?{ok:!0,status:s.status,path:i,previewUrl:c.preview?.url,liveUrl:c.live?.url}:{ok:!1,status:s.status,path:i,message:l.message||`HTTP ${s.status}`}}async function Di(e,t){return Oc("preview",e,t)}async function Oi(e,t){return Oc("live",e,t)}async function Nc(e,t){return Promise.all(t.map(n=>Di(e,n)))}async function Mc(e,t){return Promise.all(t.map(n=>Oi(e,n)))}var _u,Ni=v(()=>{"use strict";f();D();_u="https://admin.hlx.page"});var Mi={};M(Mi,{preview:()=>Uu,resolveAdminConfig:()=>Un});import _c from"chalk";import Iu from"ora";async function Uu(e,t){let n=E(),o=await ce(n),i=Un(o,t);if(!i)return;let r=Iu(`Previewing ${e.length} path(s)...`).start(),s=e.length===1?[await Di(i,e[0])]:await Nc(i,e);r.stop();let l=!1;for(let c of s)c.ok?a.success(`${c.path} \u2192 ${_c.cyan(c.previewUrl||"preview updated")}`):(a.error(`${c.path} \u2014 ${c.message}`),l=!0);l&&(process.exitCode=1)}function Un(e,t){let n=t.org||e.admin?.org,o=t.site||e.admin?.site,i=t.ref||e.admin?.ref||"main";if(!n||!o){a.error("Missing --org and --site. Set them via flags or in .edsrc.json:"),a.info(_c.dim(' { "admin": { "org": "my-org", "site": "my-site" } }')),process.exitCode=1;return}return{org:n,site:o,ref:i}}var Bn=v(()=>{"use strict";f();Ni();ye();D();J()});var _i={};M(_i,{publish:()=>Gu});import Bu from"chalk";import Hu from"ora";async function Gu(e,t){let n=E(),o=await ce(n),i=Un(o,t);if(!i)return;let r=Hu(`Publishing ${e.length} path(s)...`).start(),s=e.length===1?[await Oi(i,e[0])]:await Mc(i,e);r.stop();let l=!1;for(let c of s)c.ok?a.success(`${c.path} \u2192 ${Bu.cyan(c.liveUrl||"published")}`):(a.error(`${c.path} \u2014 ${c.message}`),l=!0);l&&(process.exitCode=1)}var Ii=v(()=>{"use strict";f();Ni();ye();D();J();Bn()});var Hn={};M(Hn,{adminWizard:()=>Wu});async function Wu(e){let t=E();if(!t){a.error("Not inside an EDS project (no EDS project markers found)."),process.exitCode=1;return}a.logoOnce(A("Admin API \u2014 preview / publish"));let{select:n,input:o,confirm:i}=await Promise.resolve().then(()=>(G(),H)),s=(await ce(t)).admin??{},l=e??await n({message:"What do you want to do?",choices:[{name:"Preview pages (staging)",value:"preview"},{name:"Publish pages (go live)",value:"publish"}]}),c=(await o({message:"GitHub org / owner",default:s.org})).trim(),d=(await o({message:"Repository / site",default:s.site})).trim(),m=(await o({message:"Git ref",default:s.ref||"main"})).trim(),u=(await o({message:"Paths (space- or comma-separated)",default:"/"})).split(/[\s,]+/).filter(Boolean);if(!c||!d||u.length===0){a.error("org, site and at least one path are required."),process.exitCode=1;return}a.info(j("Summary"));let g=I(["operation","org","site","ref","paths"]);if(a.info(P("operation",l,g)),a.info(P("org",c,g)),a.info(P("site",d,g)),a.info(P("ref",m,g)),a.info(P("paths",u.join(", "),g)),a.info(""),l==="publish"&&!await i({message:`Publish ${u.length} path(s) to LIVE?`,default:!1})){a.info("Cancelled.");return}let h={org:c,site:d,ref:m};if(l==="preview"){let{preview:$}=await Promise.resolve().then(()=>(Bn(),Mi));await $(u,h)}else{let{publish:$}=await Promise.resolve().then(()=>(Ii(),_i));await $(u,h)}}var Gn=v(()=>{"use strict";f();ye();D();J();U()});var Ic={};M(Ic,{mainMenu:()=>Vu});import{existsSync as zu}from"fs";import{readdir as Ju}from"fs/promises";import qu from"path";import Ku from"chalk";async function Ui(e){let t=qu.join(e,"blocks");return zu(t)?(await Ju(t,{withFileTypes:!0})).filter(o=>o.isDirectory()).map(o=>o.name):[]}async function Vu(){let{select:e,isEscape:t,isExit:n}=await Promise.resolve().then(()=>(G(),H));Rn.menu=!0,await a.logoOnceAnimated("");let o;for(;;){a.info(Ku.dim(" Esc quits here \xB7 goes back to this menu from any step"));let i;try{i=await e({message:"Choose an action",choices:Xu,default:o})}catch(r){if(t(r)||n(r))return;throw r}if(i==="exit")return;o=i;try{await Yu(i)}catch(r){if(n(r))return;t(r)||a.error(r instanceof Error?r.message:String(r))}process.exitCode=void 0,a.info("")}}async function Yu(e){let{select:t,input:n}=await Promise.resolve().then(()=>(G(),H));switch(e){case"new":{let{newProject:o}=await Promise.resolve().then(()=>(mo(),lo));await o(void 0,{});return}case"init":{let{initProject:o}=await Promise.resolve().then(()=>(xt(),kt));await o({});return}case"template":{let o=await n({message:"Template name",validate:r=>!!r.trim()||"Required"}),{templateNew:i}=await Promise.resolve().then(()=>(yo(),bo));await i(o.trim(),{});return}case"sandbox":{let o=await n({message:"Sandbox repo name",validate:r=>/^[a-z0-9][a-z0-9._-]*$/i.test(r.trim())||"Use a valid repo name"}),{sandboxNew:i}=await Promise.resolve().then(()=>(Ue(),Ie));await i(o.trim(),{});return}case"from-design":{let{blockFromDesign:o}=await Promise.resolve().then(()=>(gi(),fi));await o(void 0,{});return}case"migrate":{let{migrateComponent:o}=await Promise.resolve().then(()=>(Eo(),Po));await o(void 0,{});return}case"scaffold":{let{scaffoldInteractive:o}=await Promise.resolve().then(()=>(ue(),we));await o();return}case"create":{let o=await n({message:"Block name",validate:r=>Ne.test(r.trim())||"Use kebab-case, e.g. hero-banner"}),{createBlock:i}=await Promise.resolve().then(()=>(Ho(),Bo));await i(o.trim(),{});return}case"integrate":{let{integrate:o}=await Promise.resolve().then(()=>($i(),xi));await o(void 0);return}case"preview-block":{let o=E();if(!o){a.error("Not inside an EDS project (no EDS project markers found).");return}let i=await Ui(o);if(i.length===0){a.warn("No blocks found in blocks/.");return}let r=await t({message:"Which block?",choices:i.map(l=>({name:l,value:l}))}),{previewBlock:s}=await Promise.resolve().then(()=>(qe(),Ht));await s(r,{});return}case"model":{let{modelAdd:o}=await Promise.resolve().then(()=>(No(),Oo));await o(void 0,[],{});return}case"track":{let o=E();if(!o){a.error("Not inside an EDS project (no EDS project markers found).");return}let i=await Ui(o);if(i.length===0){a.warn("No blocks found in blocks/.");return}let r=await t({message:"Which block to instrument?",choices:i.map(l=>({name:l,value:l}))}),{trackBlock:s}=await Promise.resolve().then(()=>(At(),Tt));await s(r,{});return}case"schema":{let o=E();if(!o){a.error("Not inside an EDS project (no EDS project markers found).");return}let i=await Ui(o);if(i.length===0){a.warn("No blocks found in blocks/.");return}let r=await t({message:"Which block?",choices:i.map(l=>({name:l,value:l}))}),{schemaBlock:s}=await Promise.resolve().then(()=>(_o(),Mo));await s(r,{});return}case"ue":{if(await t({message:"Universal Editor:",choices:[{name:"Check readiness (which blocks are editable)",value:"check"},{name:"Open a page in the editor",value:"open"}]})==="check"){let{ueCheck:i}=await Promise.resolve().then(()=>(Dt(),Lt));await i()}else{let i=await n({message:"Page path",default:"/"}),{ueOpen:r}=await Promise.resolve().then(()=>(Dt(),Lt));await r(i.trim()||"/",{})}return}case"admin":{let{adminWizard:o}=await Promise.resolve().then(()=>(Gn(),Hn));await o();return}case"audit":{let o=await t({message:"Which audit?",choices:[{name:"Doctor \u2014 overall project health",value:"doctor"},{name:"Loading \u2014 three-phase / LCP budget",value:"loading"},{name:"Security \u2014 vulnerabilities & exploit patterns",value:"security"}]});if(o==="doctor"){let{doctor:i}=await Promise.resolve().then(()=>(Ei(),Pi));await i({})}else if(o==="loading"){let{auditLoading:i}=await Promise.resolve().then(()=>(Ai(),Ti));await i({})}else{let{auditSecurity:i}=await Promise.resolve().then(()=>(Li(),Fi));await i({})}return}case"figma-setup":{let{figmaSetup:o}=await Promise.resolve().then(()=>(ji(),Si));await o();return}}}var Xu,Uc=v(()=>{"use strict";f();D();J();Ye();Fn();Xu=[{name:"New project",value:"new",description:"Clone the latest EDS boilerplate"},{name:"Set up project",value:"init",description:"Authoring model, CI, naming"},{name:"Page template",value:"template",description:"Generate initial content"},{name:"Sandbox repo",value:"sandbox",description:"Disposable GitHub repo"},{name:"Block from design",value:"from-design",description:"Figma, Framer or Google Stitch"},{name:"Migrate component",value:"migrate",description:"Classic AEM component \u2192 EDS"},{name:"Scaffold UE",value:"scaffold",description:"Universal Editor components"},{name:"Empty block",value:"create",description:"Create a bare block"},{name:"Integration",value:"integrate",description:"GTM, chat, consent\u2026"},{name:"Model fields",value:"model",description:"Add fields to a block model (partials)"},{name:"Analytics",value:"track",description:"Instrument a block (dataLayer)"},{name:"Structured data",value:"schema",description:"Add JSON-LD to a block"},{name:"Universal Editor",value:"ue",description:"Check readiness / open the editor"},{name:"Preview block",value:"preview-block",description:"Live preview in the browser"},{name:"Pages",value:"admin",description:"Preview / publish (Admin API)"},{name:"Audit",value:"audit",description:"Doctor / loading / security"},{name:"Figma MCP",value:"figma-setup",description:"Configure the connection"},{name:"Exit",value:"exit",description:"Quit eds (or press Esc)"}]});f();import Qu from"chalk";import{Command as Zu}from"commander";var Gi={name:"aem-eds-kit",version:"0.4.54",description:"CLI for AEM Edge Delivery Services: blocks from Figma, Framer or Google Stitch designs, AEM component migration (AEMaaCS and 6.5), Universal Editor models and QA",type:"module",engines:{node:">=20"},bin:{eds:"dist/bin/eds.js"},files:["dist","samples","CHANGELOG.md"],scripts:{dev:"tsx src/bin/eds.ts",build:"tsup",test:"vitest run","test:watch":"vitest",lint:"biome check src/ tests/","lint:fix":"biome check --write src/ tests/",typecheck:"tsc --noEmit",prepare:"git config core.hooksPath .githooks || true",prepublishOnly:"npm run build"},keywords:["aem","edge-delivery-services","helix","figma","mcp","cli","adobe","aem-edge-delivery","universal-editor","aemaacs","aem-migration","framer","google-stitch","design-to-code","claude-code"],author:"Piotr Godycki <piotrgodycki@yahoo.com>",license:"MIT",repository:{type:"git",url:"git+https://github.com/piotrgodycki/aem-eds-kit.git"},homepage:"https://piotrgodycki.github.io/aem-eds-kit/",bugs:{url:"https://github.com/piotrgodycki/aem-eds-kit/issues"},dependencies:{"@inquirer/prompts":"^7.0.0",chalk:"^5.4.0",commander:"^13.0.0",execa:"^9.5.0","fast-xml-parser":"^5.11.2",ora:"^8.1.0",yaml:"^2.6.0",zod:"^3.24.0"},devDependencies:{"@biomejs/biome":"^1.9.0","@types/node":"^22.0.0",tsup:"^8.3.0",tsx:"^4.19.0",typescript:"^5.7.0",vitest:"^2.1.0"},optionalDependencies:{"@modelcontextprotocol/sdk":"^1.29.0",pixelmatch:"^6.0.0",playwright:"^1.64.0",pngjs:"^7.0.0"}};D();U();var W=new Zu;W.name("eds").description("CLI for AEM Edge Delivery Services: blocks from Figma, Framer or Stitch designs, AEM migration, Universal Editor models and QA").version(Gi.version).option("--verbose","Enable verbose output").option("--quiet","Suppress non-error output").option("--json","Output in JSON format").option("--no-color","Disable color output").showHelpAfterError("(add --help for usage)").hook("preAction",e=>{let t=e.opts();t.verbose&&a.setLevel("debug"),t.quiet&&a.setQuiet(!0),t.color===!1&&(Qu.level=0)});W.addHelpText("beforeAll",()=>A());W.command("new [dir]").description("Clone the latest EDS boilerplate into a local folder (no GitHub auth)").option("--boilerplate <repo>","da | ue | commerce, owner/repo on GitHub, or any git URL (default adobe/aem-boilerplate)").option("--ue","Use the crosswalk / Universal Editor boilerplate").option("--ref <ref>","Branch or tag to clone").option("--keep-history","Keep the boilerplate's git history (remote renamed to upstream)").option("--remote <url>","Set origin to your own repo").option("--install","Run npm install after cloning").option("--yes","Skip the guided prompts").action(async(e,t)=>{let{newProject:n}=await Promise.resolve().then(()=>(mo(),lo));await n(e,t)});var Kt=W.command("sandbox").description("Disposable EDS sandbox repos on GitHub");Kt.command("new <name>").description("Create a disposable EDS repo from a boilerplate (GitHub auth, no gh required)").option("--org <org>","Create under a GitHub org (else your account)").option("--boilerplate <repo>","Template repo (default adobe/aem-boilerplate)").option("--ue","Use the crosswalk / Universal Editor boilerplate").option("--private","Create a private repo").option("--yes","Skip the guided prompts (use flags/defaults)").action(async(e,t)=>{let{sandboxNew:n}=await Promise.resolve().then(()=>(Ue(),Ie));await n(e,t)});Kt.command("login").description("Authorize GitHub (OAuth device flow or a token) - no gh needed").action(async()=>{let{sandboxLogin:e}=await Promise.resolve().then(()=>(Ue(),Ie));await e()});Kt.command("logout").description("Remove the stored GitHub token").action(async()=>{let{sandboxLogout:e}=await Promise.resolve().then(()=>(Ue(),Ie));await e()});Kt.command("list").description("List your EDS sandboxes (repos tagged eds-sandbox)").action(async()=>{let{sandboxList:e}=await Promise.resolve().then(()=>(Ue(),Ie));await e()});Kt.command("rm <name>").description("Delete a sandbox repo (destructive)").option("--org <org>","Owner org (else your account)").option("--yes","Skip the confirmation").action(async(e,t)=>{let{sandboxRm:n}=await Promise.resolve().then(()=>(Ue(),Ie));await n(e,t)});var ef=W.command("template").description("Generate page templates / initial content");ef.command("new <name>").description("Generate EDS page initial content (sections + blocks + metadata), DA push optional").option("--path <path>","Content path (default: /templates/<name>)").option("--title <title>","Page title").option("--description <text>","Page description").option("--blocks <list>","Comma-separated block ids to seed",e=>e.split(",").map(t=>t.trim())).option("--area <area>","Site area / template label (stored in metadata)").option("--authoring <model>","Force authoring model: da | gdrive | sharepoint | ue").option("--push","Push the page to DA (da.live)").option("--org <org>","DA org (else from .edsrc.json)").option("--site <site>","DA site (else from .edsrc.json)").option("--yes","Skip prompts").action(async(e,t)=>{let{templateNew:n}=await Promise.resolve().then(()=>(yo(),bo));await n(e,t)});W.command("init").description("Set up a freshly cloned EDS boilerplate for your authoring model (interactive)").option("--name <name>","Project name (kebab-case)").option("--authoring <model>","Authoring model: ue | da | gdrive | sharepoint").option("--mountpoint <url>","Content source URL (document models)").option("--org <org>","DA org (authoring=da)").option("--site <site>","DA site (authoring=da)").option("--no-ci","Skip the GitHub Actions CI workflow").option("--no-env","Skip the local-dev .env (aem up config)").option("--no-xwalk","Skip xwalk.json (UE multi-field)").option("--yes","Skip prompts; apply with flags/defaults").action(async e=>{let{initProject:t}=await Promise.resolve().then(()=>(xt(),kt));await t(e)});var tf=W.command("migrate").description("Migrate from classic AEM to EDS");tf.command("component [dir]").description("Migrate a classic AEM component's dialog into an EDS block + UE model").option("--name <name>","Block name (otherwise inferred from the component)").option("--clientlib <dir>","Path to the component's clientlib (otherwise auto-detected)").option("--super-root <dirs>","jcr_root folder(s), comma-separated, holding a proxy component's super type (e.g. a Core Components checkout)").option("--yes","Skip confirmation prompts").action(async(e,t)=>{let{migrateComponent:n}=await Promise.resolve().then(()=>(Eo(),Po));await n(e,t)});var nf=W.command("model").description("Compose Universal Editor models");nf.command("add <block> [partials...]").description("Add reusable field groups (partials) to a block's UE model").option("--yes","Skip prompts").action(async(e,t,n)=>{let{modelAdd:o}=await Promise.resolve().then(()=>(No(),Oo));await o(e,t,n)});var of=W.command("schema").description("Structured data (JSON-LD) for blocks");of.command("block <name>").description("Inject a JSON-LD (schema.org) builder into a block's decorate()").option("--type <type>","schema.org type (Article, FAQPage, Product, ...)").option("--yes","Skip prompts").action(async(e,t)=>{let{schemaBlock:n}=await Promise.resolve().then(()=>(_o(),Mo));await n(e,t)});var rf=W.command("track").description("Instrument blocks for analytics");rf.command("block <name>").description("Add dataLayer tracking (click + form submit) to a block's decorate()").option("--no-click","Skip click tracking").option("--no-submit","Skip form-submit tracking").action(async(e,t)=>{let{trackBlock:n}=await Promise.resolve().then(()=>(At(),Tt));await n(e,t)});var Bc=W.command("ue").description("Universal Editor - readiness check + editor deep link");Bc.command("check").description("Check whether blocks are Universal-Editor-ready (offline)").action(async()=>{let{ueCheck:e}=await Promise.resolve().then(()=>(Dt(),Lt));await e()});Bc.command("open [path]").description("Open a page in the hosted Universal Editor (preview host from git)").option("--org <slug>","IMS org slug (skips the org picker)").option("--ref <branch>","Branch/ref for the preview host (default: main)").option("--url <host>","Override the delivery host (e.g. main--repo--owner.aem.page)").option("--no-open","Print the link without opening the browser").action(async(e,t)=>{let{ueOpen:n}=await Promise.resolve().then(()=>(Dt(),Lt));await n(e,t)});var ut=W.command("block").description("Manage EDS blocks");ut.command("create <name>").description("Scaffold a new EDS block (with Universal Editor model by default)").option("--no-ue-model","Skip the Universal Editor model (generated by default)").action(async(e,t)=>{let{createBlock:n}=await Promise.resolve().then(()=>(Ho(),Bo));await n(e,t)});ut.command("from-design [design]").description("Generate an EDS block from a design: a Figma URL, a Framer/Stitch page (scraped with headless Chromium), or a local SVG/PNG export (quota-free, no MCP). Interactive wizard when run with no argument.").option("--name <name>","Override the inferred block name").option("--provider <type>","Design source: figma | framer | stitch (else detected from the URL)").option("--agent <type>","Force agent type: claude | cursor | codex | ollama | omlx | local (any OpenAI-compatible server) | none").option("--model <name>","Model to run (Claude alias/id, or a local model, e.g. qwen2.5-coder:14b)").option("--dry-run","Generate prompt only, do not invoke agent").option("--source <type>","Content source: document|ue|cf|mixed (default: document)").option("--widths <list>","Design frame widths for preview breakpoints (e.g. 390,768,1440)").option("--no-ue-model","Skip the Universal Editor model (generated by default)").option("--screenshot","Add a screenshot MCP call for pixel verification (opt-in; costs a call)").option("--mcp","Force the Figma MCP adapter even when a REST token is set").option("--refresh","Ignore the cached design snapshot and re-fetch").option("--auth","Scrape with a logged-in session (Framer/Stitch) \u2014 login captured once, then reused").option("--auth-refresh","Force a fresh scrape login even if a session is saved").option("--sample","Use the bundled sample design (Kiri Bloom hero) \u2014 no URL, no token, no MCP").option("--serve","Auto-start the live preview after generating (non-interactive runs only)").option("--yes","Skip confirmation prompts").action(async(e,t)=>{let{blockFromDesign:n}=await Promise.resolve().then(()=>(gi(),fi));await n(e,t)});ut.command("list").description("List all blocks in the project").action(async e=>{let{listBlocks:t}=await Promise.resolve().then(()=>(cc(),sc));await t({...e,json:W.opts().json})});ut.command("preview [name]").description("Serve a live, breakpoint-switchable preview of a block \u2014 or a gallery of all blocks when no name is given").option("--port <port>","Port to serve on (default: 8777, falls back if taken)").option("--widths <list>","Comma-separated breakpoint widths (e.g. 375,768,1280)").option("--no-open","Do not open the browser automatically").action(async(e,t)=>{let n=await Promise.resolve().then(()=>(qe(),Ht));e?await n.previewBlock(e,t):await n.galleryPreview(t)});ut.command("test [name]").description("Visual-regression test a block (or all blocks) against committed baselines").option("--update","(Re)write the baseline screenshots instead of comparing").option("--threshold <ratio>","Max changed-pixel ratio before failing (default 0.01 = 1%)").option("--design","Compare the rendered block against its Figma design image (needs a token)").option("--widths <list>","Comma-separated breakpoint widths (e.g. 375,768,1280)").option("--port <port>","Port for the internal preview server (default: 8788)").action(async(e,t)=>{let{visualTest:n}=await Promise.resolve().then(()=>(kc(),vc));await n(e,t)});ut.command("check [name]").description("Content, link and a11y check on a block's rendered DOM (or all blocks)").option("--strict","Fail on warnings too, not just errors").option("--widths <list>","Comma-separated breakpoint widths (uses the widest)").option("--port <port>","Port for the internal preview server (default: 8789)").action(async(e,t)=>{let{blockCheck:n}=await Promise.resolve().then(()=>(jc(),Sc));await n(e,t)});var ft=W.command("scaffold").description("Scaffold standard UE components and blocks").action(async()=>{let{scaffoldInteractive:e}=await Promise.resolve().then(()=>(ue(),we));await e()});ft.command("ue").description("Scaffold default-content UE components + a field-reference block (all 17 fields)").action(async()=>{let{scaffoldUe:e}=await Promise.resolve().then(()=>(ue(),we));await e()});ft.command("blocks [names...]").description("Scaffold standard blocks (hero, cards, columns, accordion, embed) with UE models").action(async e=>{let{scaffoldBlocks:t}=await Promise.resolve().then(()=>(ue(),we));await t(e)});ft.command("ci").description("Scaffold a GitHub Actions workflow (doctor + audits + project lint/build)").action(async()=>{let{scaffoldCi:e}=await Promise.resolve().then(()=>(ue(),we));await e()});ft.command("helpers [names...]").description("Scaffold scripts/utils.js with chosen EDS helpers (interactive picker)").action(async e=>{let{scaffoldHelpers:t}=await Promise.resolve().then(()=>(ue(),we));await t(e)});ft.command("env").description("Write a local-dev .env for `aem up` (AEM_OPEN / AEM_PORT / AEM_PAGES_URL)").option("--open <path>","AEM_OPEN - path opened on start (default: /)").option("--port <port>","AEM_PORT - proxy port (default: 3007)").option("--pages-url <url>","AEM_PAGES_URL - content origin (default: from git remote)").option("--yes","Skip prompts; use flags/defaults").action(async e=>{let{scaffoldEnv:t}=await Promise.resolve().then(()=>(ue(),we));await t(e)});ft.command("xwalk").description("Write xwalk.json enabling Universal Editor multi-field support").action(async()=>{let{scaffoldXwalk:e}=await Promise.resolve().then(()=>(ue(),we));await e()});W.command("integrate [type]").description("Add a third-party service (GTM, GA4, chat, consent) to scripts/delayed.js").action(async e=>{let{integrate:t}=await Promise.resolve().then(()=>($i(),xi));await t(e)});var af=W.command("figma").description("Figma MCP integration");af.command("setup").description("Configure Figma MCP for your AI agent").action(async()=>{let{figmaSetup:e}=await Promise.resolve().then(()=>(ji(),Si));await e()});W.command("doctor").description("Audit your EDS project for common issues").action(async()=>{let{doctor:e}=await Promise.resolve().then(()=>(Ei(),Pi));await e({json:W.opts().json})});var Hc=W.command("audit").description("Run project audits");Hc.command("loading").description("Check loading order (eager/lazy/delayed phases, LCP budget)").action(async()=>{let{auditLoading:e}=await Promise.resolve().then(()=>(Ai(),Ti));await e({json:W.opts().json})});Hc.command("security").description("Scan for vulnerabilities (npm audit) and exploit patterns (XSS, secrets, tabnabbing)").action(async()=>{let{auditSecurity:e}=await Promise.resolve().then(()=>(Li(),Fi));await e({json:W.opts().json})});W.command("preview [paths...]").description("Preview pages via Admin API (interactive wizard when run with no paths)").option("--org <org>","GitHub org/owner").option("--site <site>","Repository name").option("--ref <ref>","Git ref (default: main)").action(async(e,t)=>{if(!e||e.length===0){let{adminWizard:o}=await Promise.resolve().then(()=>(Gn(),Hn));await o("preview");return}let{preview:n}=await Promise.resolve().then(()=>(Bn(),Mi));await n(e,t)});W.command("publish [paths...]").description("Publish pages to live via Admin API (interactive wizard when run with no paths)").option("--org <org>","GitHub org/owner").option("--site <site>","Repository name").option("--ref <ref>","Git ref (default: main)").action(async(e,t)=>{if(!e||e.length===0){let{adminWizard:o}=await Promise.resolve().then(()=>(Gn(),Hn));await o("publish");return}let{publish:n}=await Promise.resolve().then(()=>(Ii(),_i));await n(e,t)});(async()=>{try{if(process.argv.slice(2).length===0)if(process.stdout.isTTY){let{mainMenu:e}=await Promise.resolve().then(()=>(Uc(),Ic));await e()}else W.outputHelp();else await W.parseAsync()}catch(e){a.error(e instanceof Error?e.message:String(e)),process.exitCode=1}})();