hugoblox 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +31 -30
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,30 +1,31 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import g from 'node:fs/promises';
4
- import u from 'node:path';
3
+ import b from 'node:fs/promises';
4
+ import w from 'node:path';
5
5
  import { execa } from 'execa';
6
- import kt from 'yaml';
7
- import ae from 'node:os';
8
- import b from 'semver';
9
- import ut from 'ora';
10
- import z, { randomUUID } from 'node:crypto';
6
+ import Vt from 'yaml';
7
+ import he from 'node:os';
8
+ import S from 'semver';
9
+ import qe from 'node:dns/promises';
10
+ import kt from 'ora';
11
+ import Y, { randomUUID } from 'node:crypto';
11
12
  import { createRequire } from 'node:module';
12
13
  import { promisify } from 'node:util';
13
- import ge from 'prompts';
14
- import yt from 'node:fs';
14
+ import Ce from 'prompts';
15
+ import At from 'node:fs';
15
16
  import { fileURLToPath } from 'node:url';
16
- import K from 'chalk';
17
+ import Z from 'chalk';
17
18
  import { Buffer as Buffer$1 } from 'node:buffer';
18
19
 
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
20
+ var H=class extends Error{constructor(e,o="HBX_ERROR",r){super(e),this.name="HbxError",this.code=o,this.details=r;}},d=class extends H{constructor(e,o){super(e,"HBX_INPUT_ERROR",o);}},F=class extends H{constructor(e="Operation cancelled by user"){super(e,"HBX_ABORTED");}},te=class extends H{constructor(e,o){super(e,"HBX_CONFIG_ERROR",o);}};function Be(t){return !!(t&&typeof t=="object"&&"code"in t)}async function x(t){try{return await b.access(t),!0}catch{return false}}async function P(t){await b.mkdir(t,{recursive:true});}async function $e(t){if(!await x(t)){await P(t);return}if((await b.readdir(t)).length>0)throw new Error(`Directory ${t} is not empty`)}async function T(t,e){await P(w.dirname(t)),await b.writeFile(t,e);}function je(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((r,n,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 ne="hbx",K="HBX_DEBUG",V="HBX_LICENSE_TOKEN",De="HBX_TELEMETRY_DISABLED",we=w.join(he.homedir(),".hbx"),ie=w.join(we,"config.json"),Mt=w.join(he.homedir(),".cache","hbx"),G=w.join(Mt,"templates"),Re="HBX_UPDATE_CHECK_DISABLED",X="https://api.github.com",Ne=`${X}/repos/HugoBlox/hugo-blox-builder/contents/templates`,Le="https://github.com/HugoBlox/hugo-blox-builder.git",Oe="HBX_TEMPLATES_DIR",j="https://cli-api.hugoblox.com",Me=`${j}/api/usage-insights`,se="hugoblox",Ue=1e3*60*60*24,Fe=1e3*60*60*12;var be=[{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 ae="hbx.blocks.json";async function _(t=process.cwd()){let e=t,{root:o}=w.parse(t);for(;;){if((await Promise.all([x(w.join(e,"config","_default")),x(w.join(e,"hugoblox.yaml"))])).some(Boolean))return {root:e,manifestPath:w.join(e,ae)};if(e===o)return;e=w.dirname(e);}}async function Ve(t){let e=w.join(t,"hugoblox.yaml");if(await x(e))try{let o=await b.readFile(e,"utf8"),r=Vt.parse(o);if(!r)return;let n=r.template??{},i=r.build??{};return {templateId:n.id,templateName:n.name,requiredHugoVersion:i.hugo_version}}catch(o){throw new d("Failed to parse hugoblox.yaml",{error:o})}}async function Ge(){try{let{stdout:t}=await execa("hugo",["version"]);return Gt(t)}catch{return}}function Gt(t){let e=t.match(/v(\d+\.\d+\.\d+)/i);return e?e[1]:t.match(/(\d+\.\d+\.\d+)/)?.[1]}function ze(t,e){zt(t,e),Jt(t,e);}function zt(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,r,n)=>{let{logger:i,telemetry:s}=e,c=!!n.optsWithGlobals().json,l=await Je(r.path),u=["server"];r.defaultFlags!==false&&u.push("--disableFastRender"),u.push(...o),await We(u,l,i,{allowSignalExit:true,label:"dev server"}),await s.track({name:"dev",payload:{customPath:!!r.path,defaultFlags:r.defaultFlags!==false,args:o}}),c&&i.json({status:"success"});});}function Jt(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,r,n)=>{let{logger:i,telemetry:s}=e,c=!!n.optsWithGlobals().json,l=await Je(r.path),u=[];r.defaultFlags!==false&&u.push("--gc","--minify"),u.push(...o),await We(u,l,i,{allowSignalExit:false,label:"build"}),await s.track({name:"build",payload:{customPath:!!r.path,defaultFlags:r.defaultFlags!==false,args:o}}),c&&i.json({status:"success"});});}async function Je(t){let e=t?w.resolve(t):w.resolve(process.cwd()),o=await _(e);if(!o)throw new d("Unable to locate a HugoBlox project. Run this inside a project or pass --path.");return o.root}async function We(t,e,o,r){o.info(`Running: hugo ${t.join(" ")}`);try{await execa("hugo",t,{cwd:e,stdio:"inherit"}),o.success(`Hugo ${r.label} finished`);}catch(n){let i=n;if(r.allowSignalExit&&(i.signal==="SIGINT"||i.signal==="SIGTERM")){o.info("Hugo process stopped");return}throw new d(`Hugo ${r.label} failed: ${i.shortMessage??i.message}`,{error:i})}}var A=class extends Error{constructor(o,r){super(o);this.cause=r;this.name="NetworkError";}};async function ve(t,e={}){let{timeout:o=15e3,retries:r=3,backoff:n=500,...i}=e,s=0;for(;s<=r;){let a=new AbortController,c=setTimeout(()=>a.abort(),o);try{let l=await fetch(t,{...i,signal:a.signal});if(clearTimeout(c),l.status===429||l.status>=500&&l.status<600)throw new A(`Server error: ${l.status}`);return l}catch(l){clearTimeout(c),s++;let u=l.name==="AbortError";if(s>r)throw u?new A(`Request timed out after ${o}ms`,l):l instanceof A?l:new A("Network request failed",l);let E=n*2**(s-1);await new Promise(m=>setTimeout(m,E));}}throw new A("Unreachable")}async function Ke(){try{return await qe.lookup("google.com"),!0}catch{try{return await qe.lookup("1.1.1.1"),!0}catch{return false}}}var Yt=["github.com/HugoBlox/hugo-blox-builder","github.com/wowchemy/wowchemy-hugo-themes"];async function le(t){let e=w.join(t,"go.mod"),o;try{o=await b.readFile(e,"utf8");}catch{return []}let n=eo(o).filter(s=>Yt.some(a=>s.path.startsWith(a)));return await Promise.all(n.map(async s=>{try{let a=await Qt(s.path);return {path:s.path,current:s.version,latest:a}}catch(a){return {path:s.path,current:s.version,latest:void 0,error:a.message}}}))}async function Qt(t){if(t.includes("github.com/HugoBlox/hugo-blox-builder"))return Zt(t)}async function Zt(t){let e=await ve(`${X}/repos/HugoBlox/hugo-blox-builder/tags?per_page=100`);if(!e.ok)throw new Error(`GitHub API error: ${e.status}`);let o=await e.json(),r=t.split("github.com/HugoBlox/hugo-blox-builder/");if(r.length<2)return;let n=r[1],i=o.filter(s=>s.name.startsWith(`${n}/`)&&/v\d+\.\d+\.\d+/.test(s.name)).map(s=>s.name);if(i.length!==0)return i.sort((s,a)=>{let c=s.split("/").pop()||"0.0.0",l=a.split("/").pop()||"0.0.0";return S.rcompare(c,l)}),i[0].split("/").pop()}async function Ye(t,e){if(!t.includes("github.com/HugoBlox/hugo-blox-builder"))return;let o=t.split("github.com/HugoBlox/hugo-blox-builder/");if(o.length<2)return;let r=o[1],n=e==="main"||e.startsWith("v")?e:`v${e}`,i=e==="main"?"main":`${r}/${n.replace(/^v/,"v")}`,s=`${r}/hugo.yaml`,a=await ve(`${X}/repos/HugoBlox/hugo-blox-builder/contents/${s}?ref=${i}`,{headers:{Accept:"application/vnd.github.v3.raw"}});if(!a.ok)return;let c=await a.text();return Vt.parse(c)?.module?.hugoVersion?.min}function eo(t){let e=[],o=t.split(/\r?\n/),r=false;for(let n of o){let i=n.trim();if(i.startsWith("require (")){r=true;continue}if(r&&i===")"){r=false;continue}let s="";if(!r&&i.startsWith("require ")?s=i.replace("require","").trim():r&&(s=i),s){s=s.split("//")[0].trim();let a=s.split(/\s+/);a.length>=2&&e.push({path:a[0],version:a[1]});}}return e}function de(t,e){if(!t||!e)return {updateAvailable:false,diff:""};let o=S.coerce(t),r=S.coerce(e);return !o||!r?{updateAvailable:false,diff:""}:S.lt(o,r)?{updateAvailable:true,diff:`${J(t)} -> ${J(e)}`}:{updateAvailable:false,diff:""}}function J(t){let e=/v\d+\.\d+\.\d+-(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})-([a-f0-9]{12})/,o=t.match(e);if(o){let[r,n,i,s,a,c,l,u]=o;return `commit ${u.substring(0,7)} (released ${n}-${i}-${s})`}return t}function Ze(t){let e=process.env.HOME||process.env.USERPROFILE;if(!e)return t;let o=w.resolve(e),r=w.resolve(t);return r.startsWith(o)?r.replace(o,"~"):t}async function et(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 tt(t,e){t.command("doctor").description("Check local environment for common issues").action(async(o,r)=>{let{logger:n,config:i}=e,a=!!r.optsWithGlobals().json,c=[];c.push({name:"Node.js",ok:true,details:process.version});let l=await et("hugo",["version"]);c.push({name:"Hugo",ok:!l.startsWith("Not"),details:l});let u=oo(l),g=await et("pnpm",["--version"]);c.push({name:"pnpm",ok:!g.startsWith("Not"),details:g});let E=i.getToken();c.push({name:"Pro license",ok:!!E,details:E?"Configured":"Missing"});let m=await _();if(m){let f=await Ve(m.root);if(f){let v=f.templateName??f.templateId??"Unknown";c.push({name:"Template",ok:true,details:`${v} (${Ze(m.root)})`});let C=ro(f.requiredHugoVersion,u);C&&c.push(C);}let y=await le(m.root);for(let v of y){let C=v.path.split("/").pop()||v.path,L=v.current;if(v.latest){let ee=S.coerce(v.current),M=S.coerce(v.latest);ee&&M&&S.eq(ee,M)&&(L=`${L} (latest)`);}c.push({name:`Module: ${C}`,ok:true,details:L});let{updateAvailable:O}=de(v.current,v.latest);O&&v.latest&&c.push({name:`${C} update`,ok:false,details:`Current ${v.current}, latest ${v.latest}. Run 'hbx upgrade' to update.`,level:"warn"});}}let h={status:c.some(f=>(f.level??(f.ok?"info":"error"))==="error")?"error":"success",checks:c};if(a){n.json(h);return}for(let f of h.checks){let y=f.level??(f.ok?"info":"error");y==="info"?n.success(`${f.name}: ${f.details}`):y==="warn"?n.warn(`${f.name}: ${f.details}`):n.error(`${f.name}: ${f.details}`);}});}function oo(t){let e=t.match(/v(\d+\.\d+\.\d+)/i);return e?e[1]:t.match(/(\d+\.\d+\.\d+)/)?.[1]}function ro(t,e){if(!t||!e)return;let o=S.coerce(t),r=S.coerce(e);if(!(!o||!r))return S.lt(r,o)?{name:"Hugo version compatibility",ok:false,details:`Template requires Hugo ${o.version}, but ${r.version} is installed`,level:"error"}:S.major(r)>S.major(o)||S.minor(r)>S.minor(o)?{name:"Hugo version compatibility",ok:true,details:`Using Hugo ${r.version}; template tested with ${o.version}`,level:"warn"}:{name:"Hugo version compatibility",ok:true,details:`Template requires Hugo ${o.version} and you're running ${r.version}`,level:"info"}}function ot(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,r)=>{let{logger:n,config:i,telemetry:s}=e,c=!!r.optsWithGlobals().json,l=o.path?{root:w.resolve(o.path),manifestPath:w.join(w.resolve(o.path),"hbx.blocks.json")}:await _();if(!l)throw new d("Unable to locate a HugoBlox project - pass --path if needed");let u=i.getToken();if(!u){if(o.ci)throw new d(`Missing license key. Set ${V} or run hbx login before using --ci.`);n.warn("No Pro license detected, proceeding with OSS assets only");}let g=kt("Hydrating Pro assets...").start();try{let m=w.join(l.root,"config","_default","module.hbx.toml"),p=w.join(l.root,"node_modules","@hugoblox-pro","sample");await P(p),await T(w.join(p,"README.md"),`# HugoBlox Pro assets placeholder
21
+ `),await T(m,`# Generated by hbx install
21
22
  [[module.imports]]
22
23
  path = "github.com/HugoBlox/hugo-blox-builder"
23
24
  [[module.imports]]
24
25
  path = "node_modules/@hugoblox-pro/sample"
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
+ `),g.succeed("Assets hydrated");}catch(m){throw g.fail("Failed to hydrate assets"),m}await s.track({name:"install",payload:{ci:!!o.ci,force:!!o.force,tokenPresent:!!u,customPath:!!o.path}});let E={status:"success",path:l.root,forced:!!o.force,token:!!u};c?n.json(E):(n.success("Install complete"),u||n.info("Tip: run hbx login to unlock Pro downloads"));});}var xe="com.hugoblox.cli",ao=1,co=createRequire(import.meta.url),lo=promisify(Y.scrypt),I=null;try{I=co("keytar");}catch{I=null;}async function rt(t,e,o,r,n){let i=`device:${o}`,s,a;if(I)await I.setPassword(xe,i,r);else {let c=await po(r,e);s=c.payload,a=c.salt;}t.setDeviceInfo({id:o,label:n,secretAlias:I?i:void 0,secretFallback:s,secretFallbackSalt:a,secretFallbackVersion:s?ao:void 0}),await t.save();}async function nt(t,e){let o=t.getDeviceInfo();if(!o?.id)return;let r;if(o.secretAlias&&I&&(r=await I.getPassword(xe,o.secretAlias)),!r&&o.secretFallback&&o.secretFallbackSalt)try{let{key:n}=await it(e,o.secretFallbackSalt);r=uo(o.secretFallback,n);}catch{r=void 0;}if(r)return {id:o.id,secret:r,label:o.label}}async function Ee(t){let e=t.getDeviceInfo();e?.secretAlias&&I&&await I.deletePassword(xe,e.secretAlias),t.setDeviceInfo(void 0),await t.save();}function mo(t,e){let o=Y.randomBytes(12),r=Y.createCipheriv("aes-256-gcm",e.subarray(0,32),o),n=Buffer.concat([r.update(t,"utf8"),r.final()]),i=r.getAuthTag();return Buffer.concat([o,i,n]).toString("base64")}function uo(t,e){let o=Buffer.from(t,"base64"),r=o.subarray(0,12),n=o.subarray(12,28),i=o.subarray(28),s=Y.createDecipheriv("aes-256-gcm",e.subarray(0,32),r);return s.setAuthTag(n),Buffer.concat([s.update(i),s.final()]).toString("utf8")}async function it(t,e){let o=Buffer.from(e,"base64");return {key:await lo(t,o,32,{N:32768,r:8,p:1,maxmem:64*1024*1024}),salt:e}}async function po(t,e){let o=Y.randomBytes(16).toString("base64"),{key:r}=await it(e,o);return {payload:mo(t,r),salt:o}}async function k(t,e={}){let o=t.config.getToken();if(!o)throw new d("Set HBX_LICENSE_TOKEN or run 'hbx login' to access Pro content.");let r=await t.config.ensureTelemetryId();if(e.force)await Ee(t.config);else {let s=await nt(t.config,r);if(s)return {id:s.id,secret:s.secret}}let n=e.label??he.hostname(),i=await go(t.config,o,r,n);return await rt(t.config,r,i.deviceId,i.deviceSecret,n),t.logger.debug(`Registered device ${i.deviceId}`),{id:i.deviceId,secret:i.deviceSecret}}async function st(t){await Ee(t);}async function go(t,e,o,r){let n=await fetch(`${j}/api/license/devices/register`,{method:"POST",headers:{Authorization:`Bearer ${e}`,"Content-Type":"application/json","x-telemetry-id":o},body:JSON.stringify({deviceLabel:r})}),i=await ho(n);if(!n.ok)throw i?.code==="license_device_limit"?new d("This license has reached the maximum number of devices. Revoke an existing device and try again."):n.status===401||n.status===403?new d(i?.error??"Unable to register device"):new d(i?.error??`Device registration failed (status ${n.status})`);if(!i?.deviceId||!i?.deviceSecret)throw new d("Device registration response was missing credentials");return i}async function ho(t){try{return await t.json()}catch{return}}async function Q(t,e={}){if(e.ci){if(typeof e.initial=="string")return e.initial;throw new d(`Option required in CI mode: ${t}`)}return (await Ce({type:"text",name:"value",message:t,initial:e.initial},{onCancel:()=>{throw new F}})).value}async function at(t,e,o={}){if(o.ci){if(typeof o.initial=="string")return o.initial;throw new d(`Option required in CI mode: ${t}`)}return (await Ce({type:"select",name:"value",message:t,choices:e,initial:0},{onCancel:()=>{throw new F}})).value}async function D(t,e={}){if(e.ci){if(typeof e.initial=="boolean")return e.initial;throw new d(`Confirmation required in CI mode: ${t}`)}return (await Ce({type:"confirm",name:"value",message:t,initial:e.initial??true},{onCancel:()=>{throw new F}})).value}function Pe(t){return t?t.length<=6?"***":`${t.slice(0,3)}***${t.slice(-2)}`:"(none)"}function ct(t,e){let o=t??e;return w.resolve(process.cwd(),o)}function lt(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,r)=>{let{config:n,logger:i}=e,a=!!r.optsWithGlobals().json,c=o.token;if(!c){if(o.ci)throw new d("License key is required when using --ci");c=await Q("Enter your HugoBlox Pro license key");}let l=false;try{n.setToken(c),await n.save(),l=!0,await k(e,{force:!0});let u={status:"success",token:Pe(c)};a?i.json(u):i.success(`License key saved (${Pe(c)})`);}catch(u){throw l&&(n.clearToken(),await n.save()),wo(u)}});}function dt(t,e){t.command("logout").description("Remove stored HugoBlox credentials and device secrets").action(async(o,r)=>{let{config:n,logger:i}=e,s=!!r.optsWithGlobals().json;await st(n),n.clearToken(),await n.save();let a={status:"success"};s?i.json(a):i.success("License key removed");});}function wo(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 H?new d(`${e}. ${o}`,t.details):new d(`${e}. ${o}`)}function bo(t){return t.split("-").map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(" ")}async function mt(t){let{logger:e}=t,o=await vo(e),r=await xo(t);return o.length||r.length?[...r,...o]:be}async function vo(t){try{let e=await fetch(Ne,{headers:{"User-Agent":"hbx-cli"}});if(!e.ok)throw new Error(`GitHub responded with status ${e.status}`);return (await e.json()).filter(n=>n.type==="dir").map(n=>({id:n.name,name:bo(n.name),description:`Starter template ${n.name}`,repoPath:n.path,slug:n.name,source:"oss"}))}catch(e){return t?.debug?.(`Falling back to offline starter metadata: ${String(e)}`),be}}async function xo(t){let{logger:e,config:o}=t,r=new Headers({"User-Agent":"hbx-cli"});try{let i=await o.ensureTelemetryId();r.set("x-telemetry-id",i);}catch{}let n=o.getToken();if(n)try{let i=await k(t);r.set("Authorization",`Bearer ${n}`),r.set("X-HBX-Device-Id",i.id),r.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(`${j}/api/pro-templates`,{headers:r});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 ut(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 ${w.relative(process.cwd(),t)||"."}`);}catch(o){e.warn(`Git initialization skipped: ${String(o)}`);}}async function Te(t,e,o={},r=0){let n=t.config.getToken();if(!n)throw new d("A HugoBlox Pro license key is required before accessing Pro templates.");let i=await t.config.ensureTelemetryId(),s=await k(t,{force:r>0}),a=new Headers(o.headers??{});a.set("Authorization",`Bearer ${n}`),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(`${j}${e}`,{...o,headers:a});if((c.status===401||c.status===403)&&r===0)return await k(t,{force:true}),Te(t,e,o,r+1);if(!c.ok){let l=await Co(c);throw l?.code==="license_device_limit"?new d("This license has reached the maximum number of devices. Revoke an existing device and try again."):c.status===401||c.status===403?new d(l?.error??"Device authentication failed."):new d(l?.error??`Request failed (${c.status})`)}return c}async function Co(t){try{return await t.json()}catch{return}}var Po=3;async function gt(t,e,o,r){if(e.source==="pro"){await Ho(t,e,o,r);return}let n=process.env[Oe];if(n){await ko(e,n,o),r.debug(`Hydrated template ${e.id} from local override`);return}let i=await So(e,r),s=i!==void 0?w.join(G,e.id,i):void 0;if(s&&await x(s)){await R(s,o),r.debug(`Hydrated template ${e.id} from cache (${i})`);return}let a=await b.mkdtemp(w.join(he.tmpdir(),"hbx-template-")),c=w.join(a,"repo");try{await execa("git",["clone","--depth","1",Le,c],{stdio:"ignore"});let l=await To(c,e);s?(await P(w.dirname(s)),await b.rm(s,{recursive:!0,force:!0}),await b.cp(l,s,{recursive:!0}),await ht(w.join(G,e.id)),await R(s,o),r.debug(`Hydrated template ${e.id} from fresh cache (${i})`)):(await R(l,o),r.debug(`Hydrated template ${e.id} from repository`));}catch(l){throw new d("Failed to clone HugoBlox templates. Ensure git is installed and accessible.",{error:l})}finally{await b.rm(a,{recursive:true,force:true});}}async function ko(t,e,o){let r=w.join(e,t.id);try{await b.access(r);}catch(n){throw new d(`Local template not found at ${r}`,{error:n})}await R(r,o);}async function To(t,e){let o=e.repoPath??"",r=w.join(t,o);return await b.access(r),r}async function R(t,e){await b.rm(e,{recursive:true,force:true}),await P(w.dirname(e)),await b.cp(t,e,{recursive:true}),await b.rm(w.join(e,".git"),{recursive:true,force:true});}async function ht(t){if(!await x(t))return;let e=await b.readdir(t,{withFileTypes:true}),o=await Promise.all(e.filter(r=>r.isDirectory()).map(async r=>{let n=w.join(t,r.name),i=await b.stat(n);return {path:n,mtimeMs:i.mtimeMs}}));o.sort((r,n)=>n.mtimeMs-r.mtimeMs);for(let r of o.slice(Po))await b.rm(r.path,{recursive:true,force:true});}async function So(t,e){let o=encodeURIComponent(t.repoPath??""),r=`${X}/repos/HugoBlox/hugo-blox-builder/commits?path=${o}&per_page=1`;try{let n=await fetch(r,{headers:{"User-Agent":"hbx-cli"}});if(!n.ok)throw new Error(`GitHub responded with status ${n.status}`);return (await n.json())[0]?.sha}catch(n){e.debug(`Unable to determine latest template commit for ${t.id}: ${String(n)}`);return}}async function Ho(t,e,o,r){let n=e.version?w.join(G,e.id,e.version):void 0;if(n&&await x(n)){await R(n,o),r.debug(`Hydrated Pro template ${e.id} from cache (${e.version})`);return}let i=await b.mkdtemp(w.join(he.tmpdir(),"hbx-pro-template-")),s=w.join(i,"template.tgz"),a=w.join(i,"extract");await P(a);try{let c=await Io(t,e,s);await execa("tar",["-xzf",s,"-C",a]);let l=await _o(a,e.slug),u=e.version??c.version??void 0,g=u!==void 0?w.join(G,e.id,u):void 0;g?(await P(w.dirname(g)),await b.rm(g,{recursive:!0,force:!0}),await b.cp(l,g,{recursive:!0}),await ht(w.join(G,e.id)),await R(g,o),r.debug(`Hydrated Pro template ${e.id} from fresh cache (${u})`)):(await R(l,o),r.debug(`Hydrated Pro template ${e.id} from archive`));}catch(c){throw new d(`Failed to download Pro template ${e.name}. Ensure your license is valid and try again.`,{error:c})}finally{await b.rm(i,{recursive:true,force:true});}}async function Io(t,e,o){let r=e.downloadEndpoint??`/api/pro-templates/${encodeURIComponent(e.id)}/download`,n=await Te(t,r),i=await Bo(n);if(!i?.url)throw new d("Pro template download URL was missing");let s=await fetch(i.url);if(!s.ok)throw new d(`Pro template archive download failed (${s.status})`);let a=Buffer.from(await s.arrayBuffer());return await b.writeFile(o,a),{version:i.version}}async function _o(t,e){let o=await b.readdir(t,{withFileTypes:true}),r=o.find(i=>i.isDirectory()&&i.name===e);if(r)return w.join(t,r.name);let n=o.filter(i=>i.isDirectory());return n.length===1?w.join(t,n[0].name):t}async function Bo(t){try{return await t.json()}catch{return}}var yt="https://hugoblox.com/discord",wt="https://docs.hugoblox.com",bt="https://hugoblox.com/pro";function Se(t){return t.trim().toLowerCase().replace(/[^a-z0-9-]/g,"-").replace(/-{2,}/g,"-").replace(/^-+|-+$/g,"").slice(0,64)}async function Et(t,e,o,r){let{logger:n}=t;await gt(t,o,e,n),await jo(e,o),r.sampleContent||await Do(e,o);}async function Ct(t,e,o){o.info(`\u{1F4E6} Installing dependencies with ${e}...`);let r={...process.env},n=["install"],i=!o.isJsonMode();e==="pnpm"&&(r.PNPM_WORKSPACE_DIR=t,r.PNPM_IGNORE_WORKSPACE_ROOT_CHECK="1",await $o(t),n.push("--no-link-workspace-packages"));try{return await execa(e,n,{cwd:t,stdio:i?"ignore":"inherit",env:r}),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 $o(t){let e=w.join(t,"pnpm-workspace.yaml");if(await x(e))return;await T(e,`packages:
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
+ `);}async function Pt(t,e,o){o.info("\u{1F525} Starting dev server with Hugo (press Ctrl+C to exit)...");let r={...process.env};e==="pnpm"&&(r.PNPM_WORKSPACE_DIR=t);try{await execa(e,["dev"],{cwd:t,stdio:"inherit",env:r}),o.success("\u2705 Dev server stopped");}catch(n){let i=n;if(i.signal==="SIGINT"||i.signal==="SIGTERM"){o.info("\u2705 Dev server stopped");return}if(n?.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(n)}`),n}}async function jo(t,e,o){let r=Se(w.basename(t))||e.slug;await Ao(t,r);let n={"README.md":`# ${e.name}
28
29
 
29
30
  This site was created with the HugoBlox CLI.
30
31
  `,".gitignore":`node_modules
@@ -33,9 +34,9 @@ This site was created with the HugoBlox CLI.
33
34
  public
34
35
  .DS_Store
35
36
  modules/_vendor
36
- `};(r[".env"]=`# HBX environment variables
37
+ `};(n[".env"]=`# HBX environment variables
37
38
  HBX_LICENSE_TOKEN=
38
- `);for(let[i,s]of Object.entries(r)){let a=u.join(t,i);await w(a)||await C(a,s);}}async function go(t,e){let o=u.join(t,"package.json"),n={name:e,private:true,scripts:{dev:"hugo server -D",build:"hugo --gc --minify",lint:"echo 'TODO: add lint script'"},dependencies:{}};if(!await w(o)){await C(o,JSON.stringify(n,null,2));return}try{let r=await g.readFile(o,"utf8"),i=JSON.parse(r),s={...n,...i,name:e,scripts:{...n.scripts,...i.scripts},dependencies:{...n.dependencies,...i.dependencies}};await C(o,JSON.stringify(s,null,2));}catch{await C(o,JSON.stringify(n,null,2));}}async function ho(t,e){let o=u.join(t,"content");await g.rm(o,{recursive:true,force:true}),await x(u.dirname(u.join(o,"_index.md"))),await C(u.join(o,"_index.md"),yo(e));}function yo(t){return `---
39
+ `);for(let[i,s]of Object.entries(n)){let a=w.join(t,i);await x(a)||await T(a,s);}}async function Ao(t,e){let o=w.join(t,"package.json"),r={name:e,private:true,scripts:{dev:"hugo server -D",build:"hugo --gc --minify",lint:"echo 'TODO: add lint script'"},dependencies:{}};if(!await x(o)){await T(o,JSON.stringify(r,null,2));return}try{let n=await b.readFile(o,"utf8"),i=JSON.parse(n),s={...r,...i,name:e,scripts:{...r.scripts,...i.scripts},dependencies:{...r.dependencies,...i.dependencies}};await T(o,JSON.stringify(s,null,2));}catch{await T(o,JSON.stringify(r,null,2));}}async function Do(t,e){let o=w.join(t,"content");await b.rm(o,{recursive:true,force:true}),await P(w.dirname(w.join(o,"_index.md"))),await T(w.join(o,"_index.md"),Ro(e));}function Ro(t){return `---
39
40
  title: "${t.name}"
40
41
  type: landing
41
42
  design:
@@ -49,14 +50,14 @@ sections:
49
50
  text: "Start customizing blocks to launch your next experience."
50
51
  primary_action:
51
52
  text: "Join our Discord"
52
- url: "${it}"
53
+ url: "${yt}"
53
54
  icon: "chat-bubble-left-right"
54
55
  secondary_action:
55
56
  text: "Upgrade to Pro"
56
- url: "${at}"
57
+ url: "${bt}"
57
58
  tertiary_action:
58
59
  text: "View Docs"
59
- url: "${st}"
60
+ url: "${wt}"
60
61
  design:
61
62
  css_class: "bg-gradient-to-r from-blue-600 to-indigo-600 text-white"
62
63
  spacing:
@@ -65,17 +66,17 @@ sections:
65
66
  content:
66
67
  title: "Your next steps"
67
68
  text: |
68
- 1. Join the community on [Discord](${it}) for support and inspiration.
69
- 2. Explore the [documentation](${st}) to learn how to add blocks, deploy, and automate.
70
- 3. [Upgrade to Pro](${at}) to unlock premium blocks, design systems, and automation-ready packages.
69
+ 1. Join the community on [Discord](${yt}) for support and inspiration.
70
+ 2. Explore the [documentation](${wt}) to learn how to add blocks, deploy, and automate.
71
+ 3. [Upgrade to Pro](${bt}) to unlock premium blocks, design systems, and automation-ready packages.
71
72
  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 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
- `);}success(e){this.#e||process.stdout.write(`${K.green("\u2714")} ${e}
74
- `);}warn(e){this.#e||process.stdout.write(`${K.yellow("!")} ${e}
75
- `);}error(e){this.#e||process.stderr.write(`${K.red("\u2716")} ${e}
76
- `);}debug(e){!this.#t||this.#e||process.stdout.write(`${K.gray("debug")} ${e}
73
+ `}function No(t,e){if(!e)return;let o=e.toLowerCase(),r=t.find(n=>{let i=n.id.toLowerCase(),s=n.slug?.toLowerCase();return i===o||s===o});if(r)return r;if(e.startsWith("http")||e.startsWith("git@"))return {id:e,name:"Custom template",description:`External template: ${e}`,repoPath:e,slug:"custom",source:"custom"}}function St(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(r,n,i)=>{let{logger:s,config:a,telemetry:c}=e,u=!!i.optsWithGlobals().json,g=kt({text:"Fetching templates...",spinner:"dots"}).start(),E=await mt(e).finally(()=>{g.succeed("\u2728 Templates ready");}),p=No(E,n.template);if(!p){if(n.ci)throw new d("Template must be specified when running with --ci");let U=await at("Select a starter",E.map($=>({title:$.name,description:$.description,value:$.id})));p=E.find($=>$.id===U);}if(!p)throw new d("Unable to determine template");let h=p.source==="pro",f=await Oo(n,r,p),y=ct(f,p.slug);await $e(y);let v=typeof n.sampleContent=="boolean"?n.sampleContent:typeof n.noSampleContent=="boolean"?!n.noSampleContent:n.ci?false:await D("Include sample content? (recommended)",{initial:true}),C=h;if(!h)C=typeof n.pro=="boolean"?n.pro:n.ci?false:await D("Do you have a HugoBlox Pro license?",{initial:!!a.getToken()});else if(!a.getToken()){if(n.ci)throw new d(`"${p.name}" is a HugoBlox Pro template. Set HBX_LICENSE_TOKEN with your license key before running in CI.`);if(s.info(`"${p.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 D("Do you have a HugoBlox Pro license key to enter now?",{initial:true}))throw new d("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 $=await Tt(a.getToken());a.setToken($),await a.save();}if(!h&&C&&!a.getToken()){if(n.ci)throw new d("Set HBX_LICENSE_TOKEN before running --ci when enabling Pro features.");let U=await Tt(a.getToken());a.setToken(U),await a.save();}C&&await k(e);let L=kt(`Creating site in ${w.relative(process.cwd(),y)||"."}...`).start();try{await Et(e,y,p,{sampleContent:v,includeEnv:!0,packageManager:n.packageManager??"pnpm"}),L.succeed("Files generated");}catch(U){throw L.fail("Failed to scaffold site"),U}let O=false;n.install!==false?O=await Ct(y,n.packageManager??"pnpm",s):s.info("Skipping dependency installation"),n.git&&await ut(y,s);let ee={status:"success",template:p.id,path:y,pro:C,manifest:w.join(y,ae)};!O&&n.preview?s.warn("\u26A0\uFE0F Cannot start the dev server because dependencies failed to install."):n.install===false&&n.preview&&s.warn("\u26A0\uFE0F Install dependencies first (skip --no-install) to start the dev server automatically.");let M=false;if(O&&(M=await Lo(n,u)),await c.track({name:"new-site",payload:{template:p.id,sample:v,pro:C,ci:!!n.ci,packageManager:n.packageManager??"pnpm",install:n.install!==false,dependenciesReady:O,preview:M}}),M){await Pt(y,n.packageManager??"pnpm",s);return}if(u){s.json(ee);return}s.success(`\u2705 Site created at ${y}`),s.info("\u{1F680} Next steps:"),s.info(` \u{1F449} cd ${w.relative(process.cwd(),y)||y}`),n.install===false&&s.info(` \u{1F449} ${n.packageManager??"pnpm"} install`),s.info(" \u{1F449} pnpm dev");});}async function Lo(t,e){return e||t.ci?false:typeof t.preview=="boolean"?t.preview:t.noPreview?false:D("Start the dev server now?",{initial:true})}async function Oo(t,e,o){if(t.dir)return t.dir;if(e)return e;if(t.ci)return o.slug;let n=(await Q("Project folder name",{initial:o.slug})).trim();return n?Mo(n)?n:Se(n)||o.slug:o.slug}function Mo(t){return /[\\/]/.test(t)||t.includes(":")}async function Tt(t){let o=(await Q("Enter your HugoBlox Pro license key (from your purchase confirmation email)",{initial:t??""})).trim();if(!o)throw new d("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 r=e.config.isTelemetryEnabled();e.logger.info(`Telemetry is ${r?"enabled":"disabled"}.`);}),o.action(()=>{let r=e.config.isTelemetryEnabled();e.logger.info(`Telemetry is ${r?"enabled":"disabled"}.`),e.logger.info("Use 'hbx telemetry enable|disable' to change the setting.");});}async function _t(t,e,o){let r=S.coerce(e)?.version;if(!r)return;let n=[{path:"hugoblox.yaml",regex:/(hugo_version:\s*['"]?)([\d.]+)(['"]?)/,name:"hugoblox.yaml"},{path:"netlify.toml",regex:/(HUGO_VERSION\s*=\s*['"])([\d.]+)(['"])/,name:"netlify.toml"},{path:".github/workflows/deploy.yml",regex:/(WC_HUGO_VERSION:\s*['"]?)([\d.]+)(['"]?)/,name:"GitHub Actions"}];for(let i of n){let s=w.join(t,i.path);if(await x(s))try{let a=await b.readFile(s,"utf8"),c=a.match(i.regex);if(c){let l=c[2],u=S.coerce(l),g=S.coerce(r);if(u&&g&&S.lt(u,g)){let E=a.replace(i.regex,`$1${r}$3`);await b.writeFile(s,E,"utf8"),o.success(`Updated ${i.name} Hugo version to ${r}`);}}}catch{}}}function jt(t,e){t.command("upgrade").alias("update").description("Upgrade HugoBlox modules to the latest version").option("-y, --yes","Skip confirmation").option("--ci","Run in non-interactive mode").option("--force","Force upgrade even if Hugo version is incompatible").option("--canary","Upgrade to the latest development commit (main branch) instead of stable release").action(async(o,r)=>{let{logger:n}=e;await Ke()||(n.error("\u274C You appear to be offline. Please check your internet connection."),process.exit(1));let i=await _();if(!i)throw new d("No Hugo project found in the current directory.");let s=kt("Checking for updates...").start(),a=await le(i.root);if(a.length===0){s.stop(),n.info("\u2139\uFE0F No official HugoBlox modules found in go.mod");return}let c=a.filter(m=>m.error);if(c.length>0){s.stop(),n.error("\u274C Failed to check for updates for some modules:");for(let m of c)n.error(` ${m.path}: ${m.error}`);process.exit(1);}let l=[];if(o.canary)s.text="Checking canary versions...",l.push(...a.map(m=>({path:m.path,version:"main"})));else {let m=a.map(p=>{let{updateAvailable:h,diff:f}=de(p.current,p.latest);return {...p,updateAvailable:h,diff:f}}).filter(p=>p.updateAvailable&&p.latest);if(m.length===0){s.stop(),n.success("\u2705 All HugoBlox modules are up to date");return}l.push(...m.map(p=>({path:p.path,version:p.latest||""})));}s.text="Checking version requirements...";let u=await Promise.all(l.map(async m=>{try{let p=await Ye(m.path,m.version);return {...m,min:p}}catch{return {...m,min:void 0}}}));if(s.stop(),!o.force){let m=await Ge();if(m){let p=u.filter(h=>{if(!h.min)return false;let f=S.coerce(h.min),y=S.coerce(m);return f&&y&&S.lt(y,f)});if(p.length>0){n.error("\u274C Hugo version incompatible with upgrade targets:");for(let h of p)n.error(` ${h.path.split("/").pop()} requires Hugo >= ${h.min} (you have ${m})`);n.info("\u{1F449} Please upgrade Hugo first: https://gohugo.io/installation/"),n.info(" Or run with --force to ignore this check."),process.exit(1);}}else n.warn("\u26A0\uFE0F Could not detect local Hugo version. Skipping compatibility check.");}if(o.canary){n.warn("\u26A0\uFE0F Upgrading modules to latest canary (development) version.");for(let m of a)n.info(` ${m.path.split("/").pop()}: ${J(m.current)} -> @main`);}else {n.info(`\u{1F4E6} Updates available for ${l.length} module(s):`);for(let m of l){let p=a.find(h=>h.path===m.path)?.current||"?";n.info(` ${m.path.split("/").pop()}`),n.info(` Current: ${J(p)}`),n.info(` Latest: ${J(m.version)}`);}}if(!o.yes&&!o.ci&&!await D(o.canary?"Are you sure you want to upgrade to the bleeding edge?":"Do you want to upgrade now?",{initial:true})){n.info("Upgrade cancelled");return}let g=l.map(m=>`${m.path}@${m.version}`);await Fo(i.root,g,n);let E=u.reduce((m,p)=>{if(!p.min)return m;let h=S.coerce(p.min),f=S.coerce(m);return h&&(!f||S.gt(h,f))?p.min:m},void 0);E&&await _t(i.root,E,n),n.info(""),n.warn("\u26A0\uFE0F Important: Please review the release notes for any breaking changes."),n.info("\u{1F449} https://github.com/HugoBlox/hugo-blox-builder/releases");});}async function Fo(t,e,o){let r=kt("Upgrading modules...").start();try{await execa("hugo",["mod","get",...e],{cwd:t}),r.text="Tidying go.mod...",await execa("hugo",["mod","tidy"],{cwd:t}),r.succeed(`\u2705 Upgraded ${e.length} module(s)`);}catch(n){r.fail("Failed to upgrade modules"),o.error(String(n)),process.exit(1);}}var N;function ue(){if(N)return N;let t=process.env.HBX_CLI_VERSION??process.env.npm_package_version;if(t)return N=t,N;let e=Go(import.meta.url);try{let o=At.readFileSync(e,"utf8");N=JSON.parse(o).version??"0.0.0";}catch{N="0.0.0";}return N}function Go(t){let e=w.dirname(fileURLToPath(t)),o=w.resolve(e,"../package.json");return At.existsSync(o)?o:w.resolve(e,"../../package.json")}function Dt(t,e){t.command("version").description("Print CLI version").action((o,r)=>{let{logger:n}=e,i=!!r.optsWithGlobals().json,s=ue(),a={status:"success",version:s};i?n.json(a):n.info(`hbx ${s}`);});}var fe=class t{#e;constructor(e){this.#e=e;}static async load(){try{let e=await b.readFile(ie,"utf8"),o=JSON.parse(e);return new t(o)}catch(e){if(e.code==="ENOENT")return new t({});throw new te("Failed to read configuration",{error:e})}}toJSON(){return this.#e}getToken(){return process.env[V]??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[De]==="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=Y.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 b.mkdir(we,{recursive:true});let e=JSON.stringify(this.#e,null,2);await b.writeFile(ie,e,{mode:384}),await b.chmod(ie,384);}};var ge=class{#e;#t;constructor(e={}){this.#e=e.json??false,this.#t=e.debug??process.env[K]==="1";}isJsonMode(){return this.#e}setJsonMode(e){this.#e=e;}setDebug(e){this.#t=e;}info(e){this.#e||process.stdout.write(`${Z.blue("i")} ${e}
74
+ `);}success(e){this.#e||process.stdout.write(`${Z.green("\u2714")} ${e}
75
+ `);}warn(e){this.#e||process.stdout.write(`${Z.yellow("!")} ${e}
76
+ `);}error(e){this.#e||process.stderr.write(`${Z.red("\u2716")} ${e}
77
+ `);}debug(e){!this.#t||this.#e||process.stdout.write(`${Z.gray("debug")} ${e}
77
78
  `);}json(e){let o=JSON.stringify(e,null,2);process.stdout.write(`${o}
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 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)}`);}}
79
+ `);}};var Jo=new Set(["command","project","duration","status","errorCode","errorMessage","metadata"]),Wo=50,qo=6144,Rt=25e3,ye=class{#e;#t;#r;#n=[];#o;#i=false;#s;#a;#c;constructor(e,o,r){this.#e=e,this.#t=o,this.#r=r,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.#n.push({...e,timestamp:new Date().toISOString(),payload:e.payload??{}}),await this.flush());}async flush(){if(!this.#n.length)return;if(this.#o){await this.#o;return}let e=this.#n.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(),n=[...e.map(i=>Qo(i))];for(;n.length;){let i=[],s;for(;n.length&&i.length<Wo;){let a=n[0];if(!a)break;let c=[...i,a],l=this.#m(c,o),u=JSON.stringify(l);if(Buffer$1.byteLength(u,"utf8")>Rt){if(!i.length){n.shift(),this.#t.warn("Dropped telemetry event because payload exceeded max size");continue}break}let g=n.shift();if(!g)break;i.push(g),s=u;}!i.length||!s||await this.#u(s,o);}}#m(e,o){return {clientId:o&&o.length>=8?o:"anonymous",os:he.platform(),osVersion:Yo(),arch:process.arch,nodeVersion:process.version,ci:Ko(),command:this.#s,releaseChannel:this.#a,sessionId:this.#c,cliVersion:this.#r,version:this.#r,hasLicense:!!this.#e.getToken(),events:e}}async#u(e,o){let r=Buffer$1.byteLength(e,"utf8");if(r>Rt){this.#t.warn("Telemetry payload skipped because it exceeded the maximum request size");return}try{let n=new AbortController,i=setTimeout(()=>n.abort(),5e3),s=await fetch(Me,{method:"POST",headers:{"Content-Type":"application/json","Content-Length":String(r),"User-Agent":`hbx-cli/${this.#r}`,...o?{"x-telemetry-id":o}:void 0},body:e,signal:n.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(n){this.#t.debug(`telemetry send failed: ${String(n)}`);}}};function Ko(){return process.env.CI==="1"||process.env.CONTINUOUS_INTEGRATION==="1"||!!process.env.BUILD_NUMBER||!!process.env.RUN_ID}function Yo(){let t=he.version;if(typeof t=="function")try{return t()}catch{return he.release()}return he.release()}function Qo(t){let e=Zo(t.payload);if(!e){let{payload:o,...r}=t;return r}try{let o=JSON.stringify(e);return Buffer$1.byteLength(o,"utf8")>qo?{...t,payload:{truncated:!0}}:{...t,payload:e}}catch{return {...t,payload:{truncated:true}}}}function Zo(t){if(!t||typeof t!="object")return;let e={};for(let o of Jo)if(Object.hasOwn(t,o)){let r=t[o];if(o==="metadata"&&(r==null||typeof r!="object"))continue;e[o]=r;}return Object.keys(e).length?e:void 0}async function Lt(t,e,o){if(process.env[Re]==="1")return;let r=e.getUpdateMetadata()??{},n=Date.now(),i=r.latestVersion,s=r.lastChecked??0;if(!i||n-s>Ue){let l=await tr(t,o);l.latestVersion&&(i=l.latestVersion),l.checkedAt>0&&(s=l.checkedAt,e.setUpdateMetadata({lastChecked:s,latestVersion:i}),await e.save());}if(!i||!S.valid(i)||!S.gt(i,t)||!er(r,n,i))return;let c=`npm install -g ${se}`;o.warn(`A new version of hbx is available: ${i} (current ${t}).
80
+ Update with: ${c} (or pnpm add -g ${se}).`),e.setUpdateMetadata({lastNotifiedAt:n,latestVersion:i}),await e.save();}function er(t,e,o){return !t||t.lastNotifiedAt===void 0||t.latestVersion!==o?true:e-t.lastNotifiedAt>Fe}async function tr(t,e){try{let o=await fetch(`https://registry.npmjs.org/${encodeURIComponent(se)}/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 rr(t=process.argv){let e=ue(),o=await fe.load(),r=new ge({debug:process.env[K]==="1"});await o.ensureTelemetryId();let n=new ye(o,r,e),i={config:o,logger:r,telemetry:n};await Lt(e,o,r),await ar(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 l=c?.optsWithGlobals?.()??a.optsWithGlobals();r.setJsonMode(!!l.json),r.setDebug(!!l.debug||process.env[K]==="1"),n.setCommand(sr(c));}),St(s,i),je(s,i),ot(s,i),ze(s,i),tt(s,i),lt(s,i),dt(s,i),jt(s,i),Ht(s,i),Dt(s,i);try{await s.parseAsync(t);}catch(a){nr(a,r);}}function nr(t,e){if(Be(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 H?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"))&&rr();function sr(t){if(!t)return ne;let e=[],o=t;for(;o?.parent;){let r=o.name?.();r&&e.unshift(r),o=o.parent;}return e.length?`${ne} ${e.join(" ")}`.trim():ne}async function ar(t){if(process.env[V]&&t.config.getToken()&&!t.config.getDeviceInfo())try{await k(t);}catch(e){t.logger.debug(`Skipping device registration warm-up: ${String(e)}`);}}
80
81
 
81
- export { Ro as bootstrap };
82
+ export { rr as bootstrap };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hugoblox",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "The official CLI for creating and managing HugoBlox sites.",
5
5
  "type": "module",
6
6
  "bin": {