hugoblox 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
+ declare function bootstrap(argv?: string[]): Promise<void>;
1
2
 
2
- export { }
3
+ export { bootstrap };
package/dist/index.js CHANGED
@@ -16,17 +16,17 @@ import { fileURLToPath } from 'node:url';
16
16
  import K from 'chalk';
17
17
  import { Buffer as Buffer$1 } from 'node:buffer';
18
18
 
19
- var P=class extends Error{constructor(e,o="HBX_ERROR",n){super(e),this.name="HbxError",this.code=o,this.details=n;}},l=class extends P{constructor(e,o){super(e,"HBX_INPUT_ERROR",o);}},R=class extends P{constructor(e="Operation cancelled by user"){super(e,"HBX_ABORTED");}},q=class extends P{constructor(e,o){super(e,"HBX_CONFIG_ERROR",o);}};function Ce(t){return !!(t&&typeof t=="object"&&"code"in t)}async function w(t){try{return await g.access(t),!0}catch{return false}}async function x(t){await g.mkdir(t,{recursive:true});}async function Te(t){if(!await w(t)){await x(t);return}if((await g.readdir(t)).length>0)throw new Error(`Directory ${t} is not empty`)}async function C(t,e){await x(u.dirname(t)),await g.writeFile(t,e);}function Pe(t,e){t.command("block").description("Manage Hugo Blox blocks").command("add").argument("<id>","Block identifier").description("Add a Hugo Blox block to the current project").option("--example <slug>","Include sample content for the block").option("--dry-run","Print the actions without writing files").option("--yes","Overwrite files when they already exist").action((n,r,i)=>{let{logger:s}=e,a=!!i.optsWithGlobals().json,c="Block management is coming soon. Follow https://hugoblox.com/changelog for updates or join Discord to preview it early.";if(a){s.json({status:"pending",message:c});return}s.info(c);});}var Z="hbx",G="HBX_DEBUG",L="HBX_LICENSE_TOKEN",Se="HBX_TELEMETRY_DISABLED",de=u.join(ae.homedir(),".hbx"),ee=u.join(de,"config.json"),Tt=u.join(ae.homedir(),".cache","hbx"),O=u.join(Tt,"templates"),Ie="HBX_UPDATE_CHECK_DISABLED",X="https://api.github.com",_e=`${X}/repos/HugoBlox/hugo-blox-builder/contents/templates`,He="https://github.com/HugoBlox/hugo-blox-builder.git",Be="HBX_TEMPLATES_DIR",D="https://cli-api.hugoblox.com",De=`${D}/api/usage-insights`,te="hugoblox",je=1e3*60*60*24,Ne=1e3*60*60*12,me="github.com/HugoBlox/hugo-blox-builder/modules/blox-tailwind",pe=[{id:"academic-cv",name:"Academic CV",description:"Publish your academic CV and showcase your research.",repoPath:"templates/academic-cv",slug:"academic-cv",tags:["academic","cv"],source:"oss"},{id:"startup",name:"Startup",description:"Marketing site for SaaS and startups.",repoPath:"templates/startup",slug:"startup",tags:["business"],source:"oss"},{id:"folio",name:"Portfolio",description:"Minimal portfolio for creatives.",repoPath:"templates/folio",slug:"folio",tags:["portfolio"],source:"oss"}];var oe="hbx.blocks.json";async function F(t=process.cwd()){let e=t,{root:o}=u.parse(t);for(;;){if((await Promise.all([w(u.join(e,"config","_default")),w(u.join(e,"hugoblox.yaml"))])).some(Boolean))return {root:e,manifestPath:u.join(e,oe)};if(e===o)return;e=u.dirname(e);}}async function Ae(t){let e=u.join(t,"hugoblox.yaml");if(await w(e))try{let o=await g.readFile(e,"utf8"),n=kt.parse(o);if(!n)return;let r=n.template??{},i=n.build??{};return {templateId:r.id,templateName:r.name,requiredHugoVersion:i.hugo_version}}catch(o){throw new l("Failed to parse hugoblox.yaml",{error:o})}}function Re(t,e){It(t,e),_t(t,e);}function It(t,e){t.command("dev [hugoArgs...]").description("Start the Hugo development server (hugo server)").option("--path <dir>","Project directory (defaults to cwd)").option("--no-default-flags","Disable automatic --disableFastRender flag").action(async(o,n,r)=>{let{logger:i,telemetry:s}=e,c=!!r.optsWithGlobals().json,d=await Le(n.path),m=["server"];n.defaultFlags!==false&&m.push("--disableFastRender"),m.push(...o),await Oe(m,d,i,{allowSignalExit:true,label:"dev server"}),await s.track({name:"dev",payload:{customPath:!!n.path,defaultFlags:n.defaultFlags!==false,args:o}}),c&&i.json({status:"success"});});}function _t(t,e){t.command("build [hugoArgs...]").description("Run a production Hugo build (hugo --gc --minify)").option("--path <dir>","Project directory (defaults to cwd)").option("--no-default-flags","Disable automatic --gc/--minify flags").action(async(o,n,r)=>{let{logger:i,telemetry:s}=e,c=!!r.optsWithGlobals().json,d=await Le(n.path),m=[];n.defaultFlags!==false&&m.push("--gc","--minify"),m.push(...o),await Oe(m,d,i,{allowSignalExit:false,label:"build"}),await s.track({name:"build",payload:{customPath:!!n.path,defaultFlags:n.defaultFlags!==false,args:o}}),c&&i.json({status:"success"});});}async function Le(t){let e=t?u.resolve(t):u.resolve(process.cwd()),o=await F(e);if(!o)throw new l("Unable to locate a Hugo Blox project. Run this inside a project or pass --path.");return o.root}async function Oe(t,e,o,n){o.info(`Running: hugo ${t.join(" ")}`);try{await execa("hugo",t,{cwd:e,stdio:"inherit"}),o.success(`Hugo ${n.label} finished`);}catch(r){let i=r;if(n.allowSignalExit&&(i.signal==="SIGINT"||i.signal==="SIGTERM")){o.info("Hugo process stopped");return}throw new l(`Hugo ${n.label} failed: ${i.shortMessage??i.message}`,{error:i})}}function Fe(t){let e=process.env.HOME||process.env.USERPROFILE;if(!e)return t;let o=u.resolve(e),n=u.resolve(t);return n.startsWith(o)?n.replace(o,"~"):t}async function Ue(t,e){try{let o=await execa(t,e,{reject:!1});return o.exitCode===0?o.stdout.trim():`Failed (${o.stderr.trim()})`}catch(o){return `Not available (${o.message})`}}function Ve(t,e){t.command("doctor").description("Check local environment for common issues").action(async(o,n)=>{let{logger:r,config:i}=e,a=!!n.optsWithGlobals().json,c=[];c.push({name:"Node.js",ok:true,details:process.version});let d=await Ue("hugo",["version"]);c.push({name:"Hugo",ok:!d.startsWith("Not"),details:d});let m=jt(d),h=await Ue("pnpm",["--version"]);c.push({name:"pnpm",ok:!h.startsWith("Not"),details:h});let S=i.getToken();c.push({name:"Pro token",ok:!!S,details:S?"Configured":"Missing"});let T=await F();if(T){let f=await Ae(T.root);if(f){let I=f.templateName??f.templateId??"Unknown";c.push({name:"Template",ok:true,details:`${I} (${Fe(T.root)})`});let v=Nt(f.requiredHugoVersion,m);v&&c.push(v);}let p=await At(T.root);if(p?.current){let I=p.current;if(p.latest){let V=b.coerce(p.current),H=b.coerce(p.latest);V&&H&&b.eq(V,H)&&(I=`${I} (latest)`);}c.push({name:"blox-tailwind module",ok:true,details:I});let v=Rt(p.current,p.latest);v&&c.push(v);}}let A={status:c.some(f=>(f.level??(f.ok?"info":"error"))==="error")?"error":"success",checks:c};if(a){r.json(A);return}for(let f of A.checks){let p=f.level??(f.ok?"info":"error");p==="info"?r.success(`${f.name}: ${f.details}`):p==="warn"?r.warn(`${f.name}: ${f.details}`):r.error(`${f.name}: ${f.details}`);}});}function jt(t){let e=t.match(/v(\d+\.\d+\.\d+)/i);return e?e[1]:t.match(/(\d+\.\d+\.\d+)/)?.[1]}function Nt(t,e){if(!t||!e)return;let o=b.coerce(t),n=b.coerce(e);if(!(!o||!n))return b.lt(n,o)?{name:"Hugo version compatibility",ok:false,details:`Template requires Hugo ${o.version}, but ${n.version} is installed`,level:"error"}:b.major(n)>b.major(o)||b.minor(n)>b.minor(o)?{name:"Hugo version compatibility",ok:true,details:`Using Hugo ${n.version}; template tested with ${o.version}`,level:"warn"}:{name:"Hugo version compatibility",ok:true,details:`Template requires Hugo ${o.version} and you're running ${n.version}`,level:"info"}}async function At(t){let e=u.join(t,"go.mod");try{let o=await g.readFile(e,"utf8"),n=Lt(o,me),r=await $t();return {current:n,latest:r}}catch{return}}async function $t(){try{let t=await fetch(`${X}/repos/HugoBlox/hugo-blox-builder/tags?per_page=100`);if(!t.ok)throw new Error(`GitHub responded with status ${t.status}`);return (await t.json()).find(n=>n.name.startsWith("modules/blox-tailwind/")&&/v\d+/.test(n.name))?.name.split("/").pop()}catch{return}}function Rt(t,e){if(!t||!e)return;let o=b.coerce(t),n=b.coerce(e);if(!(!o||!n)&&b.lt(o,n))return {name:"blox-tailwind update",ok:false,details:`Current ${o.version}, latest ${n.version}. Run 'hugo mod get ${me}@${n.version}'.`,level:"warn"}}function Lt(t,e){let o=t.split(/\r?\n/),n=false;for(let r of o){let i=r.trim();if(i.startsWith("require (")){n=true;continue}if(n&&i===")"){n=false;continue}if(!n&&i.startsWith("require ")){let a=i.replace("require","").trim().match(new RegExp(`${e}\\s+(v[\\w.-+]+)`));if(a)return a[1]}if(n&&i.startsWith(e)){let s=i.split(/\s+/);if(s[0]===e&&s[1])return s[1]}}}function Ge(t,e){t.command("install").description("Hydrate Hugo Blox Pro assets").option("--ci","Fail when prompts would appear").option("--force","Force re-download of assets").option("--path <dir>","Project directory (defaults to cwd)").action(async(o,n)=>{let{logger:r,config:i,telemetry:s}=e,c=!!n.optsWithGlobals().json,d=o.path?{root:u.resolve(o.path),manifestPath:u.join(u.resolve(o.path),"hbx.blocks.json")}:await F();if(!d)throw new l("Unable to locate a Hugo Blox project - pass --path if needed");let m=i.getToken();if(!m){if(o.ci)throw new l(`Missing token. Set ${L} or run hbx login before using --ci.`);r.warn("No Pro token detected, proceeding with OSS assets only");}let h=ut("Hydrating Pro assets...").start();try{let T=u.join(d.root,"config","_default","module.hbx.toml"),y=u.join(d.root,"node_modules","@hugoblox-pro","sample");await x(y),await C(u.join(y,"README.md"),`# Hugo Blox Pro assets placeholder
20
- `),await C(T,`# Generated by hbx install
19
+ var T=class extends Error{constructor(e,o="HBX_ERROR",n){super(e),this.name="HbxError",this.code=o,this.details=n;}},l=class extends T{constructor(e,o){super(e,"HBX_INPUT_ERROR",o);}},$=class extends T{constructor(e="Operation cancelled by user"){super(e,"HBX_ABORTED");}},q=class extends T{constructor(e,o){super(e,"HBX_CONFIG_ERROR",o);}};function Ce(t){return !!(t&&typeof t=="object"&&"code"in t)}async function w(t){try{return await g.access(t),!0}catch{return false}}async function x(t){await g.mkdir(t,{recursive:true});}async function Pe(t){if(!await w(t)){await x(t);return}if((await g.readdir(t)).length>0)throw new Error(`Directory ${t} is not empty`)}async function C(t,e){await x(u.dirname(t)),await g.writeFile(t,e);}function Te(t,e){t.command("block").description("Manage HugoBlox blocks").command("add").argument("<id>","Block identifier").description("Add a HugoBlox block to the current project").option("--example <slug>","Include sample content for the block").option("--dry-run","Print the actions without writing files").option("--yes","Overwrite files when they already exist").action((n,r,i)=>{let{logger:s}=e,a=!!i.optsWithGlobals().json,c="Block management is coming soon. Follow https://hugoblox.com/changelog for updates or join Discord to preview it early.";if(a){s.json({status:"pending",message:c});return}s.info(c);});}var Z="hbx",G="HBX_DEBUG",L="HBX_LICENSE_TOKEN",Se="HBX_TELEMETRY_DISABLED",de=u.join(ae.homedir(),".hbx"),ee=u.join(de,"config.json"),Pt=u.join(ae.homedir(),".cache","hbx"),O=u.join(Pt,"templates"),Ie="HBX_UPDATE_CHECK_DISABLED",X="https://api.github.com",_e=`${X}/repos/HugoBlox/hugo-blox-builder/contents/templates`,He="https://github.com/HugoBlox/hugo-blox-builder.git",Be="HBX_TEMPLATES_DIR",D="https://cli-api.hugoblox.com",De=`${D}/api/usage-insights`,te="hugoblox",je=1e3*60*60*24,Ne=1e3*60*60*12,me="github.com/HugoBlox/hugo-blox-builder/modules/blox-tailwind",pe=[{id:"academic-cv",name:"Academic CV",description:"Publish your academic CV and showcase your research.",repoPath:"templates/academic-cv",slug:"academic-cv",tags:["academic","cv"],source:"oss"},{id:"startup",name:"Startup",description:"Marketing site for SaaS and startups.",repoPath:"templates/startup",slug:"startup",tags:["business"],source:"oss"},{id:"folio",name:"Portfolio",description:"Minimal portfolio for creatives.",repoPath:"templates/folio",slug:"folio",tags:["portfolio"],source:"oss"}];var oe="hbx.blocks.json";async function F(t=process.cwd()){let e=t,{root:o}=u.parse(t);for(;;){if((await Promise.all([w(u.join(e,"config","_default")),w(u.join(e,"hugoblox.yaml"))])).some(Boolean))return {root:e,manifestPath:u.join(e,oe)};if(e===o)return;e=u.dirname(e);}}async function Ae(t){let e=u.join(t,"hugoblox.yaml");if(await w(e))try{let o=await g.readFile(e,"utf8"),n=kt.parse(o);if(!n)return;let r=n.template??{},i=n.build??{};return {templateId:r.id,templateName:r.name,requiredHugoVersion:i.hugo_version}}catch(o){throw new l("Failed to parse hugoblox.yaml",{error:o})}}function $e(t,e){It(t,e),_t(t,e);}function It(t,e){t.command("dev [hugoArgs...]").description("Start the Hugo development server (hugo server)").option("--path <dir>","Project directory (defaults to cwd)").option("--no-default-flags","Disable automatic --disableFastRender flag").action(async(o,n,r)=>{let{logger:i,telemetry:s}=e,c=!!r.optsWithGlobals().json,d=await Le(n.path),m=["server"];n.defaultFlags!==false&&m.push("--disableFastRender"),m.push(...o),await Oe(m,d,i,{allowSignalExit:true,label:"dev server"}),await s.track({name:"dev",payload:{customPath:!!n.path,defaultFlags:n.defaultFlags!==false,args:o}}),c&&i.json({status:"success"});});}function _t(t,e){t.command("build [hugoArgs...]").description("Run a production Hugo build (hugo --gc --minify)").option("--path <dir>","Project directory (defaults to cwd)").option("--no-default-flags","Disable automatic --gc/--minify flags").action(async(o,n,r)=>{let{logger:i,telemetry:s}=e,c=!!r.optsWithGlobals().json,d=await Le(n.path),m=[];n.defaultFlags!==false&&m.push("--gc","--minify"),m.push(...o),await Oe(m,d,i,{allowSignalExit:false,label:"build"}),await s.track({name:"build",payload:{customPath:!!n.path,defaultFlags:n.defaultFlags!==false,args:o}}),c&&i.json({status:"success"});});}async function Le(t){let e=t?u.resolve(t):u.resolve(process.cwd()),o=await F(e);if(!o)throw new l("Unable to locate a HugoBlox project. Run this inside a project or pass --path.");return o.root}async function Oe(t,e,o,n){o.info(`Running: hugo ${t.join(" ")}`);try{await execa("hugo",t,{cwd:e,stdio:"inherit"}),o.success(`Hugo ${n.label} finished`);}catch(r){let i=r;if(n.allowSignalExit&&(i.signal==="SIGINT"||i.signal==="SIGTERM")){o.info("Hugo process stopped");return}throw new l(`Hugo ${n.label} failed: ${i.shortMessage??i.message}`,{error:i})}}function Fe(t){let e=process.env.HOME||process.env.USERPROFILE;if(!e)return t;let o=u.resolve(e),n=u.resolve(t);return n.startsWith(o)?n.replace(o,"~"):t}async function Ue(t,e){try{let o=await execa(t,e,{reject:!1});return o.exitCode===0?o.stdout.trim():`Failed (${o.stderr.trim()})`}catch(o){return `Not available (${o.message})`}}function Ve(t,e){t.command("doctor").description("Check local environment for common issues").action(async(o,n)=>{let{logger:r,config:i}=e,a=!!n.optsWithGlobals().json,c=[];c.push({name:"Node.js",ok:true,details:process.version});let d=await Ue("hugo",["version"]);c.push({name:"Hugo",ok:!d.startsWith("Not"),details:d});let m=jt(d),h=await Ue("pnpm",["--version"]);c.push({name:"pnpm",ok:!h.startsWith("Not"),details:h});let S=i.getToken();c.push({name:"Pro license",ok:!!S,details:S?"Configured":"Missing"});let P=await F();if(P){let f=await Ae(P.root);if(f){let I=f.templateName??f.templateId??"Unknown";c.push({name:"Template",ok:true,details:`${I} (${Fe(P.root)})`});let v=Nt(f.requiredHugoVersion,m);v&&c.push(v);}let p=await At(P.root);if(p?.current){let I=p.current;if(p.latest){let V=b.coerce(p.current),H=b.coerce(p.latest);V&&H&&b.eq(V,H)&&(I=`${I} (latest)`);}c.push({name:"blox-tailwind module",ok:true,details:I});let v=$t(p.current,p.latest);v&&c.push(v);}}let A={status:c.some(f=>(f.level??(f.ok?"info":"error"))==="error")?"error":"success",checks:c};if(a){r.json(A);return}for(let f of A.checks){let p=f.level??(f.ok?"info":"error");p==="info"?r.success(`${f.name}: ${f.details}`):p==="warn"?r.warn(`${f.name}: ${f.details}`):r.error(`${f.name}: ${f.details}`);}});}function jt(t){let e=t.match(/v(\d+\.\d+\.\d+)/i);return e?e[1]:t.match(/(\d+\.\d+\.\d+)/)?.[1]}function Nt(t,e){if(!t||!e)return;let o=b.coerce(t),n=b.coerce(e);if(!(!o||!n))return b.lt(n,o)?{name:"Hugo version compatibility",ok:false,details:`Template requires Hugo ${o.version}, but ${n.version} is installed`,level:"error"}:b.major(n)>b.major(o)||b.minor(n)>b.minor(o)?{name:"Hugo version compatibility",ok:true,details:`Using Hugo ${n.version}; template tested with ${o.version}`,level:"warn"}:{name:"Hugo version compatibility",ok:true,details:`Template requires Hugo ${o.version} and you're running ${n.version}`,level:"info"}}async function At(t){let e=u.join(t,"go.mod");try{let o=await g.readFile(e,"utf8"),n=Lt(o,me),r=await Rt();return {current:n,latest:r}}catch{return}}async function Rt(){try{let t=await fetch(`${X}/repos/HugoBlox/hugo-blox-builder/tags?per_page=100`);if(!t.ok)throw new Error(`GitHub responded with status ${t.status}`);return (await t.json()).find(n=>n.name.startsWith("modules/blox-tailwind/")&&/v\d+/.test(n.name))?.name.split("/").pop()}catch{return}}function $t(t,e){if(!t||!e)return;let o=b.coerce(t),n=b.coerce(e);if(!(!o||!n)&&b.lt(o,n))return {name:"blox-tailwind update",ok:false,details:`Current ${o.version}, latest ${n.version}. Run 'hugo mod get ${me}@${n.version}'.`,level:"warn"}}function Lt(t,e){let o=t.split(/\r?\n/),n=false;for(let r of o){let i=r.trim();if(i.startsWith("require (")){n=true;continue}if(n&&i===")"){n=false;continue}if(!n&&i.startsWith("require ")){let a=i.replace("require","").trim().match(new RegExp(`${e}\\s+(v[\\w.-+]+)`));if(a)return a[1]}if(n&&i.startsWith(e)){let s=i.split(/\s+/);if(s[0]===e&&s[1])return s[1]}}}function Ge(t,e){t.command("install").description("Hydrate HugoBlox Pro assets").option("--ci","Fail when prompts would appear").option("--force","Force re-download of assets").option("--path <dir>","Project directory (defaults to cwd)").action(async(o,n)=>{let{logger:r,config:i,telemetry:s}=e,c=!!n.optsWithGlobals().json,d=o.path?{root:u.resolve(o.path),manifestPath:u.join(u.resolve(o.path),"hbx.blocks.json")}:await F();if(!d)throw new l("Unable to locate a HugoBlox project - pass --path if needed");let m=i.getToken();if(!m){if(o.ci)throw new l(`Missing license key. Set ${L} or run hbx login before using --ci.`);r.warn("No Pro license detected, proceeding with OSS assets only");}let h=ut("Hydrating Pro assets...").start();try{let P=u.join(d.root,"config","_default","module.hbx.toml"),y=u.join(d.root,"node_modules","@hugoblox-pro","sample");await x(y),await C(u.join(y,"README.md"),`# HugoBlox Pro assets placeholder
20
+ `),await C(P,`# Generated by hbx install
21
21
  [[module.imports]]
22
22
  path = "github.com/HugoBlox/hugo-blox-builder"
23
23
  [[module.imports]]
24
24
  path = "node_modules/@hugoblox-pro/sample"
25
- `),h.succeed("Assets hydrated");}catch(T){throw h.fail("Failed to hydrate assets"),T}await s.track({name:"install",payload:{ci:!!o.ci,force:!!o.force,tokenPresent:!!m,customPath:!!o.path}});let S={status:"success",path:d.root,forced:!!o.force,token:!!m};c?r.json(S):(r.success("Install complete"),m||r.info("Tip: run hbx login to unlock Pro downloads"));});}var ue="com.hugoblox.cli",Ut=1,Vt=createRequire(import.meta.url),Gt=promisify(z.scrypt),k=null;try{k=Vt("keytar");}catch{k=null;}async function Xe(t,e,o,n,r){let i=`device:${o}`,s,a;if(k)await k.setPassword(ue,i,n);else {let c=await Jt(n,e);s=c.payload,a=c.salt;}t.setDeviceInfo({id:o,label:r,secretAlias:k?i:void 0,secretFallback:s,secretFallbackSalt:a,secretFallbackVersion:s?Ut:void 0}),await t.save();}async function ze(t,e){let o=t.getDeviceInfo();if(!o?.id)return;let n;if(o.secretAlias&&k&&(n=await k.getPassword(ue,o.secretAlias)),!n&&o.secretFallback&&o.secretFallbackSalt)try{let{key:r}=await Je(e,o.secretFallbackSalt);n=zt(o.secretFallback,r);}catch{n=void 0;}if(n)return {id:o.id,secret:n,label:o.label}}async function fe(t){let e=t.getDeviceInfo();e?.secretAlias&&k&&await k.deletePassword(ue,e.secretAlias),t.setDeviceInfo(void 0),await t.save();}function Xt(t,e){let o=z.randomBytes(12),n=z.createCipheriv("aes-256-gcm",e.subarray(0,32),o),r=Buffer.concat([n.update(t,"utf8"),n.final()]),i=n.getAuthTag();return Buffer.concat([o,i,r]).toString("base64")}function zt(t,e){let o=Buffer.from(t,"base64"),n=o.subarray(0,12),r=o.subarray(12,28),i=o.subarray(28),s=z.createDecipheriv("aes-256-gcm",e.subarray(0,32),n);return s.setAuthTag(r),Buffer.concat([s.update(i),s.final()]).toString("utf8")}async function Je(t,e){let o=Buffer.from(e,"base64");return {key:await Gt(t,o,32,{N:32768,r:8,p:1,maxmem:64*1024*1024}),salt:e}}async function Jt(t,e){let o=z.randomBytes(16).toString("base64"),{key:n}=await Je(e,o);return {payload:Xt(t,n),salt:o}}async function E(t,e={}){let o=t.config.getToken();if(!o)throw new l("Set HBX_LICENSE_TOKEN or run 'hbx login' to access Pro content.");let n=await t.config.ensureTelemetryId();if(e.force)await fe(t.config);else {let s=await ze(t.config,n);if(s)return {id:s.id,secret:s.secret}}let r=e.label??ae.hostname(),i=await Kt(t.config,o,n,r);return await Xe(t.config,n,i.deviceId,i.deviceSecret,r),t.logger.debug(`Registered device ${i.deviceId}`),{id:i.deviceId,secret:i.deviceSecret}}async function We(t){await fe(t);}async function Kt(t,e,o,n){let r=await fetch(`${D}/api/license/devices/register`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json","x-telemetry-id":o},body:JSON.stringify({deviceLabel:n})}),i=await qt(r);if(!r.ok)throw i?.code==="license_device_limit"?new l("This license has reached the maximum number of devices. Revoke an existing device and try again."):r.status===401||r.status===403?new l(i?.error??"Unable to register device"):new l(i?.error??`Device registration failed (status ${r.status})`);if(!i?.deviceId||!i?.deviceSecret)throw new l("Device registration response was missing credentials");return i}async function qt(t){try{return await t.json()}catch{return}}async function J(t,e={}){if(e.ci){if(typeof e.initial=="string")return e.initial;throw new l(`Option required in CI mode: ${t}`)}return (await ge({type:"text",name:"value",message:t,initial:e.initial},{onCancel:()=>{throw new R}})).value}async function Ke(t,e,o={}){if(o.ci){if(typeof o.initial=="string")return o.initial;throw new l(`Option required in CI mode: ${t}`)}return (await ge({type:"select",name:"value",message:t,choices:e,initial:0},{onCancel:()=>{throw new R}})).value}async function W(t,e={}){if(e.ci){if(typeof e.initial=="boolean")return e.initial;throw new l(`Confirmation required in CI mode: ${t}`)}return (await ge({type:"confirm",name:"value",message:t,initial:e.initial??true},{onCancel:()=>{throw new R}})).value}function he(t){return t?t.length<=6?"***":`${t.slice(0,3)}***${t.slice(-2)}`:"(none)"}function qe(t,e){let o=t??e;return u.resolve(process.cwd(),o)}function Ye(t,e){t.command("login").description("Authenticate with Hugo Blox Pro and register this device for template access").option("--token <value>","License token").option("--ci","Fail when token is missing").action(async(o,n)=>{let{config:r,logger:i}=e,a=!!n.optsWithGlobals().json,c=o.token;if(!c){if(o.ci)throw new l("Token is required when using --ci");c=await J("Enter your Hugo Blox Pro token");}let d=false;try{r.setToken(c),await r.save(),d=!0,await E(e,{force:!0});let m={status:"success",token:he(c)};a?i.json(m):i.success(`Token saved (${he(c)})`);}catch(m){throw d&&(r.clearToken(),await r.save()),Qt(m)}});}function Qe(t,e){t.command("logout").description("Remove stored Hugo Blox credentials and device secrets").action(async(o,n)=>{let{config:r,logger:i}=e,s=!!n.optsWithGlobals().json;await We(r),r.clearToken(),await r.save();let a={status:"success"};s?i.json(a):i.success("Token removed");});}function Qt(t){let e=t instanceof Error?t.message:"Device registration failed",o="HBX must register this machine before downloading Pro templates. Check your internet connection, ensure your license has a free device slot, or revoke an old device and rerun 'hbx login'.";return t instanceof P?new l(`${e}. ${o}`,t.details):new l(`${e}. ${o}`)}function Zt(t){return t.split("-").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function Ze(t){let{logger:e}=t,o=await eo(e),n=await to(t);return o.length||n.length?[...n,...o]:pe}async function eo(t){try{let e=await fetch(_e,{headers:{"User-Agent":"hbx-cli"}});if(!e.ok)throw new Error(`GitHub responded with status ${e.status}`);return (await e.json()).filter(r=>r.type==="dir").map(r=>({id:r.name,name:Zt(r.name),description:`Starter template ${r.name}`,repoPath:r.path,slug:r.name,source:"oss"}))}catch(e){return t?.debug?.(`Falling back to offline starter metadata: ${String(e)}`),pe}}async function to(t){let{logger:e,config:o}=t,n=new Headers({"User-Agent":"hbx-cli"});try{let i=await o.ensureTelemetryId();n.set("x-telemetry-id",i);}catch{}let r=o.getToken();if(r)try{let i=await E(t);n.set("Authorization",`Bearer ${r}`),n.set("X-HBX-Device-Id",i.id),n.set("X-HBX-Device-Secret",i.secret);}catch(i){e?.debug?.(`Skipping device-auth headers for Pro templates: ${String(i)}`);}try{let i=await fetch(`${D}/api/pro-templates`,{headers:n});if(!i.ok)throw new Error(`catalog responded with status ${i.status}`);return (await i.json()).templates.map(a=>({id:a.id,name:`${a.name} (Pro)`,description:a.description??void 0,repoPath:void 0,slug:a.slug??a.id,source:"pro",version:a.version,sizeBytes:a.sizeBytes,updatedAt:a.updatedAt,commitHash:a.commitHash,downloadEndpoint:a.downloadUrl}))}catch(i){return e.debug(`Unable to fetch Pro template catalog: ${String(i)}`),[]}}async function et(t,e){try{await execa("git",["init"],{cwd:t}),await execa("git",["add","."],{cwd:t}),await execa("git",["commit","-m","chore: initialize site"],{cwd:t,reject:!1}),e.success(`Initialized git repository in ${u.relative(process.cwd(),t)||"."}`);}catch(o){e.warn(`Git initialization skipped: ${String(o)}`);}}async function we(t,e,o={},n=0){let r=t.config.getToken();if(!r)throw new l("A Hugo Blox Pro token is required before accessing Pro templates.");let i=await t.config.ensureTelemetryId(),s=await E(t,{force:n>0}),a=new Headers(o.headers??{});a.set("Authorization",`Bearer ${r}`),a.set("X-HBX-Device-Id",s.id),a.set("X-HBX-Device-Secret",s.secret),a.set("X-Telemetry-Id",i);let c=await fetch(`${D}${e}`,{...o,headers:a});if((c.status===401||c.status===403)&&n===0)return await E(t,{force:true}),we(t,e,o,n+1);if(!c.ok){let d=await no(c);throw d?.code==="license_device_limit"?new l("This license has reached the maximum number of devices. Revoke an existing device and try again."):c.status===401||c.status===403?new l(d?.error??"Device authentication failed."):new l(d?.error??`Request failed (${c.status})`)}return c}async function no(t){try{return await t.json()}catch{return}}var ro=3;async function nt(t,e,o,n){if(e.source==="pro"){await co(t,e,o,n);return}let r=process.env[Be];if(r){await io(e,r,o),n.debug(`Hydrated template ${e.id} from local override`);return}let i=await ao(e,n),s=i!==void 0?u.join(O,e.id,i):void 0;if(s&&await w(s)){await j(s,o),n.debug(`Hydrated template ${e.id} from cache (${i})`);return}let a=await g.mkdtemp(u.join(ae.tmpdir(),"hbx-template-")),c=u.join(a,"repo");try{await execa("git",["clone","--depth","1",He,c],{stdio:"ignore"});let d=await so(c,e);s?(await x(u.dirname(s)),await g.rm(s,{recursive:!0,force:!0}),await g.cp(d,s,{recursive:!0}),await rt(u.join(O,e.id)),await j(s,o),n.debug(`Hydrated template ${e.id} from fresh cache (${i})`)):(await j(d,o),n.debug(`Hydrated template ${e.id} from repository`));}catch(d){throw new l("Failed to clone Hugo Blox templates. Ensure git is installed and accessible.",{error:d})}finally{await g.rm(a,{recursive:true,force:true});}}async function io(t,e,o){let n=u.join(e,t.id);try{await g.access(n);}catch(r){throw new l(`Local template not found at ${n}`,{error:r})}await j(n,o);}async function so(t,e){let o=e.repoPath??"",n=u.join(t,o);return await g.access(n),n}async function j(t,e){await g.rm(e,{recursive:true,force:true}),await x(u.dirname(e)),await g.cp(t,e,{recursive:true}),await g.rm(u.join(e,".git"),{recursive:true,force:true});}async function rt(t){if(!await w(t))return;let e=await g.readdir(t,{withFileTypes:true}),o=await Promise.all(e.filter(n=>n.isDirectory()).map(async n=>{let r=u.join(t,n.name),i=await g.stat(r);return {path:r,mtimeMs:i.mtimeMs}}));o.sort((n,r)=>r.mtimeMs-n.mtimeMs);for(let n of o.slice(ro))await g.rm(n.path,{recursive:true,force:true});}async function ao(t,e){let o=encodeURIComponent(t.repoPath??""),n=`${X}/repos/HugoBlox/hugo-blox-builder/commits?path=${o}&per_page=1`;try{let r=await fetch(n,{headers:{"User-Agent":"hbx-cli"}});if(!r.ok)throw new Error(`GitHub responded with status ${r.status}`);return (await r.json())[0]?.sha}catch(r){e.debug(`Unable to determine latest template commit for ${t.id}: ${String(r)}`);return}}async function co(t,e,o,n){let r=e.version?u.join(O,e.id,e.version):void 0;if(r&&await w(r)){await j(r,o),n.debug(`Hydrated Pro template ${e.id} from cache (${e.version})`);return}let i=await g.mkdtemp(u.join(ae.tmpdir(),"hbx-pro-template-")),s=u.join(i,"template.tgz"),a=u.join(i,"extract");await x(a);try{let c=await lo(t,e,s);await execa("tar",["-xzf",s,"-C",a]);let d=await mo(a,e.slug),m=e.version??c.version??void 0,h=m!==void 0?u.join(O,e.id,m):void 0;h?(await x(u.dirname(h)),await g.rm(h,{recursive:!0,force:!0}),await g.cp(d,h,{recursive:!0}),await rt(u.join(O,e.id)),await j(h,o),n.debug(`Hydrated Pro template ${e.id} from fresh cache (${m})`)):(await j(d,o),n.debug(`Hydrated Pro template ${e.id} from archive`));}catch(c){throw new l(`Failed to download Pro template ${e.name}. Ensure your license is valid and try again.`,{error:c})}finally{await g.rm(i,{recursive:true,force:true});}}async function lo(t,e,o){let n=e.downloadEndpoint??`/api/pro-templates/${encodeURIComponent(e.id)}/download`,r=await we(t,n),i=await po(r);if(!i?.url)throw new l("Pro template download URL was missing");let s=await fetch(i.url);if(!s.ok)throw new l(`Pro template archive download failed (${s.status})`);let a=Buffer.from(await s.arrayBuffer());return await g.writeFile(o,a),{version:i.version}}async function mo(t,e){let o=await g.readdir(t,{withFileTypes:true}),n=o.find(i=>i.isDirectory()&&i.name===e);if(n)return u.join(t,n.name);let r=o.filter(i=>i.isDirectory());return r.length===1?u.join(t,r[0].name):t}async function po(t){try{return await t.json()}catch{return}}var it="https://hugoblox.com/discord",st="https://docs.hugoblox.com",at="https://hugoblox.com/pro";function be(t){return t.trim().toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}async function dt(t,e,o,n){let{logger:r}=t;await nt(t,o,e,r),await fo(e,o),n.sampleContent||await ho(e,o);}async function mt(t,e,o){o.info(`\u{1F4E6} Installing dependencies with ${e}...`);let n={...process.env},r=["install"],i=!o.isJsonMode();e==="pnpm"&&(n.PNPM_WORKSPACE_DIR=t,n.PNPM_IGNORE_WORKSPACE_ROOT_CHECK="1",await uo(t),r.push("--no-link-workspace-packages"));try{return await execa(e,r,{cwd:t,stdio:i?"ignore":"inherit",env:n}),o.success("\u2705 Dependencies installed"),!0}catch(s){return i?o.warn(`\u26A0\uFE0F Failed to install dependencies automatically. Run ${e} install inside ${t}`):o.warn(`\u26A0\uFE0F Failed to install dependencies automatically: ${String(s)}`),false}}async function uo(t){let e=u.join(t,"pnpm-workspace.yaml");if(await w(e))return;await C(e,`packages:
25
+ `),h.succeed("Assets hydrated");}catch(P){throw h.fail("Failed to hydrate assets"),P}await s.track({name:"install",payload:{ci:!!o.ci,force:!!o.force,tokenPresent:!!m,customPath:!!o.path}});let S={status:"success",path:d.root,forced:!!o.force,token:!!m};c?r.json(S):(r.success("Install complete"),m||r.info("Tip: run hbx login to unlock Pro downloads"));});}var ue="com.hugoblox.cli",Ut=1,Vt=createRequire(import.meta.url),Gt=promisify(z.scrypt),k=null;try{k=Vt("keytar");}catch{k=null;}async function Xe(t,e,o,n,r){let i=`device:${o}`,s,a;if(k)await k.setPassword(ue,i,n);else {let c=await Jt(n,e);s=c.payload,a=c.salt;}t.setDeviceInfo({id:o,label:r,secretAlias:k?i:void 0,secretFallback:s,secretFallbackSalt:a,secretFallbackVersion:s?Ut:void 0}),await t.save();}async function ze(t,e){let o=t.getDeviceInfo();if(!o?.id)return;let n;if(o.secretAlias&&k&&(n=await k.getPassword(ue,o.secretAlias)),!n&&o.secretFallback&&o.secretFallbackSalt)try{let{key:r}=await Je(e,o.secretFallbackSalt);n=zt(o.secretFallback,r);}catch{n=void 0;}if(n)return {id:o.id,secret:n,label:o.label}}async function fe(t){let e=t.getDeviceInfo();e?.secretAlias&&k&&await k.deletePassword(ue,e.secretAlias),t.setDeviceInfo(void 0),await t.save();}function Xt(t,e){let o=z.randomBytes(12),n=z.createCipheriv("aes-256-gcm",e.subarray(0,32),o),r=Buffer.concat([n.update(t,"utf8"),n.final()]),i=n.getAuthTag();return Buffer.concat([o,i,r]).toString("base64")}function zt(t,e){let o=Buffer.from(t,"base64"),n=o.subarray(0,12),r=o.subarray(12,28),i=o.subarray(28),s=z.createDecipheriv("aes-256-gcm",e.subarray(0,32),n);return s.setAuthTag(r),Buffer.concat([s.update(i),s.final()]).toString("utf8")}async function Je(t,e){let o=Buffer.from(e,"base64");return {key:await Gt(t,o,32,{N:32768,r:8,p:1,maxmem:64*1024*1024}),salt:e}}async function Jt(t,e){let o=z.randomBytes(16).toString("base64"),{key:n}=await Je(e,o);return {payload:Xt(t,n),salt:o}}async function E(t,e={}){let o=t.config.getToken();if(!o)throw new l("Set HBX_LICENSE_TOKEN or run 'hbx login' to access Pro content.");let n=await t.config.ensureTelemetryId();if(e.force)await fe(t.config);else {let s=await ze(t.config,n);if(s)return {id:s.id,secret:s.secret}}let r=e.label??ae.hostname(),i=await Kt(t.config,o,n,r);return await Xe(t.config,n,i.deviceId,i.deviceSecret,r),t.logger.debug(`Registered device ${i.deviceId}`),{id:i.deviceId,secret:i.deviceSecret}}async function We(t){await fe(t);}async function Kt(t,e,o,n){let r=await fetch(`${D}/api/license/devices/register`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json","x-telemetry-id":o},body:JSON.stringify({deviceLabel:n})}),i=await qt(r);if(!r.ok)throw i?.code==="license_device_limit"?new l("This license has reached the maximum number of devices. Revoke an existing device and try again."):r.status===401||r.status===403?new l(i?.error??"Unable to register device"):new l(i?.error??`Device registration failed (status ${r.status})`);if(!i?.deviceId||!i?.deviceSecret)throw new l("Device registration response was missing credentials");return i}async function qt(t){try{return await t.json()}catch{return}}async function J(t,e={}){if(e.ci){if(typeof e.initial=="string")return e.initial;throw new l(`Option required in CI mode: ${t}`)}return (await ge({type:"text",name:"value",message:t,initial:e.initial},{onCancel:()=>{throw new $}})).value}async function Ke(t,e,o={}){if(o.ci){if(typeof o.initial=="string")return o.initial;throw new l(`Option required in CI mode: ${t}`)}return (await ge({type:"select",name:"value",message:t,choices:e,initial:0},{onCancel:()=>{throw new $}})).value}async function W(t,e={}){if(e.ci){if(typeof e.initial=="boolean")return e.initial;throw new l(`Confirmation required in CI mode: ${t}`)}return (await ge({type:"confirm",name:"value",message:t,initial:e.initial??true},{onCancel:()=>{throw new $}})).value}function he(t){return t?t.length<=6?"***":`${t.slice(0,3)}***${t.slice(-2)}`:"(none)"}function qe(t,e){let o=t??e;return u.resolve(process.cwd(),o)}function Ye(t,e){t.command("login").description("Authenticate with HugoBlox Pro and register this device for template access").option("--token <value>","License key").option("--ci","Fail when license key is missing").action(async(o,n)=>{let{config:r,logger:i}=e,a=!!n.optsWithGlobals().json,c=o.token;if(!c){if(o.ci)throw new l("License key is required when using --ci");c=await J("Enter your HugoBlox Pro license key");}let d=false;try{r.setToken(c),await r.save(),d=!0,await E(e,{force:!0});let m={status:"success",token:he(c)};a?i.json(m):i.success(`License key saved (${he(c)})`);}catch(m){throw d&&(r.clearToken(),await r.save()),Qt(m)}});}function Qe(t,e){t.command("logout").description("Remove stored HugoBlox credentials and device secrets").action(async(o,n)=>{let{config:r,logger:i}=e,s=!!n.optsWithGlobals().json;await We(r),r.clearToken(),await r.save();let a={status:"success"};s?i.json(a):i.success("License key removed");});}function Qt(t){let e=t instanceof Error?t.message:"Device registration failed",o="HBX must register this machine before downloading Pro templates. Check your internet connection, ensure your license has a free device slot, or revoke an old device and rerun 'hbx login'.";return t instanceof T?new l(`${e}. ${o}`,t.details):new l(`${e}. ${o}`)}function Zt(t){return t.split("-").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function Ze(t){let{logger:e}=t,o=await eo(e),n=await to(t);return o.length||n.length?[...n,...o]:pe}async function eo(t){try{let e=await fetch(_e,{headers:{"User-Agent":"hbx-cli"}});if(!e.ok)throw new Error(`GitHub responded with status ${e.status}`);return (await e.json()).filter(r=>r.type==="dir").map(r=>({id:r.name,name:Zt(r.name),description:`Starter template ${r.name}`,repoPath:r.path,slug:r.name,source:"oss"}))}catch(e){return t?.debug?.(`Falling back to offline starter metadata: ${String(e)}`),pe}}async function to(t){let{logger:e,config:o}=t,n=new Headers({"User-Agent":"hbx-cli"});try{let i=await o.ensureTelemetryId();n.set("x-telemetry-id",i);}catch{}let r=o.getToken();if(r)try{let i=await E(t);n.set("Authorization",`Bearer ${r}`),n.set("X-HBX-Device-Id",i.id),n.set("X-HBX-Device-Secret",i.secret);}catch(i){e?.debug?.(`Skipping device-auth headers for Pro templates: ${String(i)}`);}try{let i=await fetch(`${D}/api/pro-templates`,{headers:n});if(!i.ok)throw new Error(`catalog responded with status ${i.status}`);return (await i.json()).templates.map(a=>({id:a.id,name:`${a.name} (Pro)`,description:a.description??void 0,repoPath:void 0,slug:a.slug??a.id,source:"pro",version:a.version,sizeBytes:a.sizeBytes,updatedAt:a.updatedAt,commitHash:a.commitHash,downloadEndpoint:a.downloadUrl}))}catch(i){return e.debug(`Unable to fetch Pro template catalog: ${String(i)}`),[]}}async function et(t,e){try{await execa("git",["init"],{cwd:t}),await execa("git",["add","."],{cwd:t}),await execa("git",["commit","-m","chore: initialize site"],{cwd:t,reject:!1}),e.success(`Initialized git repository in ${u.relative(process.cwd(),t)||"."}`);}catch(o){e.warn(`Git initialization skipped: ${String(o)}`);}}async function we(t,e,o={},n=0){let r=t.config.getToken();if(!r)throw new l("A HugoBlox Pro license key is required before accessing Pro templates.");let i=await t.config.ensureTelemetryId(),s=await E(t,{force:n>0}),a=new Headers(o.headers??{});a.set("Authorization",`Bearer ${r}`),a.set("X-HBX-Device-Id",s.id),a.set("X-HBX-Device-Secret",s.secret),a.set("X-Telemetry-Id",i);let c=await fetch(`${D}${e}`,{...o,headers:a});if((c.status===401||c.status===403)&&n===0)return await E(t,{force:true}),we(t,e,o,n+1);if(!c.ok){let d=await no(c);throw d?.code==="license_device_limit"?new l("This license has reached the maximum number of devices. Revoke an existing device and try again."):c.status===401||c.status===403?new l(d?.error??"Device authentication failed."):new l(d?.error??`Request failed (${c.status})`)}return c}async function no(t){try{return await t.json()}catch{return}}var ro=3;async function nt(t,e,o,n){if(e.source==="pro"){await co(t,e,o,n);return}let r=process.env[Be];if(r){await io(e,r,o),n.debug(`Hydrated template ${e.id} from local override`);return}let i=await ao(e,n),s=i!==void 0?u.join(O,e.id,i):void 0;if(s&&await w(s)){await j(s,o),n.debug(`Hydrated template ${e.id} from cache (${i})`);return}let a=await g.mkdtemp(u.join(ae.tmpdir(),"hbx-template-")),c=u.join(a,"repo");try{await execa("git",["clone","--depth","1",He,c],{stdio:"ignore"});let d=await so(c,e);s?(await x(u.dirname(s)),await g.rm(s,{recursive:!0,force:!0}),await g.cp(d,s,{recursive:!0}),await rt(u.join(O,e.id)),await j(s,o),n.debug(`Hydrated template ${e.id} from fresh cache (${i})`)):(await j(d,o),n.debug(`Hydrated template ${e.id} from repository`));}catch(d){throw new l("Failed to clone HugoBlox templates. Ensure git is installed and accessible.",{error:d})}finally{await g.rm(a,{recursive:true,force:true});}}async function io(t,e,o){let n=u.join(e,t.id);try{await g.access(n);}catch(r){throw new l(`Local template not found at ${n}`,{error:r})}await j(n,o);}async function so(t,e){let o=e.repoPath??"",n=u.join(t,o);return await g.access(n),n}async function j(t,e){await g.rm(e,{recursive:true,force:true}),await x(u.dirname(e)),await g.cp(t,e,{recursive:true}),await g.rm(u.join(e,".git"),{recursive:true,force:true});}async function rt(t){if(!await w(t))return;let e=await g.readdir(t,{withFileTypes:true}),o=await Promise.all(e.filter(n=>n.isDirectory()).map(async n=>{let r=u.join(t,n.name),i=await g.stat(r);return {path:r,mtimeMs:i.mtimeMs}}));o.sort((n,r)=>r.mtimeMs-n.mtimeMs);for(let n of o.slice(ro))await g.rm(n.path,{recursive:true,force:true});}async function ao(t,e){let o=encodeURIComponent(t.repoPath??""),n=`${X}/repos/HugoBlox/hugo-blox-builder/commits?path=${o}&per_page=1`;try{let r=await fetch(n,{headers:{"User-Agent":"hbx-cli"}});if(!r.ok)throw new Error(`GitHub responded with status ${r.status}`);return (await r.json())[0]?.sha}catch(r){e.debug(`Unable to determine latest template commit for ${t.id}: ${String(r)}`);return}}async function co(t,e,o,n){let r=e.version?u.join(O,e.id,e.version):void 0;if(r&&await w(r)){await j(r,o),n.debug(`Hydrated Pro template ${e.id} from cache (${e.version})`);return}let i=await g.mkdtemp(u.join(ae.tmpdir(),"hbx-pro-template-")),s=u.join(i,"template.tgz"),a=u.join(i,"extract");await x(a);try{let c=await lo(t,e,s);await execa("tar",["-xzf",s,"-C",a]);let d=await mo(a,e.slug),m=e.version??c.version??void 0,h=m!==void 0?u.join(O,e.id,m):void 0;h?(await x(u.dirname(h)),await g.rm(h,{recursive:!0,force:!0}),await g.cp(d,h,{recursive:!0}),await rt(u.join(O,e.id)),await j(h,o),n.debug(`Hydrated Pro template ${e.id} from fresh cache (${m})`)):(await j(d,o),n.debug(`Hydrated Pro template ${e.id} from archive`));}catch(c){throw new l(`Failed to download Pro template ${e.name}. Ensure your license is valid and try again.`,{error:c})}finally{await g.rm(i,{recursive:true,force:true});}}async function lo(t,e,o){let n=e.downloadEndpoint??`/api/pro-templates/${encodeURIComponent(e.id)}/download`,r=await we(t,n),i=await po(r);if(!i?.url)throw new l("Pro template download URL was missing");let s=await fetch(i.url);if(!s.ok)throw new l(`Pro template archive download failed (${s.status})`);let a=Buffer.from(await s.arrayBuffer());return await g.writeFile(o,a),{version:i.version}}async function mo(t,e){let o=await g.readdir(t,{withFileTypes:true}),n=o.find(i=>i.isDirectory()&&i.name===e);if(n)return u.join(t,n.name);let r=o.filter(i=>i.isDirectory());return r.length===1?u.join(t,r[0].name):t}async function po(t){try{return await t.json()}catch{return}}var it="https://hugoblox.com/discord",st="https://docs.hugoblox.com",at="https://hugoblox.com/pro";function be(t){return t.trim().toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}async function dt(t,e,o,n){let{logger:r}=t;await nt(t,o,e,r),await fo(e,o),n.sampleContent||await ho(e,o);}async function mt(t,e,o){o.info(`\u{1F4E6} Installing dependencies with ${e}...`);let n={...process.env},r=["install"],i=!o.isJsonMode();e==="pnpm"&&(n.PNPM_WORKSPACE_DIR=t,n.PNPM_IGNORE_WORKSPACE_ROOT_CHECK="1",await uo(t),r.push("--no-link-workspace-packages"));try{return await execa(e,r,{cwd:t,stdio:i?"ignore":"inherit",env:n}),o.success("\u2705 Dependencies installed"),!0}catch(s){return i?o.warn(`\u26A0\uFE0F Failed to install dependencies automatically. Run ${e} install inside ${t}`):o.warn(`\u26A0\uFE0F Failed to install dependencies automatically: ${String(s)}`),false}}async function uo(t){let e=u.join(t,"pnpm-workspace.yaml");if(await w(e))return;await C(e,`packages:
26
26
  - './*'
27
27
  `);}async function pt(t,e,o){o.info("\u{1F525} Starting dev server with Hugo (press Ctrl+C to exit)...");let n={...process.env};e==="pnpm"&&(n.PNPM_WORKSPACE_DIR=t);try{await execa(e,["dev"],{cwd:t,stdio:"inherit",env:n}),o.success("\u2705 Dev server stopped");}catch(r){let i=r;if(i.signal==="SIGINT"||i.signal==="SIGTERM"){o.info("\u2705 Dev server stopped");return}if(r?.code==="ENOENT"||/[hH]ugo/.test(String(i.stderr))){o.error("Hugo executable not found. Install Hugo (https://gohugo.io/getting-started/installing/) or deploy with the Copilot at https://hugoblox.com/templates/");return}throw o.error(`Dev server exited with an error: ${String(r)}`),r}}async function fo(t,e,o){let n=be(u.basename(t))||e.slug;await go(t,n);let r={"README.md":`# ${e.name}
28
28
 
29
- This site was created with the Hugo Blox CLI.
29
+ This site was created with the HugoBlox CLI.
30
30
  `,".gitignore":`node_modules
31
31
  .cache
32
32
  .env
@@ -44,7 +44,7 @@ design:
44
44
  sections:
45
45
  - block: hero
46
46
  content:
47
- eyebrow: "You're live on Hugo Blox"
47
+ eyebrow: "You're live on HugoBlox"
48
48
  title: "Great job launching ${t.name}"
49
49
  text: "Start customizing blocks to launch your next experience."
50
50
  primary_action:
@@ -69,11 +69,13 @@ sections:
69
69
  2. Explore the [documentation](${st}) to learn how to add blocks, deploy, and automate.
70
70
  3. [Upgrade to Pro](${at}) to unlock premium blocks, design systems, and automation-ready packages.
71
71
  4. Share feedback and showcase your build to help the ecosystem grow.
72
- `}function wo(t,e){if(!e)return;let o=e.toLowerCase(),n=t.find(r=>{let i=r.id.toLowerCase(),s=r.slug?.toLowerCase();return i===o||s===o});if(n)return n;if(e.startsWith("http")||e.startsWith("git@"))return {id:e,name:"Custom template",description:`External template: ${e}`,repoPath:e,slug:"custom",source:"custom"}}function gt(t,e){t.command("create").description("Create a new Hugo Blox site").argument("[dir]","Target directory (defaults to template slug, e.g., new-site)").option("--template <id>","Starter template ID").option("--dir <path>","Target directory").option("--package-manager <name>","Package manager","pnpm").option("--no-install","Skip dependency installation").option("--git","Initialize a git repository").option("--ci","Run in non-interactive mode").option("--sample-content","Force include sample content").option("--no-sample-content","Skip sample content").option("--pro","Mark the project as Pro ready").option("--preview","Automatically start the dev server after setup").option("--no-preview","Skip the dev server prompt").action(async(n,r,i)=>{let{logger:s,config:a,telemetry:c}=e,m=!!i.optsWithGlobals().json,h=ut({text:"Fetching templates...",spinner:"dots"}).start(),S=await Ze(e).finally(()=>{h.succeed("\u2728 Templates ready");}),y=wo(S,r.template);if(!y){if(r.ci)throw new l("Template must be specified when running with --ci");let $=await Ke("Select a starter",S.map(B=>({title:B.name,description:B.description,value:B.id})));y=S.find(B=>B.id===$);}if(!y)throw new l("Unable to determine template");let A=y.source==="pro",f=await vo(r,n,y),p=qe(f,y.slug);await Te(p);let I=typeof r.sampleContent=="boolean"?r.sampleContent:typeof r.noSampleContent=="boolean"?!r.noSampleContent:r.ci?false:await W("Include sample content? (recommended)",{initial:true}),v=A;if(!A)v=typeof r.pro=="boolean"?r.pro:r.ci?false:await W("Do you have a Hugo Blox Pro license?",{initial:!!a.getToken()});else if(!a.getToken()){if(r.ci)throw new l(`"${y.name}" is a Hugo Blox Pro template. Set HBX_LICENSE_TOKEN with your license key before running in CI.`);if(s.info(`"${y.name}" is part of Hugo Blox Pro. Purchase a license at https://hugoblox.com/pro to receive your key via email (powered by Lemon Squeezy).`),!await W("Do you have a Hugo Blox Pro license key to enter now?",{initial:true}))throw new l("Pro templates require an active license. Purchase at https://hugoblox.com/pro and rerun this command after running 'hbx login' or setting HBX_LICENSE_TOKEN.");let B=await ft(a.getToken());a.setToken(B),await a.save();}if(!A&&v&&!a.getToken()){if(r.ci)throw new l("Set HBX_LICENSE_TOKEN before running --ci when enabling Pro features.");let $=await ft(a.getToken());a.setToken($),await a.save();}v&&await E(e);let V=ut(`Creating site in ${u.relative(process.cwd(),p)||"."}...`).start();try{await dt(e,p,y,{sampleContent:I,includeEnv:!0,packageManager:r.packageManager??"pnpm"}),V.succeed("Files generated");}catch($){throw V.fail("Failed to scaffold site"),$}let H=false;r.install!==false?H=await mt(p,r.packageManager??"pnpm",s):s.info("Skipping dependency installation"),r.git&&await et(p,s);let Et={status:"success",template:y.id,path:p,pro:v,manifest:u.join(p,oe)};!H&&r.preview?s.warn("\u26A0\uFE0F Cannot start the dev server because dependencies failed to install."):r.install===false&&r.preview&&s.warn("\u26A0\uFE0F Install dependencies first (skip --no-install) to start the dev server automatically.");let le=false;if(H&&(le=await bo(r,m)),await c.track({name:"new-site",payload:{template:y.id,sample:I,pro:v,ci:!!r.ci,packageManager:r.packageManager??"pnpm",install:r.install!==false,dependenciesReady:H,preview:le}}),le){await pt(p,r.packageManager??"pnpm",s);return}if(m){s.json(Et);return}s.success(`\u2705 Site created at ${p}`),s.info("\u{1F680} Next steps:"),s.info(` \u{1F449} cd ${u.relative(process.cwd(),p)||p}`),r.install===false&&s.info(` \u{1F449} ${r.packageManager??"pnpm"} install`),s.info(" \u{1F449} pnpm dev");});}async function bo(t,e){return e||t.ci?false:typeof t.preview=="boolean"?t.preview:t.noPreview?false:W("Start the dev server now?",{initial:true})}async function vo(t,e,o){if(t.dir)return t.dir;if(e)return e;if(t.ci)return o.slug;let r=(await J("Project folder name",{initial:o.slug})).trim();return r?xo(r)?r:be(r)||o.slug:o.slug}function xo(t){return /[\\/]/.test(t)||t.includes(":")}async function ft(t){let o=(await J("Enter your Hugo Blox Pro license key (from your purchase confirmation email)",{initial:t??""})).trim();if(!o)throw new l("A Hugo Blox Pro license key is required to continue. Check your purchase email or visit https://hugoblox.com/pro.");return o}function ht(t,e){let o=t.command("telemetry").description("Manage Hugo Blox telemetry preferences");o.command("enable").description("Enable anonymous telemetry").action(async()=>{e.config.setTelemetryEnabled(true),await e.config.save(),e.logger.success("Telemetry enabled. Thanks for helping improve Hugo Blox!");}),o.command("disable").description("Disable telemetry collection").action(async()=>{e.config.setTelemetryEnabled(false),await e.config.save(),e.logger.success("Telemetry disabled. You can re-enable it anytime.");}),o.command("status").description("Show whether telemetry is enabled").action(()=>{let n=e.config.isTelemetryEnabled();e.logger.info(`Telemetry is ${n?"enabled":"disabled"}.`);}),o.action(()=>{let n=e.config.isTelemetryEnabled();e.logger.info(`Telemetry is ${n?"enabled":"disabled"}.`),e.logger.info("Use 'hbx telemetry enable|disable' to change the setting.");});}var N;function ne(){if(N)return N;let t=process.env.HBX_CLI_VERSION??process.env.npm_package_version;if(t)return N=t,N;let e=Co(import.meta.url);try{let o=yt.readFileSync(e,"utf8");N=JSON.parse(o).version??"0.0.0";}catch{N="0.0.0";}return N}function Co(t){let e=u.dirname(fileURLToPath(t)),o=u.resolve(e,"../package.json");return yt.existsSync(o)?o:u.resolve(e,"../../package.json")}function wt(t,e){t.command("version").description("Print CLI version").action((o,n)=>{let{logger:r}=e,i=!!n.optsWithGlobals().json,s=ne(),a={status:"success",version:s};i?r.json(a):r.info(`hbx ${s}`);});}var ie=class t{#e;constructor(e){this.#e=e;}static async load(){try{let e=await g.readFile(ee,"utf8"),o=JSON.parse(e);return new t(o)}catch(e){if(e.code==="ENOENT")return new t({});throw new q("Failed to read configuration",{error:e})}}toJSON(){return this.#e}getToken(){return process.env[L]??this.#e.token}setToken(e){this.#e={...this.#e,token:e};}clearToken(){let e={...this.#e};e.token=void 0,e.device=void 0,this.#e=e;}isTelemetryEnabled(){return process.env[Se]==="1"?false:typeof this.#e.telemetry?.enabled=="boolean"?this.#e.telemetry.enabled:true}setTelemetryEnabled(e){this.#e={...this.#e,telemetry:{...this.#e.telemetry,enabled:e,lastPrompted:Date.now()}};}getTelemetryId(){return this.#e.telemetry?.id}async ensureTelemetryId(){let e=this.getTelemetryId();if(e)return e;let o=z.randomUUID();return this.#e={...this.#e,telemetry:{...this.#e.telemetry,id:o}},await this.save(),o}getDefaultTemplate(){return this.#e.defaults?.template}getUpdateMetadata(){return this.#e.updates}setUpdateMetadata(e){this.#e={...this.#e,updates:{...this.#e.updates,...e}};}getDeviceInfo(){return this.#e.device}setDeviceInfo(e){this.#e={...this.#e,device:e};}async save(){await g.mkdir(de,{recursive:true});let e=JSON.stringify(this.#e,null,2);await g.writeFile(ee,e,{mode:384}),await g.chmod(ee,384);}};var se=class{#e;#t;constructor(e={}){this.#e=e.json??false,this.#t=e.debug??process.env[G]==="1";}isJsonMode(){return this.#e}setJsonMode(e){this.#e=e;}setDebug(e){this.#t=e;}info(e){this.#e||process.stdout.write(`${K.blue("i")} ${e}
72
+ `}function wo(t,e){if(!e)return;let o=e.toLowerCase(),n=t.find(r=>{let i=r.id.toLowerCase(),s=r.slug?.toLowerCase();return i===o||s===o});if(n)return n;if(e.startsWith("http")||e.startsWith("git@"))return {id:e,name:"Custom template",description:`External template: ${e}`,repoPath:e,slug:"custom",source:"custom"}}function gt(t,e){t.command("create").description("Create a new HugoBlox site").argument("[dir]","Target directory (defaults to template slug, e.g., new-site)").option("--template <id>","Starter template ID").option("--dir <path>","Target directory").option("--package-manager <name>","Package manager","pnpm").option("--no-install","Skip dependency installation").option("--git","Initialize a git repository").option("--ci","Run in non-interactive mode").option("--sample-content","Force include sample content").option("--no-sample-content","Skip sample content").option("--pro","Mark the project as Pro ready").option("--preview","Automatically start the dev server after setup").option("--no-preview","Skip the dev server prompt").action(async(n,r,i)=>{let{logger:s,config:a,telemetry:c}=e,m=!!i.optsWithGlobals().json,h=ut({text:"Fetching templates...",spinner:"dots"}).start(),S=await Ze(e).finally(()=>{h.succeed("\u2728 Templates ready");}),y=wo(S,r.template);if(!y){if(r.ci)throw new l("Template must be specified when running with --ci");let R=await Ke("Select a starter",S.map(B=>({title:B.name,description:B.description,value:B.id})));y=S.find(B=>B.id===R);}if(!y)throw new l("Unable to determine template");let A=y.source==="pro",f=await vo(r,n,y),p=qe(f,y.slug);await Pe(p);let I=typeof r.sampleContent=="boolean"?r.sampleContent:typeof r.noSampleContent=="boolean"?!r.noSampleContent:r.ci?false:await W("Include sample content? (recommended)",{initial:true}),v=A;if(!A)v=typeof r.pro=="boolean"?r.pro:r.ci?false:await W("Do you have a HugoBlox Pro license?",{initial:!!a.getToken()});else if(!a.getToken()){if(r.ci)throw new l(`"${y.name}" is a HugoBlox Pro template. Set HBX_LICENSE_TOKEN with your license key before running in CI.`);if(s.info(`"${y.name}" is part of HugoBlox Pro. Purchase a license at https://hugoblox.com/pro to receive your key via email (powered by Lemon Squeezy).`),!await W("Do you have a HugoBlox Pro license key to enter now?",{initial:true}))throw new l("Pro templates require an active license. Purchase at https://hugoblox.com/pro and rerun this command after running 'hbx login' or setting HBX_LICENSE_TOKEN.");let B=await ft(a.getToken());a.setToken(B),await a.save();}if(!A&&v&&!a.getToken()){if(r.ci)throw new l("Set HBX_LICENSE_TOKEN before running --ci when enabling Pro features.");let R=await ft(a.getToken());a.setToken(R),await a.save();}v&&await E(e);let V=ut(`Creating site in ${u.relative(process.cwd(),p)||"."}...`).start();try{await dt(e,p,y,{sampleContent:I,includeEnv:!0,packageManager:r.packageManager??"pnpm"}),V.succeed("Files generated");}catch(R){throw V.fail("Failed to scaffold site"),R}let H=false;r.install!==false?H=await mt(p,r.packageManager??"pnpm",s):s.info("Skipping dependency installation"),r.git&&await et(p,s);let Et={status:"success",template:y.id,path:p,pro:v,manifest:u.join(p,oe)};!H&&r.preview?s.warn("\u26A0\uFE0F Cannot start the dev server because dependencies failed to install."):r.install===false&&r.preview&&s.warn("\u26A0\uFE0F Install dependencies first (skip --no-install) to start the dev server automatically.");let le=false;if(H&&(le=await bo(r,m)),await c.track({name:"new-site",payload:{template:y.id,sample:I,pro:v,ci:!!r.ci,packageManager:r.packageManager??"pnpm",install:r.install!==false,dependenciesReady:H,preview:le}}),le){await pt(p,r.packageManager??"pnpm",s);return}if(m){s.json(Et);return}s.success(`\u2705 Site created at ${p}`),s.info("\u{1F680} Next steps:"),s.info(` \u{1F449} cd ${u.relative(process.cwd(),p)||p}`),r.install===false&&s.info(` \u{1F449} ${r.packageManager??"pnpm"} install`),s.info(" \u{1F449} pnpm dev");});}async function bo(t,e){return e||t.ci?false:typeof t.preview=="boolean"?t.preview:t.noPreview?false:W("Start the dev server now?",{initial:true})}async function vo(t,e,o){if(t.dir)return t.dir;if(e)return e;if(t.ci)return o.slug;let r=(await J("Project folder name",{initial:o.slug})).trim();return r?xo(r)?r:be(r)||o.slug:o.slug}function xo(t){return /[\\/]/.test(t)||t.includes(":")}async function ft(t){let o=(await J("Enter your HugoBlox Pro license key (from your purchase confirmation email)",{initial:t??""})).trim();if(!o)throw new l("A HugoBlox Pro license key is required to continue. Check your purchase email or visit https://hugoblox.com/pro.");return o}function ht(t,e){let o=t.command("telemetry").description("Manage HugoBlox telemetry preferences");o.command("enable").description("Enable anonymous telemetry").action(async()=>{e.config.setTelemetryEnabled(true),await e.config.save(),e.logger.success("Telemetry enabled. Thanks for helping improve HugoBlox!");}),o.command("disable").description("Disable telemetry collection").action(async()=>{e.config.setTelemetryEnabled(false),await e.config.save(),e.logger.success("Telemetry disabled. You can re-enable it anytime.");}),o.command("status").description("Show whether telemetry is enabled").action(()=>{let n=e.config.isTelemetryEnabled();e.logger.info(`Telemetry is ${n?"enabled":"disabled"}.`);}),o.action(()=>{let n=e.config.isTelemetryEnabled();e.logger.info(`Telemetry is ${n?"enabled":"disabled"}.`),e.logger.info("Use 'hbx telemetry enable|disable' to change the setting.");});}var N;function ne(){if(N)return N;let t=process.env.HBX_CLI_VERSION??process.env.npm_package_version;if(t)return N=t,N;let e=Co(import.meta.url);try{let o=yt.readFileSync(e,"utf8");N=JSON.parse(o).version??"0.0.0";}catch{N="0.0.0";}return N}function Co(t){let e=u.dirname(fileURLToPath(t)),o=u.resolve(e,"../package.json");return yt.existsSync(o)?o:u.resolve(e,"../../package.json")}function wt(t,e){t.command("version").description("Print CLI version").action((o,n)=>{let{logger:r}=e,i=!!n.optsWithGlobals().json,s=ne(),a={status:"success",version:s};i?r.json(a):r.info(`hbx ${s}`);});}var ie=class t{#e;constructor(e){this.#e=e;}static async load(){try{let e=await g.readFile(ee,"utf8"),o=JSON.parse(e);return new t(o)}catch(e){if(e.code==="ENOENT")return new t({});throw new q("Failed to read configuration",{error:e})}}toJSON(){return this.#e}getToken(){return process.env[L]??this.#e.token}setToken(e){this.#e={...this.#e,token:e};}clearToken(){let e={...this.#e};e.token=void 0,e.device=void 0,this.#e=e;}isTelemetryEnabled(){return process.env[Se]==="1"?false:typeof this.#e.telemetry?.enabled=="boolean"?this.#e.telemetry.enabled:true}setTelemetryEnabled(e){this.#e={...this.#e,telemetry:{...this.#e.telemetry,enabled:e,lastPrompted:Date.now()}};}getTelemetryId(){return this.#e.telemetry?.id}async ensureTelemetryId(){let e=this.getTelemetryId();if(e)return e;let o=z.randomUUID();return this.#e={...this.#e,telemetry:{...this.#e.telemetry,id:o}},await this.save(),o}getDefaultTemplate(){return this.#e.defaults?.template}getUpdateMetadata(){return this.#e.updates}setUpdateMetadata(e){this.#e={...this.#e,updates:{...this.#e.updates,...e}};}getDeviceInfo(){return this.#e.device}setDeviceInfo(e){this.#e={...this.#e,device:e};}async save(){await g.mkdir(de,{recursive:true});let e=JSON.stringify(this.#e,null,2);await g.writeFile(ee,e,{mode:384}),await g.chmod(ee,384);}};var se=class{#e;#t;constructor(e={}){this.#e=e.json??false,this.#t=e.debug??process.env[G]==="1";}isJsonMode(){return this.#e}setJsonMode(e){this.#e=e;}setDebug(e){this.#t=e;}info(e){this.#e||process.stdout.write(`${K.blue("i")} ${e}
73
73
  `);}success(e){this.#e||process.stdout.write(`${K.green("\u2714")} ${e}
74
74
  `);}warn(e){this.#e||process.stdout.write(`${K.yellow("!")} ${e}
75
75
  `);}error(e){this.#e||process.stderr.write(`${K.red("\u2716")} ${e}
76
76
  `);}debug(e){!this.#t||this.#e||process.stdout.write(`${K.gray("debug")} ${e}
77
77
  `);}json(e){let o=JSON.stringify(e,null,2);process.stdout.write(`${o}
78
78
  `);}};var ko=new Set(["command","project","duration","status","errorCode","errorMessage","metadata"]),So=50,Io=6144,bt=25e3,ce=class{#e;#t;#n;#r=[];#o;#i=false;#s;#a;#c;constructor(e,o,n){this.#e=e,this.#t=o,this.#n=n,this.#a=process.env.HBX_RELEASE_CHANNEL??process.env.RELEASE_CHANNEL??"stable",this.#c=randomUUID(),this.#l();}isEnabled(){return this.#e.isTelemetryEnabled()}setCommand(e){this.#s=e;}async track(e){this.isEnabled()&&(this.#r.push({...e,timestamp:new Date().toISOString(),payload:e.payload??{}}),await this.flush());}async flush(){if(!this.#r.length)return;if(this.#o){await this.#o;return}let e=this.#r.splice(0);this.#o=this.#d(e).finally(()=>{this.#o=void 0;}),await this.#o;}#l(){if(this.#i)return;let e=()=>{this.flush();};process.once("beforeExit",e),process.once("exit",e),process.once("SIGINT",e),process.once("SIGTERM",e),this.#i=true;}async#d(e){if(!e.length)return;let o=this.#e.getTelemetryId(),r=[...e.map(i=>Bo(i))];for(;r.length;){let i=[],s;for(;r.length&&i.length<So;){let a=r[0];if(!a)break;let c=[...i,a],d=this.#m(c,o),m=JSON.stringify(d);if(Buffer$1.byteLength(m,"utf8")>bt){if(!i.length){r.shift(),this.#t.warn("Dropped telemetry event because payload exceeded max size");continue}break}let h=r.shift();if(!h)break;i.push(h),s=m;}!i.length||!s||await this.#p(s,o);}}#m(e,o){return {clientId:o&&o.length>=8?o:"anonymous",os:ae.platform(),osVersion:Ho(),arch:process.arch,nodeVersion:process.version,ci:_o(),command:this.#s,releaseChannel:this.#a,sessionId:this.#c,cliVersion:this.#n,version:this.#n,hasLicense:!!this.#e.getToken(),events:e}}async#p(e,o){let n=Buffer$1.byteLength(e,"utf8");if(n>bt){this.#t.warn("Telemetry payload skipped because it exceeded the maximum request size");return}try{let r=new AbortController,i=setTimeout(()=>r.abort(),5e3),s=await fetch(De,{method:"POST",headers:{"Content-Type":"application/json","Content-Length":String(n),"User-Agent":`hbx-cli/${this.#n}`,...o?{"x-telemetry-id":o}:void 0},body:e,signal:r.signal});if(clearTimeout(i),s.status===413){this.#t.warn("Telemetry payload rejected (too large)");return}if(!s.ok)throw new Error(`telemetry responded with status ${s.status}`)}catch(r){this.#t.debug(`telemetry send failed: ${String(r)}`);}}};function _o(){return process.env.CI==="1"||process.env.CONTINUOUS_INTEGRATION==="1"||!!process.env.BUILD_NUMBER||!!process.env.RUN_ID}function Ho(){let t=ae.version;if(typeof t=="function")try{return t()}catch{return ae.release()}return ae.release()}function Bo(t){let e=Do(t.payload);if(!e){let{payload:o,...n}=t;return n}try{let o=JSON.stringify(e);return Buffer$1.byteLength(o,"utf8")>Io?{...t,payload:{truncated:!0}}:{...t,payload:e}}catch{return {...t,payload:{truncated:true}}}}function Do(t){if(!t||typeof t!="object")return;let e={};for(let o of ko)if(Object.hasOwn(t,o)){let n=t[o];if(o==="metadata"&&(n==null||typeof n!="object"))continue;e[o]=n;}return Object.keys(e).length?e:void 0}async function xt(t,e,o){if(process.env[Ie]==="1")return;let n=e.getUpdateMetadata()??{},r=Date.now(),i=n.latestVersion,s=n.lastChecked??0;if(!i||r-s>je){let d=await No(t,o);d.latestVersion&&(i=d.latestVersion),d.checkedAt>0&&(s=d.checkedAt,e.setUpdateMetadata({lastChecked:s,latestVersion:i}),await e.save());}if(!i||!b.valid(i)||!b.gt(i,t)||!jo(n,r,i))return;let c=`npm install -g ${te}`;o.warn(`A new version of hbx is available: ${i} (current ${t}).
79
- Update with: ${c} (or pnpm add -g ${te}).`),e.setUpdateMetadata({lastNotifiedAt:r,latestVersion:i}),await e.save();}function jo(t,e,o){return !t||t.lastNotifiedAt===void 0||t.latestVersion!==o?true:e-t.lastNotifiedAt>Ne}async function No(t,e){try{let o=await fetch(`https://registry.npmjs.org/${encodeURIComponent(te)}/latest`,{headers:{"User-Agent":`hbx-cli/${t}`}});if(!o.ok)throw new Error(`npm registry responded with status ${o.status}`);return {latestVersion:(await o.json()).version,checkedAt:Date.now()}}catch(o){return e.debug(`update check failed: ${String(o)}`),{checkedAt:Date.now()}}}async function $o(){let t=ne(),e=await ie.load(),o=new se({debug:process.env[G]==="1"});await e.ensureTelemetryId();let n=new ce(e,o,t),r={config:e,logger:o,telemetry:n};await xt(t,e,o),await Oo(r);let i=new Command;i.name("hbx").description("Hugo Blox Experience CLI").version(t,"-v, --version","Show CLI version").option("--json","Output machine-readable JSON").option("--debug","Enable verbose logging"),i.hook("preAction",(s,a)=>{let c=a?.optsWithGlobals?.()??s.optsWithGlobals();o.setJsonMode(!!c.json),o.setDebug(!!c.debug||process.env[G]==="1"),n.setCommand(Lo(a));}),gt(i,r),Pe(i,r),Ge(i,r),Re(i,r),Ve(i,r),Ye(i,r),Qe(i,r),ht(i,r),wt(i,r);try{await i.parseAsync(process.argv);}catch(s){Ro(s,o);}}function Ro(t,e){if(Ce(t)){let o={status:"error",code:t.code,message:t.message,details:t.details};e.isJsonMode()?e.json(o):e.error(`${t.code}: ${t.message}`);}else t instanceof P?e.error(`${t.code}: ${t.message}`):t instanceof Error?e.error(t.message):e.error("Unknown error");process.exit(1);}$o();function Lo(t){if(!t)return Z;let e=[],o=t;for(;o?.parent;){let n=o.name?.();n&&e.unshift(n),o=o.parent;}return e.length?`${Z} ${e.join(" ")}`.trim():Z}async function Oo(t){if(process.env[L]&&t.config.getToken()&&!t.config.getDeviceInfo())try{await E(t);}catch(e){t.logger.debug(`Skipping device registration warm-up: ${String(e)}`);}}
79
+ Update with: ${c} (or pnpm add -g ${te}).`),e.setUpdateMetadata({lastNotifiedAt:r,latestVersion:i}),await e.save();}function jo(t,e,o){return !t||t.lastNotifiedAt===void 0||t.latestVersion!==o?true:e-t.lastNotifiedAt>Ne}async function No(t,e){try{let o=await fetch(`https://registry.npmjs.org/${encodeURIComponent(te)}/latest`,{headers:{"User-Agent":`hbx-cli/${t}`}});if(!o.ok)throw new Error(`npm registry responded with status ${o.status}`);return {latestVersion:(await o.json()).version,checkedAt:Date.now()}}catch(o){return e.debug(`update check failed: ${String(o)}`),{checkedAt:Date.now()}}}async function Ro(t=process.argv){let e=ne(),o=await ie.load(),n=new se({debug:process.env[G]==="1"});await o.ensureTelemetryId();let r=new ce(o,n,e),i={config:o,logger:n,telemetry:r};await xt(e,o,n),await Mo(i);let s=new Command;s.name("hbx").description("HugoBlox Experience CLI").version(e,"-v, --version","Show CLI version").option("--json","Output machine-readable JSON").option("--debug","Enable verbose logging"),s.hook("preAction",(a,c)=>{let d=c?.optsWithGlobals?.()??a.optsWithGlobals();n.setJsonMode(!!d.json),n.setDebug(!!d.debug||process.env[G]==="1"),r.setCommand(Oo(c));}),gt(s,i),Te(s,i),Ge(s,i),$e(s,i),Ve(s,i),Ye(s,i),Qe(s,i),ht(s,i),wt(s,i);try{await s.parseAsync(t);}catch(a){$o(a,n);}}function $o(t,e){if(Ce(t)){let o={status:"error",code:t.code,message:t.message,details:t.details};e.isJsonMode()?e.json(o):e.error(`${t.code}: ${t.message}`);}else t instanceof T?e.error(`${t.code}: ${t.message}`):t instanceof Error?e.error(t.message):e.error("Unknown error");process.exit(1);}(process.argv[1]===fileURLToPath(import.meta.url)||process.argv[1].endsWith("/bin/hbx")||process.argv[1].endsWith("/bin/hugoblox"))&&Ro();function Oo(t){if(!t)return Z;let e=[],o=t;for(;o?.parent;){let n=o.name?.();n&&e.unshift(n),o=o.parent;}return e.length?`${Z} ${e.join(" ")}`.trim():Z}async function Mo(t){if(process.env[L]&&t.config.getToken()&&!t.config.getDeviceInfo())try{await E(t);}catch(e){t.logger.debug(`Skipping device registration warm-up: ${String(e)}`);}}
80
+
81
+ export { Ro as bootstrap };
package/package.json CHANGED
@@ -1,58 +1,62 @@
1
1
  {
2
- "name": "hugoblox",
3
- "version": "0.1.0",
4
- "description": "The official CLI for creating and managing HugoBlox sites.",
5
- "type": "module",
6
- "bin": {
7
- "hbx": "dist/index.js",
8
- "hugoblox": "dist/index.js"
9
- },
10
- "exports": {
11
- ".": {
12
- "import": "./dist/index.js"
13
- }
14
- },
15
- "files": ["dist"],
16
- "engines": {
17
- "node": ">=18"
18
- },
19
- "keywords": [
20
- "hugoblox",
21
- "hbx",
22
- "hugo",
23
- "blox",
24
- "cli",
25
- "static-site-generator"
26
- ],
27
- "scripts": {
28
- "build": "tsup",
29
- "build:publish": "cross-env HBX_PUBLISH_BUILD=1 tsup",
30
- "dev": "tsx watch src/index.ts",
31
- "lint": "biome check .",
32
- "format": "biome format --write .",
33
- "test": "vitest run",
34
- "test:watch": "vitest",
35
- "publish:package": "pnpm lint && pnpm test && pnpm build:publish && node scripts/publish.js"
36
- },
37
- "dependencies": {
38
- "chalk": "5.3.0",
39
- "commander": "11.1.0",
40
- "execa": "8.0.1",
41
- "ora": "7.0.1",
42
- "prompts": "2.4.2",
43
- "semver": "7.6.0",
44
- "yaml": "2.5.0",
45
- "keytar": "7.9.0"
46
- },
47
- "devDependencies": {
48
- "@biomejs/biome": "1.6.4",
49
- "@types/node": "20.11.20",
50
- "@types/keytar": "4.4.2",
51
- "@vitest/coverage-v8": "1.4.0",
52
- "cross-env": "7.0.3",
53
- "tsup": "8.0.1",
54
- "tsx": "4.7.0",
55
- "typescript": "5.3.3",
56
- "vitest": "1.4.0"
57
- }
58
- }
2
+ "name": "hugoblox",
3
+ "version": "0.1.1",
4
+ "description": "The official CLI for creating and managing HugoBlox sites.",
5
+ "type": "module",
6
+ "bin": {
7
+ "hbx": "dist/index.js",
8
+ "hugoblox": "dist/index.js"
9
+ },
10
+ "types": "dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist"
19
+ ],
20
+ "engines": {
21
+ "node": ">=18"
22
+ },
23
+ "keywords": [
24
+ "hugoblox",
25
+ "hbx",
26
+ "hugo",
27
+ "blox",
28
+ "cli",
29
+ "static-site-generator"
30
+ ],
31
+ "dependencies": {
32
+ "chalk": "5.3.0",
33
+ "commander": "11.1.0",
34
+ "execa": "8.0.1",
35
+ "ora": "7.0.1",
36
+ "prompts": "2.4.2",
37
+ "semver": "7.6.0",
38
+ "yaml": "2.5.0",
39
+ "keytar": "7.9.0"
40
+ },
41
+ "devDependencies": {
42
+ "@biomejs/biome": "1.6.4",
43
+ "@types/node": "20.11.20",
44
+ "@types/keytar": "4.4.2",
45
+ "@vitest/coverage-v8": "1.4.0",
46
+ "cross-env": "7.0.3",
47
+ "tsup": "8.0.1",
48
+ "tsx": "4.7.0",
49
+ "typescript": "5.3.3",
50
+ "vitest": "1.4.0"
51
+ },
52
+ "scripts": {
53
+ "build": "tsup",
54
+ "build:publish": "cross-env HBX_PUBLISH_BUILD=1 tsup",
55
+ "dev": "tsx watch src/index.ts",
56
+ "lint": "biome check .",
57
+ "format": "biome format --write .",
58
+ "test": "vitest run",
59
+ "test:watch": "vitest",
60
+ "publish:package": "pnpm lint && pnpm test && pnpm build:publish && node scripts/publish.js"
61
+ }
62
+ }