nebutra 0.3.4 → 0.3.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +111 -111
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{b as a}from"./chunk-JDX5NXDX.js";import{a as b,b as x,c as K,d as ge,e as Pe,f as me}from"./chunk-LGUMYJ4Q.js";import{a as Qn}from"./chunk-FSRPMVAS.js";import{readFileSync as Cl}from"fs";import{dirname as Al,join as xl,resolve as Ol}from"path";import{fileURLToPath as Jn}from"url";import{Command as _l}from"commander";import{execFileSync as _t}from"child_process";import{promises as ke}from"fs";import H from"path";import*as w from"@clack/prompts";import Ue from"picocolors";var c={SUCCESS:0,ERROR:1,INVALID_ARGS:2,NOT_FOUND:3,PERMISSION_DENIED:4,CONFLICT:5,NETWORK_ERROR:6,TIMEOUT:7,CANCELLED:8,CONFIG_ERROR:9,DRY_RUN_OK:10,INCOMPATIBLE:11,RESOURCE_EXHAUSTED:12},Qt={[c.SUCCESS]:"Command completed successfully",[c.ERROR]:"General or unknown error occurred",[c.INVALID_ARGS]:"Invalid arguments or options provided",[c.NOT_FOUND]:"Requested resource not found",[c.PERMISSION_DENIED]:"Permission denied or authentication required",[c.CONFLICT]:"Resource already exists",[c.NETWORK_ERROR]:"Network or external service error (may be retryable)",[c.TIMEOUT]:"Operation timed out (may be retryable)",[c.CANCELLED]:"Operation cancelled by user",[c.CONFIG_ERROR]:"Configuration error or missing configuration",[c.DRY_RUN_OK]:"Dry-run completed successfully",[c.INCOMPATIBLE]:"Incompatible version or dependency conflict",[c.RESOURCE_EXHAUSTED]:"System resource exhausted"};import{existsSync as eo,readdirSync as tr,readFileSync as to,statSync as ro}from"fs";import{dirname as er,join as xt,parse as no}from"path";import{fileURLToPath as oo}from"url";var Zn={"@nebutra/ui":"^0.1.0","@nebutra/tokens":"^0.1.0","@nebutra/icons":"^0.1.0","@nebutra/brand":"^0.1.0","@nebutra/design-tokens":"^0.1.0","@nebutra/design-sync":"^0.1.0","@nebutra/identity":"^0.1.0","@nebutra/tenant":"^0.1.0","@nebutra/permissions":"^0.1.0","@nebutra/vault":"^0.1.0","@nebutra/audit":"^0.1.0","@nebutra/billing":"^0.1.0","@nebutra/contracts":"^0.1.0","@nebutra/license":"^0.1.0","@nebutra/metering":"^0.1.0","@nebutra/queue":"^0.1.0","@nebutra/search":"^0.1.0","@nebutra/cache":"^0.1.0","@nebutra/notifications":"^0.1.0","@nebutra/webhooks":"^0.1.0","@nebutra/uploads":"^0.1.0","@nebutra/email":"^0.1.0","@nebutra/agents":"^0.1.0","@nebutra/mcp":"^0.1.0","@nebutra/logger":"^0.1.0"};function Zt(e){return Zn[e]??null}var ao=`const featureEnvKeys = {{envKeysArray}} as const;
2
+ import{b as a}from"./chunk-JDX5NXDX.js";import{a as b,b as x,c as K,d as ge,e as Pe,f as me}from"./chunk-LGUMYJ4Q.js";import{a as eo}from"./chunk-FSRPMVAS.js";import{readFileSync as xl,realpathSync as Jn}from"fs";import{dirname as Ol,join as _l,resolve as Xn}from"path";import{fileURLToPath as Jt}from"url";import{Command as Pl}from"commander";import{execFileSync as _t}from"child_process";import{promises as ke}from"fs";import H from"path";import*as w from"@clack/prompts";import Ue from"picocolors";var c={SUCCESS:0,ERROR:1,INVALID_ARGS:2,NOT_FOUND:3,PERMISSION_DENIED:4,CONFLICT:5,NETWORK_ERROR:6,TIMEOUT:7,CANCELLED:8,CONFIG_ERROR:9,DRY_RUN_OK:10,INCOMPATIBLE:11,RESOURCE_EXHAUSTED:12},Zt={[c.SUCCESS]:"Command completed successfully",[c.ERROR]:"General or unknown error occurred",[c.INVALID_ARGS]:"Invalid arguments or options provided",[c.NOT_FOUND]:"Requested resource not found",[c.PERMISSION_DENIED]:"Permission denied or authentication required",[c.CONFLICT]:"Resource already exists",[c.NETWORK_ERROR]:"Network or external service error (may be retryable)",[c.TIMEOUT]:"Operation timed out (may be retryable)",[c.CANCELLED]:"Operation cancelled by user",[c.CONFIG_ERROR]:"Configuration error or missing configuration",[c.DRY_RUN_OK]:"Dry-run completed successfully",[c.INCOMPATIBLE]:"Incompatible version or dependency conflict",[c.RESOURCE_EXHAUSTED]:"System resource exhausted"};import{existsSync as ro,readdirSync as rr,readFileSync as no,statSync as oo}from"fs";import{dirname as tr,join as xt,parse as ao}from"path";import{fileURLToPath as io}from"url";var to={"@nebutra/ui":"^0.1.0","@nebutra/tokens":"^0.1.0","@nebutra/icons":"^0.1.0","@nebutra/brand":"^0.1.0","@nebutra/design-tokens":"^0.1.0","@nebutra/design-sync":"^0.1.0","@nebutra/identity":"^0.1.0","@nebutra/tenant":"^0.1.0","@nebutra/permissions":"^0.1.0","@nebutra/vault":"^0.1.0","@nebutra/audit":"^0.1.0","@nebutra/billing":"^0.1.0","@nebutra/contracts":"^0.1.0","@nebutra/license":"^0.1.0","@nebutra/metering":"^0.1.0","@nebutra/queue":"^0.1.0","@nebutra/search":"^0.1.0","@nebutra/cache":"^0.1.0","@nebutra/notifications":"^0.1.0","@nebutra/webhooks":"^0.1.0","@nebutra/uploads":"^0.1.0","@nebutra/email":"^0.1.0","@nebutra/agents":"^0.1.0","@nebutra/mcp":"^0.1.0","@nebutra/logger":"^0.1.0"};function er(e){return to[e]??null}var so=`const featureEnvKeys = {{envKeysArray}} as const;
3
3
 
4
4
  export const platformFeature = {
5
5
  name: "{{feature}}",
@@ -19,7 +19,7 @@ export function getFeatureProvider() {
19
19
  envKeys: featureEnvKeys,
20
20
  };
21
21
  }
22
- `,io=`# {{feature}} Feature
22
+ `,co=`# {{feature}} Feature
23
23
 
24
24
  Installed by \`nebutra add {{feature}}\`.
25
25
 
@@ -31,7 +31,7 @@ Next steps:
31
31
  1. Set the required environment variables in \`{{envFile}}\`.
32
32
  2. Wire this starter into the generated package or app surface.
33
33
  3. Replace the placeholder helper with your production adapter.
34
- `,so="integrations";function Te(e,t=so){let r=`packages/${t}/${e}`;return[{path:`${r}/src/index.ts`,content:ao},{path:`${r}/README.md`,content:io}]}var co={queue:{name:"queue",description:"Background job queue starter for Nebutra-style monorepos.",envFile:".env.local",providers:[{id:"upstash",description:"HTTP queue transport powered by Upstash QStash.",dependencies:[{name:"@upstash/qstash",version:"latest"}],env:[{key:"QSTASH_TOKEN",description:"Upstash QStash REST token"},{key:"QSTASH_CURRENT_SIGNING_KEY",description:"Upstash current signing key for webhook verification"},{key:"QSTASH_NEXT_SIGNING_KEY",description:"Upstash next signing key for webhook rotation"}]},{id:"bullmq",description:"Redis-backed worker queue powered by BullMQ.",dependencies:[{name:"bullmq",version:"latest"},{name:"ioredis",version:"latest"}],env:[{key:"REDIS_URL",description:"Redis connection string for BullMQ workers"}]}],files:[{path:"packages/integrations/queue/src/index.ts",content:`const queueEnvKeys = {{envKeysArray}} as const;
34
+ `,lo="integrations";function Te(e,t=lo){let r=`packages/${t}/${e}`;return[{path:`${r}/src/index.ts`,content:so},{path:`${r}/README.md`,content:co}]}var uo={queue:{name:"queue",description:"Background job queue starter for Nebutra-style monorepos.",envFile:".env.local",providers:[{id:"upstash",description:"HTTP queue transport powered by Upstash QStash.",dependencies:[{name:"@upstash/qstash",version:"latest"}],env:[{key:"QSTASH_TOKEN",description:"Upstash QStash REST token"},{key:"QSTASH_CURRENT_SIGNING_KEY",description:"Upstash current signing key for webhook verification"},{key:"QSTASH_NEXT_SIGNING_KEY",description:"Upstash next signing key for webhook rotation"}]},{id:"bullmq",description:"Redis-backed worker queue powered by BullMQ.",dependencies:[{name:"bullmq",version:"latest"},{name:"ioredis",version:"latest"}],env:[{key:"REDIS_URL",description:"Redis connection string for BullMQ workers"}]}],files:[{path:"packages/integrations/queue/src/index.ts",content:`const queueEnvKeys = {{envKeysArray}} as const;
35
35
 
36
36
  export const queueFeature = {
37
37
  name: "queue",
@@ -95,17 +95,17 @@ Next steps:
95
95
  1. Add credentials to \`{{envFile}}\`.
96
96
  2. Point your indexing jobs at the configured provider.
97
97
  3. Replace the placeholder helpers with production query/index code.
98
- `}]},cache:{name:"cache",description:"Cache adapter starter aligned with create-sailor cache providers.",envFile:".env.local",providers:[{id:"upstash-redis",description:"Serverless Redis cache powered by Upstash.",dependencies:[{name:"@upstash/redis",version:"latest"}],env:[{key:"UPSTASH_REDIS_REST_URL",description:"Upstash Redis REST URL"}]},{id:"vercel-kv",description:"Vercel KV compatible cache adapter.",dependencies:[{name:"@vercel/kv",version:"latest"}],env:[{key:"KV_REST_API_URL",description:"Vercel KV REST API URL"}]},{id:"redis",description:"Self-hosted Redis cache adapter.",dependencies:[{name:"ioredis",version:"latest"}],env:[{key:"REDIS_URL",description:"Redis connection URL"}]},{id:"dragonfly",description:"Dragonfly Redis-compatible cache adapter.",dependencies:[{name:"ioredis",version:"latest"}],env:[{key:"DRAGONFLY_URL",description:"Dragonfly connection URL"}]}],files:Te("cache")},notifications:{name:"notifications",description:"Notification workflow starter for product and lifecycle messages.",envFile:".env.local",providers:[{id:"novu",description:"Novu notification workflow provider.",dependencies:[{name:"@novu/node",version:"latest"}],env:[{key:"NOVU_API_KEY",description:"Novu API key"}]},{id:"knock",description:"Knock notification workflow provider.",dependencies:[{name:"@knocklabs/node",version:"latest"}],env:[{key:"KNOCK_API_KEY",description:"Knock API key"}]},{id:"custom",description:"Custom notification adapter surface.",env:[{key:"NOTIFICATIONS_WEBHOOK_URL",description:"Custom notification webhook URL"}]}],files:Te("notifications")},webhooks:{name:"webhooks",description:"Outbound webhook starter with provider-specific signing hooks.",envFile:".env.local",providers:[{id:"svix",description:"Svix-backed outbound webhook delivery.",dependencies:[{name:"svix",version:"latest"}],env:[{key:"SVIX_AUTH_TOKEN",description:"Svix authentication token"}]},{id:"custom",description:"Custom outbound webhook adapter.",env:[{key:"WEBHOOK_SIGNING_SECRET",description:"Webhook signing secret"}]}],files:Te("webhooks")},cms:{name:"cms",description:"Headless CMS integration starter for marketing and docs content.",envFile:".env.local",providers:[{id:"sanity",description:"Sanity content lake client starter.",dependencies:[{name:"next-sanity",version:"latest"}],env:[{key:"NEXT_PUBLIC_SANITY_PROJECT_ID",description:"Sanity project ID"},{key:"NEXT_PUBLIC_SANITY_DATASET",description:"Sanity dataset"}]},{id:"contentful",description:"Contentful content API starter.",dependencies:[{name:"contentful",version:"latest"}],env:[{key:"CONTENTFUL_SPACE_ID",description:"Contentful space ID"},{key:"CONTENTFUL_ACCESS_TOKEN",description:"Contentful access token"}]},{id:"strapi",description:"Strapi REST client starter.",env:[{key:"STRAPI_URL",description:"Strapi base URL"},{key:"STRAPI_API_TOKEN",description:"Strapi API token"}]}],files:Te("cms")},"feature-flags":{name:"feature-flags",description:"Feature flag starter for gradual rollout and runtime controls.",envFile:".env.local",providers:[{id:"vercel-flags",description:"Vercel Flags SDK starter.",dependencies:[{name:"@vercel/flags",version:"latest"}],env:[{key:"FLAGS_SECRET",description:"Feature flag signing secret"}]},{id:"growthbook",description:"GrowthBook feature flag client starter.",dependencies:[{name:"@growthbook/growthbook",version:"latest"}],env:[{key:"GROWTHBOOK_CLIENT_KEY",description:"GrowthBook client key"}]},{id:"configcat",description:"ConfigCat feature flag client starter.",dependencies:[{name:"configcat-node",version:"latest"}],env:[{key:"CONFIGCAT_SDK_KEY",description:"ConfigCat SDK key"}]}],files:Te("feature-flags","platform")},captcha:{name:"captcha",description:"Captcha verification starter for abuse prevention.",envFile:".env.local",providers:[{id:"turnstile",description:"Cloudflare Turnstile verification surface.",env:[{key:"NEXT_PUBLIC_TURNSTILE_SITE_KEY",description:"Turnstile site key"},{key:"TURNSTILE_SECRET_KEY",description:"Turnstile secret key"}]},{id:"hcaptcha",description:"hCaptcha verification surface.",env:[{key:"NEXT_PUBLIC_HCAPTCHA_SITE_KEY",description:"hCaptcha site key"},{key:"HCAPTCHA_SECRET_KEY",description:"hCaptcha secret key"}]},{id:"aliyun-slide",description:"Aliyun slide captcha verification surface.",env:[{key:"ALIYUN_CAPTCHA_SCENE_ID",description:"Aliyun captcha scene ID"},{key:"ALIYUN_CAPTCHA_SECRET",description:"Aliyun captcha secret"}]}],files:Te("captcha","iam")}},lo=["iam","commerce","integrations","ai","design","platform","ops"];function uo(){let e;try{e=er(oo(import.meta.url))}catch{e=process.cwd()}for(;e&&e!==no(e).root;){try{let t=tr(e);if(t.includes("pnpm-workspace.yaml")||t.includes("packages")){let r=xt(e,"packages");if(eo(r)&&ro(r).isDirectory())return r}}catch{}e=er(e)}return null}function mo(e,t,r,n,o){let i=(t.env??[]).map(l=>({key:l,description:`${l} (declared by ${o})`})),s=Zt(o)??"latest";return{name:e,description:t.summary??r.description??`${e} feature`,group:t.category??n,dependencies:[{name:o,version:s}],env:i,envFile:t.envFile??".env.local",files:[]}}var Ze=null;function po(){if(Ze)return Ze;let e={},t=uo();if(!t)return Ze=e,e;for(let r of lo){let n=xt(t,r),o;try{o=tr(n)}catch{continue}for(let i of o){let s=xt(n,i,"package.json"),l;try{l=to(s,"utf-8")}catch{continue}let u;try{u=JSON.parse(l)}catch{continue}let m=u.nebutra,f=m?.featureId;!m||!f||!u.name||(e[f]=mo(f,m,u,r,u.name))}}return Ze=e,e}function rr(){return{...po(),...co}}function nr(){return Object.values(rr())}async function or(e){return rr()[e]??null}function Ot(e){return e instanceof Error&&e.message.startsWith("EXIT:")}function ar(e){try{return _t("npm",["list",e],{stdio:"pipe"}),!0}catch{return!1}}function ir(e){process.stdout.write(`${JSON.stringify(e,null,2)}
99
- `)}function fo(e,t){let r=[];if(t["21st"]){let n=t["21st"],o=n.startsWith("http")?n:`https://21st.dev/r/${n}`;r.push({type:"run-command",source:"21st",component:n,resolvedUrl:o,command:`pnpm dlx shadcn@latest add "${o}"`})}return t.v0&&r.push({type:"run-command",source:"v0",component:"v0-component",resolvedUrl:t.v0,command:`pnpm dlx shadcn@latest add "${t.v0}"`}),e.length>0&&!t["21st"]&&!t.v0&&a.warn("Local feature installs are handled separately from external registry flows."),{mode:"dry-run",planType:"external-add",cwd:process.cwd(),timestamp:new Date().toISOString(),operations:r,summary:{execute:r.length}}}function sr(e,t){if(!t||t.length===0)return[];let r=new Map;for(let n of t)r.set(`${e}:${n.name}`,n);return Array.from(r.values())}function cr(e){let t=new Map;for(let r of e)t.has(r.key)||t.set(r.key,r);return Array.from(t.values())}function go(e,t){let r=t.envEntries.map(n=>n.key);return e.replaceAll("{{feature}}",t.feature).replaceAll("{{provider}}",t.provider??"default").replaceAll("{{providerDescription}}",t.providerDescription??"No provider selected").replaceAll("{{envFile}}",t.envFile).replaceAll("{{envKeysCsv}}",r.join(", ")).replaceAll("{{envKeysArray}}",JSON.stringify(r))}async function et(e){try{return await ke.readFile(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function yo(e,t){if(t)return H.join(e,t);let r=[".env.local",".env"];for(let n of r)try{return await ke.access(H.join(e,n)),H.join(e,n)}catch{}return H.join(e,".env.local")}function ho(e){let t=new Set;for(let r of e.matchAll(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/gm))r[1]&&t.add(r[1]);return t}function bo(e){return e?Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r))):{}}function lr(e,t){if(!(!e.providers||e.providers.length===0))return t?e.providers.find(r=>r.id===t):e.providers[0]}async function vo(e,t,r){let n=H.join(t,"package.json"),o=await et(n);if(!o)throw new Error(`No package.json found in ${t}. Run this command from a project root.`);let i=JSON.parse(o),s=cr(e.flatMap(p=>[...p.descriptor.env??[],...p.provider?.env??[]])),l=await yo(t,e[0]?.descriptor.envFile),u=await et(l)??"",m=ho(u),f=s.filter(p=>!m.has(p.key)),y=s.filter(p=>m.has(p.key)),C=[];for(let p of e){let F=cr([...p.descriptor.env??[],...p.provider?.env??[]]),_e={feature:p.name,provider:p.provider?.id,providerDescription:p.provider?.description,envFile:H.relative(t,l)||H.basename(l),envEntries:F};for(let Ct of p.descriptor.files??[]){let At=H.join(t,Ct.path),Xn=H.relative(t,At)||Ct.path,Jt=go(Ct.content,_e),Xt=await et(At),Xe,Qe;Xt===null?(Xe="create",Qe="file missing"):Xt===Jt?(Xe="skip",Qe="already matches registry template"):(Xe="conflict",Qe="file exists with different content"),C.push({type:"write-file",feature:p.name,path:At,relativePath:Xn,status:Xe,reason:Qe,content:Jt})}}let L=sr("dependencies",e.flatMap(p=>[...p.descriptor.dependencies??[],...p.provider?.dependencies??[]])),D=sr("devDependencies",e.flatMap(p=>[...p.descriptor.devDependencies??[],...p.provider?.devDependencies??[]])),q=[];for(let p of L){let F=i.dependencies?.[p.name];q.push({section:"dependencies",name:p.name,action:F?F===p.version?"keep":"update":"add",from:F,to:p.version})}for(let p of D){let F=i.devDependencies?.[p.name];q.push({section:"devDependencies",name:p.name,action:F?F===p.version?"keep":"update":"add",from:F,to:p.version})}let ue={type:"merge-env",path:l,relativePath:H.relative(t,l)||H.basename(l),created:u.length===0,add:f,keep:y},ie={type:"update-package-json",path:n,relativePath:H.relative(t,n)||"package.json",changes:q},Re={create:C.filter(p=>p.status==="create").length,update:q.filter(p=>p.action==="add"||p.action==="update").length,append:f.length,skip:C.filter(p=>p.status==="skip").length+q.filter(p=>p.action==="keep").length+y.length,conflict:C.filter(p=>p.status==="conflict").length};return{mode:r,planType:"local-feature-install",cwd:t,timestamp:new Date().toISOString(),features:e.map(p=>({name:p.name,description:p.descriptor.description,provider:p.provider?.id,providerDescription:p.provider?.description})),operations:[...C,ue,ie],summary:Re}}function dr(e){return e.summary.create>0||e.summary.update>0||e.summary.append>0}function wo(e){return e.summary.conflict>0}async function So(e){let t=e.operations.find(o=>o.type==="update-package-json"),r=e.operations.find(o=>o.type==="merge-env"),n=e.operations.filter(o=>o.type==="write-file");for(let o of n)o.status==="create"&&(await ke.mkdir(H.dirname(o.path),{recursive:!0}),await ke.writeFile(o.path,o.content,"utf8"));if(r&&r.add.length>0){let o=await et(r.path)??"",i=r.add.map(u=>`# ${u.description}
98
+ `}]},cache:{name:"cache",description:"Cache adapter starter aligned with create-sailor cache providers.",envFile:".env.local",providers:[{id:"upstash-redis",description:"Serverless Redis cache powered by Upstash.",dependencies:[{name:"@upstash/redis",version:"latest"}],env:[{key:"UPSTASH_REDIS_REST_URL",description:"Upstash Redis REST URL"}]},{id:"vercel-kv",description:"Vercel KV compatible cache adapter.",dependencies:[{name:"@vercel/kv",version:"latest"}],env:[{key:"KV_REST_API_URL",description:"Vercel KV REST API URL"}]},{id:"redis",description:"Self-hosted Redis cache adapter.",dependencies:[{name:"ioredis",version:"latest"}],env:[{key:"REDIS_URL",description:"Redis connection URL"}]},{id:"dragonfly",description:"Dragonfly Redis-compatible cache adapter.",dependencies:[{name:"ioredis",version:"latest"}],env:[{key:"DRAGONFLY_URL",description:"Dragonfly connection URL"}]}],files:Te("cache")},notifications:{name:"notifications",description:"Notification workflow starter for product and lifecycle messages.",envFile:".env.local",providers:[{id:"novu",description:"Novu notification workflow provider.",dependencies:[{name:"@novu/node",version:"latest"}],env:[{key:"NOVU_API_KEY",description:"Novu API key"}]},{id:"knock",description:"Knock notification workflow provider.",dependencies:[{name:"@knocklabs/node",version:"latest"}],env:[{key:"KNOCK_API_KEY",description:"Knock API key"}]},{id:"custom",description:"Custom notification adapter surface.",env:[{key:"NOTIFICATIONS_WEBHOOK_URL",description:"Custom notification webhook URL"}]}],files:Te("notifications")},webhooks:{name:"webhooks",description:"Outbound webhook starter with provider-specific signing hooks.",envFile:".env.local",providers:[{id:"svix",description:"Svix-backed outbound webhook delivery.",dependencies:[{name:"svix",version:"latest"}],env:[{key:"SVIX_AUTH_TOKEN",description:"Svix authentication token"}]},{id:"custom",description:"Custom outbound webhook adapter.",env:[{key:"WEBHOOK_SIGNING_SECRET",description:"Webhook signing secret"}]}],files:Te("webhooks")},cms:{name:"cms",description:"Headless CMS integration starter for marketing and docs content.",envFile:".env.local",providers:[{id:"sanity",description:"Sanity content lake client starter.",dependencies:[{name:"next-sanity",version:"latest"}],env:[{key:"NEXT_PUBLIC_SANITY_PROJECT_ID",description:"Sanity project ID"},{key:"NEXT_PUBLIC_SANITY_DATASET",description:"Sanity dataset"}]},{id:"contentful",description:"Contentful content API starter.",dependencies:[{name:"contentful",version:"latest"}],env:[{key:"CONTENTFUL_SPACE_ID",description:"Contentful space ID"},{key:"CONTENTFUL_ACCESS_TOKEN",description:"Contentful access token"}]},{id:"strapi",description:"Strapi REST client starter.",env:[{key:"STRAPI_URL",description:"Strapi base URL"},{key:"STRAPI_API_TOKEN",description:"Strapi API token"}]}],files:Te("cms")},"feature-flags":{name:"feature-flags",description:"Feature flag starter for gradual rollout and runtime controls.",envFile:".env.local",providers:[{id:"vercel-flags",description:"Vercel Flags SDK starter.",dependencies:[{name:"@vercel/flags",version:"latest"}],env:[{key:"FLAGS_SECRET",description:"Feature flag signing secret"}]},{id:"growthbook",description:"GrowthBook feature flag client starter.",dependencies:[{name:"@growthbook/growthbook",version:"latest"}],env:[{key:"GROWTHBOOK_CLIENT_KEY",description:"GrowthBook client key"}]},{id:"configcat",description:"ConfigCat feature flag client starter.",dependencies:[{name:"configcat-node",version:"latest"}],env:[{key:"CONFIGCAT_SDK_KEY",description:"ConfigCat SDK key"}]}],files:Te("feature-flags","platform")},captcha:{name:"captcha",description:"Captcha verification starter for abuse prevention.",envFile:".env.local",providers:[{id:"turnstile",description:"Cloudflare Turnstile verification surface.",env:[{key:"NEXT_PUBLIC_TURNSTILE_SITE_KEY",description:"Turnstile site key"},{key:"TURNSTILE_SECRET_KEY",description:"Turnstile secret key"}]},{id:"hcaptcha",description:"hCaptcha verification surface.",env:[{key:"NEXT_PUBLIC_HCAPTCHA_SITE_KEY",description:"hCaptcha site key"},{key:"HCAPTCHA_SECRET_KEY",description:"hCaptcha secret key"}]},{id:"aliyun-slide",description:"Aliyun slide captcha verification surface.",env:[{key:"ALIYUN_CAPTCHA_SCENE_ID",description:"Aliyun captcha scene ID"},{key:"ALIYUN_CAPTCHA_SECRET",description:"Aliyun captcha secret"}]}],files:Te("captcha","iam")}},mo=["iam","commerce","integrations","ai","design","platform","ops"];function po(){let e;try{e=tr(io(import.meta.url))}catch{e=process.cwd()}for(;e&&e!==ao(e).root;){try{let t=rr(e);if(t.includes("pnpm-workspace.yaml")||t.includes("packages")){let r=xt(e,"packages");if(ro(r)&&oo(r).isDirectory())return r}}catch{}e=tr(e)}return null}function fo(e,t,r,n,o){let i=(t.env??[]).map(l=>({key:l,description:`${l} (declared by ${o})`})),s=er(o)??"latest";return{name:e,description:t.summary??r.description??`${e} feature`,group:t.category??n,dependencies:[{name:o,version:s}],env:i,envFile:t.envFile??".env.local",files:[]}}var Ze=null;function go(){if(Ze)return Ze;let e={},t=po();if(!t)return Ze=e,e;for(let r of mo){let n=xt(t,r),o;try{o=rr(n)}catch{continue}for(let i of o){let s=xt(n,i,"package.json"),l;try{l=no(s,"utf-8")}catch{continue}let u;try{u=JSON.parse(l)}catch{continue}let m=u.nebutra,f=m?.featureId;!m||!f||!u.name||(e[f]=fo(f,m,u,r,u.name))}}return Ze=e,e}function nr(){return{...go(),...uo}}function or(){return Object.values(nr())}async function ar(e){return nr()[e]??null}function Ot(e){return e instanceof Error&&e.message.startsWith("EXIT:")}function ir(e){try{return _t("npm",["list",e],{stdio:"pipe"}),!0}catch{return!1}}function sr(e){process.stdout.write(`${JSON.stringify(e,null,2)}
99
+ `)}function yo(e,t){let r=[];if(t["21st"]){let n=t["21st"],o=n.startsWith("http")?n:`https://21st.dev/r/${n}`;r.push({type:"run-command",source:"21st",component:n,resolvedUrl:o,command:`pnpm dlx shadcn@latest add "${o}"`})}return t.v0&&r.push({type:"run-command",source:"v0",component:"v0-component",resolvedUrl:t.v0,command:`pnpm dlx shadcn@latest add "${t.v0}"`}),e.length>0&&!t["21st"]&&!t.v0&&a.warn("Local feature installs are handled separately from external registry flows."),{mode:"dry-run",planType:"external-add",cwd:process.cwd(),timestamp:new Date().toISOString(),operations:r,summary:{execute:r.length}}}function cr(e,t){if(!t||t.length===0)return[];let r=new Map;for(let n of t)r.set(`${e}:${n.name}`,n);return Array.from(r.values())}function lr(e){let t=new Map;for(let r of e)t.has(r.key)||t.set(r.key,r);return Array.from(t.values())}function ho(e,t){let r=t.envEntries.map(n=>n.key);return e.replaceAll("{{feature}}",t.feature).replaceAll("{{provider}}",t.provider??"default").replaceAll("{{providerDescription}}",t.providerDescription??"No provider selected").replaceAll("{{envFile}}",t.envFile).replaceAll("{{envKeysCsv}}",r.join(", ")).replaceAll("{{envKeysArray}}",JSON.stringify(r))}async function et(e){try{return await ke.readFile(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function bo(e,t){if(t)return H.join(e,t);let r=[".env.local",".env"];for(let n of r)try{return await ke.access(H.join(e,n)),H.join(e,n)}catch{}return H.join(e,".env.local")}function vo(e){let t=new Set;for(let r of e.matchAll(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/gm))r[1]&&t.add(r[1]);return t}function wo(e){return e?Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r))):{}}function dr(e,t){if(!(!e.providers||e.providers.length===0))return t?e.providers.find(r=>r.id===t):e.providers[0]}async function So(e,t,r){let n=H.join(t,"package.json"),o=await et(n);if(!o)throw new Error(`No package.json found in ${t}. Run this command from a project root.`);let i=JSON.parse(o),s=lr(e.flatMap(p=>[...p.descriptor.env??[],...p.provider?.env??[]])),l=await bo(t,e[0]?.descriptor.envFile),u=await et(l)??"",m=vo(u),f=s.filter(p=>!m.has(p.key)),y=s.filter(p=>m.has(p.key)),C=[];for(let p of e){let F=lr([...p.descriptor.env??[],...p.provider?.env??[]]),_e={feature:p.name,provider:p.provider?.id,providerDescription:p.provider?.description,envFile:H.relative(t,l)||H.basename(l),envEntries:F};for(let Ct of p.descriptor.files??[]){let At=H.join(t,Ct.path),Zn=H.relative(t,At)||Ct.path,Xt=ho(Ct.content,_e),Qt=await et(At),Xe,Qe;Qt===null?(Xe="create",Qe="file missing"):Qt===Xt?(Xe="skip",Qe="already matches registry template"):(Xe="conflict",Qe="file exists with different content"),C.push({type:"write-file",feature:p.name,path:At,relativePath:Zn,status:Xe,reason:Qe,content:Xt})}}let L=cr("dependencies",e.flatMap(p=>[...p.descriptor.dependencies??[],...p.provider?.dependencies??[]])),D=cr("devDependencies",e.flatMap(p=>[...p.descriptor.devDependencies??[],...p.provider?.devDependencies??[]])),q=[];for(let p of L){let F=i.dependencies?.[p.name];q.push({section:"dependencies",name:p.name,action:F?F===p.version?"keep":"update":"add",from:F,to:p.version})}for(let p of D){let F=i.devDependencies?.[p.name];q.push({section:"devDependencies",name:p.name,action:F?F===p.version?"keep":"update":"add",from:F,to:p.version})}let ue={type:"merge-env",path:l,relativePath:H.relative(t,l)||H.basename(l),created:u.length===0,add:f,keep:y},ie={type:"update-package-json",path:n,relativePath:H.relative(t,n)||"package.json",changes:q},Re={create:C.filter(p=>p.status==="create").length,update:q.filter(p=>p.action==="add"||p.action==="update").length,append:f.length,skip:C.filter(p=>p.status==="skip").length+q.filter(p=>p.action==="keep").length+y.length,conflict:C.filter(p=>p.status==="conflict").length};return{mode:r,planType:"local-feature-install",cwd:t,timestamp:new Date().toISOString(),features:e.map(p=>({name:p.name,description:p.descriptor.description,provider:p.provider?.id,providerDescription:p.provider?.description})),operations:[...C,ue,ie],summary:Re}}function ur(e){return e.summary.create>0||e.summary.update>0||e.summary.append>0}function Ro(e){return e.summary.conflict>0}async function ko(e){let t=e.operations.find(o=>o.type==="update-package-json"),r=e.operations.find(o=>o.type==="merge-env"),n=e.operations.filter(o=>o.type==="write-file");for(let o of n)o.status==="create"&&(await ke.mkdir(H.dirname(o.path),{recursive:!0}),await ke.writeFile(o.path,o.content,"utf8"));if(r&&r.add.length>0){let o=await et(r.path)??"",i=r.add.map(u=>`# ${u.description}
100
100
  ${u.key}=`),s=o.trim().length>0?`
101
101
 
102
102
  `:"",l=`${o.replace(/\s+$/,"")}${s}${i.join(`
103
103
 
104
104
  `)}
105
- `;await ke.writeFile(r.path,l,"utf8")}if(t){let o=await ke.readFile(t.path,"utf8"),i=JSON.parse(o);for(let s of t.changes){if(s.action==="keep")continue;let l=s.section==="dependencies"?"dependencies":"devDependencies";i[l]={...i[l]??{},[s.name]:s.to},i[l]=bo(i[l])}await ke.writeFile(t.path,`${JSON.stringify(i,null,2)}
106
- `,"utf8")}}async function Ro(e,t,r){let n=[];for(let o of e){let i=await or(o);i||(a.error(`Feature '${o}' not found in the local registry.`),a.info("Use one of the supported local features or choose --21st / --v0 for external UI installs."),process.exit(c.INVALID_ARGS));let s=lr(i,t.provider);if(t.provider&&!s&&(a.error(`Provider '${t.provider}' is not supported for feature '${o}'.`),process.exit(c.INVALID_ARGS)),!s&&i.providers&&i.providers.length>0)if(r)s=i.providers[0];else{let l=await w.select({message:`Select a provider for ${o}`,options:i.providers.map(u=>({value:u.id,label:u.id,hint:u.description}))});w.isCancel(l)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),s=lr(i,String(l))}n.push({name:o,descriptor:i,provider:s})}return n}function ko(e){w.log.info(Ue.yellow("Planned local install:"));for(let t of e.features)w.log.message(` - ${t.name}${t.provider?` (${t.provider})`:""}: ${t.description}`);for(let t of e.operations)if(t.type==="write-file"&&w.log.message(` - ${t.status.toUpperCase()} ${t.relativePath}`),t.type==="merge-env"&&t.add.length>0&&w.log.message(` - APPEND ${t.add.map(r=>r.key).join(", ")} to ${t.relativePath}`),t.type==="update-package-json"){let r=t.changes.filter(n=>n.action==="add"||n.action==="update");r.length>0&&w.log.message(` - UPDATE ${t.relativePath}: ${r.map(n=>`${n.name}@${n.to}`).join(", ")}`)}}async function ur(e,t){t.dryRun||w.intro(Ue.bgCyan(Ue.black(" nebutra add ")));let r=t.yes||!process.stdin.isTTY;if(e.length===0&&!t["21st"]&&!t.v0&&(t.dryRun?a.warn("No components specified."):(w.log.warn("No components specified."),w.outro("Operation aborted.")),process.exit(c.INVALID_ARGS)),t.dryRun&&(t["21st"]||t.v0)&&(ir(fo(e,t)),process.exit(c.DRY_RUN_OK)),t.ifNotExists&&(t["21st"]||t.v0)&&(t["21st"]&&ar(t["21st"])||t.v0&&ar("shadcn-component"))&&(a.info("Component already exists. Skipping installation."),process.exit(c.SUCCESS)),t["21st"]){let n=r||await w.confirm({message:`Install 21st.dev component: ${t["21st"]}?`,initialValue:!0});(w.isCancel(n)||!n)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),w.log.info(Ue.cyan(`Invoking shadcn integration for 21st.dev component: ${t["21st"]}...`));try{let o=t["21st"],i=o.startsWith("http")?o:`https://21st.dev/r/${o}`;_t("pnpm",["dlx","shadcn@latest","add",i],{stdio:"inherit"}),a.success(`Successfully installed ${o}`),process.exit(c.SUCCESS)}catch(o){if(Ot(o))throw o;a.error(`Failed to install component: ${o instanceof Error?o.message:"Unknown error"}`),process.exit(c.ERROR)}}if(t.v0){let n=r||await w.confirm({message:`Install v0 component from: ${t.v0}?`,initialValue:!0});(w.isCancel(n)||!n)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),w.log.info(Ue.cyan(`Invoking shadcn integration for v0 URL: ${t.v0}...`));try{_t("pnpm",["dlx","shadcn@latest","add",t.v0],{stdio:"inherit"}),a.success("Successfully installed v0 component"),process.exit(c.SUCCESS)}catch(o){if(Ot(o))throw o;a.error(`Failed to install component: ${o instanceof Error?o.message:"Unknown error"}`),process.exit(c.ERROR)}}try{let n=await Ro(e,t,r),o=await vo(n,process.cwd(),t.dryRun?"dry-run":"apply");if(t.dryRun&&(ir(o),process.exit(c.DRY_RUN_OK)),wo(o)){let s=o.operations.filter(l=>l.type==="write-file"&&l.status==="conflict").map(l=>l.relativePath);t.ifNotExists&&!dr(o)&&(a.info("Feature already appears to be installed. Skipping because --if-not-exists was set."),process.exit(c.SUCCESS)),a.error(`Refusing to overwrite existing files: ${s.join(", ")}`),process.exit(c.CONFLICT)}dr(o)||(a.info("Feature install already satisfied. No files, env keys, or dependencies needed changes."),process.exit(c.SUCCESS)),ko(o);let i=r||await w.confirm({message:`Proceed with installing ${o.features.map(s=>s.name).join(", ")}?`,initialValue:!0});(w.isCancel(i)||!i)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),await So(o),a.success(`Installed ${o.features.map(s=>s.name).join(", ")} into ${o.cwd}`),process.exit(c.SUCCESS)}catch(n){if(Ot(n))throw n;a.error(n instanceof Error?n.message:String(n)),process.exit(c.CONFIG_ERROR)}}import j from"picocolors";import{stderr as ye,stdout as mr}from"process";import se from"picocolors";function Eo(){return process.env.NEBUTRA_NON_TTY||process.env.CI||process.env.GITHUB_ACTIONS?!1:process.stderr.isTTY===!0}function pr(e){if(e)return e;let t=process.env.NEBUTRA_OUTPUT_FORMAT;return t&&["json","table","plain"].includes(t)?t:Eo()?"plain":"json"}function Co(e,t){if(e.length===0)return"";let r=t||Object.keys(e[0]),n={};for(let l of r){n[String(l)]=String(l).length;for(let u of e){let m=String(u[l]??"");n[String(l)]=Math.max(n[String(l)],m.length)}}let o=r.map(l=>String(l).padEnd(n[String(l)])).join(" | "),i=r.map(l=>"-".repeat(n[String(l)])).join("-+-"),s=[o,i];for(let l of e){let u=r.map(m=>String(l[m]??"").padEnd(n[String(m)])).join(" | ");s.push(u)}return s.join(`
107
- `)}function Ao(e){return JSON.stringify(e)}function fr(e){if(!Array.isArray(e))return Pt(e);if(e.length===0)return"(empty)";if(typeof e[0]!="object"||e[0]===null)return Pt(e);let t=Co(e);return se.gray(t)}function Pt(e){return typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):e==null?"":Array.isArray(e)?e.length===0?"(empty list)":e.every(t=>typeof t=="string"||typeof t=="number")?e.join(", "):JSON.stringify(e,null,2):typeof e=="object"?JSON.stringify(e,null,2):String(e)}function k(e,t){let r=pr(t?.format),n=t?.stream==="stderr"?ye:mr,o;switch(r){case"json":o=Ao(e);break;case"table":o=fr(e);break;default:o=Pt(e);break}n.write(o+`
108
- `)}function O(e,t={}){let r=pr(t.format),n;switch(r){case"json":n=JSON.stringify(e);break;case"table":n=fr(e);break;default:n=JSON.stringify(e,null,2);break}mr.write(n+`
105
+ `;await ke.writeFile(r.path,l,"utf8")}if(t){let o=await ke.readFile(t.path,"utf8"),i=JSON.parse(o);for(let s of t.changes){if(s.action==="keep")continue;let l=s.section==="dependencies"?"dependencies":"devDependencies";i[l]={...i[l]??{},[s.name]:s.to},i[l]=wo(i[l])}await ke.writeFile(t.path,`${JSON.stringify(i,null,2)}
106
+ `,"utf8")}}async function Eo(e,t,r){let n=[];for(let o of e){let i=await ar(o);i||(a.error(`Feature '${o}' not found in the local registry.`),a.info("Use one of the supported local features or choose --21st / --v0 for external UI installs."),process.exit(c.INVALID_ARGS));let s=dr(i,t.provider);if(t.provider&&!s&&(a.error(`Provider '${t.provider}' is not supported for feature '${o}'.`),process.exit(c.INVALID_ARGS)),!s&&i.providers&&i.providers.length>0)if(r)s=i.providers[0];else{let l=await w.select({message:`Select a provider for ${o}`,options:i.providers.map(u=>({value:u.id,label:u.id,hint:u.description}))});w.isCancel(l)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),s=dr(i,String(l))}n.push({name:o,descriptor:i,provider:s})}return n}function Co(e){w.log.info(Ue.yellow("Planned local install:"));for(let t of e.features)w.log.message(` - ${t.name}${t.provider?` (${t.provider})`:""}: ${t.description}`);for(let t of e.operations)if(t.type==="write-file"&&w.log.message(` - ${t.status.toUpperCase()} ${t.relativePath}`),t.type==="merge-env"&&t.add.length>0&&w.log.message(` - APPEND ${t.add.map(r=>r.key).join(", ")} to ${t.relativePath}`),t.type==="update-package-json"){let r=t.changes.filter(n=>n.action==="add"||n.action==="update");r.length>0&&w.log.message(` - UPDATE ${t.relativePath}: ${r.map(n=>`${n.name}@${n.to}`).join(", ")}`)}}async function mr(e,t){t.dryRun||w.intro(Ue.bgCyan(Ue.black(" nebutra add ")));let r=t.yes||!process.stdin.isTTY;if(e.length===0&&!t["21st"]&&!t.v0&&(t.dryRun?a.warn("No components specified."):(w.log.warn("No components specified."),w.outro("Operation aborted.")),process.exit(c.INVALID_ARGS)),t.dryRun&&(t["21st"]||t.v0)&&(sr(yo(e,t)),process.exit(c.DRY_RUN_OK)),t.ifNotExists&&(t["21st"]||t.v0)&&(t["21st"]&&ir(t["21st"])||t.v0&&ir("shadcn-component"))&&(a.info("Component already exists. Skipping installation."),process.exit(c.SUCCESS)),t["21st"]){let n=r||await w.confirm({message:`Install 21st.dev component: ${t["21st"]}?`,initialValue:!0});(w.isCancel(n)||!n)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),w.log.info(Ue.cyan(`Invoking shadcn integration for 21st.dev component: ${t["21st"]}...`));try{let o=t["21st"],i=o.startsWith("http")?o:`https://21st.dev/r/${o}`;_t("pnpm",["dlx","shadcn@latest","add",i],{stdio:"inherit"}),a.success(`Successfully installed ${o}`),process.exit(c.SUCCESS)}catch(o){if(Ot(o))throw o;a.error(`Failed to install component: ${o instanceof Error?o.message:"Unknown error"}`),process.exit(c.ERROR)}}if(t.v0){let n=r||await w.confirm({message:`Install v0 component from: ${t.v0}?`,initialValue:!0});(w.isCancel(n)||!n)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),w.log.info(Ue.cyan(`Invoking shadcn integration for v0 URL: ${t.v0}...`));try{_t("pnpm",["dlx","shadcn@latest","add",t.v0],{stdio:"inherit"}),a.success("Successfully installed v0 component"),process.exit(c.SUCCESS)}catch(o){if(Ot(o))throw o;a.error(`Failed to install component: ${o instanceof Error?o.message:"Unknown error"}`),process.exit(c.ERROR)}}try{let n=await Eo(e,t,r),o=await So(n,process.cwd(),t.dryRun?"dry-run":"apply");if(t.dryRun&&(sr(o),process.exit(c.DRY_RUN_OK)),Ro(o)){let s=o.operations.filter(l=>l.type==="write-file"&&l.status==="conflict").map(l=>l.relativePath);t.ifNotExists&&!ur(o)&&(a.info("Feature already appears to be installed. Skipping because --if-not-exists was set."),process.exit(c.SUCCESS)),a.error(`Refusing to overwrite existing files: ${s.join(", ")}`),process.exit(c.CONFLICT)}ur(o)||(a.info("Feature install already satisfied. No files, env keys, or dependencies needed changes."),process.exit(c.SUCCESS)),Co(o);let i=r||await w.confirm({message:`Proceed with installing ${o.features.map(s=>s.name).join(", ")}?`,initialValue:!0});(w.isCancel(i)||!i)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),await ko(o),a.success(`Installed ${o.features.map(s=>s.name).join(", ")} into ${o.cwd}`),process.exit(c.SUCCESS)}catch(n){if(Ot(n))throw n;a.error(n instanceof Error?n.message:String(n)),process.exit(c.CONFIG_ERROR)}}import j from"picocolors";import{stderr as ye,stdout as pr}from"process";import se from"picocolors";function Ao(){return process.env.NEBUTRA_NON_TTY||process.env.CI||process.env.GITHUB_ACTIONS?!1:process.stderr.isTTY===!0}function fr(e){if(e)return e;let t=process.env.NEBUTRA_OUTPUT_FORMAT;return t&&["json","table","plain"].includes(t)?t:Ao()?"plain":"json"}function xo(e,t){if(e.length===0)return"";let r=t||Object.keys(e[0]),n={};for(let l of r){n[String(l)]=String(l).length;for(let u of e){let m=String(u[l]??"");n[String(l)]=Math.max(n[String(l)],m.length)}}let o=r.map(l=>String(l).padEnd(n[String(l)])).join(" | "),i=r.map(l=>"-".repeat(n[String(l)])).join("-+-"),s=[o,i];for(let l of e){let u=r.map(m=>String(l[m]??"").padEnd(n[String(m)])).join(" | ");s.push(u)}return s.join(`
107
+ `)}function Oo(e){return JSON.stringify(e)}function gr(e){if(!Array.isArray(e))return Pt(e);if(e.length===0)return"(empty)";if(typeof e[0]!="object"||e[0]===null)return Pt(e);let t=xo(e);return se.gray(t)}function Pt(e){return typeof e=="string"?e:typeof e=="number"||typeof e=="boolean"?String(e):e==null?"":Array.isArray(e)?e.length===0?"(empty list)":e.every(t=>typeof t=="string"||typeof t=="number")?e.join(", "):JSON.stringify(e,null,2):typeof e=="object"?JSON.stringify(e,null,2):String(e)}function k(e,t){let r=fr(t?.format),n=t?.stream==="stderr"?ye:pr,o;switch(r){case"json":o=Oo(e);break;case"table":o=gr(e);break;default:o=Pt(e);break}n.write(o+`
108
+ `)}function O(e,t={}){let r=fr(t.format),n;switch(r){case"json":n=JSON.stringify(e);break;case"table":n=gr(e);break;default:n=JSON.stringify(e,null,2);break}pr.write(n+`
109
109
  `)}function d(e,t="info"){let r;switch(t){case"error":r=se.red("\u2716");break;case"warn":r=se.yellow("\u26A0");break;case"success":r=se.green("\u2713");break;default:r=se.blue("\u2139");break}let n=`${r} ${e}`;ye.write(n+`
110
110
  `)}function A(e,t){if(!(process.env.NEBUTRA_DEBUG||process.argv.includes("--debug")))return;let n=se.dim(`[debug] ${e}`);ye.write(n+`
111
111
  `),t&&Object.keys(t).length>0&&ye.write(se.dim(JSON.stringify(t,null,2))+`
@@ -113,14 +113,14 @@ ${u.key}=`),s=o.trim().length>0?`
113
113
  `),ye.write(se.bold(se.cyan(e))+`
114
114
  `),ye.write(se.gray("-".repeat(e.length))+`
115
115
  `),ye.write(`
116
- `)}async function J(e,t={}){let r=process.env.NEBUTRA_API_URL||"http://localhost:3100",n=process.env.NEBUTRA_ADMIN_KEY;if(!n)return{ok:!1,status:401,error:"NEBUTRA_ADMIN_KEY environment variable not set. Set it to your admin API key."};let o=new URL(e,r).toString(),i=t.method||"GET",s=t.body?JSON.stringify(t.body):void 0;if(t.dryRun){let l={mode:"dry-run",timestamp:new Date().toISOString(),method:i,url:o,...s&&{body:JSON.parse(s)},headers:{"X-Admin-Key":"***","Content-Type":"application/json"}};return O(l),{ok:!0,status:0,data:l}}try{let l=await fetch(o,{method:i,headers:{"X-Admin-Key":n,"Content-Type":"application/json"},...s&&{body:s}}),u=await l.json().catch(()=>null);return l.ok?{ok:!0,status:l.status,data:u}:{ok:!1,status:l.status,error:u?.error||`HTTP ${l.status}`}}catch(l){return{ok:!1,status:0,error:`Network error: ${l instanceof Error?l.message:String(l)}`}}}function S(e,t,r){if(t==="json"){let n={command:r||"admin",...e};console.log(JSON.stringify(n,null,2))}else console.log(JSON.stringify(e,null,2))}async function xo(e){a.info("Fetching tenants...");let t=new URLSearchParams;e.limit&&t.append("limit",String(e.limit)),e.offset&&t.append("offset",String(e.offset)),e.status&&t.append("status",e.status);let r=`/api/v1/admin/tenants${t.toString()?`?${t.toString()}`:""}`,n=await J(r,{dryRun:e.dryRun});if(n.ok||(a.error(`Failed to fetch tenants: ${n.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(n.data,e.format,"admin:tenants");return}let o={tenants:n.data?.tenants||[],total:n.data?.total||0,limit:n.data?.limit,offset:n.data?.offset};e.format==="json"?S(o,e.format,"admin:tenants"):(a.info(`Found ${o.total} tenant(s)`),o.tenants.length>0&&(console.log(`
117
- Tenants:`),o.tenants.forEach(i=>{console.log(` ${j.blue(i.id)} \u2014 ${i.name||"(unnamed)"}`),console.log(` Status: ${i.status}`),i.plan&&console.log(` Plan: ${i.plan}`)})))}async function Oo(e,t){a.info(`Fetching tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}`,{dryRun:t.dryRun});if(r.ok||(a.error(`Failed to fetch tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:tenant");return}if(t.format==="json")S({tenant:r.data},t.format,"admin:tenant");else{let n=r.data;a.success(`Tenant ${j.blue(n.id)}`),console.log(` Name: ${n.name}`),console.log(` Status: ${n.status}`),console.log(` Plan: ${n.plan}`),console.log(` Created: ${n.createdAt}`),n.suspendedAt&&console.log(` Suspended: ${n.suspendedAt}`)}}async function _o(e,t){t.yes||(a.warn(`Suspending tenant ${e} will disable all operations`),a.info("Use --yes to confirm"),process.exit(c.CANCELLED)),a.info(`Suspending tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}/suspend`,{method:"POST",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to suspend tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:suspend");return}a.success(`Tenant ${j.blue(e)} suspended`),t.format==="json"&&S({suspended:!0,tenantId:e},t.format,"admin:suspend")}async function Po(e,t){a.info(`Unsuspending tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}/unsuspend`,{method:"POST",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to unsuspend tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:unsuspend");return}a.success(`Tenant ${j.blue(e)} unsuspended`),t.format==="json"&&S({unsuspended:!0,tenantId:e},t.format,"admin:unsuspend")}async function To(e){a.info("Fetching usage report...");let t=new URLSearchParams;e.period&&t.append("period",e.period),e.top&&t.append("top",String(e.top));let r=`/api/v1/admin/usage/report${t.toString()?`?${t.toString()}`:""}`,n=await J(r,{dryRun:e.dryRun});if(n.ok||(a.error(`Failed to fetch usage report: ${n.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(n.data,e.format,"admin:usage");return}let o={period:n.data?.period,topTenants:n.data?.topTenants||[],totalUsage:n.data?.totalUsage};e.format==="json"?S(o,e.format,"admin:usage"):(a.info(`Usage report for period: ${o.period}`),console.log(`Total usage: ${o.totalUsage}`),o.topTenants.length>0&&(console.log(`
118
- Top tenants:`),o.topTenants.forEach((i,s)=>{console.log(` ${s+1}. ${i.tenantName||i.tenantId} \u2014 ${i.usage}`)})))}async function Io(e){a.info("Fetching dead letter queue...");let t=await J("/api/v1/admin/dlq/list",{dryRun:e.dryRun});if(t.ok||(a.error(`Failed to fetch DLQ: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:dlq:list");return}let r={messages:t.data?.messages||[],count:t.data?.count||0};e.format==="json"?S(r,e.format,"admin:dlq:list"):(a.info(`Found ${r.count} message(s) in DLQ`),r.messages.length>0&&(console.log(`
119
- Messages:`),r.messages.forEach(n=>{console.log(` ${j.blue(n.id)}`),console.log(` Type: ${n.type}`),console.log(` Error: ${n.error}`),console.log(` Created: ${n.createdAt}`)})))}async function $o(e,t){a.info(`Replaying DLQ message ${e}...`);let r=await J(`/api/v1/admin/dlq/replay/${e}`,{method:"POST",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to replay message: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:dlq:replay");return}a.success(`Message ${j.blue(e)} replayed`),t.format==="json"&&S({replayed:!0,messageId:e},t.format,"admin:dlq:replay")}async function jo(e){e.yes||(a.warn("This will permanently delete all messages in the DLQ"),a.info("Use --yes to confirm"),process.exit(c.CANCELLED)),a.info("Purging DLQ...");let t=await J("/api/v1/admin/dlq/purge",{method:"POST",dryRun:e.dryRun});if(t.ok||(a.error(`Failed to purge DLQ: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:dlq:purge");return}a.success("DLQ purged"),e.format==="json"&&S({purged:!0,count:t.data?.count},e.format,"admin:dlq:purge")}async function No(e){a.info("Fetching feature flags...");let t=await J("/api/v1/admin/feature-flags",{dryRun:e.dryRun});if(t.ok||(a.error(`Failed to fetch flags: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:flags:list");return}let r={flags:t.data?.flags||[],total:t.data?.total||0};e.format==="json"?S(r,e.format,"admin:flags:list"):(a.info(`Found ${r.total} flag(s)`),r.flags.length>0&&(console.log(`
120
- Flags:`),r.flags.forEach(n=>{let o=n.override!==void 0?j.yellow(String(n.override)):j.gray(String(n.default));console.log(` ${j.blue(n.name)} = ${o}`)})))}async function Uo(e,t,r){a.info(`Setting flag ${e}...`);let n=t;t==="true"?n=!0:t==="false"?n=!1:Number.isNaN(Number(t))||(n=Number(t));let o=await J(`/api/v1/admin/feature-flags/${e}`,{method:"POST",body:{value:n},dryRun:r.dryRun});if(o.ok||(a.error(`Failed to set flag: ${o.error}`),process.exit(c.NETWORK_ERROR)),r.dryRun){S(o.data,r.format,"admin:flags:set");return}a.success(`Flag ${j.blue(e)} set to ${n}`),r.format==="json"&&S({flag:e,value:n},r.format,"admin:flags:set")}async function Lo(e,t){a.info(`Unsetting flag ${e}...`);let r=await J(`/api/v1/admin/feature-flags/${e}`,{method:"DELETE",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to unset flag: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:flags:unset");return}a.success(`Flag ${j.blue(e)} unset`),t.format==="json"&&S({flag:e,unset:!0},t.format,"admin:flags:unset")}async function Do(e){a.info("Fetching audit log...");let t=new URLSearchParams;e.actor&&t.append("actor",e.actor),e.action&&t.append("action",e.action),e.since&&t.append("since",e.since),e.limit&&t.append("limit",String(e.limit));let r=`/api/v1/admin/audit${t.toString()?`?${t.toString()}`:""}`,n=await J(r,{dryRun:e.dryRun});if(n.ok||(a.error(`Failed to fetch audit log: ${n.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(n.data,e.format,"admin:audit");return}let o={entries:n.data?.entries||[],total:n.data?.total||0};e.format==="json"?S(o,e.format,"admin:audit"):(a.info(`Found ${o.total} audit log entries`),o.entries.length>0&&(console.log(`
121
- Audit entries:`),o.entries.forEach(i=>{console.log(` ${i.timestamp} \u2014 ${j.blue(i.action)} by ${i.actor}`),i.details&&console.log(` ${i.details}`)})))}async function Fo(e){a.info("Running platform health check...");let t=await J("/api/v1/system/status",{dryRun:e.dryRun});if(t.ok||(a.error(`Failed to fetch health status: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:health");return}let r={status:t.data?.status||"unknown",services:t.data?.services||{},timestamp:t.data?.timestamp};if(e.format==="json")S(r,e.format,"admin:health");else{let n=r.status==="healthy"?j.green:r.status==="degraded"?j.yellow:j.red;a.info(`Platform status: ${n(r.status)}`),r.services&&Object.keys(r.services).length>0&&(console.log(`
122
- Services:`),Object.entries(r.services).forEach(([o,i])=>{let s=i.status==="healthy"?j.green("\u2713"):j.red("\u2717");console.log(` ${s} ${o}: ${i.status}`),i.latency&&console.log(` Latency: ${i.latency}ms`),i.error&&console.log(` Error: ${i.error}`)}))}}function gr(e){let t=e.command("admin").description("Platform admin operations");t.command("tenants").description("List all tenants/organizations").option("--limit <n>","Maximum number of tenants to return",o=>parseInt(o,10)).option("--offset <n>","Offset for pagination",o=>parseInt(o,10)).option("--status <status>","Filter by status (active|suspended)").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await xo({limit:o.limit,offset:o.offset,status:o.status,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),t.command("tenant <id>").description("Get tenant details").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await Oo(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("suspend <id>").description("Suspend a tenant (requires --yes)").option("--yes","Confirm suspension").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await _o(o,{yes:i.yes||s.yes,format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("unsuspend <id>").description("Unsuspend a tenant").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await Po(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("usage").description("Cross-tenant usage report").option("--period <period>","Report period (daily|weekly|monthly)").option("--top <n>","Show top N tenants",o=>parseInt(o,10)).option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await To({period:o.period,top:o.top,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})});let r=t.command("dlq").description("Dead letter queue management");r.command("list").description("List failed messages in DLQ").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await Io({format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),r.command("replay <id>").description("Replay a failed message").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await $o(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),r.command("purge").description("Purge the dead letter queue (requires --yes)").option("--yes","Confirm purge").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await jo({yes:o.yes||i.yes,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})});let n=t.command("flags").description("Feature flag management");n.command("list").description("List all feature flags").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await No({format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),n.command("set <flag> <value>").description("Set a feature flag override").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i,s)=>{let l=s.optsWithGlobals?.()||s;await Uo(o,i,{format:s.format||l.format,dryRun:s.dryRun||l.dryRun})}),n.command("unset <flag>").description("Remove a feature flag override").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await Lo(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("audit").description("Query audit log with optional filters").option("--actor <userId>","Filter by actor/user ID").option("--action <type>","Filter by action type").option("--since <date>","Filter entries since date (ISO format)").option("--limit <n>","Maximum number of entries to return",o=>parseInt(o,10)).option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await Do({actor:o.actor,action:o.action,since:o.since,limit:o.limit,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),t.command("health").description("Platform-wide health check").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await Fo({format:o.format||i.format,dryRun:o.dryRun||i.dryRun})})}import{existsSync as Mo,readFileSync as Bo,writeFileSync as Go}from"fs";import{resolve as Tt}from"path";var h={pm:["npm","pnpm","yarn","bun"],region:["global","cn","hybrid"],orm:["prisma","drizzle","none"],db:["postgres","mysql","sqlite","none"],auth:["clerk","betterauth","none"],socialLogin:["wechat","qq","dingtalk","workweixin","feishu","weibo"],payment:["stripe","lemon","wechat","alipay","none"],ai:["openai","anthropic","deepseek","xai","moonshot","google","mistral","cohere","perplexity","ai21","upstage","siliconflow","volcengine-ark","bailian","zhipu","baichuan","minimax","stepfun","sensetime","tencent","lingyi","openrouter","vercel-gateway","litellm","portkey","aws-bedrock","azure-openai","gcp-vertex","groq","fireworks","together","huggingface","replicate","lepton","anyscale","octoai","deepinfra","novita","custom","none"],deploy:["vercel","railway","cloudflare","selfhost","none"],docs:["fumadocs","mintlify","docusaurus","nextra","vitepress","none"],email:["resend","postmark","ses","aliyun-dm","tencent-ses","netease","none"],storage:["r2","s3","supabase-storage","aliyun-oss","tencent-cos","qiniu","none"],monitoring:["sentry","datadog","bugsnag","aliyun-arms","tingyun","none"],analytics:["posthog","plausible","umami","mixpanel","baidu","sensors","growingio","none"],sms:["twilio","messagebird","plivo","aliyun-sms","tencent-sms","yunpian","none"],queue:["qstash","bullmq","upstash","sqs","none"],search:["meilisearch","typesense","algolia","pgvector","none"],cache:["upstash-redis","vercel-kv","redis","dragonfly","none"],notifications:["novu","knock","custom","none"],webhooks:["svix","custom","none"],cms:["sanity","contentful","strapi","none"],featureFlags:["vercel-flags","growthbook","configcat","none"],captcha:["turnstile","hcaptcha","aliyun-slide","none"],mcp:["on","off"],metering:["auto","on","off"],billingMode:["usage","seat","credits"],idp:["clerk","oauth-server"]},Vo=[{flags:"-p, --pm <id>",description:"Package manager: npm, pnpm, yarn, or bun"},{flags:"--region <id>",description:"Target region: global, cn, or hybrid"},{flags:"--orm <id>",description:"ORM: prisma, drizzle, or none"},{flags:"--db <id>",description:"Database: postgres, mysql, sqlite, or none"},{flags:"--auth <id>",description:"Auth provider: clerk, betterauth, or none"},{flags:"--social-login <ids>",description:"Comma-separated CN social login providers"},{flags:"--payment <id>",description:"Payment provider: stripe, lemon, wechat, alipay, or none"},{flags:"--ai <ids>",description:"Expert/non-interactive AI provider seed ids"},{flags:"--deploy <target>",description:"Deploy target: vercel, railway, cloudflare, selfhost, or none"},{flags:"--docs <id>",description:"Docs framework: fumadocs, mintlify, docusaurus, nextra, vitepress, or none"},{flags:"--email <id>",description:"Transactional email provider"},{flags:"--storage <id>",description:"Object storage provider"},{flags:"--monitoring <id>",description:"Monitoring provider"},{flags:"--analytics <id>",description:"Analytics provider"},{flags:"--sms <id>",description:"SMS provider"},{flags:"--queue <id>",description:"Queue provider"},{flags:"--search <id>",description:"Search provider"},{flags:"--cache <id>",description:"Cache provider"},{flags:"--notifications <id>",description:"Notifications provider"},{flags:"--webhooks <id>",description:"Outbound webhooks provider"},{flags:"--cms <id>",description:"Headless CMS provider"},{flags:"--feature-flags <id>",description:"Feature flag provider"},{flags:"--captcha <id>",description:"Captcha provider"},{flags:"--mcp <mode>",description:"MCP server mode: on or off"},{flags:"--metering <mode>",description:"Metering mode: auto, on, or off"},{flags:"--billing-mode <mode>",description:"Billing mode: usage, seat, or credits"},{flags:"--idp <id>",description:"Identity provider: clerk or oauth-server"},{flags:"--i18n",description:"Enable i18n",default:!0},{flags:"--no-i18n",description:"Disable i18n"},{flags:"--no-install",description:"Skip package install"},{flags:"--no-git",description:"Skip git init"},{flags:"--dry-run",description:"Preview project scaffolding without creating files (exit code 10)"},{flags:"--json",description:"Emit machine-readable JSON events"},{flags:"--yes",description:"Skip all interactive prompts (Agent mode)"}],ce={name:"nebutra",description:"Governance-first CLI for Nebutra Sailor scaffolding, registry-backed features, and platform operations",usage:"nebutra [command] [options]",options:[{flags:"--format <type>",description:"Output format: json, table, plain"},{flags:"--yes, --no-interactive",description:"Skip all interactive prompts (Agent mode)"},{flags:"--no-color",description:"Disable colored output"},{flags:"--verbose",description:"Enable verbose output"},{flags:"--quiet",description:"Suppress non-essential output"}],subcommands:[{name:"init",description:"Initialize a Nebutra project and create nebutra.config.json",usage:"nebutra init [options]",options:[{flags:"--dry-run",description:"Preview changes without writing files (exits with code 10)"},{flags:"--yes",description:"Skip all interactive prompts (Agent mode)"},{flags:"--if-not-exists",description:"Skip initialization if nebutra.config.json already exists"}],arguments:[],examples:[{command:"nebutra init",description:"Initialize Nebutra configuration in the current directory"},{command:"nebutra init --dry-run",description:"Preview initialization changes without writing files"},{command:"nebutra init --yes --if-not-exists",description:"Initialize without prompts, skip if already configured"}]},{name:"add",description:"Add a registry-backed platform feature or external UI component",usage:"nebutra add [components...] [options]",arguments:[{name:"components",description:"Local feature names to install from the Nebutra registry",required:!1,variadic:!0}],options:[{flags:"--21st <id>",description:"Fetch and install a component from 21st.dev registry"},{flags:"--v0 <url>",description:"Fetch and install a component from v0.dev by URL"},{flags:"--dry-run",description:"Preview what would be installed without making changes (exit code 10)"},{flags:"--yes",description:"Skip all interactive prompts and use defaults (Agent mode)"},{flags:"--if-not-exists",description:"Skip installation if component already exists"}],examples:[{command:"nebutra add cache --provider upstash-redis --yes",description:"Install the local cache feature with the Upstash Redis provider"},{command:"nebutra add --21st button-01",description:"Add a component from 21st.dev (shadcn-style registry)"},{command:'nebutra add --v0 "https://v0.dev/r/..." --dry-run',description:"Preview adding a component from v0.dev without making changes"},{command:"nebutra add webhooks --provider svix --yes --if-not-exists",description:"Install webhooks without prompts, skip if already configured"}]},{name:"create",description:"Scaffold a topology-first Nebutra Sailor project with governed defaults",usage:"nebutra create [dir] [options]",arguments:[{name:"dir",description:"Target directory for the new project (optional, will prompt if not provided)",required:!1}],options:Vo,examples:[{command:"nebutra create my-saas-app --region=hybrid --ai=openai,deepseek",description:"Create a topology-first project with hybrid defaults and selected AI providers"},{command:"nebutra create my-cn-app --region=cn --payment=wechat --storage=aliyun-oss --deploy=selfhost -y",description:"Create a non-interactive China-ready scaffold"},{command:"nebutra create my-app --storage=supabase-storage --dry-run --json",description:"Preview scaffolding with structured JSON output"}]},{name:"mcp",description:"Start the Nebutra MCP server for AI agents and editors",usage:"nebutra mcp [options]",arguments:[],options:[{flags:"--stdio",description:"Use stdio transport for communication (default: enabled)",default:!0},{flags:"--verbose",description:"Enable verbose logging for MCP server"}],examples:[{command:"nebutra mcp",description:"Start the MCP server for AI-powered project context integration"},{command:"nebutra mcp --verbose",description:"Start the MCP server with detailed logging output"}]},{name:"schema",description:"Show command schema and argument documentation (Agent-friendly JSON output)",usage:"nebutra schema [command] [options]",arguments:[{name:"command",description:"Command name to show schema for (e.g., init, add, create)",required:!1}],options:[{flags:"--all",description:"Show full schema for all commands as JSON",default:!1},{flags:"--list",description:"List all available command names",default:!1},{flags:"--exit-codes",description:"Show exit codes reference",default:!1}],examples:[{command:"nebutra schema --all",description:"Show complete JSON of all commands, args, options, value domains"},{command:"nebutra schema init",description:"Show schema for init command (arguments, options, defaults, examples)"},{command:"nebutra schema add",description:"Show schema for add command with enum values"},{command:"nebutra schema --list",description:"List just the command names (quick discovery)"},{command:"nebutra schema --exit-codes",description:"Show exit codes reference for all possible exit codes"}]},{name:"brand",description:"Manage governed brand tokens, palettes, and visual system outputs",usage:"nebutra brand [subcommand]",examples:[{command:"nebutra brand palette --primary=#0047FF",description:"Generate a token-aligned blue palette"}]},{name:"i18n",description:"Manage localization files and multilingual product copy",usage:"nebutra i18n [subcommand]"},{name:"infra",description:"Manage local infrastructure services for Nebutra development",usage:"nebutra infra [subcommand]",examples:[{command:"nebutra infra up --lite",description:"Start lightweight local infrastructure"}]},{name:"env",description:"Validate and manage environment variables across apps and packages",usage:"nebutra env [subcommand]"},{name:"license",description:"Manage Nebutra Sailor commercial license activation and status",usage:"nebutra license [subcommand]",arguments:[],options:[],subcommands:[{name:"activate",description:"Activate a commercial license key for local development",usage:"nebutra license activate <key>",arguments:[{name:"key",description:"Your Nebutra Sailor commercial license key",required:!0}],options:[{flags:"--quiet",description:"Suppress output"}],examples:[{command:"nebutra license activate liz_1234567890",description:"Activate your license key globally"}]},{name:"status",description:"Check the locally configured license status",usage:"nebutra license status",arguments:[],options:[{flags:"--quiet",description:"Suppress output"}],examples:[{command:"nebutra license status",description:"Check if you have an active license"}]}]},{name:"ai",description:"Configure AI providers, gateway routing, and agent-ready defaults",usage:"nebutra ai [subcommand]"},{name:"auth",description:"Configure authentication providers and tenant access defaults",usage:"nebutra auth [subcommand]"},{name:"billing",description:"Manage billing providers, subscriptions, usage, and return flows",usage:"nebutra billing [subcommand]"},{name:"stats",description:"Show monorepo statistics, health signals, and platform inventory",usage:"nebutra stats [options]"},{name:"db",description:"Manage database schema, migrations, seeds, and generated clients",usage:"nebutra db [subcommand]"},{name:"generate",description:"Generate apps, modules, API surfaces, and typed project artifacts",usage:"nebutra generate [type] [name]"},{name:"dev",description:"Start development workflows for selected Nebutra apps or presets",usage:"nebutra dev [options]"},{name:"build",description:"Run build workflows through the Nebutra CLI",usage:"nebutra build [options]"},{name:"lint",description:"Run lint workflows through the Nebutra CLI",usage:"nebutra lint [options]"},{name:"typecheck",description:"Run TypeScript checks through the Nebutra CLI",usage:"nebutra typecheck [options]"},{name:"test",description:"Run unit, architecture, and E2E verification workflows",usage:"nebutra test [scope]"},{name:"workflow",description:"Initialize and inspect workflow runtime adapters",usage:"nebutra workflow [subcommand]"},{name:"backend",description:"Manage backend runtime service workflows",usage:"nebutra backend [subcommand]"},{name:"e2e",description:"Run browser end-to-end verification suites",usage:"nebutra e2e [suite]"},{name:"theme",description:"Inspect registry-backed Nebutra themes and governance metadata",usage:"nebutra theme [subcommand]"},{name:"admin",description:"Operate tenant, platform health, and administrative workflows",usage:"nebutra admin [subcommand]"},{name:"community",description:"Inspect community health, showcases, and external adoption signals",usage:"nebutra community [subcommand]"},{name:"growth",description:"Analyze product growth, funnels, retention, and lifecycle signals",usage:"nebutra growth [subcommand]"},{name:"ecosystem",description:"Manage template marketplace, ideas, project showcase, and ecosystem sync",usage:"nebutra ecosystem [subcommand]"},{name:"services",description:"Inspect and manage microservice health, logs, scaling, and rollouts",usage:"nebutra services [subcommand]"},{name:"search",description:"Manage search indexes, reindexing, and search diagnostics",usage:"nebutra search [subcommand]"},{name:"secrets",description:"Manage encrypted tenant and platform secrets",usage:"nebutra secrets [subcommand]"},{name:"completions",description:"Generate shell completions for the current Nebutra command surface",usage:"nebutra completions [shell]",arguments:[{name:"shell",description:"Shell to generate completions for: bash, zsh, fish, or install",required:!1}]},{name:"logout",description:"Clear local Nebutra CLI session state",usage:"nebutra logout"},{name:"upgrade",description:"Upgrade local Nebutra CLI tooling",usage:"nebutra upgrade"},{name:"link",description:"Link a local project to Nebutra platform metadata",usage:"nebutra link"},{name:"unlink",description:"Unlink local Nebutra project metadata",usage:"nebutra unlink"},{name:"doctor",description:"Check local project setup and common Nebutra configuration issues",usage:"nebutra doctor"}]};var hr="nebutra.config.json",qo=h.ai.filter(e=>e!=="none"),yr={"aws-bedrock":["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"],"azure-openai":["AZURE_OPENAI_API_KEY","AZURE_OPENAI_ENDPOINT"],"gcp-vertex":["GOOGLE_APPLICATION_CREDENTIALS","GOOGLE_CLOUD_PROJECT"],"vercel-gateway":["AI_GATEWAY_API_KEY"],"volcengine-ark":["VOLCENGINE_ARK_API_KEY"],bailian:["DASHSCOPE_API_KEY"],litellm:["LITELLM_API_KEY","LITELLM_BASE_URL"],portkey:["PORTKEY_API_KEY"],custom:["AI_CUSTOM_API_KEY","AI_CUSTOM_BASE_URL"]};function ne(e,t,r){if(t==="json"){let n={command:r||"ai",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(n,null,2))}else e&&typeof e=="object"&&"stdout"in e&&e.stdout&&console.log(e.stdout),e&&typeof e=="object"&&"stderr"in e&&e.stderr&&(e.exitCode??0)!==0&&console.error(e.stderr)}function Ko(e){return e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function zo(e){return yr[e]?yr[e]:[`${e.replace(/-/g,"_").toUpperCase()}_API_KEY`]}function rt(){return Object.fromEntries(qo.map(e=>[e,{id:e,name:Ko(e),envVars:zo(e)}]))}function le(){return Tt(process.cwd(),hr)}function Ee(){let e=le();if(!Mo(e))return{$schema:"https://nebutra.com/schema.json"};try{return JSON.parse(Bo(e,"utf-8"))}catch(t){a.error(`Failed to parse ${hr}: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}function nt(e){Go(le(),`${JSON.stringify(e,null,2)}
123
- `)}function he(e){return e.ai={providers:{},routes:{},...e.ai},e.ai.providers={...e.ai.providers},e.ai.routes={...e.ai.routes},e.ai}function br(e){let t=rt(),r=[...new Set(e.map(o=>o.toLowerCase()))],n=r.filter(o=>!t[o]);return n.length>0&&(a.error(`Unknown AI provider(s): ${n.join(", ")}. Valid providers: ${Object.keys(t).join(", ")}`),process.exit(c.INVALID_ARGS)),r}function Wo(e){let t=e?.split(",").map(n=>n.trim()).filter(Boolean)??[];t.length===0&&(a.error("Route fallback cannot be empty. Use --fallback provider:model,provider:model"),process.exit(c.INVALID_ARGS));let r=t.filter(n=>!/^[a-z0-9-]+:[^,\s]+$/i.test(n));return r.length>0&&(a.error(`Invalid fallback target(s): ${r.join(", ")}. Expected provider:model.`),process.exit(c.INVALID_ARGS)),t}function vr(e){let t=he(e),r=t.providers??{},n=t.routes??{},o=Object.entries(r).filter(([,i])=>i.enabled).map(([i])=>i);return{path:le(),gateway:t.gateway??null,providers:r,enabledProviders:o,routes:n}}function re(e){let t=typeof e.opts=="function"?e.opts():e,r=typeof e.optsWithGlobals=="function"?e.optsWithGlobals():t,n=t.format??r.format??Yo();return{...r,...t,...n?{format:n}:{}}}function Yo(){let e=process.argv.find(r=>r.startsWith("--format="));if(e)return e.slice(9);let t=process.argv.indexOf("--format");if(t>=0)return process.argv[t+1]}function Le(e){return e?e.length<=8?"***":`${e.substring(0,8)}***`:"not set"}async function Ho(e){e.format!=="json"&&a.info("Checking configured AI models and providers...");let t={openai:{name:"OpenAI",keyVars:["OPENAI_API_KEY"],configured:!1},anthropic:{name:"Anthropic Claude",keyVars:["ANTHROPIC_API_KEY"],configured:!1},openrouter:{name:"OpenRouter",keyVars:["OPENROUTER_API_KEY"],configured:!1},vercel:{name:"Vercel AI SDK",keyVars:["VERCEL_AI_API_KEY"],configured:!1}};for(let n of Object.values(t))n.configured=n.keyVars.some(o=>process.env[o]);let r={providers:Object.entries(t).map(([n,o])=>({id:n,name:o.name,configured:o.configured,keys:o.keyVars.map(i=>({name:i,value:Le(process.env[i])}))})),configuredCount:Object.values(t).filter(n=>n.configured).length,totalProviders:Object.keys(t).length};e.dryRun||(r.configuredCount===0?a.warn("No AI providers configured. Set API keys to enable AI features."):a.success(`${r.configuredCount} AI provider(s) configured`)),ne(r,e.format,"ai:models")}async function Jo(e){e.format!=="json"&&a.info("Scanning for available agents...");try{let t=Tt(process.cwd(),"backends/gateway/src/routes/agents"),r=[];try{let o=await import("fs");o.existsSync(t)&&(r=o.readdirSync(t).filter(s=>s.endsWith(".ts")&&!s.endsWith(".d.ts")).map(s=>({name:s.replace(".ts",""),path:`backends/gateway/src/routes/agents/${s}`})))}catch{r=[]}let n={agents:r.length>0?r:[{name:"No agents found",path:"create agents in backends/gateway/src/routes/agents/"}],count:r.length};e.dryRun||(n.count===0?a.info("No agents configured. Create agents in backends/gateway/src/routes/agents/"):a.success(`Found ${n.count} agent(s)`)),ne(n,e.format,"ai:agents")}catch(t){a.error(`Failed to scan agents: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}async function Xo(e,t){(!e||e.trim().length===0)&&(a.error("Prompt cannot be empty"),process.exit(c.INVALID_ARGS)),t.format!=="json"&&(a.info("Testing AI prompt against default model..."),a.info("Note: Ensure API gateway is running on http://localhost:3001"));let r={prompt:e,note:"To execute this test, the API gateway must be running locally. Run: pnpm --filter @nebutra/gateway dev",endpoint:"http://localhost:3001/api/ai/test",method:"POST",payload:{prompt:e.substring(0,100)}};t.dryRun||a.warn("AI test execution requires a running API gateway. Start it with: pnpm --filter @nebutra/gateway dev"),ne(r,t.format,"ai:test")}async function Qo(e){e.format!=="json"&&a.info("Checking AI configuration...");let t={providers:{openai:{key:Le(process.env.OPENAI_API_KEY),configured:!!process.env.OPENAI_API_KEY},anthropic:{key:Le(process.env.ANTHROPIC_API_KEY),configured:!!process.env.ANTHROPIC_API_KEY},openrouter:{key:Le(process.env.OPENROUTER_API_KEY),configured:!!process.env.OPENROUTER_API_KEY}},environment:{NODE_ENV:process.env.NODE_ENV||"development",NEBUTRA_LOG_LEVEL:process.env.NEBUTRA_LOG_LEVEL||"info"}};try{let n=Tt(process.cwd(),"nebutra.config.ts"),o=await import("fs");if(o.existsSync(n)){let s=o.readFileSync(n,"utf-8").match(/preset:\s*["']([^"']+)["']/);s&&(t.preset=s[1])}}catch{}let r=Object.entries(t.providers).filter(([,n])=>n.configured).map(([n])=>n);e.dryRun||(r.length===0?a.warn("No AI providers configured. Set environment variables to enable AI features."):a.success(`Configuration loaded: ${r.join(", ")}`)),ne(t,e.format,"ai:config")}async function Zo(e){let t=Ee(),r=he(t),n=rt(),o=Object.values(n).map(s=>{let l=r.providers?.[s.id];return{id:s.id,name:s.name,enabled:l?.enabled===!0,configured:s.envVars.some(u=>!!process.env[u]),envVars:s.envVars.map(u=>({name:u,value:Le(process.env[u])}))}}),i={configPath:le(),providers:o,enabledCount:o.filter(s=>s.enabled).length,totalProviders:o.length};if(e.format!=="json"){let s=o.filter(l=>l.enabled);s.length===0?a.warn("No runtime AI providers enabled in nebutra.config.json."):a.success(`Enabled AI providers: ${s.map(l=>l.id).join(", ")}`)}ne(i,e.format,"ai:provider:list")}async function ea(e,t){let r=br(e),n=Ee(),o=he(n),i=rt(),s=new Date().toISOString();for(let u of r)o.providers[u]={enabled:!0,envVars:i[u].envVars,enabledAt:o.providers?.[u]?.enabledAt??s};nt(n);let l={configPath:le(),enabled:r,env:t.env===!0?r.flatMap(u=>i[u].envVars.map(m=>({provider:u,name:m,example:`${m}=`}))):void 0,ai:vr(n)};if(t.format!=="json"&&(a.success(`Enabled AI provider(s): ${r.join(", ")}`),t.env)){a.info("Required environment variables:");for(let u of r)for(let m of i[u].envVars)console.log(`${m}=`)}ne(l,t.format,"ai:provider:enable")}async function ta(e,t){let r=br(e),n=Ee(),o=he(n),i=rt(),s=new Date().toISOString();for(let u of r)o.providers[u]={enabled:!1,envVars:o.providers?.[u]?.envVars??i[u].envVars,disabledAt:s};nt(n);let l={configPath:le(),disabled:r,ai:vr(n)};t.format!=="json"&&a.success(`Disabled AI provider(s): ${r.join(", ")}`),ne(l,t.format,"ai:provider:disable")}async function ra(e){let t=Ee(),r=he(t),n=new Date().toISOString();r.gateway={enabled:!0,mode:"local",initializedAt:r.gateway?.initializedAt??n,updatedAt:n},nt(t);let o={configPath:le(),gateway:r.gateway};e.format!=="json"&&a.success("AI gateway governance initialized in nebutra.config.json"),ne(o,e.format,"ai:gateway:init")}async function na(e){let t=Ee(),r=he(t),n={configPath:le(),gateway:r.gateway??null,initialized:r.gateway?.enabled===!0};e.format!=="json"&&(n.initialized?a.success("AI gateway governance is initialized"):a.warn("AI gateway governance is not initialized. Run: nebutra ai gateway init")),ne(n,e.format,"ai:gateway:status")}async function oa(e,t){(!e||e.trim().length===0)&&(a.error("Route name cannot be empty"),process.exit(c.INVALID_ARGS)),t.policy||(a.error("Route policy is required. Use --policy <policy>."),process.exit(c.INVALID_ARGS));let r=Wo(t.fallback),n=Ee(),o=he(n);o.routes[e]={policy:t.policy,fallback:r,updatedAt:new Date().toISOString()},nt(n);let i={configPath:le(),route:{name:e,...o.routes[e]},routes:o.routes};t.format!=="json"&&a.success(`AI route '${e}' set with policy '${t.policy}'`),ne(i,t.format,"ai:route:set")}async function aa(e){let t=Ee(),r=he(t),n=Object.entries(r.routes??{}).map(([i,s])=>({name:i,...s})),o={configPath:le(),routes:n,count:n.length};e.format!=="json"&&(n.length===0?a.warn("No AI routes configured. Run: nebutra ai route set chat --policy cost-latency-balanced --fallback openai:gpt-5.4"):a.success(`Configured AI routes: ${n.map(i=>i.name).join(", ")}`)),ne(o,e.format,"ai:route:list")}function wr(e){let t=e.command("ai").description("Manage AI models, agents, and configuration"),r=t.command("provider").description("Manage runtime AI provider governance");r.command("list").description("List supported and enabled AI providers").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await Zo({format:s.format,interactive:s.yes!==!0})}),r.command("enable <providers...>").description("Enable one or more runtime AI providers in nebutra.config.json").option("--env","Print required environment variable placeholders").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await ea(i,{env:l.env===!0,format:l.format,interactive:l.yes!==!0})}),r.command("disable <providers...>").description("Disable one or more runtime AI providers in nebutra.config.json").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await ta(i,{format:l.format,interactive:l.yes!==!0})});let n=t.command("gateway").description("Manage local AI gateway governance");n.command("init").description("Initialize the local AI gateway governance block").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await ra({format:s.format,interactive:s.yes!==!0})}),n.command("status").description("Show local AI gateway governance status").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await na({format:s.format,interactive:s.yes!==!0})});let o=t.command("route").description("Manage AI routing policies");o.command("set <name>").description("Create or update an AI route policy").requiredOption("--policy <policy>","Routing policy id").requiredOption("--fallback <list>","Comma-separated provider:model fallback chain").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await oa(i,{policy:l.policy,fallback:l.fallback,format:l.format,interactive:l.yes!==!0})}),o.command("list").description("List configured AI routes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await aa({format:s.format,interactive:s.yes!==!0})}),t.command("models").description("List configured AI models and providers").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await Ho({dryRun:s.dryRun===!0,format:s.format,interactive:s.yes!==!0})}),t.command("agents").description("List available agents in the project").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await Jo({dryRun:s.dryRun===!0,format:s.format,interactive:s.yes!==!0})}),t.command("test <prompt>").description("Send a test prompt to the default AI model (requires running API gateway)").option("--dry-run","Preview without executing").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await Xo(i,{dryRun:l.dryRun===!0,format:l.format,interactive:l.yes!==!0})}),t.command("config").description("Show current AI configuration and provider status").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await Qo({dryRun:s.dryRun===!0,format:s.format,interactive:s.yes!==!0})})}import{resolve as ia}from"path";function It(e,t,r){if(t==="json"){let n={command:r||"auth",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(n,null,2))}else e&&typeof e=="object"&&"stdout"in e&&e.stdout&&console.log(e.stdout),e&&typeof e=="object"&&"stderr"in e&&e.stderr&&(e.exitCode??0)!==0&&console.error(e.stderr)}function v(e,t){return e?e.length<=8?"***":`${e.substring(0,8)}*** (${t||e.length} chars)`:"not set"}function sa(){try{let e=ia(process.cwd(),"nebutra.config.ts"),t=Qn("fs");if(t.existsSync(e)){let r=t.readFileSync(e,"utf-8");if(r.includes("clerk"))return"clerk";if(r.includes("better-auth"))return"better-auth";if(r.includes("nextauth"))return"nextauth";if(r.includes("supabase"))return"supabase"}}catch{}return"clerk"}async function ca(e){a.info("Checking authentication configuration...");let t=sa(),r={provider:t,configured:!1,keys:{}};t==="clerk"?(r.keys={CLERK_SECRET_KEY:v(process.env.CLERK_SECRET_KEY,"secret"),NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,"publishable"),CLERK_WEBHOOK_SECRET:v(process.env.CLERK_WEBHOOK_SECRET,"webhook")},r.configured=!!process.env.CLERK_SECRET_KEY&&!!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY):t==="better-auth"?(r.keys={BETTER_AUTH_SECRET:v(process.env.BETTER_AUTH_SECRET,"secret"),BETTER_AUTH_URL:process.env.BETTER_AUTH_URL||"not set"},r.configured=!!process.env.BETTER_AUTH_SECRET):t==="nextauth"?(r.keys={AUTH_SECRET:v(process.env.AUTH_SECRET,"secret"),NEXTAUTH_SECRET:v(process.env.NEXTAUTH_SECRET,"legacy secret"),NEXTAUTH_URL:process.env.NEXTAUTH_URL||"not set",AUTH_URL:process.env.AUTH_URL||"not set",GOOGLE_CLIENT_ID:v(process.env.GOOGLE_CLIENT_ID,"google client"),GITHUB_CLIENT_ID:v(process.env.GITHUB_CLIENT_ID,"github client")},r.configured=!!(process.env.AUTH_SECRET||process.env.NEXTAUTH_SECRET)):(r.keys={NEXT_PUBLIC_SUPABASE_URL:process.env.NEXT_PUBLIC_SUPABASE_URL||"not set",NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY,"publishable"),NEXT_PUBLIC_SUPABASE_ANON_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,"anon"),SUPABASE_URL:process.env.SUPABASE_URL||"not set",SUPABASE_PUBLISHABLE_KEY:v(process.env.SUPABASE_PUBLISHABLE_KEY,"publishable"),SUPABASE_ANON_KEY:v(process.env.SUPABASE_ANON_KEY,"anon"),SUPABASE_SERVICE_ROLE_KEY:v(process.env.SUPABASE_SERVICE_ROLE_KEY,"service role"),SUPABASE_WEBHOOK_SECRET:v(process.env.SUPABASE_WEBHOOK_SECRET,"webhook")},r.configured=!!((process.env.SUPABASE_URL||process.env.NEXT_PUBLIC_SUPABASE_URL)&&(process.env.SUPABASE_PUBLISHABLE_KEY||process.env.SUPABASE_ANON_KEY||process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY||process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY)&&process.env.SUPABASE_SERVICE_ROLE_KEY)),e.dryRun||(r.configured?a.success(`Auth provider configured: ${t}`):a.warn(`Auth provider ${t} is not fully configured`)),It(r,e.format,"auth:status")}async function la(e,t){let r=["clerk","better-auth","nextauth","supabase"];r.includes(e.toLowerCase())||(a.error(`Invalid provider: ${e}. Choose from: ${r.join(", ")}`),process.exit(c.INVALID_ARGS));let n=e.toLowerCase();a.info(`Setting up ${n} authentication...`),n==="clerk"?(a.info("Clerk setup requires:"),a.info("1. A Clerk account (https://clerk.com)"),a.info("2. A Clerk application created"),a.info("3. API keys from the Clerk dashboard"),a.info(""),a.info("To complete setup:"),a.info("1. Go to https://dashboard.clerk.com"),a.info("2. Copy your Secret Key and Publishable Key"),a.info("3. Add them to .env.local:"),a.info(' CLERK_SECRET_KEY="sk_..."'),a.info(' NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_..."'),a.info(""),a.info("Webhook setup (optional):"),a.info("1. In Clerk dashboard, go to Webhooks"),a.info("2. Create endpoint: https://yourdomain.com/api/webhooks/clerk"),a.info("3. Copy the signing secret to .env.local:"),a.info(' CLERK_WEBHOOK_SECRET="whsec_..."')):n==="better-auth"?(a.info("Better Auth setup requires:"),a.info("1. Database URL configured (DATABASE_URL env var)"),a.info("2. A generated auth secret"),a.info(""),a.info("To complete setup:"),a.info("1. Ensure DATABASE_URL is set in .env.local"),a.info("2. Generate a new secret:"),a.info(" openssl rand -base64 32"),a.info("3. Add to .env.local:"),a.info(' BETTER_AUTH_SECRET="<generated_secret>"'),a.info(' BETTER_AUTH_URL="http://localhost:3000"'),a.info(""),a.info("4. Run database migration:"),a.info(" pnpm --filter @nebutra/web db:push")):n==="nextauth"?(a.info("NextAuth / Auth.js setup requires:"),a.info("1. A generated Auth.js secret"),a.info("2. NEXTAUTH_URL or AUTH_URL pointing at the web app origin"),a.info("3. OAuth provider credentials for each enabled provider"),a.info(""),a.info("To complete setup:"),a.info("1. Generate a new secret:"),a.info(" openssl rand -base64 32"),a.info("2. Add to the production environment:"),a.info(' AUTH_PROVIDER="nextauth"'),a.info(' NEXT_PUBLIC_AUTH_PROVIDER="nextauth"'),a.info(' AUTH_SECRET="<generated_secret>"'),a.info(' NEXTAUTH_URL="https://app.nebutra.com"'),a.info(' GOOGLE_CLIENT_ID="..."'),a.info(' GOOGLE_CLIENT_SECRET="..."')):(a.info("Supabase Auth setup requires:"),a.info("1. Supabase project URL"),a.info("2. Public anon key for browser auth"),a.info("3. Service role key for server-side user/session validation"),a.info(""),a.info("To complete setup:"),a.info(' AUTH_PROVIDER="supabase"'),a.info(' NEXT_PUBLIC_AUTH_PROVIDER="supabase"'),a.info(' NEXT_PUBLIC_SUPABASE_URL="https://xxx.supabase.co"'),a.info(' NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),a.info(' NEXT_PUBLIC_SUPABASE_ANON_KEY="..."'),a.info(' SUPABASE_URL="https://xxx.supabase.co"'),a.info(' SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),a.info(' SUPABASE_ANON_KEY="..."'),a.info(' SUPABASE_SERVICE_ROLE_KEY="..."')),t.dryRun||a.success(`Setup instructions for ${n} displayed above`),It({provider:n,setupGuide:"Complete setup by following the instructions above",documentationUrl:n==="clerk"?"https://clerk.com/docs":n==="better-auth"?"https://www.better-auth.com":n==="nextauth"?"https://authjs.dev":"https://supabase.com/docs/guides/auth"},t.format,"auth:setup")}async function da(e){a.info("Checking authentication keys and secrets...");let r={keys:{clerk:{CLERK_SECRET_KEY:v(process.env.CLERK_SECRET_KEY,"secret key"),NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,"publishable key"),CLERK_WEBHOOK_SECRET:v(process.env.CLERK_WEBHOOK_SECRET,"webhook secret")},betterAuth:{BETTER_AUTH_SECRET:v(process.env.BETTER_AUTH_SECRET,"secret"),BETTER_AUTH_URL:process.env.BETTER_AUTH_URL||"not set"},nextAuth:{AUTH_SECRET:v(process.env.AUTH_SECRET,"secret"),NEXTAUTH_SECRET:v(process.env.NEXTAUTH_SECRET,"legacy secret"),NEXTAUTH_URL:process.env.NEXTAUTH_URL||"not set",AUTH_URL:process.env.AUTH_URL||"not set",GOOGLE_CLIENT_ID:v(process.env.GOOGLE_CLIENT_ID,"google client"),GITHUB_CLIENT_ID:v(process.env.GITHUB_CLIENT_ID,"github client")},supabase:{NEXT_PUBLIC_SUPABASE_URL:process.env.NEXT_PUBLIC_SUPABASE_URL||"not set",NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY,"publishable"),NEXT_PUBLIC_SUPABASE_ANON_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,"anon"),SUPABASE_URL:process.env.SUPABASE_URL||"not set",SUPABASE_PUBLISHABLE_KEY:v(process.env.SUPABASE_PUBLISHABLE_KEY,"publishable"),SUPABASE_ANON_KEY:v(process.env.SUPABASE_ANON_KEY,"anon"),SUPABASE_SERVICE_ROLE_KEY:v(process.env.SUPABASE_SERVICE_ROLE_KEY,"service role")},common:{DATABASE_URL:v(process.env.DATABASE_URL,"database url"),JWT_SECRET:v(process.env.JWT_SECRET,"jwt secret")}},configured:{clerk:{secret:!!process.env.CLERK_SECRET_KEY,publishable:!!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY},betterAuth:{secret:!!process.env.BETTER_AUTH_SECRET,url:!!process.env.BETTER_AUTH_URL},nextAuth:{secret:!!(process.env.AUTH_SECRET||process.env.NEXTAUTH_SECRET),url:!!(process.env.NEXTAUTH_URL||process.env.AUTH_URL)},supabase:{url:!!(process.env.SUPABASE_URL||process.env.NEXT_PUBLIC_SUPABASE_URL),publishableKey:!!(process.env.SUPABASE_PUBLISHABLE_KEY||process.env.SUPABASE_ANON_KEY||process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY||process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY),serviceRole:!!process.env.SUPABASE_SERVICE_ROLE_KEY}}};if(!e.dryRun){let n=r.configured.clerk.secret&&r.configured.clerk.publishable,o=r.configured.betterAuth.secret&&r.configured.betterAuth.url,i=r.configured.nextAuth.secret&&r.configured.nextAuth.url,s=r.configured.supabase.url&&r.configured.supabase.publishableKey&&r.configured.supabase.serviceRole;!n&&!o&&!i&&!s?a.warn("No authentication keys configured"):(a.info("Auth keys status:"),n&&a.success("Clerk configured"),o&&a.success("Better Auth configured"),i&&a.success("NextAuth configured"),s&&a.success("Supabase configured"))}It(r,e.format,"auth:keys")}function Sr(e){let t=e.command("auth").description("Manage authentication configuration (Clerk, Better Auth, NextAuth, or Supabase)");t.command("status").description("Check current authentication provider configuration").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await ca({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("setup <provider>").description("Configure Clerk, Better Auth, NextAuth, or Supabase (interactive wizard)").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async(r,n)=>{let o=n.optsWithGlobals?.()||n;await la(r,{dryRun:n.dryRun||!1,format:n.format||o.format,interactive:o.yes!==!0})}),t.command("keys").description("Show authentication-related environment variables (masked)").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await da({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}import be from"fs";import oe from"path";import*as ot from"@clack/prompts";import Er from"picocolors";var Rr=["ts","py"],ua=`{
116
+ `)}async function J(e,t={}){let r=process.env.NEBUTRA_API_URL||"http://localhost:3100",n=process.env.NEBUTRA_ADMIN_KEY;if(!n)return{ok:!1,status:401,error:"NEBUTRA_ADMIN_KEY environment variable not set. Set it to your admin API key."};let o=new URL(e,r).toString(),i=t.method||"GET",s=t.body?JSON.stringify(t.body):void 0;if(t.dryRun){let l={mode:"dry-run",timestamp:new Date().toISOString(),method:i,url:o,...s&&{body:JSON.parse(s)},headers:{"X-Admin-Key":"***","Content-Type":"application/json"}};return O(l),{ok:!0,status:0,data:l}}try{let l=await fetch(o,{method:i,headers:{"X-Admin-Key":n,"Content-Type":"application/json"},...s&&{body:s}}),u=await l.json().catch(()=>null);return l.ok?{ok:!0,status:l.status,data:u}:{ok:!1,status:l.status,error:u?.error||`HTTP ${l.status}`}}catch(l){return{ok:!1,status:0,error:`Network error: ${l instanceof Error?l.message:String(l)}`}}}function S(e,t,r){if(t==="json"){let n={command:r||"admin",...e};console.log(JSON.stringify(n,null,2))}else console.log(JSON.stringify(e,null,2))}async function _o(e){a.info("Fetching tenants...");let t=new URLSearchParams;e.limit&&t.append("limit",String(e.limit)),e.offset&&t.append("offset",String(e.offset)),e.status&&t.append("status",e.status);let r=`/api/v1/admin/tenants${t.toString()?`?${t.toString()}`:""}`,n=await J(r,{dryRun:e.dryRun});if(n.ok||(a.error(`Failed to fetch tenants: ${n.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(n.data,e.format,"admin:tenants");return}let o={tenants:n.data?.tenants||[],total:n.data?.total||0,limit:n.data?.limit,offset:n.data?.offset};e.format==="json"?S(o,e.format,"admin:tenants"):(a.info(`Found ${o.total} tenant(s)`),o.tenants.length>0&&(console.log(`
117
+ Tenants:`),o.tenants.forEach(i=>{console.log(` ${j.blue(i.id)} \u2014 ${i.name||"(unnamed)"}`),console.log(` Status: ${i.status}`),i.plan&&console.log(` Plan: ${i.plan}`)})))}async function Po(e,t){a.info(`Fetching tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}`,{dryRun:t.dryRun});if(r.ok||(a.error(`Failed to fetch tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:tenant");return}if(t.format==="json")S({tenant:r.data},t.format,"admin:tenant");else{let n=r.data;a.success(`Tenant ${j.blue(n.id)}`),console.log(` Name: ${n.name}`),console.log(` Status: ${n.status}`),console.log(` Plan: ${n.plan}`),console.log(` Created: ${n.createdAt}`),n.suspendedAt&&console.log(` Suspended: ${n.suspendedAt}`)}}async function To(e,t){t.yes||(a.warn(`Suspending tenant ${e} will disable all operations`),a.info("Use --yes to confirm"),process.exit(c.CANCELLED)),a.info(`Suspending tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}/suspend`,{method:"POST",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to suspend tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:suspend");return}a.success(`Tenant ${j.blue(e)} suspended`),t.format==="json"&&S({suspended:!0,tenantId:e},t.format,"admin:suspend")}async function Io(e,t){a.info(`Unsuspending tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}/unsuspend`,{method:"POST",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to unsuspend tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:unsuspend");return}a.success(`Tenant ${j.blue(e)} unsuspended`),t.format==="json"&&S({unsuspended:!0,tenantId:e},t.format,"admin:unsuspend")}async function $o(e){a.info("Fetching usage report...");let t=new URLSearchParams;e.period&&t.append("period",e.period),e.top&&t.append("top",String(e.top));let r=`/api/v1/admin/usage/report${t.toString()?`?${t.toString()}`:""}`,n=await J(r,{dryRun:e.dryRun});if(n.ok||(a.error(`Failed to fetch usage report: ${n.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(n.data,e.format,"admin:usage");return}let o={period:n.data?.period,topTenants:n.data?.topTenants||[],totalUsage:n.data?.totalUsage};e.format==="json"?S(o,e.format,"admin:usage"):(a.info(`Usage report for period: ${o.period}`),console.log(`Total usage: ${o.totalUsage}`),o.topTenants.length>0&&(console.log(`
118
+ Top tenants:`),o.topTenants.forEach((i,s)=>{console.log(` ${s+1}. ${i.tenantName||i.tenantId} \u2014 ${i.usage}`)})))}async function jo(e){a.info("Fetching dead letter queue...");let t=await J("/api/v1/admin/dlq/list",{dryRun:e.dryRun});if(t.ok||(a.error(`Failed to fetch DLQ: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:dlq:list");return}let r={messages:t.data?.messages||[],count:t.data?.count||0};e.format==="json"?S(r,e.format,"admin:dlq:list"):(a.info(`Found ${r.count} message(s) in DLQ`),r.messages.length>0&&(console.log(`
119
+ Messages:`),r.messages.forEach(n=>{console.log(` ${j.blue(n.id)}`),console.log(` Type: ${n.type}`),console.log(` Error: ${n.error}`),console.log(` Created: ${n.createdAt}`)})))}async function No(e,t){a.info(`Replaying DLQ message ${e}...`);let r=await J(`/api/v1/admin/dlq/replay/${e}`,{method:"POST",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to replay message: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:dlq:replay");return}a.success(`Message ${j.blue(e)} replayed`),t.format==="json"&&S({replayed:!0,messageId:e},t.format,"admin:dlq:replay")}async function Uo(e){e.yes||(a.warn("This will permanently delete all messages in the DLQ"),a.info("Use --yes to confirm"),process.exit(c.CANCELLED)),a.info("Purging DLQ...");let t=await J("/api/v1/admin/dlq/purge",{method:"POST",dryRun:e.dryRun});if(t.ok||(a.error(`Failed to purge DLQ: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:dlq:purge");return}a.success("DLQ purged"),e.format==="json"&&S({purged:!0,count:t.data?.count},e.format,"admin:dlq:purge")}async function Lo(e){a.info("Fetching feature flags...");let t=await J("/api/v1/admin/feature-flags",{dryRun:e.dryRun});if(t.ok||(a.error(`Failed to fetch flags: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:flags:list");return}let r={flags:t.data?.flags||[],total:t.data?.total||0};e.format==="json"?S(r,e.format,"admin:flags:list"):(a.info(`Found ${r.total} flag(s)`),r.flags.length>0&&(console.log(`
120
+ Flags:`),r.flags.forEach(n=>{let o=n.override!==void 0?j.yellow(String(n.override)):j.gray(String(n.default));console.log(` ${j.blue(n.name)} = ${o}`)})))}async function Do(e,t,r){a.info(`Setting flag ${e}...`);let n=t;t==="true"?n=!0:t==="false"?n=!1:Number.isNaN(Number(t))||(n=Number(t));let o=await J(`/api/v1/admin/feature-flags/${e}`,{method:"POST",body:{value:n},dryRun:r.dryRun});if(o.ok||(a.error(`Failed to set flag: ${o.error}`),process.exit(c.NETWORK_ERROR)),r.dryRun){S(o.data,r.format,"admin:flags:set");return}a.success(`Flag ${j.blue(e)} set to ${n}`),r.format==="json"&&S({flag:e,value:n},r.format,"admin:flags:set")}async function Fo(e,t){a.info(`Unsetting flag ${e}...`);let r=await J(`/api/v1/admin/feature-flags/${e}`,{method:"DELETE",dryRun:t.dryRun});if(r.ok||(a.error(`Failed to unset flag: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:flags:unset");return}a.success(`Flag ${j.blue(e)} unset`),t.format==="json"&&S({flag:e,unset:!0},t.format,"admin:flags:unset")}async function Vo(e){a.info("Fetching audit log...");let t=new URLSearchParams;e.actor&&t.append("actor",e.actor),e.action&&t.append("action",e.action),e.since&&t.append("since",e.since),e.limit&&t.append("limit",String(e.limit));let r=`/api/v1/admin/audit${t.toString()?`?${t.toString()}`:""}`,n=await J(r,{dryRun:e.dryRun});if(n.ok||(a.error(`Failed to fetch audit log: ${n.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(n.data,e.format,"admin:audit");return}let o={entries:n.data?.entries||[],total:n.data?.total||0};e.format==="json"?S(o,e.format,"admin:audit"):(a.info(`Found ${o.total} audit log entries`),o.entries.length>0&&(console.log(`
121
+ Audit entries:`),o.entries.forEach(i=>{console.log(` ${i.timestamp} \u2014 ${j.blue(i.action)} by ${i.actor}`),i.details&&console.log(` ${i.details}`)})))}async function Mo(e){a.info("Running platform health check...");let t=await J("/api/v1/system/status",{dryRun:e.dryRun});if(t.ok||(a.error(`Failed to fetch health status: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:health");return}let r={status:t.data?.status||"unknown",services:t.data?.services||{},timestamp:t.data?.timestamp};if(e.format==="json")S(r,e.format,"admin:health");else{let n=r.status==="healthy"?j.green:r.status==="degraded"?j.yellow:j.red;a.info(`Platform status: ${n(r.status)}`),r.services&&Object.keys(r.services).length>0&&(console.log(`
122
+ Services:`),Object.entries(r.services).forEach(([o,i])=>{let s=i.status==="healthy"?j.green("\u2713"):j.red("\u2717");console.log(` ${s} ${o}: ${i.status}`),i.latency&&console.log(` Latency: ${i.latency}ms`),i.error&&console.log(` Error: ${i.error}`)}))}}function yr(e){let t=e.command("admin").description("Platform admin operations");t.command("tenants").description("List all tenants/organizations").option("--limit <n>","Maximum number of tenants to return",o=>parseInt(o,10)).option("--offset <n>","Offset for pagination",o=>parseInt(o,10)).option("--status <status>","Filter by status (active|suspended)").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await _o({limit:o.limit,offset:o.offset,status:o.status,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),t.command("tenant <id>").description("Get tenant details").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await Po(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("suspend <id>").description("Suspend a tenant (requires --yes)").option("--yes","Confirm suspension").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await To(o,{yes:i.yes||s.yes,format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("unsuspend <id>").description("Unsuspend a tenant").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await Io(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("usage").description("Cross-tenant usage report").option("--period <period>","Report period (daily|weekly|monthly)").option("--top <n>","Show top N tenants",o=>parseInt(o,10)).option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await $o({period:o.period,top:o.top,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})});let r=t.command("dlq").description("Dead letter queue management");r.command("list").description("List failed messages in DLQ").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await jo({format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),r.command("replay <id>").description("Replay a failed message").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await No(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),r.command("purge").description("Purge the dead letter queue (requires --yes)").option("--yes","Confirm purge").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await Uo({yes:o.yes||i.yes,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})});let n=t.command("flags").description("Feature flag management");n.command("list").description("List all feature flags").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await Lo({format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),n.command("set <flag> <value>").description("Set a feature flag override").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i,s)=>{let l=s.optsWithGlobals?.()||s;await Do(o,i,{format:s.format||l.format,dryRun:s.dryRun||l.dryRun})}),n.command("unset <flag>").description("Remove a feature flag override").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async(o,i)=>{let s=i.optsWithGlobals?.()||i;await Fo(o,{format:i.format||s.format,dryRun:i.dryRun||s.dryRun})}),t.command("audit").description("Query audit log with optional filters").option("--actor <userId>","Filter by actor/user ID").option("--action <type>","Filter by action type").option("--since <date>","Filter entries since date (ISO format)").option("--limit <n>","Maximum number of entries to return",o=>parseInt(o,10)).option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await Vo({actor:o.actor,action:o.action,since:o.since,limit:o.limit,format:o.format||i.format,dryRun:o.dryRun||i.dryRun})}),t.command("health").description("Platform-wide health check").option("--format <type>","Output format: json or plain").option("--dry-run","Show request without executing").action(async o=>{let i=o.optsWithGlobals?.()||o;await Mo({format:o.format||i.format,dryRun:o.dryRun||i.dryRun})})}import{existsSync as Go,readFileSync as qo,writeFileSync as Ko}from"fs";import{resolve as Tt}from"path";var h={pm:["npm","pnpm","yarn","bun"],region:["global","cn","hybrid"],orm:["prisma","drizzle","none"],db:["postgres","mysql","sqlite","none"],auth:["clerk","betterauth","none"],socialLogin:["wechat","qq","dingtalk","workweixin","feishu","weibo"],payment:["stripe","lemon","wechat","alipay","none"],ai:["openai","anthropic","deepseek","xai","moonshot","google","mistral","cohere","perplexity","ai21","upstage","siliconflow","volcengine-ark","bailian","zhipu","baichuan","minimax","stepfun","sensetime","tencent","lingyi","openrouter","vercel-gateway","litellm","portkey","aws-bedrock","azure-openai","gcp-vertex","groq","fireworks","together","huggingface","replicate","lepton","anyscale","octoai","deepinfra","novita","custom","none"],deploy:["vercel","railway","cloudflare","selfhost","none"],docs:["fumadocs","mintlify","docusaurus","nextra","vitepress","none"],email:["resend","postmark","ses","aliyun-dm","tencent-ses","netease","none"],storage:["r2","s3","supabase-storage","aliyun-oss","tencent-cos","qiniu","none"],monitoring:["sentry","datadog","bugsnag","aliyun-arms","tingyun","none"],analytics:["posthog","plausible","umami","mixpanel","baidu","sensors","growingio","none"],sms:["twilio","messagebird","plivo","aliyun-sms","tencent-sms","yunpian","none"],queue:["qstash","bullmq","upstash","sqs","none"],search:["meilisearch","typesense","algolia","pgvector","none"],cache:["upstash-redis","vercel-kv","redis","dragonfly","none"],notifications:["novu","knock","custom","none"],webhooks:["svix","custom","none"],cms:["sanity","contentful","strapi","none"],featureFlags:["vercel-flags","growthbook","configcat","none"],captcha:["turnstile","hcaptcha","aliyun-slide","none"],mcp:["on","off"],metering:["auto","on","off"],billingMode:["usage","seat","credits"],idp:["clerk","oauth-server"]},Bo=[{flags:"-p, --pm <id>",description:"Package manager: npm, pnpm, yarn, or bun"},{flags:"--region <id>",description:"Target region: global, cn, or hybrid"},{flags:"--orm <id>",description:"ORM: prisma, drizzle, or none"},{flags:"--db <id>",description:"Database: postgres, mysql, sqlite, or none"},{flags:"--auth <id>",description:"Auth provider: clerk, betterauth, or none"},{flags:"--social-login <ids>",description:"Comma-separated CN social login providers"},{flags:"--payment <id>",description:"Payment provider: stripe, lemon, wechat, alipay, or none"},{flags:"--ai <ids>",description:"Expert/non-interactive AI provider seed ids"},{flags:"--deploy <target>",description:"Deploy target: vercel, railway, cloudflare, selfhost, or none"},{flags:"--docs <id>",description:"Docs framework: fumadocs, mintlify, docusaurus, nextra, vitepress, or none"},{flags:"--email <id>",description:"Transactional email provider"},{flags:"--storage <id>",description:"Object storage provider"},{flags:"--monitoring <id>",description:"Monitoring provider"},{flags:"--analytics <id>",description:"Analytics provider"},{flags:"--sms <id>",description:"SMS provider"},{flags:"--queue <id>",description:"Queue provider"},{flags:"--search <id>",description:"Search provider"},{flags:"--cache <id>",description:"Cache provider"},{flags:"--notifications <id>",description:"Notifications provider"},{flags:"--webhooks <id>",description:"Outbound webhooks provider"},{flags:"--cms <id>",description:"Headless CMS provider"},{flags:"--feature-flags <id>",description:"Feature flag provider"},{flags:"--captcha <id>",description:"Captcha provider"},{flags:"--mcp <mode>",description:"MCP server mode: on or off"},{flags:"--metering <mode>",description:"Metering mode: auto, on, or off"},{flags:"--billing-mode <mode>",description:"Billing mode: usage, seat, or credits"},{flags:"--idp <id>",description:"Identity provider: clerk or oauth-server"},{flags:"--i18n",description:"Enable i18n",default:!0},{flags:"--no-i18n",description:"Disable i18n"},{flags:"--no-install",description:"Skip package install"},{flags:"--no-git",description:"Skip git init"},{flags:"--dry-run",description:"Preview project scaffolding without creating files (exit code 10)"},{flags:"--json",description:"Emit machine-readable JSON events"},{flags:"--yes",description:"Skip all interactive prompts (Agent mode)"}],ce={name:"nebutra",description:"Governance-first CLI for Nebutra Sailor scaffolding, registry-backed features, and platform operations",usage:"nebutra [command] [options]",options:[{flags:"--format <type>",description:"Output format: json, table, plain"},{flags:"--yes, --no-interactive",description:"Skip all interactive prompts (Agent mode)"},{flags:"--no-color",description:"Disable colored output"},{flags:"--verbose",description:"Enable verbose output"},{flags:"--quiet",description:"Suppress non-essential output"}],subcommands:[{name:"init",description:"Initialize a Nebutra project and create nebutra.config.json",usage:"nebutra init [options]",options:[{flags:"--dry-run",description:"Preview changes without writing files (exits with code 10)"},{flags:"--yes",description:"Skip all interactive prompts (Agent mode)"},{flags:"--if-not-exists",description:"Skip initialization if nebutra.config.json already exists"}],arguments:[],examples:[{command:"nebutra init",description:"Initialize Nebutra configuration in the current directory"},{command:"nebutra init --dry-run",description:"Preview initialization changes without writing files"},{command:"nebutra init --yes --if-not-exists",description:"Initialize without prompts, skip if already configured"}]},{name:"add",description:"Add a registry-backed platform feature or external UI component",usage:"nebutra add [components...] [options]",arguments:[{name:"components",description:"Local feature names to install from the Nebutra registry",required:!1,variadic:!0}],options:[{flags:"--21st <id>",description:"Fetch and install a component from 21st.dev registry"},{flags:"--v0 <url>",description:"Fetch and install a component from v0.dev by URL"},{flags:"--dry-run",description:"Preview what would be installed without making changes (exit code 10)"},{flags:"--yes",description:"Skip all interactive prompts and use defaults (Agent mode)"},{flags:"--if-not-exists",description:"Skip installation if component already exists"}],examples:[{command:"nebutra add cache --provider upstash-redis --yes",description:"Install the local cache feature with the Upstash Redis provider"},{command:"nebutra add --21st button-01",description:"Add a component from 21st.dev (shadcn-style registry)"},{command:'nebutra add --v0 "https://v0.dev/r/..." --dry-run',description:"Preview adding a component from v0.dev without making changes"},{command:"nebutra add webhooks --provider svix --yes --if-not-exists",description:"Install webhooks without prompts, skip if already configured"}]},{name:"create",description:"Scaffold a topology-first Nebutra Sailor project with governed defaults",usage:"nebutra create [dir] [options]",arguments:[{name:"dir",description:"Target directory for the new project (optional, will prompt if not provided)",required:!1}],options:Bo,examples:[{command:"nebutra create my-saas-app --region=hybrid --ai=openai,deepseek",description:"Create a topology-first project with hybrid defaults and selected AI providers"},{command:"nebutra create my-cn-app --region=cn --payment=wechat --storage=aliyun-oss --deploy=selfhost -y",description:"Create a non-interactive China-ready scaffold"},{command:"nebutra create my-app --storage=supabase-storage --dry-run --json",description:"Preview scaffolding with structured JSON output"}]},{name:"mcp",description:"Start the Nebutra MCP server for AI agents and editors",usage:"nebutra mcp [options]",arguments:[],options:[{flags:"--stdio",description:"Use stdio transport for communication (default: enabled)",default:!0},{flags:"--verbose",description:"Enable verbose logging for MCP server"}],examples:[{command:"nebutra mcp",description:"Start the MCP server for AI-powered project context integration"},{command:"nebutra mcp --verbose",description:"Start the MCP server with detailed logging output"}]},{name:"schema",description:"Show command schema and argument documentation (Agent-friendly JSON output)",usage:"nebutra schema [command] [options]",arguments:[{name:"command",description:"Command name to show schema for (e.g., init, add, create)",required:!1}],options:[{flags:"--all",description:"Show full schema for all commands as JSON",default:!1},{flags:"--list",description:"List all available command names",default:!1},{flags:"--exit-codes",description:"Show exit codes reference",default:!1}],examples:[{command:"nebutra schema --all",description:"Show complete JSON of all commands, args, options, value domains"},{command:"nebutra schema init",description:"Show schema for init command (arguments, options, defaults, examples)"},{command:"nebutra schema add",description:"Show schema for add command with enum values"},{command:"nebutra schema --list",description:"List just the command names (quick discovery)"},{command:"nebutra schema --exit-codes",description:"Show exit codes reference for all possible exit codes"}]},{name:"brand",description:"Manage governed brand tokens, palettes, and visual system outputs",usage:"nebutra brand [subcommand]",examples:[{command:"nebutra brand palette --primary=#0047FF",description:"Generate a token-aligned blue palette"}]},{name:"i18n",description:"Manage localization files and multilingual product copy",usage:"nebutra i18n [subcommand]"},{name:"infra",description:"Manage local infrastructure services for Nebutra development",usage:"nebutra infra [subcommand]",examples:[{command:"nebutra infra up --lite",description:"Start lightweight local infrastructure"}]},{name:"env",description:"Validate and manage environment variables across apps and packages",usage:"nebutra env [subcommand]"},{name:"license",description:"Manage Nebutra Sailor commercial license activation and status",usage:"nebutra license [subcommand]",arguments:[],options:[],subcommands:[{name:"activate",description:"Activate a commercial license key for local development",usage:"nebutra license activate <key>",arguments:[{name:"key",description:"Your Nebutra Sailor commercial license key",required:!0}],options:[{flags:"--quiet",description:"Suppress output"}],examples:[{command:"nebutra license activate liz_1234567890",description:"Activate your license key globally"}]},{name:"status",description:"Check the locally configured license status",usage:"nebutra license status",arguments:[],options:[{flags:"--quiet",description:"Suppress output"}],examples:[{command:"nebutra license status",description:"Check if you have an active license"}]}]},{name:"ai",description:"Configure AI providers, gateway routing, and agent-ready defaults",usage:"nebutra ai [subcommand]"},{name:"auth",description:"Configure authentication providers and tenant access defaults",usage:"nebutra auth [subcommand]"},{name:"billing",description:"Manage billing providers, subscriptions, usage, and return flows",usage:"nebutra billing [subcommand]"},{name:"stats",description:"Show monorepo statistics, health signals, and platform inventory",usage:"nebutra stats [options]"},{name:"db",description:"Manage database schema, migrations, seeds, and generated clients",usage:"nebutra db [subcommand]"},{name:"generate",description:"Generate apps, modules, API surfaces, and typed project artifacts",usage:"nebutra generate [type] [name]"},{name:"dev",description:"Start development workflows for selected Nebutra apps or presets",usage:"nebutra dev [options]"},{name:"build",description:"Run build workflows through the Nebutra CLI",usage:"nebutra build [options]"},{name:"lint",description:"Run lint workflows through the Nebutra CLI",usage:"nebutra lint [options]"},{name:"typecheck",description:"Run TypeScript checks through the Nebutra CLI",usage:"nebutra typecheck [options]"},{name:"test",description:"Run unit, architecture, and E2E verification workflows",usage:"nebutra test [scope]"},{name:"workflow",description:"Initialize and inspect workflow runtime adapters",usage:"nebutra workflow [subcommand]"},{name:"backend",description:"Manage backend runtime service workflows",usage:"nebutra backend [subcommand]"},{name:"e2e",description:"Run browser end-to-end verification suites",usage:"nebutra e2e [suite]"},{name:"theme",description:"Inspect registry-backed Nebutra themes and governance metadata",usage:"nebutra theme [subcommand]"},{name:"admin",description:"Operate tenant, platform health, and administrative workflows",usage:"nebutra admin [subcommand]"},{name:"community",description:"Inspect community health, showcases, and external adoption signals",usage:"nebutra community [subcommand]"},{name:"growth",description:"Analyze product growth, funnels, retention, and lifecycle signals",usage:"nebutra growth [subcommand]"},{name:"ecosystem",description:"Manage template marketplace, ideas, project showcase, and ecosystem sync",usage:"nebutra ecosystem [subcommand]"},{name:"services",description:"Inspect and manage microservice health, logs, scaling, and rollouts",usage:"nebutra services [subcommand]"},{name:"search",description:"Manage search indexes, reindexing, and search diagnostics",usage:"nebutra search [subcommand]"},{name:"secrets",description:"Manage encrypted tenant and platform secrets",usage:"nebutra secrets [subcommand]"},{name:"completions",description:"Generate shell completions for the current Nebutra command surface",usage:"nebutra completions [shell]",arguments:[{name:"shell",description:"Shell to generate completions for: bash, zsh, fish, or install",required:!1}]},{name:"logout",description:"Clear local Nebutra CLI session state",usage:"nebutra logout"},{name:"upgrade",description:"Upgrade local Nebutra CLI tooling",usage:"nebutra upgrade"},{name:"link",description:"Link a local project to Nebutra platform metadata",usage:"nebutra link"},{name:"unlink",description:"Unlink local Nebutra project metadata",usage:"nebutra unlink"},{name:"doctor",description:"Check local project setup and common Nebutra configuration issues",usage:"nebutra doctor"}]};var br="nebutra.config.json",zo=h.ai.filter(e=>e!=="none"),hr={"aws-bedrock":["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"],"azure-openai":["AZURE_OPENAI_API_KEY","AZURE_OPENAI_ENDPOINT"],"gcp-vertex":["GOOGLE_APPLICATION_CREDENTIALS","GOOGLE_CLOUD_PROJECT"],"vercel-gateway":["AI_GATEWAY_API_KEY"],"volcengine-ark":["VOLCENGINE_ARK_API_KEY"],bailian:["DASHSCOPE_API_KEY"],litellm:["LITELLM_API_KEY","LITELLM_BASE_URL"],portkey:["PORTKEY_API_KEY"],custom:["AI_CUSTOM_API_KEY","AI_CUSTOM_BASE_URL"]};function ne(e,t,r){if(t==="json"){let n={command:r||"ai",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(n,null,2))}else e&&typeof e=="object"&&"stdout"in e&&e.stdout&&console.log(e.stdout),e&&typeof e=="object"&&"stderr"in e&&e.stderr&&(e.exitCode??0)!==0&&console.error(e.stderr)}function Wo(e){return e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function Yo(e){return hr[e]?hr[e]:[`${e.replace(/-/g,"_").toUpperCase()}_API_KEY`]}function rt(){return Object.fromEntries(zo.map(e=>[e,{id:e,name:Wo(e),envVars:Yo(e)}]))}function le(){return Tt(process.cwd(),br)}function Ee(){let e=le();if(!Go(e))return{$schema:"https://nebutra.com/schema.json"};try{return JSON.parse(qo(e,"utf-8"))}catch(t){a.error(`Failed to parse ${br}: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}function nt(e){Ko(le(),`${JSON.stringify(e,null,2)}
123
+ `)}function he(e){return e.ai={providers:{},routes:{},...e.ai},e.ai.providers={...e.ai.providers},e.ai.routes={...e.ai.routes},e.ai}function vr(e){let t=rt(),r=[...new Set(e.map(o=>o.toLowerCase()))],n=r.filter(o=>!t[o]);return n.length>0&&(a.error(`Unknown AI provider(s): ${n.join(", ")}. Valid providers: ${Object.keys(t).join(", ")}`),process.exit(c.INVALID_ARGS)),r}function Ho(e){let t=e?.split(",").map(n=>n.trim()).filter(Boolean)??[];t.length===0&&(a.error("Route fallback cannot be empty. Use --fallback provider:model,provider:model"),process.exit(c.INVALID_ARGS));let r=t.filter(n=>!/^[a-z0-9-]+:[^,\s]+$/i.test(n));return r.length>0&&(a.error(`Invalid fallback target(s): ${r.join(", ")}. Expected provider:model.`),process.exit(c.INVALID_ARGS)),t}function wr(e){let t=he(e),r=t.providers??{},n=t.routes??{},o=Object.entries(r).filter(([,i])=>i.enabled).map(([i])=>i);return{path:le(),gateway:t.gateway??null,providers:r,enabledProviders:o,routes:n}}function re(e){let t=typeof e.opts=="function"?e.opts():e,r=typeof e.optsWithGlobals=="function"?e.optsWithGlobals():t,n=t.format??r.format??Jo();return{...r,...t,...n?{format:n}:{}}}function Jo(){let e=process.argv.find(r=>r.startsWith("--format="));if(e)return e.slice(9);let t=process.argv.indexOf("--format");if(t>=0)return process.argv[t+1]}function Le(e){return e?e.length<=8?"***":`${e.substring(0,8)}***`:"not set"}async function Xo(e){e.format!=="json"&&a.info("Checking configured AI models and providers...");let t={openai:{name:"OpenAI",keyVars:["OPENAI_API_KEY"],configured:!1},anthropic:{name:"Anthropic Claude",keyVars:["ANTHROPIC_API_KEY"],configured:!1},openrouter:{name:"OpenRouter",keyVars:["OPENROUTER_API_KEY"],configured:!1},vercel:{name:"Vercel AI SDK",keyVars:["VERCEL_AI_API_KEY"],configured:!1}};for(let n of Object.values(t))n.configured=n.keyVars.some(o=>process.env[o]);let r={providers:Object.entries(t).map(([n,o])=>({id:n,name:o.name,configured:o.configured,keys:o.keyVars.map(i=>({name:i,value:Le(process.env[i])}))})),configuredCount:Object.values(t).filter(n=>n.configured).length,totalProviders:Object.keys(t).length};e.dryRun||(r.configuredCount===0?a.warn("No AI providers configured. Set API keys to enable AI features."):a.success(`${r.configuredCount} AI provider(s) configured`)),ne(r,e.format,"ai:models")}async function Qo(e){e.format!=="json"&&a.info("Scanning for available agents...");try{let t=Tt(process.cwd(),"backends/gateway/src/routes/agents"),r=[];try{let o=await import("fs");o.existsSync(t)&&(r=o.readdirSync(t).filter(s=>s.endsWith(".ts")&&!s.endsWith(".d.ts")).map(s=>({name:s.replace(".ts",""),path:`backends/gateway/src/routes/agents/${s}`})))}catch{r=[]}let n={agents:r.length>0?r:[{name:"No agents found",path:"create agents in backends/gateway/src/routes/agents/"}],count:r.length};e.dryRun||(n.count===0?a.info("No agents configured. Create agents in backends/gateway/src/routes/agents/"):a.success(`Found ${n.count} agent(s)`)),ne(n,e.format,"ai:agents")}catch(t){a.error(`Failed to scan agents: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}async function Zo(e,t){(!e||e.trim().length===0)&&(a.error("Prompt cannot be empty"),process.exit(c.INVALID_ARGS)),t.format!=="json"&&(a.info("Testing AI prompt against default model..."),a.info("Note: Ensure API gateway is running on http://localhost:3001"));let r={prompt:e,note:"To execute this test, the API gateway must be running locally. Run: pnpm --filter @nebutra/gateway dev",endpoint:"http://localhost:3001/api/ai/test",method:"POST",payload:{prompt:e.substring(0,100)}};t.dryRun||a.warn("AI test execution requires a running API gateway. Start it with: pnpm --filter @nebutra/gateway dev"),ne(r,t.format,"ai:test")}async function ea(e){e.format!=="json"&&a.info("Checking AI configuration...");let t={providers:{openai:{key:Le(process.env.OPENAI_API_KEY),configured:!!process.env.OPENAI_API_KEY},anthropic:{key:Le(process.env.ANTHROPIC_API_KEY),configured:!!process.env.ANTHROPIC_API_KEY},openrouter:{key:Le(process.env.OPENROUTER_API_KEY),configured:!!process.env.OPENROUTER_API_KEY}},environment:{NODE_ENV:process.env.NODE_ENV||"development",NEBUTRA_LOG_LEVEL:process.env.NEBUTRA_LOG_LEVEL||"info"}};try{let n=Tt(process.cwd(),"nebutra.config.ts"),o=await import("fs");if(o.existsSync(n)){let s=o.readFileSync(n,"utf-8").match(/preset:\s*["']([^"']+)["']/);s&&(t.preset=s[1])}}catch{}let r=Object.entries(t.providers).filter(([,n])=>n.configured).map(([n])=>n);e.dryRun||(r.length===0?a.warn("No AI providers configured. Set environment variables to enable AI features."):a.success(`Configuration loaded: ${r.join(", ")}`)),ne(t,e.format,"ai:config")}async function ta(e){let t=Ee(),r=he(t),n=rt(),o=Object.values(n).map(s=>{let l=r.providers?.[s.id];return{id:s.id,name:s.name,enabled:l?.enabled===!0,configured:s.envVars.some(u=>!!process.env[u]),envVars:s.envVars.map(u=>({name:u,value:Le(process.env[u])}))}}),i={configPath:le(),providers:o,enabledCount:o.filter(s=>s.enabled).length,totalProviders:o.length};if(e.format!=="json"){let s=o.filter(l=>l.enabled);s.length===0?a.warn("No runtime AI providers enabled in nebutra.config.json."):a.success(`Enabled AI providers: ${s.map(l=>l.id).join(", ")}`)}ne(i,e.format,"ai:provider:list")}async function ra(e,t){let r=vr(e),n=Ee(),o=he(n),i=rt(),s=new Date().toISOString();for(let u of r)o.providers[u]={enabled:!0,envVars:i[u].envVars,enabledAt:o.providers?.[u]?.enabledAt??s};nt(n);let l={configPath:le(),enabled:r,env:t.env===!0?r.flatMap(u=>i[u].envVars.map(m=>({provider:u,name:m,example:`${m}=`}))):void 0,ai:wr(n)};if(t.format!=="json"&&(a.success(`Enabled AI provider(s): ${r.join(", ")}`),t.env)){a.info("Required environment variables:");for(let u of r)for(let m of i[u].envVars)console.log(`${m}=`)}ne(l,t.format,"ai:provider:enable")}async function na(e,t){let r=vr(e),n=Ee(),o=he(n),i=rt(),s=new Date().toISOString();for(let u of r)o.providers[u]={enabled:!1,envVars:o.providers?.[u]?.envVars??i[u].envVars,disabledAt:s};nt(n);let l={configPath:le(),disabled:r,ai:wr(n)};t.format!=="json"&&a.success(`Disabled AI provider(s): ${r.join(", ")}`),ne(l,t.format,"ai:provider:disable")}async function oa(e){let t=Ee(),r=he(t),n=new Date().toISOString();r.gateway={enabled:!0,mode:"local",initializedAt:r.gateway?.initializedAt??n,updatedAt:n},nt(t);let o={configPath:le(),gateway:r.gateway};e.format!=="json"&&a.success("AI gateway governance initialized in nebutra.config.json"),ne(o,e.format,"ai:gateway:init")}async function aa(e){let t=Ee(),r=he(t),n={configPath:le(),gateway:r.gateway??null,initialized:r.gateway?.enabled===!0};e.format!=="json"&&(n.initialized?a.success("AI gateway governance is initialized"):a.warn("AI gateway governance is not initialized. Run: nebutra ai gateway init")),ne(n,e.format,"ai:gateway:status")}async function ia(e,t){(!e||e.trim().length===0)&&(a.error("Route name cannot be empty"),process.exit(c.INVALID_ARGS)),t.policy||(a.error("Route policy is required. Use --policy <policy>."),process.exit(c.INVALID_ARGS));let r=Ho(t.fallback),n=Ee(),o=he(n);o.routes[e]={policy:t.policy,fallback:r,updatedAt:new Date().toISOString()},nt(n);let i={configPath:le(),route:{name:e,...o.routes[e]},routes:o.routes};t.format!=="json"&&a.success(`AI route '${e}' set with policy '${t.policy}'`),ne(i,t.format,"ai:route:set")}async function sa(e){let t=Ee(),r=he(t),n=Object.entries(r.routes??{}).map(([i,s])=>({name:i,...s})),o={configPath:le(),routes:n,count:n.length};e.format!=="json"&&(n.length===0?a.warn("No AI routes configured. Run: nebutra ai route set chat --policy cost-latency-balanced --fallback openai:gpt-5.4"):a.success(`Configured AI routes: ${n.map(i=>i.name).join(", ")}`)),ne(o,e.format,"ai:route:list")}function Sr(e){let t=e.command("ai").description("Manage AI models, agents, and configuration"),r=t.command("provider").description("Manage runtime AI provider governance");r.command("list").description("List supported and enabled AI providers").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await ta({format:s.format,interactive:s.yes!==!0})}),r.command("enable <providers...>").description("Enable one or more runtime AI providers in nebutra.config.json").option("--env","Print required environment variable placeholders").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await ra(i,{env:l.env===!0,format:l.format,interactive:l.yes!==!0})}),r.command("disable <providers...>").description("Disable one or more runtime AI providers in nebutra.config.json").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await na(i,{format:l.format,interactive:l.yes!==!0})});let n=t.command("gateway").description("Manage local AI gateway governance");n.command("init").description("Initialize the local AI gateway governance block").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await oa({format:s.format,interactive:s.yes!==!0})}),n.command("status").description("Show local AI gateway governance status").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await aa({format:s.format,interactive:s.yes!==!0})});let o=t.command("route").description("Manage AI routing policies");o.command("set <name>").description("Create or update an AI route policy").requiredOption("--policy <policy>","Routing policy id").requiredOption("--fallback <list>","Comma-separated provider:model fallback chain").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await ia(i,{policy:l.policy,fallback:l.fallback,format:l.format,interactive:l.yes!==!0})}),o.command("list").description("List configured AI routes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await sa({format:s.format,interactive:s.yes!==!0})}),t.command("models").description("List configured AI models and providers").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await Xo({dryRun:s.dryRun===!0,format:s.format,interactive:s.yes!==!0})}),t.command("agents").description("List available agents in the project").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await Qo({dryRun:s.dryRun===!0,format:s.format,interactive:s.yes!==!0})}),t.command("test <prompt>").description("Send a test prompt to the default AI model (requires running API gateway)").option("--dry-run","Preview without executing").option("--format <type>","Output format: json or plain").action(async(i,s)=>{let l=re(s);await Zo(i,{dryRun:l.dryRun===!0,format:l.format,interactive:l.yes!==!0})}),t.command("config").description("Show current AI configuration and provider status").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async i=>{let s=re(i);await ea({dryRun:s.dryRun===!0,format:s.format,interactive:s.yes!==!0})})}import{resolve as ca}from"path";function It(e,t,r){if(t==="json"){let n={command:r||"auth",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(n,null,2))}else e&&typeof e=="object"&&"stdout"in e&&e.stdout&&console.log(e.stdout),e&&typeof e=="object"&&"stderr"in e&&e.stderr&&(e.exitCode??0)!==0&&console.error(e.stderr)}function v(e,t){return e?e.length<=8?"***":`${e.substring(0,8)}*** (${t||e.length} chars)`:"not set"}function la(){try{let e=ca(process.cwd(),"nebutra.config.ts"),t=eo("fs");if(t.existsSync(e)){let r=t.readFileSync(e,"utf-8");if(r.includes("clerk"))return"clerk";if(r.includes("better-auth"))return"better-auth";if(r.includes("nextauth"))return"nextauth";if(r.includes("supabase"))return"supabase"}}catch{}return"clerk"}async function da(e){a.info("Checking authentication configuration...");let t=la(),r={provider:t,configured:!1,keys:{}};t==="clerk"?(r.keys={CLERK_SECRET_KEY:v(process.env.CLERK_SECRET_KEY,"secret"),NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,"publishable"),CLERK_WEBHOOK_SECRET:v(process.env.CLERK_WEBHOOK_SECRET,"webhook")},r.configured=!!process.env.CLERK_SECRET_KEY&&!!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY):t==="better-auth"?(r.keys={BETTER_AUTH_SECRET:v(process.env.BETTER_AUTH_SECRET,"secret"),BETTER_AUTH_URL:process.env.BETTER_AUTH_URL||"not set"},r.configured=!!process.env.BETTER_AUTH_SECRET):t==="nextauth"?(r.keys={AUTH_SECRET:v(process.env.AUTH_SECRET,"secret"),NEXTAUTH_SECRET:v(process.env.NEXTAUTH_SECRET,"legacy secret"),NEXTAUTH_URL:process.env.NEXTAUTH_URL||"not set",AUTH_URL:process.env.AUTH_URL||"not set",GOOGLE_CLIENT_ID:v(process.env.GOOGLE_CLIENT_ID,"google client"),GITHUB_CLIENT_ID:v(process.env.GITHUB_CLIENT_ID,"github client")},r.configured=!!(process.env.AUTH_SECRET||process.env.NEXTAUTH_SECRET)):(r.keys={NEXT_PUBLIC_SUPABASE_URL:process.env.NEXT_PUBLIC_SUPABASE_URL||"not set",NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY,"publishable"),NEXT_PUBLIC_SUPABASE_ANON_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,"anon"),SUPABASE_URL:process.env.SUPABASE_URL||"not set",SUPABASE_PUBLISHABLE_KEY:v(process.env.SUPABASE_PUBLISHABLE_KEY,"publishable"),SUPABASE_ANON_KEY:v(process.env.SUPABASE_ANON_KEY,"anon"),SUPABASE_SERVICE_ROLE_KEY:v(process.env.SUPABASE_SERVICE_ROLE_KEY,"service role"),SUPABASE_WEBHOOK_SECRET:v(process.env.SUPABASE_WEBHOOK_SECRET,"webhook")},r.configured=!!((process.env.SUPABASE_URL||process.env.NEXT_PUBLIC_SUPABASE_URL)&&(process.env.SUPABASE_PUBLISHABLE_KEY||process.env.SUPABASE_ANON_KEY||process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY||process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY)&&process.env.SUPABASE_SERVICE_ROLE_KEY)),e.dryRun||(r.configured?a.success(`Auth provider configured: ${t}`):a.warn(`Auth provider ${t} is not fully configured`)),It(r,e.format,"auth:status")}async function ua(e,t){let r=["clerk","better-auth","nextauth","supabase"];r.includes(e.toLowerCase())||(a.error(`Invalid provider: ${e}. Choose from: ${r.join(", ")}`),process.exit(c.INVALID_ARGS));let n=e.toLowerCase();a.info(`Setting up ${n} authentication...`),n==="clerk"?(a.info("Clerk setup requires:"),a.info("1. A Clerk account (https://clerk.com)"),a.info("2. A Clerk application created"),a.info("3. API keys from the Clerk dashboard"),a.info(""),a.info("To complete setup:"),a.info("1. Go to https://dashboard.clerk.com"),a.info("2. Copy your Secret Key and Publishable Key"),a.info("3. Add them to .env.local:"),a.info(' CLERK_SECRET_KEY="sk_..."'),a.info(' NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_..."'),a.info(""),a.info("Webhook setup (optional):"),a.info("1. In Clerk dashboard, go to Webhooks"),a.info("2. Create endpoint: https://yourdomain.com/api/webhooks/clerk"),a.info("3. Copy the signing secret to .env.local:"),a.info(' CLERK_WEBHOOK_SECRET="whsec_..."')):n==="better-auth"?(a.info("Better Auth setup requires:"),a.info("1. Database URL configured (DATABASE_URL env var)"),a.info("2. A generated auth secret"),a.info(""),a.info("To complete setup:"),a.info("1. Ensure DATABASE_URL is set in .env.local"),a.info("2. Generate a new secret:"),a.info(" openssl rand -base64 32"),a.info("3. Add to .env.local:"),a.info(' BETTER_AUTH_SECRET="<generated_secret>"'),a.info(' BETTER_AUTH_URL="http://localhost:3000"'),a.info(""),a.info("4. Run database migration:"),a.info(" pnpm --filter @nebutra/web db:push")):n==="nextauth"?(a.info("NextAuth / Auth.js setup requires:"),a.info("1. A generated Auth.js secret"),a.info("2. NEXTAUTH_URL or AUTH_URL pointing at the web app origin"),a.info("3. OAuth provider credentials for each enabled provider"),a.info(""),a.info("To complete setup:"),a.info("1. Generate a new secret:"),a.info(" openssl rand -base64 32"),a.info("2. Add to the production environment:"),a.info(' AUTH_PROVIDER="nextauth"'),a.info(' NEXT_PUBLIC_AUTH_PROVIDER="nextauth"'),a.info(' AUTH_SECRET="<generated_secret>"'),a.info(' NEXTAUTH_URL="https://app.nebutra.com"'),a.info(' GOOGLE_CLIENT_ID="..."'),a.info(' GOOGLE_CLIENT_SECRET="..."')):(a.info("Supabase Auth setup requires:"),a.info("1. Supabase project URL"),a.info("2. Public anon key for browser auth"),a.info("3. Service role key for server-side user/session validation"),a.info(""),a.info("To complete setup:"),a.info(' AUTH_PROVIDER="supabase"'),a.info(' NEXT_PUBLIC_AUTH_PROVIDER="supabase"'),a.info(' NEXT_PUBLIC_SUPABASE_URL="https://xxx.supabase.co"'),a.info(' NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),a.info(' NEXT_PUBLIC_SUPABASE_ANON_KEY="..."'),a.info(' SUPABASE_URL="https://xxx.supabase.co"'),a.info(' SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),a.info(' SUPABASE_ANON_KEY="..."'),a.info(' SUPABASE_SERVICE_ROLE_KEY="..."')),t.dryRun||a.success(`Setup instructions for ${n} displayed above`),It({provider:n,setupGuide:"Complete setup by following the instructions above",documentationUrl:n==="clerk"?"https://clerk.com/docs":n==="better-auth"?"https://www.better-auth.com":n==="nextauth"?"https://authjs.dev":"https://supabase.com/docs/guides/auth"},t.format,"auth:setup")}async function ma(e){a.info("Checking authentication keys and secrets...");let r={keys:{clerk:{CLERK_SECRET_KEY:v(process.env.CLERK_SECRET_KEY,"secret key"),NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,"publishable key"),CLERK_WEBHOOK_SECRET:v(process.env.CLERK_WEBHOOK_SECRET,"webhook secret")},betterAuth:{BETTER_AUTH_SECRET:v(process.env.BETTER_AUTH_SECRET,"secret"),BETTER_AUTH_URL:process.env.BETTER_AUTH_URL||"not set"},nextAuth:{AUTH_SECRET:v(process.env.AUTH_SECRET,"secret"),NEXTAUTH_SECRET:v(process.env.NEXTAUTH_SECRET,"legacy secret"),NEXTAUTH_URL:process.env.NEXTAUTH_URL||"not set",AUTH_URL:process.env.AUTH_URL||"not set",GOOGLE_CLIENT_ID:v(process.env.GOOGLE_CLIENT_ID,"google client"),GITHUB_CLIENT_ID:v(process.env.GITHUB_CLIENT_ID,"github client")},supabase:{NEXT_PUBLIC_SUPABASE_URL:process.env.NEXT_PUBLIC_SUPABASE_URL||"not set",NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY,"publishable"),NEXT_PUBLIC_SUPABASE_ANON_KEY:v(process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY,"anon"),SUPABASE_URL:process.env.SUPABASE_URL||"not set",SUPABASE_PUBLISHABLE_KEY:v(process.env.SUPABASE_PUBLISHABLE_KEY,"publishable"),SUPABASE_ANON_KEY:v(process.env.SUPABASE_ANON_KEY,"anon"),SUPABASE_SERVICE_ROLE_KEY:v(process.env.SUPABASE_SERVICE_ROLE_KEY,"service role")},common:{DATABASE_URL:v(process.env.DATABASE_URL,"database url"),JWT_SECRET:v(process.env.JWT_SECRET,"jwt secret")}},configured:{clerk:{secret:!!process.env.CLERK_SECRET_KEY,publishable:!!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY},betterAuth:{secret:!!process.env.BETTER_AUTH_SECRET,url:!!process.env.BETTER_AUTH_URL},nextAuth:{secret:!!(process.env.AUTH_SECRET||process.env.NEXTAUTH_SECRET),url:!!(process.env.NEXTAUTH_URL||process.env.AUTH_URL)},supabase:{url:!!(process.env.SUPABASE_URL||process.env.NEXT_PUBLIC_SUPABASE_URL),publishableKey:!!(process.env.SUPABASE_PUBLISHABLE_KEY||process.env.SUPABASE_ANON_KEY||process.env.NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY||process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY),serviceRole:!!process.env.SUPABASE_SERVICE_ROLE_KEY}}};if(!e.dryRun){let n=r.configured.clerk.secret&&r.configured.clerk.publishable,o=r.configured.betterAuth.secret&&r.configured.betterAuth.url,i=r.configured.nextAuth.secret&&r.configured.nextAuth.url,s=r.configured.supabase.url&&r.configured.supabase.publishableKey&&r.configured.supabase.serviceRole;!n&&!o&&!i&&!s?a.warn("No authentication keys configured"):(a.info("Auth keys status:"),n&&a.success("Clerk configured"),o&&a.success("Better Auth configured"),i&&a.success("NextAuth configured"),s&&a.success("Supabase configured"))}It(r,e.format,"auth:keys")}function Rr(e){let t=e.command("auth").description("Manage authentication configuration (Clerk, Better Auth, NextAuth, or Supabase)");t.command("status").description("Check current authentication provider configuration").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await da({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("setup <provider>").description("Configure Clerk, Better Auth, NextAuth, or Supabase (interactive wizard)").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async(r,n)=>{let o=n.optsWithGlobals?.()||n;await ua(r,{dryRun:n.dryRun||!1,format:n.format||o.format,interactive:o.yes!==!0})}),t.command("keys").description("Show authentication-related environment variables (masked)").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await ma({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}import be from"fs";import oe from"path";import*as ot from"@clack/prompts";import Cr from"picocolors";var kr=["ts","py"],pa=`{
124
124
  "name": "@nebutra/gateway",
125
125
  "version": "0.1.0",
126
126
  "private": true,
@@ -135,19 +135,19 @@ Services:`),Object.entries(r.services).forEach(([o,i])=>{let s=i.status==="healt
135
135
  "hono": "^4.6.0"
136
136
  }
137
137
  }
138
- `,ma=`import { Hono } from "hono";
138
+ `,fa=`import { Hono } from "hono";
139
139
 
140
140
  const app = new Hono();
141
141
 
142
142
  app.get("/healthz", (c) => c.json({ status: "ok" }));
143
143
 
144
144
  export default app;
145
- `,pa=`# @nebutra/gateway
145
+ `,ga=`# @nebutra/gateway
146
146
 
147
147
  TypeScript / Hono BFF \u2014 auth, tenancy, rate-limit, and routing.
148
148
 
149
149
  Per ADR 2026-05-10, this is the DEFAULT for new backend work.
150
- `;function fa(e){return`[project]
150
+ `;function ya(e){return`[project]
151
151
  name = "${e}"
152
152
  version = "0.1.0"
153
153
  description = "Nebutra Python backend service: ${e}"
@@ -164,7 +164,7 @@ build-backend = "hatchling.build"
164
164
 
165
165
  [tool.hatch.build.targets.wheel]
166
166
  packages = ["src"]
167
- `}function ga(e){return`# backends/python/${e}
167
+ `}function ha(e){return`# backends/python/${e}
168
168
 
169
169
  A Python (FastAPI) backend service.
170
170
 
@@ -190,7 +190,7 @@ it belongs in \`backends/gateway\` (TypeScript) instead.
190
190
  uv sync
191
191
  uv run uvicorn src.main:app --reload --port 8000
192
192
  \`\`\`
193
- `}var ya=`from fastapi import FastAPI
193
+ `}var ba=`from fastapi import FastAPI
194
194
  from pydantic import BaseModel
195
195
 
196
196
  app = FastAPI(title="nebutra-python-service")
@@ -203,35 +203,35 @@ class HealthResponse(BaseModel):
203
203
  @app.get("/healthz", response_model=HealthResponse)
204
204
  async def healthz() -> HealthResponse:
205
205
  return HealthResponse(status="ok")
206
- `;async function ha(e,t){let r=oe.join(e,"backends/gateway");be.existsSync(r)&&(a.info(`backends/gateway already exists in this monorepo \u2014 nothing to do.
206
+ `;async function va(e,t){let r=oe.join(e,"backends/gateway");be.existsSync(r)&&(a.info(`backends/gateway already exists in this monorepo \u2014 nothing to do.
207
207
  (This command is primarily for downstream consumers using create-sailor.)`),process.exit(c.SUCCESS)),t.dryRun&&(process.stdout.write(JSON.stringify({mode:"dry-run",command:"backend init ts",files:["backends/gateway/package.json","backends/gateway/src/index.ts","backends/gateway/README.md"]},null,2)+`
208
- `),process.exit(c.DRY_RUN_OK)),be.mkdirSync(oe.join(r,"src"),{recursive:!0}),be.writeFileSync(oe.join(r,"package.json"),ua),be.writeFileSync(oe.join(r,"src/index.ts"),ma),be.writeFileSync(oe.join(r,"README.md"),pa),a.success("Created backends/gateway scaffold"),process.exit(c.SUCCESS)}function kr(e){return/^[a-z][a-z0-9_-]{0,40}$/.test(e)}async function ba(e,t){let r=t.name,n=process.stdout.isTTY===!0&&!t.yes;if(!r&&n){let s=await ot.text({message:"Service name (lowercase, hyphens or underscores):",placeholder:"translator",validate:l=>kr(l)?void 0:"Invalid name"});ot.isCancel(s)&&(a.warn("Cancelled."),process.exit(c.CANCELLED)),r=s}r||(a.error("Missing --name. Required in non-interactive mode."),process.exit(c.INVALID_ARGS)),kr(r)||(a.error(`Invalid name: ${Er.red(r)}. Use lowercase letters, digits, hyphen, underscore.`),process.exit(c.INVALID_ARGS));let o=oe.join(e,"backends/python",r);be.existsSync(o)&&(a.error(`backends/python/${r} already exists \u2014 refusing to overwrite.`),process.exit(c.CONFLICT));let i=[[oe.join(o,"pyproject.toml"),fa(r)],[oe.join(o,"README.md"),ga(r)],[oe.join(o,"src/main.py"),ya],[oe.join(o,"src/__init__.py"),""]];t.dryRun&&(process.stdout.write(JSON.stringify({mode:"dry-run",command:`backend init py --name ${r}`,files:i.map(([s])=>s)},null,2)+`
209
- `),process.exit(c.DRY_RUN_OK));for(let[s,l]of i)be.mkdirSync(oe.dirname(s),{recursive:!0}),be.writeFileSync(s,l);a.success(`Created backends/python/${r} scaffold`),a.info("Update README.md to cite which ADR justification applies (batch | ML | specialized libs)."),process.exit(c.SUCCESS)}async function va(e,t={}){Rr.includes(e)||(a.error(`Invalid runtime: ${Er.red(e)}. Valid: ${Rr.join(", ")}`),process.exit(c.INVALID_ARGS));let r=b();e==="ts"?await ha(r,t):await ba(r,t)}function Cr(e){e.command("backend").description("Scaffold backend services (ts | py)").command("init <runtime>").description("Scaffold a backend service (runtime: ts | py)").option("--name <name>","Service name (Python only; prompted if omitted)").option("--dry-run","Preview files that would be created (exit code 10)").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await va(r,{name:n.name,dryRun:n.dryRun||!1,yes:o.yes||!1,quiet:o.quiet||!1})})}function $t(e,t,r){if(t==="json"){let n={command:r||"billing",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(n,null,2))}else e&&typeof e=="object"&&"stdout"in e&&e.stdout&&console.log(e.stdout),e&&typeof e=="object"&&"stderr"in e&&e.stderr&&(e.exitCode??0)!==0&&console.error(e.stderr)}function wa(e,t){return e?e.length<=8?"***":`${e.substring(0,8)}*** (${t||e.length} chars)`:"not set"}var at={stripe:{name:"Stripe",keyVars:["STRIPE_SECRET_KEY","STRIPE_PUBLISHABLE_KEY"],webhookUrl:"/api/webhooks/stripe",setupUrl:"https://dashboard.stripe.com"},lemonsqueezy:{name:"Lemon Squeezy",keyVars:["LEMONSQUEEZY_API_KEY"],webhookUrl:"/api/webhooks/lemonsqueezy",setupUrl:"https://app.lemonsqueezy.com/settings/api"},polar:{name:"Polar",keyVars:["POLAR_ACCESS_TOKEN"],webhookUrl:"/api/webhooks/polar",setupUrl:"https://app.polar.sh/settings/api"},chinapay:{name:"ChinaPay",keyVars:["CHINAPAY_MERCHANT_ID","CHINAPAY_SECRET_KEY"],webhookUrl:"/api/webhooks/chinapay",setupUrl:"https://www.chinapay.com"}};async function Sa(e){a.info("Checking payment provider configuration...");let t=Object.entries(at).map(([o,i])=>{let s=i.keyVars.every(l=>process.env[l]);return{id:o,name:i.name,configured:s,keys:i.keyVars.map(l=>({name:l,value:wa(process.env[l],"key")}))}}),r=t.filter(o=>o.configured),n={providers:t,configuredCount:r.length,totalProviders:t.length,configuredList:r.map(o=>o.name)};e.dryRun||(n.configuredCount===0?a.warn("No payment providers configured. Set API keys to enable billing."):a.success(`${n.configuredCount} payment provider(s) configured`)),$t(n,e.format,"billing:status")}async function Ra(e,t){let r=Object.keys(at);r.includes(e.toLowerCase())||(a.error(`Invalid provider: ${e}. Choose from: ${r.join(", ")}`),process.exit(c.INVALID_ARGS));let n=e.toLowerCase(),o=at[n];a.info(`Setting up ${o.name} payment provider...`),a.info(""),a.info("Setup steps:"),a.info(`1. Go to ${o.setupUrl}`),a.info("2. Create or log in to your account"),a.info("3. Generate API credentials"),a.info("4. Add the following to .env.local:"),a.info(""),o.keyVars.forEach(s=>{a.info(` ${s}="<your_${s.toLowerCase()}>"`.padStart(45))}),a.info(""),a.info("5. (Optional) Configure webhook in provider dashboard:"),a.info(` Webhook URL: https://yourdomain.com${o.webhookUrl}`),t.dryRun||a.success(`Setup instructions for ${o.name} displayed above`);let i={provider:n,name:o.name,requiredKeys:o.keyVars,webhookUrl:o.webhookUrl,setupGuide:"Follow the instructions above to complete setup",documentationUrl:o.setupUrl};$t(i,t.format,"billing:setup")}async function ka(e){a.info("Checking billing webhook configuration...");let t=process.env.NEXT_PUBLIC_APP_URL||"https://yourdomain.com",r=Object.entries(at).map(([o,i])=>({provider:o,name:i.name,url:`${t}${i.webhookUrl}`,endpoint:i.webhookUrl,configured:i.keyVars.every(s=>process.env[s])})),n={baseUrl:t,webhooks:r,configurationSteps:["1. Set NEXT_PUBLIC_APP_URL in .env.local to your domain","2. Copy the webhook URL for each provider","3. Configure in the provider's dashboard","4. Ensure the API key is also set"]};e.dryRun||(a.info("Webhook endpoints:"),r.forEach(o=>{o.configured?a.success(`${o.name}: configured`):a.warn(`${o.name}: not configured (missing API key)`)})),$t(n,e.format,"billing:webhooks")}function Ar(e){let t=e.command("billing").description("Manage payment providers and billing configuration");t.command("status").description("Check which payment providers are configured").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Sa({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("setup <provider>").description("Configure payment provider (Stripe, Lemon Squeezy, Polar, or ChinaPay)").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async(r,n)=>{let o=n.optsWithGlobals?.()||n;await Ra(r,{dryRun:n.dryRun||!1,format:n.format||o.format,interactive:o.yes!==!0})}),t.command("webhooks").description("Show webhook endpoints for each payment provider").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await ka({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}function De(e,t,r){if(t==="json"){let n={command:r||"brand",exitCode:e.exitCode,success:e.exitCode===0,...e.stdout&&{stdout:e.stdout},...e.stderr&&{stderr:e.stderr}};console.log(JSON.stringify(n,null,2))}else e.stdout&&console.log(e.stdout),e.stderr&&e.exitCode!==0&&console.error(e.stderr)}function xr(e){return/^#[0-9A-Fa-f]{6}$/.test(e)}async function Ea(e){a.info("Initializing brand system...");let t=await K("brand:init",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:init"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||a.success("Brand system initialized successfully")}async function Ca(e){a.info("Applying brand configuration...");let t=await K("brand:apply",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:apply"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||a.success("Brand applied successfully")}async function Aa(e){let t=[];e.primary&&(xr(e.primary)||(a.error(`Invalid primary color format: ${e.primary}. Expected hex format like #0033FE`),process.exit(c.INVALID_ARGS)),t.push(`--primary=${e.primary}`)),e.secondary&&(xr(e.secondary)||(a.error(`Invalid secondary color format: ${e.secondary}. Expected hex format like #0BF1C3`),process.exit(c.INVALID_ARGS)),t.push(`--secondary=${e.secondary}`)),t.length===0&&(a.warn("No colors specified. Usage: nebutra brand palette --primary=#HEX --secondary=#HEX"),a.info("Example: nebutra brand palette --primary=#0033FE --secondary=#0BF1C3"),process.exit(c.INVALID_ARGS)),a.info(`Generating color palette: ${t.join(" ")}`);let r=await x({command:"node",args:["scripts/generate-palette.mjs",...t],dryRun:e.dryRun,interactive:e.interactive??!0,label:"Generate brand palette"});De(r,e.format,"brand:palette"),r.exitCode!==0&&process.exit(r.exitCode),e.dryRun||a.success("Color palette generated successfully")}async function xa(e){a.info("Syncing brand tokens across packages...");let t=await K("brand:sync",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:sync"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||a.success("Brand tokens synced successfully")}async function Oa(e){a.info("Verifying brand token consistency...");let t=await K("brand:verify-tokens",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:verify-tokens"),t.exitCode!==0&&(a.error("Brand token verification failed. There are inconsistencies in your design tokens."),process.exit(t.exitCode)),e.dryRun||a.success("All brand tokens are consistent")}function Or(e){let t=e.command("brand").description("Manage Nebutra brand system and design tokens");t.command("init").description("Initialize brand system configuration").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Ea({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("apply").description("Apply brand configuration to the project").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Ca({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("palette").description("Generate brand color palette from custom colors").option("--primary <hex>","Primary brand color (hex format, e.g. #0033FE)").option("--secondary <hex>","Secondary brand color (hex format, e.g. #0BF1C3)").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Aa({primary:r.primary,secondary:r.secondary,dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("sync").description("Synchronize brand tokens across all packages").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await xa({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("verify").description("Verify brand token consistency across the project").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Oa({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}import pe from"picocolors";var _a=process.env.NEBUTRA_API_URL||"http://localhost:3001/api";async function N(e,t={}){let r=`${_a}${e}`,n=await fetch(r,{...t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${process.env.NEBUTRA_ADMIN_TOKEN||""}`,...t.headers}});if(!n.ok){let o=await n.text().catch(()=>n.statusText);throw new Error(`API Error (${n.status}): ${o}`)}return n.json()}function Pa(e){let t={dau_retention:.25,engagement_rate:.25,content_velocity:.2,response_time:.15,member_retention:.15},r={},n=0;for(let[o,i]of Object.entries(t)){let s=Math.min(100,(e[o]||0)*100);r[o]=s,n+=s*i}return{score:Math.round(n),breakdown:r}}async function Ta(e){try{a.info("Fetching showcase submissions...");let t=new URLSearchParams;e.status&&t.append("status",e.status),e.category&&t.append("category",e.category);let r=await N(`/community/showcase?${t.toString()}`);if(!r.submissions||r.submissions.length===0)return a.warn("No showcase submissions found"),c.SUCCESS;a.info(`
208
+ `),process.exit(c.DRY_RUN_OK)),be.mkdirSync(oe.join(r,"src"),{recursive:!0}),be.writeFileSync(oe.join(r,"package.json"),pa),be.writeFileSync(oe.join(r,"src/index.ts"),fa),be.writeFileSync(oe.join(r,"README.md"),ga),a.success("Created backends/gateway scaffold"),process.exit(c.SUCCESS)}function Er(e){return/^[a-z][a-z0-9_-]{0,40}$/.test(e)}async function wa(e,t){let r=t.name,n=process.stdout.isTTY===!0&&!t.yes;if(!r&&n){let s=await ot.text({message:"Service name (lowercase, hyphens or underscores):",placeholder:"translator",validate:l=>Er(l)?void 0:"Invalid name"});ot.isCancel(s)&&(a.warn("Cancelled."),process.exit(c.CANCELLED)),r=s}r||(a.error("Missing --name. Required in non-interactive mode."),process.exit(c.INVALID_ARGS)),Er(r)||(a.error(`Invalid name: ${Cr.red(r)}. Use lowercase letters, digits, hyphen, underscore.`),process.exit(c.INVALID_ARGS));let o=oe.join(e,"backends/python",r);be.existsSync(o)&&(a.error(`backends/python/${r} already exists \u2014 refusing to overwrite.`),process.exit(c.CONFLICT));let i=[[oe.join(o,"pyproject.toml"),ya(r)],[oe.join(o,"README.md"),ha(r)],[oe.join(o,"src/main.py"),ba],[oe.join(o,"src/__init__.py"),""]];t.dryRun&&(process.stdout.write(JSON.stringify({mode:"dry-run",command:`backend init py --name ${r}`,files:i.map(([s])=>s)},null,2)+`
209
+ `),process.exit(c.DRY_RUN_OK));for(let[s,l]of i)be.mkdirSync(oe.dirname(s),{recursive:!0}),be.writeFileSync(s,l);a.success(`Created backends/python/${r} scaffold`),a.info("Update README.md to cite which ADR justification applies (batch | ML | specialized libs)."),process.exit(c.SUCCESS)}async function Sa(e,t={}){kr.includes(e)||(a.error(`Invalid runtime: ${Cr.red(e)}. Valid: ${kr.join(", ")}`),process.exit(c.INVALID_ARGS));let r=b();e==="ts"?await va(r,t):await wa(r,t)}function Ar(e){e.command("backend").description("Scaffold backend services (ts | py)").command("init <runtime>").description("Scaffold a backend service (runtime: ts | py)").option("--name <name>","Service name (Python only; prompted if omitted)").option("--dry-run","Preview files that would be created (exit code 10)").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await Sa(r,{name:n.name,dryRun:n.dryRun||!1,yes:o.yes||!1,quiet:o.quiet||!1})})}function $t(e,t,r){if(t==="json"){let n={command:r||"billing",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(n,null,2))}else e&&typeof e=="object"&&"stdout"in e&&e.stdout&&console.log(e.stdout),e&&typeof e=="object"&&"stderr"in e&&e.stderr&&(e.exitCode??0)!==0&&console.error(e.stderr)}function Ra(e,t){return e?e.length<=8?"***":`${e.substring(0,8)}*** (${t||e.length} chars)`:"not set"}var at={stripe:{name:"Stripe",keyVars:["STRIPE_SECRET_KEY","STRIPE_PUBLISHABLE_KEY"],webhookUrl:"/api/webhooks/stripe",setupUrl:"https://dashboard.stripe.com"},lemonsqueezy:{name:"Lemon Squeezy",keyVars:["LEMONSQUEEZY_API_KEY"],webhookUrl:"/api/webhooks/lemonsqueezy",setupUrl:"https://app.lemonsqueezy.com/settings/api"},polar:{name:"Polar",keyVars:["POLAR_ACCESS_TOKEN"],webhookUrl:"/api/webhooks/polar",setupUrl:"https://app.polar.sh/settings/api"},chinapay:{name:"ChinaPay",keyVars:["CHINAPAY_MERCHANT_ID","CHINAPAY_SECRET_KEY"],webhookUrl:"/api/webhooks/chinapay",setupUrl:"https://www.chinapay.com"}};async function ka(e){a.info("Checking payment provider configuration...");let t=Object.entries(at).map(([o,i])=>{let s=i.keyVars.every(l=>process.env[l]);return{id:o,name:i.name,configured:s,keys:i.keyVars.map(l=>({name:l,value:Ra(process.env[l],"key")}))}}),r=t.filter(o=>o.configured),n={providers:t,configuredCount:r.length,totalProviders:t.length,configuredList:r.map(o=>o.name)};e.dryRun||(n.configuredCount===0?a.warn("No payment providers configured. Set API keys to enable billing."):a.success(`${n.configuredCount} payment provider(s) configured`)),$t(n,e.format,"billing:status")}async function Ea(e,t){let r=Object.keys(at);r.includes(e.toLowerCase())||(a.error(`Invalid provider: ${e}. Choose from: ${r.join(", ")}`),process.exit(c.INVALID_ARGS));let n=e.toLowerCase(),o=at[n];a.info(`Setting up ${o.name} payment provider...`),a.info(""),a.info("Setup steps:"),a.info(`1. Go to ${o.setupUrl}`),a.info("2. Create or log in to your account"),a.info("3. Generate API credentials"),a.info("4. Add the following to .env.local:"),a.info(""),o.keyVars.forEach(s=>{a.info(` ${s}="<your_${s.toLowerCase()}>"`.padStart(45))}),a.info(""),a.info("5. (Optional) Configure webhook in provider dashboard:"),a.info(` Webhook URL: https://yourdomain.com${o.webhookUrl}`),t.dryRun||a.success(`Setup instructions for ${o.name} displayed above`);let i={provider:n,name:o.name,requiredKeys:o.keyVars,webhookUrl:o.webhookUrl,setupGuide:"Follow the instructions above to complete setup",documentationUrl:o.setupUrl};$t(i,t.format,"billing:setup")}async function Ca(e){a.info("Checking billing webhook configuration...");let t=process.env.NEXT_PUBLIC_APP_URL||"https://yourdomain.com",r=Object.entries(at).map(([o,i])=>({provider:o,name:i.name,url:`${t}${i.webhookUrl}`,endpoint:i.webhookUrl,configured:i.keyVars.every(s=>process.env[s])})),n={baseUrl:t,webhooks:r,configurationSteps:["1. Set NEXT_PUBLIC_APP_URL in .env.local to your domain","2. Copy the webhook URL for each provider","3. Configure in the provider's dashboard","4. Ensure the API key is also set"]};e.dryRun||(a.info("Webhook endpoints:"),r.forEach(o=>{o.configured?a.success(`${o.name}: configured`):a.warn(`${o.name}: not configured (missing API key)`)})),$t(n,e.format,"billing:webhooks")}function xr(e){let t=e.command("billing").description("Manage payment providers and billing configuration");t.command("status").description("Check which payment providers are configured").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await ka({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("setup <provider>").description("Configure payment provider (Stripe, Lemon Squeezy, Polar, or ChinaPay)").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async(r,n)=>{let o=n.optsWithGlobals?.()||n;await Ea(r,{dryRun:n.dryRun||!1,format:n.format||o.format,interactive:o.yes!==!0})}),t.command("webhooks").description("Show webhook endpoints for each payment provider").option("--dry-run","Preview without making changes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Ca({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}function De(e,t,r){if(t==="json"){let n={command:r||"brand",exitCode:e.exitCode,success:e.exitCode===0,...e.stdout&&{stdout:e.stdout},...e.stderr&&{stderr:e.stderr}};console.log(JSON.stringify(n,null,2))}else e.stdout&&console.log(e.stdout),e.stderr&&e.exitCode!==0&&console.error(e.stderr)}function Or(e){return/^#[0-9A-Fa-f]{6}$/.test(e)}async function Aa(e){a.info("Initializing brand system...");let t=await K("brand:init",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:init"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||a.success("Brand system initialized successfully")}async function xa(e){a.info("Applying brand configuration...");let t=await K("brand:apply",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:apply"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||a.success("Brand applied successfully")}async function Oa(e){let t=[];e.primary&&(Or(e.primary)||(a.error(`Invalid primary color format: ${e.primary}. Expected hex format like #0033FE`),process.exit(c.INVALID_ARGS)),t.push(`--primary=${e.primary}`)),e.secondary&&(Or(e.secondary)||(a.error(`Invalid secondary color format: ${e.secondary}. Expected hex format like #0BF1C3`),process.exit(c.INVALID_ARGS)),t.push(`--secondary=${e.secondary}`)),t.length===0&&(a.warn("No colors specified. Usage: nebutra brand palette --primary=#HEX --secondary=#HEX"),a.info("Example: nebutra brand palette --primary=#0033FE --secondary=#0BF1C3"),process.exit(c.INVALID_ARGS)),a.info(`Generating color palette: ${t.join(" ")}`);let r=await x({command:"node",args:["scripts/generate-palette.mjs",...t],dryRun:e.dryRun,interactive:e.interactive??!0,label:"Generate brand palette"});De(r,e.format,"brand:palette"),r.exitCode!==0&&process.exit(r.exitCode),e.dryRun||a.success("Color palette generated successfully")}async function _a(e){a.info("Syncing brand tokens across packages...");let t=await K("brand:sync",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:sync"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||a.success("Brand tokens synced successfully")}async function Pa(e){a.info("Verifying brand token consistency...");let t=await K("brand:verify-tokens",{dryRun:e.dryRun,interactive:e.interactive??!0});De(t,e.format,"brand:verify-tokens"),t.exitCode!==0&&(a.error("Brand token verification failed. There are inconsistencies in your design tokens."),process.exit(t.exitCode)),e.dryRun||a.success("All brand tokens are consistent")}function _r(e){let t=e.command("brand").description("Manage Nebutra brand system and design tokens");t.command("init").description("Initialize brand system configuration").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Aa({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("apply").description("Apply brand configuration to the project").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await xa({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("palette").description("Generate brand color palette from custom colors").option("--primary <hex>","Primary brand color (hex format, e.g. #0033FE)").option("--secondary <hex>","Secondary brand color (hex format, e.g. #0BF1C3)").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Oa({primary:r.primary,secondary:r.secondary,dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("sync").description("Synchronize brand tokens across all packages").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await _a({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("verify").description("Verify brand token consistency across the project").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Pa({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}import pe from"picocolors";var Ta=process.env.NEBUTRA_API_URL||"http://localhost:3001/api";async function N(e,t={}){let r=`${Ta}${e}`,n=await fetch(r,{...t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${process.env.NEBUTRA_ADMIN_TOKEN||""}`,...t.headers}});if(!n.ok){let o=await n.text().catch(()=>n.statusText);throw new Error(`API Error (${n.status}): ${o}`)}return n.json()}function Ia(e){let t={dau_retention:.25,engagement_rate:.25,content_velocity:.2,response_time:.15,member_retention:.15},r={},n=0;for(let[o,i]of Object.entries(t)){let s=Math.min(100,(e[o]||0)*100);r[o]=s,n+=s*i}return{score:Math.round(n),breakdown:r}}async function $a(e){try{a.info("Fetching showcase submissions...");let t=new URLSearchParams;e.status&&t.append("status",e.status),e.category&&t.append("category",e.category);let r=await N(`/community/showcase?${t.toString()}`);if(!r.submissions||r.submissions.length===0)return a.warn("No showcase submissions found"),c.SUCCESS;a.info(`
210
210
  Showcase Submissions (${r.submissions.length})
211
- `);for(let n of r.submissions);return c.SUCCESS}catch(t){return a.error(`Failed to list showcase: ${t.message}`),c.ERROR}}async function Ia(e,t){try{if(!t.yes)return a.warn(`Approve showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Approving showcase submission ${e}...`);let r=await N(`/community/showcase/${e}/approve`,{method:"POST"});return a.success(`Approved: ${r.title}`),c.SUCCESS}catch(r){return a.error(`Failed to approve showcase: ${r.message}`),c.ERROR}}async function $a(e,t){try{if(!t.yes)return a.warn(`Reject showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;let r=t.reason||"Does not meet guidelines";a.info(`Rejecting showcase submission ${e}...`);let n=await N(`/community/showcase/${e}/reject`,{method:"POST",body:JSON.stringify({reason:r})});return a.success(`Rejected: ${n.title}`),c.SUCCESS}catch(r){return a.error(`Failed to reject showcase: ${r.message}`),c.ERROR}}async function ja(e,t){try{if(!t.yes)return a.warn(`Mark showcase as featured: ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Featuring showcase submission ${e}...`);let r=await N(`/community/showcase/${e}/feature`,{method:"POST"});return a.success(`Featured: ${r.title}`),c.SUCCESS}catch(r){return a.error(`Failed to feature showcase: ${r.message}`),c.ERROR}}async function Na(e){try{a.info("Fetching showcase statistics...");let t=await N("/community/showcase/stats");return a.info(`
211
+ `);for(let n of r.submissions);return c.SUCCESS}catch(t){return a.error(`Failed to list showcase: ${t.message}`),c.ERROR}}async function ja(e,t){try{if(!t.yes)return a.warn(`Approve showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Approving showcase submission ${e}...`);let r=await N(`/community/showcase/${e}/approve`,{method:"POST"});return a.success(`Approved: ${r.title}`),c.SUCCESS}catch(r){return a.error(`Failed to approve showcase: ${r.message}`),c.ERROR}}async function Na(e,t){try{if(!t.yes)return a.warn(`Reject showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;let r=t.reason||"Does not meet guidelines";a.info(`Rejecting showcase submission ${e}...`);let n=await N(`/community/showcase/${e}/reject`,{method:"POST",body:JSON.stringify({reason:r})});return a.success(`Rejected: ${n.title}`),c.SUCCESS}catch(r){return a.error(`Failed to reject showcase: ${r.message}`),c.ERROR}}async function Ua(e,t){try{if(!t.yes)return a.warn(`Mark showcase as featured: ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Featuring showcase submission ${e}...`);let r=await N(`/community/showcase/${e}/feature`,{method:"POST"});return a.success(`Featured: ${r.title}`),c.SUCCESS}catch(r){return a.error(`Failed to feature showcase: ${r.message}`),c.ERROR}}async function La(e){try{a.info("Fetching showcase statistics...");let t=await N("/community/showcase/stats");return a.info(`
212
212
  Showcase Statistics
213
- `),c.SUCCESS}catch(t){return a.error(`Failed to fetch showcase stats: ${t.message}`),c.ERROR}}async function Ua(e){try{a.info("Fetching community content...");let t=new URLSearchParams;e.status&&t.append("status",e.status),e.type&&t.append("type",e.type);let r=await N(`/community/content?${t.toString()}`);if(!r.items||r.items.length===0)return a.warn("No content found"),c.SUCCESS;a.info(`
213
+ `),c.SUCCESS}catch(t){return a.error(`Failed to fetch showcase stats: ${t.message}`),c.ERROR}}async function Da(e){try{a.info("Fetching community content...");let t=new URLSearchParams;e.status&&t.append("status",e.status),e.type&&t.append("type",e.type);let r=await N(`/community/content?${t.toString()}`);if(!r.items||r.items.length===0)return a.warn("No content found"),c.SUCCESS;a.info(`
214
214
  Community Content (${r.items.length})
215
- `);for(let n of r.items);return c.SUCCESS}catch(t){return a.error(`Failed to list content: ${t.message}`),c.ERROR}}async function La(e,t){try{let r=["approve","flag","archive","delete"];if(!r.includes(t.action))return a.error(`Invalid action. Must be one of: ${r.join(", ")}`),c.ERROR;if(!t.yes)return a.warn(`${t.action} content ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Moderating content ${e} (${t.action})...`);let n=await N(`/community/content/${e}/moderate`,{method:"POST",body:JSON.stringify({action:t.action})});return a.success(`Content ${t.action}d: ${n.title}`),c.SUCCESS}catch(r){return a.error(`Failed to moderate content: ${r.message}`),c.ERROR}}async function Da(e,t){try{if(!t.yes)return a.warn(`Publish content ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Publishing content ${e}...`);let r=await N(`/community/content/${e}/publish`,{method:"POST"});return a.success(`Published: ${r.title}`),c.SUCCESS}catch(r){return a.error(`Failed to publish content: ${r.message}`),c.ERROR}}async function Fa(e){try{a.info("Fetching content analytics...");let t=await N("/community/content/analytics");a.info(`
215
+ `);for(let n of r.items);return c.SUCCESS}catch(t){return a.error(`Failed to list content: ${t.message}`),c.ERROR}}async function Fa(e,t){try{let r=["approve","flag","archive","delete"];if(!r.includes(t.action))return a.error(`Invalid action. Must be one of: ${r.join(", ")}`),c.ERROR;if(!t.yes)return a.warn(`${t.action} content ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Moderating content ${e} (${t.action})...`);let n=await N(`/community/content/${e}/moderate`,{method:"POST",body:JSON.stringify({action:t.action})});return a.success(`Content ${t.action}d: ${n.title}`),c.SUCCESS}catch(r){return a.error(`Failed to moderate content: ${r.message}`),c.ERROR}}async function Va(e,t){try{if(!t.yes)return a.warn(`Publish content ${e}? Use --yes to confirm`),c.SUCCESS;a.info(`Publishing content ${e}...`);let r=await N(`/community/content/${e}/publish`,{method:"POST"});return a.success(`Published: ${r.title}`),c.SUCCESS}catch(r){return a.error(`Failed to publish content: ${r.message}`),c.ERROR}}async function Ma(e){try{a.info("Fetching content analytics...");let t=await N("/community/content/analytics");a.info(`
216
216
  Content Performance Metrics
217
- `);for(let r of t.topContent.slice(0,5));return e.format,c.SUCCESS}catch(t){return a.error(`Failed to fetch analytics: ${t.message}`),c.ERROR}}async function Va(e){try{a.info("Fetching community members...");let t=new URLSearchParams;e.role&&t.append("role",e.role),e.sort&&t.append("sort",e.sort);let r=await N(`/community/members?${t.toString()}`);if(!r.members||r.members.length===0)return a.warn("No members found"),c.SUCCESS;a.info(`
217
+ `);for(let r of t.topContent.slice(0,5));return e.format,c.SUCCESS}catch(t){return a.error(`Failed to fetch analytics: ${t.message}`),c.ERROR}}async function Ba(e){try{a.info("Fetching community members...");let t=new URLSearchParams;e.role&&t.append("role",e.role),e.sort&&t.append("sort",e.sort);let r=await N(`/community/members?${t.toString()}`);if(!r.members||r.members.length===0)return a.warn("No members found"),c.SUCCESS;a.info(`
218
218
  Community Members (${r.members.length})
219
- `);for(let n of r.members){let i={owner:pe.red,admin:pe.yellow,moderator:pe.blue,member:pe.gray}[String(n.role)]??pe.gray}return c.SUCCESS}catch(t){return a.error(`Failed to list members: ${t.message}`),c.ERROR}}async function Ma(e,t){try{a.info(`Fetching profile for ${e}...`);let r=await N(`/community/members/${e}`);return a.info(`
219
+ `);for(let n of r.members){let i={owner:pe.red,admin:pe.yellow,moderator:pe.blue,member:pe.gray}[String(n.role)]??pe.gray}return c.SUCCESS}catch(t){return a.error(`Failed to list members: ${t.message}`),c.ERROR}}async function Ga(e,t){try{a.info(`Fetching profile for ${e}...`);let r=await N(`/community/members/${e}`);return a.info(`
220
220
  Member Profile
221
- `),c.SUCCESS}catch(r){return a.error(`Failed to fetch member profile: ${r.message}`),c.ERROR}}async function Ba(e,t,r){try{let n=["member","moderator","admin","owner"];if(!n.includes(t))return a.error(`Invalid role. Must be one of: ${n.join(", ")}`),c.ERROR;if(!r.yes)return a.warn(`Change ${e} role to ${t}? Use --yes to confirm`),c.SUCCESS;a.info("Updating member role...");let o=await N(`/community/members/${e}/role`,{method:"POST",body:JSON.stringify({role:t})});return a.success(`Updated ${o.name} \u2192 ${pe.bold(t)}`),c.SUCCESS}catch(n){return a.error(`Failed to update member role: ${n.message}`),c.ERROR}}async function Ga(e,t){try{a.info(`Sending invite to ${e}...`);let r=await N("/community/members/invite",{method:"POST",body:JSON.stringify({email:e})});return a.success(`Invite sent to ${e}`),c.SUCCESS}catch(r){return a.error(`Failed to send invite: ${r.message}`),c.ERROR}}async function qa(e,t){try{if(!t.yes)return a.warn(`Ban member ${e}? Use --yes to confirm`),c.SUCCESS;let r=t.reason||"Violation of community guidelines";a.info(`Banning member ${e}...`);let n=await N(`/community/members/${e}/ban`,{method:"POST",body:JSON.stringify({reason:r})});return a.success(`Banned: ${n.name}`),c.SUCCESS}catch(r){return a.error(`Failed to ban member: ${r.message}`),c.ERROR}}async function Ka(e){try{a.info("Computing community health score...");let t=e.period||"30d",r=await N(`/community/health?period=${t}`),{score:n,breakdown:o}=Pa(r.metrics);a.info(`
221
+ `),c.SUCCESS}catch(r){return a.error(`Failed to fetch member profile: ${r.message}`),c.ERROR}}async function qa(e,t,r){try{let n=["member","moderator","admin","owner"];if(!n.includes(t))return a.error(`Invalid role. Must be one of: ${n.join(", ")}`),c.ERROR;if(!r.yes)return a.warn(`Change ${e} role to ${t}? Use --yes to confirm`),c.SUCCESS;a.info("Updating member role...");let o=await N(`/community/members/${e}/role`,{method:"POST",body:JSON.stringify({role:t})});return a.success(`Updated ${o.name} \u2192 ${pe.bold(t)}`),c.SUCCESS}catch(n){return a.error(`Failed to update member role: ${n.message}`),c.ERROR}}async function Ka(e,t){try{a.info(`Sending invite to ${e}...`);let r=await N("/community/members/invite",{method:"POST",body:JSON.stringify({email:e})});return a.success(`Invite sent to ${e}`),c.SUCCESS}catch(r){return a.error(`Failed to send invite: ${r.message}`),c.ERROR}}async function za(e,t){try{if(!t.yes)return a.warn(`Ban member ${e}? Use --yes to confirm`),c.SUCCESS;let r=t.reason||"Violation of community guidelines";a.info(`Banning member ${e}...`);let n=await N(`/community/members/${e}/ban`,{method:"POST",body:JSON.stringify({reason:r})});return a.success(`Banned: ${n.name}`),c.SUCCESS}catch(r){return a.error(`Failed to ban member: ${r.message}`),c.ERROR}}async function Wa(e){try{a.info("Computing community health score...");let t=e.period||"30d",r=await N(`/community/health?period=${t}`),{score:n,breakdown:o}=Ia(r.metrics);a.info(`
222
222
  Community Health Report (${t})
223
- `);for(let[i,s]of Object.entries(o)){let l=i.replace(/_/g," ").toLowerCase(),u="\u2588".repeat(Math.round(s/5))+"\u2591".repeat(20-Math.round(s/5))}return e.format,c.SUCCESS}catch(t){return a.error(`Failed to compute health: ${t.message}`),c.ERROR}}async function za(e){try{a.info("Fetching moderation queue...");let t=await N("/community/moderation/queue");if(!t.items||t.items.length===0)return a.success("No pending moderation items"),c.SUCCESS;a.info(`
223
+ `);for(let[i,s]of Object.entries(o)){let l=i.replace(/_/g," ").toLowerCase(),u="\u2588".repeat(Math.round(s/5))+"\u2591".repeat(20-Math.round(s/5))}return e.format,c.SUCCESS}catch(t){return a.error(`Failed to compute health: ${t.message}`),c.ERROR}}async function Ya(e){try{a.info("Fetching moderation queue...");let t=await N("/community/moderation/queue");if(!t.items||t.items.length===0)return a.success("No pending moderation items"),c.SUCCESS;a.info(`
224
224
  Moderation Queue (${t.items.length} pending)
225
- `);for(let r of t.items){let o={low:pe.gray("\u25CF"),medium:pe.yellow("\u25CF"),high:pe.red("\u25CF")}[String(r.severity)]??"\u25CF"}return c.SUCCESS}catch(t){return a.error(`Failed to fetch queue: ${t.message}`),c.ERROR}}async function Wa(e){try{a.info("Running AI-assisted moderation sweep..."),e.dryRun&&a.warn("DRY RUN MODE - no changes will be made");let t=await N("/community/moderation/auto",{method:"POST",body:JSON.stringify({dryRun:e.dryRun||!1})});return a.info(`
225
+ `);for(let r of t.items){let o={low:pe.gray("\u25CF"),medium:pe.yellow("\u25CF"),high:pe.red("\u25CF")}[String(r.severity)]??"\u25CF"}return c.SUCCESS}catch(t){return a.error(`Failed to fetch queue: ${t.message}`),c.ERROR}}async function Ha(e){try{a.info("Running AI-assisted moderation sweep..."),e.dryRun&&a.warn("DRY RUN MODE - no changes will be made");let t=await N("/community/moderation/auto",{method:"POST",body:JSON.stringify({dryRun:e.dryRun||!1})});return a.info(`
226
226
  Moderation Results
227
- `),e.dryRun?a.info("DRY RUN COMPLETE - no changes committed"):a.success("Moderation sweep complete"),c.SUCCESS}catch(t){return a.error(`Failed to run moderation: ${t.message}`),c.ERROR}}function _r(e){let t=e.command("community").description("Manage Nebutra-Sailor community dimension"),r=t.command("showcase").description("Project showcase management");r.command("list").description("List submitted projects").option("--status <status>","Filter by status (pending|approved|rejected|featured)").option("--category <category>","Filter by category").action(s=>Ta(s).then(process.exit)),r.command("approve <id>").description("Approve a showcase submission").option("--yes","Skip confirmation").action((s,l)=>Ia(s,l).then(process.exit)),r.command("reject <id>").description("Reject a showcase submission").option("--reason <text>","Rejection reason").option("--yes","Skip confirmation").action((s,l)=>$a(s,l).then(process.exit)),r.command("feature <id>").description("Mark as featured").option("--yes","Skip confirmation").action((s,l)=>ja(s,l).then(process.exit)),r.command("stats").description("Showcase engagement metrics").action(s=>Na(s).then(process.exit));let n=t.command("content").description("Content moderation pipeline");n.command("list").description("List community content").option("--status <status>","Filter by status (draft|published|flagged|archived)").option("--type <type>","Filter by type (article|discussion|announcement)").action(s=>Ua(s).then(process.exit)),n.command("moderate <id>").description("Moderate content").option("--action <action>","Action (approve|flag|archive|delete)").option("--yes","Skip confirmation").action((s,l)=>La(s,l).then(process.exit)),n.command("publish <id>").description("Publish approved content").option("--yes","Skip confirmation").action((s,l)=>Da(s,l).then(process.exit)),n.command("analytics").description("Content performance metrics").option("--format <format>","Output format (json|text)").action(s=>Fa(s).then(process.exit));let o=t.command("members").description("Member management");o.command("list").description("List members").option("--role <role>","Filter by role (member|admin|owner|moderator)").option("--sort <sort>","Sort by (engagement|joined|name)").action(s=>Va(s).then(process.exit)),o.command("profile <userId>").description("View member profile + activity").action((s,l)=>Ma(s,l).then(process.exit)),o.command("role <userId> <role>").description("Update member role").option("--yes","Skip confirmation").action((s,l,u)=>Ba(s,l,u).then(process.exit)),o.command("invite <email>").description("Invite to community").action((s,l)=>Ga(s,l).then(process.exit)),o.command("ban <userId>").description("Ban member").option("--reason <text>","Ban reason").option("--yes","Skip confirmation").action((s,l)=>qa(s,l).then(process.exit)),t.command("health").description("Community health dashboard").option("--period <period>","Time period (7d|30d|90d)","30d").option("--format <format>","Output format (json|text)").action(s=>Ka(s).then(process.exit));let i=t.command("moderate").description("AI-assisted moderation queue");i.command("queue").description("Show pending moderation items").action(s=>za(s).then(process.exit)),i.command("auto").description("Run AI moderation sweep").option("--dry-run","Preview without committing").action(s=>Wa(s).then(process.exit))}import{appendFileSync as Ya,existsSync as Ha,readFileSync as Ja,writeFileSync as Xa}from"fs";import{homedir as Fe}from"os";import{join as Ie}from"path";import*as W from"@clack/prompts";import z from"picocolors";var it=(ce.subcommands??[]).map(e=>e.name),Pr={init:"Initialize a Nebutra project and create nebutra.config.json",add:"Add a registry-backed platform feature or external UI component",create:"Scaffold a topology-first Nebutra Sailor project",mcp:"Start the Nebutra MCP server for AI agents and editors",completions:"Generate shell completions",doctor:"Check your Nebutra project setup",schema:"Show command schema and argument documentation",brand:"Manage governed brand tokens and palettes",i18n:"Manage localization files and multilingual product copy",infra:"Manage local infrastructure services",env:"Validate and manage environment variables",license:"Manage Nebutra Sailor commercial license activation and status",db:"Database migration and management",generate:"Scaffold apps, modules, and code",dev:"Start development server",build:"Run build workflows",lint:"Run lint workflows",typecheck:"Run TypeScript checks",test:"Run unit and E2E tests",workflow:"Workflow provider scaffolding",backend:"Backend runtime service workflows",e2e:"Run browser E2E suites",theme:"Theme registry and governance metadata",ai:"AI provider and gateway routing configuration",auth:"Authentication setup",billing:"Billing and subscription management",stats:"Project statistics and health checks",admin:"Platform administration",community:"Community health and showcase",growth:"Growth analytics and insights",ecosystem:"Template marketplace, ideas, showcase, and ecosystem sync",services:"Microservice management",search:"Search index management",secrets:"Encrypted secrets management",logout:"Clear local session state",upgrade:"Upgrade local CLI tooling",link:"Link local project metadata",unlink:"Unlink local project metadata"},Qa=["--help","--version","--21st","--v0","--stdio","--format","--yes","--no-interactive","--no-color","--verbose","--quiet","--dry-run","--if-not-exists","--provider","-p","--pm","--region","--orm","--db","--auth","--social-login","--payment","--ai","--deploy","--docs","--email","--storage","--monitoring","--analytics","--sms","--queue","--search","--cache","--notifications","--webhooks","--cms","--feature-flags","--captcha","--mcp","--metering","--billing-mode","--idp","--i18n","--no-i18n","--no-install","--no-git","--json"],jt=["-p","--pm","--region","--orm","--db","--auth","--social-login","--payment","--ai","--deploy","--docs","--email","--storage","--monitoring","--analytics","--sms","--queue","--search","--cache","--notifications","--webhooks","--cms","--feature-flags","--captcha","--mcp","--metering","--billing-mode","--idp","--i18n","--no-i18n","--no-install","--no-git","--dry-run","--json","--yes"],Za={"-p":h.pm,"--pm":h.pm,"--region":h.region,"--orm":h.orm,"--db":h.db,"--auth":h.auth,"--payment":h.payment,"--deploy":h.deploy,"--docs":h.docs,"--email":h.email,"--storage":h.storage,"--monitoring":h.monitoring,"--analytics":h.analytics,"--sms":h.sms,"--queue":h.queue,"--search":h.search,"--cache":h.cache,"--notifications":h.notifications,"--webhooks":h.webhooks,"--cms":h.cms,"--feature-flags":h.featureFlags,"--captcha":h.captcha,"--mcp":h.mcp,"--metering":h.metering,"--billing-mode":h.billingMode,"--idp":h.idp},ei=Object.entries(Za).map(([e,t])=>` ${e})
227
+ `),e.dryRun?a.info("DRY RUN COMPLETE - no changes committed"):a.success("Moderation sweep complete"),c.SUCCESS}catch(t){return a.error(`Failed to run moderation: ${t.message}`),c.ERROR}}function Pr(e){let t=e.command("community").description("Manage Nebutra-Sailor community dimension"),r=t.command("showcase").description("Project showcase management");r.command("list").description("List submitted projects").option("--status <status>","Filter by status (pending|approved|rejected|featured)").option("--category <category>","Filter by category").action(s=>$a(s).then(process.exit)),r.command("approve <id>").description("Approve a showcase submission").option("--yes","Skip confirmation").action((s,l)=>ja(s,l).then(process.exit)),r.command("reject <id>").description("Reject a showcase submission").option("--reason <text>","Rejection reason").option("--yes","Skip confirmation").action((s,l)=>Na(s,l).then(process.exit)),r.command("feature <id>").description("Mark as featured").option("--yes","Skip confirmation").action((s,l)=>Ua(s,l).then(process.exit)),r.command("stats").description("Showcase engagement metrics").action(s=>La(s).then(process.exit));let n=t.command("content").description("Content moderation pipeline");n.command("list").description("List community content").option("--status <status>","Filter by status (draft|published|flagged|archived)").option("--type <type>","Filter by type (article|discussion|announcement)").action(s=>Da(s).then(process.exit)),n.command("moderate <id>").description("Moderate content").option("--action <action>","Action (approve|flag|archive|delete)").option("--yes","Skip confirmation").action((s,l)=>Fa(s,l).then(process.exit)),n.command("publish <id>").description("Publish approved content").option("--yes","Skip confirmation").action((s,l)=>Va(s,l).then(process.exit)),n.command("analytics").description("Content performance metrics").option("--format <format>","Output format (json|text)").action(s=>Ma(s).then(process.exit));let o=t.command("members").description("Member management");o.command("list").description("List members").option("--role <role>","Filter by role (member|admin|owner|moderator)").option("--sort <sort>","Sort by (engagement|joined|name)").action(s=>Ba(s).then(process.exit)),o.command("profile <userId>").description("View member profile + activity").action((s,l)=>Ga(s,l).then(process.exit)),o.command("role <userId> <role>").description("Update member role").option("--yes","Skip confirmation").action((s,l,u)=>qa(s,l,u).then(process.exit)),o.command("invite <email>").description("Invite to community").action((s,l)=>Ka(s,l).then(process.exit)),o.command("ban <userId>").description("Ban member").option("--reason <text>","Ban reason").option("--yes","Skip confirmation").action((s,l)=>za(s,l).then(process.exit)),t.command("health").description("Community health dashboard").option("--period <period>","Time period (7d|30d|90d)","30d").option("--format <format>","Output format (json|text)").action(s=>Wa(s).then(process.exit));let i=t.command("moderate").description("AI-assisted moderation queue");i.command("queue").description("Show pending moderation items").action(s=>Ya(s).then(process.exit)),i.command("auto").description("Run AI moderation sweep").option("--dry-run","Preview without committing").action(s=>Ha(s).then(process.exit))}import{appendFileSync as Ja,existsSync as Xa,readFileSync as Qa,writeFileSync as Za}from"fs";import{homedir as Fe}from"os";import{join as Ie}from"path";import*as W from"@clack/prompts";import z from"picocolors";var it=(ce.subcommands??[]).map(e=>e.name),Tr={init:"Initialize a Nebutra project and create nebutra.config.json",add:"Add a registry-backed platform feature or external UI component",create:"Scaffold a topology-first Nebutra Sailor project",mcp:"Start the Nebutra MCP server for AI agents and editors",completions:"Generate shell completions",doctor:"Check your Nebutra project setup",schema:"Show command schema and argument documentation",brand:"Manage governed brand tokens and palettes",i18n:"Manage localization files and multilingual product copy",infra:"Manage local infrastructure services",env:"Validate and manage environment variables",license:"Manage Nebutra Sailor commercial license activation and status",db:"Database migration and management",generate:"Scaffold apps, modules, and code",dev:"Start development server",build:"Run build workflows",lint:"Run lint workflows",typecheck:"Run TypeScript checks",test:"Run unit and E2E tests",workflow:"Workflow provider scaffolding",backend:"Backend runtime service workflows",e2e:"Run browser E2E suites",theme:"Theme registry and governance metadata",ai:"AI provider and gateway routing configuration",auth:"Authentication setup",billing:"Billing and subscription management",stats:"Project statistics and health checks",admin:"Platform administration",community:"Community health and showcase",growth:"Growth analytics and insights",ecosystem:"Template marketplace, ideas, showcase, and ecosystem sync",services:"Microservice management",search:"Search index management",secrets:"Encrypted secrets management",logout:"Clear local session state",upgrade:"Upgrade local CLI tooling",link:"Link local project metadata",unlink:"Unlink local project metadata"},ei=["--help","--version","--21st","--v0","--stdio","--format","--yes","--no-interactive","--no-color","--verbose","--quiet","--dry-run","--if-not-exists","--provider","-p","--pm","--region","--orm","--db","--auth","--social-login","--payment","--ai","--deploy","--docs","--email","--storage","--monitoring","--analytics","--sms","--queue","--search","--cache","--notifications","--webhooks","--cms","--feature-flags","--captcha","--mcp","--metering","--billing-mode","--idp","--i18n","--no-i18n","--no-install","--no-git","--json"],jt=["-p","--pm","--region","--orm","--db","--auth","--social-login","--payment","--ai","--deploy","--docs","--email","--storage","--monitoring","--analytics","--sms","--queue","--search","--cache","--notifications","--webhooks","--cms","--feature-flags","--captcha","--mcp","--metering","--billing-mode","--idp","--i18n","--no-i18n","--no-install","--no-git","--dry-run","--json","--yes"],ti={"-p":h.pm,"--pm":h.pm,"--region":h.region,"--orm":h.orm,"--db":h.db,"--auth":h.auth,"--payment":h.payment,"--deploy":h.deploy,"--docs":h.docs,"--email":h.email,"--storage":h.storage,"--monitoring":h.monitoring,"--analytics":h.analytics,"--sms":h.sms,"--queue":h.queue,"--search":h.search,"--cache":h.cache,"--notifications":h.notifications,"--webhooks":h.webhooks,"--cms":h.cms,"--feature-flags":h.featureFlags,"--captcha":h.captcha,"--mcp":h.mcp,"--metering":h.metering,"--billing-mode":h.billingMode,"--idp":h.idp},ri=Object.entries(ti).map(([e,t])=>` ${e})
228
228
  COMPREPLY=( $(compgen -W "${t.join(" ")}" -- \${cur}) )
229
229
  return 0
230
230
  ;;`).join(`
231
- `),ti=jt.map(e=>` "${e}"`).join(`
232
- `),ri=it.map(e=>`complete -c nebutra -n "__fish_use_subcommand_only" -f -a "${e}" -d "${Pr[e]}"`).join(`
233
- `),ni=jt.map(e=>`complete -c nebutra -n "__fish_seen_subcommand_from create" -f -a "${e}" -d "create-sailor option"`).join(`
234
- `);function Tr(){return`#!/usr/bin/env bash
231
+ `),ni=jt.map(e=>` "${e}"`).join(`
232
+ `),oi=it.map(e=>`complete -c nebutra -n "__fish_use_subcommand_only" -f -a "${e}" -d "${Tr[e]}"`).join(`
233
+ `),ai=jt.map(e=>`complete -c nebutra -n "__fish_seen_subcommand_from create" -f -a "${e}" -d "create-sailor option"`).join(`
234
+ `);function Ir(){return`#!/usr/bin/env bash
235
235
 
236
236
  _nebutra_completions() {
237
237
  local cur prev opts cmd
@@ -243,10 +243,10 @@ _nebutra_completions() {
243
243
  local subcommands="${it.join(" ")}"
244
244
 
245
245
  # Flags
246
- local flags="${Qa.join(" ")}"
246
+ local flags="${ei.join(" ")}"
247
247
 
248
248
  case "\${prev}" in
249
- ${ei}
249
+ ${ri}
250
250
  esac
251
251
 
252
252
  if [[ \${cur} == -* ]]; then
@@ -270,11 +270,11 @@ ${ei}
270
270
  }
271
271
 
272
272
  complete -o bashdefault -o default -o nospace -F _nebutra_completions nebutra
273
- `}function Ir(){return`#compdef nebutra
273
+ `}function $r(){return`#compdef nebutra
274
274
 
275
275
  _nebutra() {
276
276
  local -a commands=(
277
- ${it.map(e=>`"${e}:${Pr[e]}"`).join(`
277
+ ${it.map(e=>`"${e}:${Tr[e]}"`).join(`
278
278
  `)}
279
279
  )
280
280
 
@@ -291,7 +291,7 @@ _nebutra() {
291
291
  )
292
292
 
293
293
  local -a create_flags=(
294
- ${ti}
294
+ ${ni}
295
295
  )
296
296
 
297
297
  local -a mcp_flags=(
@@ -332,12 +332,12 @@ ${ti}
332
332
  }
333
333
 
334
334
  _nebutra
335
- `}function $r(){return`# Fish shell completions for nebutra
335
+ `}function jr(){return`# Fish shell completions for nebutra
336
336
 
337
337
  complete -c nebutra -f -n "__fish_seen_subcommand_from; and not __fish_seen_subcommand_from ${it.join(" ")}" -d "Nebutra governance CLI"
338
338
 
339
339
  # Subcommands
340
- ${ri}
340
+ ${oi}
341
341
 
342
342
  # Flags
343
343
  complete -c nebutra -f -a "--help" -d "Show help message"
@@ -349,7 +349,7 @@ complete -c nebutra -n "__fish_seen_subcommand_from add" -f -a "--v0" -d "Fetch
349
349
  complete -c nebutra -n "__fish_seen_subcommand_from add" -f -a "--provider" -d "Specify a backend provider"
350
350
 
351
351
  # create command flags
352
- ${ni}
352
+ ${ai}
353
353
 
354
354
  # mcp command flags
355
355
  complete -c nebutra -n "__fish_seen_subcommand_from mcp" -f -a "--stdio" -d "Use stdio transport (default)"
@@ -364,16 +364,16 @@ complete -c nebutra -n "__fish_seen_subcommand_from completions" -f -a "install"
364
364
  complete -c nebutra -n "__fish_seen_subcommand_from schema" -f -a "--all" -d "Show full schema for all commands"
365
365
  complete -c nebutra -n "__fish_seen_subcommand_from schema" -f -a "--list" -d "List all available command names"
366
366
  complete -c nebutra -n "__fish_seen_subcommand_from schema" -f -a "--exit-codes" -d "Show exit codes reference"
367
- `}function jr(e){let r={bash:Tr,zsh:Ir,fish:$r}[e.toLowerCase()];r||(console.error(z.red(`Error: Unknown shell '${e}'. Supported: bash, zsh, fish`)),process.exit(c.INVALID_ARGS)),console.log(r())}async function oi(){let t=(process.env.SHELL||"/bin/bash").split("/").pop()||"bash";W.intro(z.bgCyan(z.black(" nebutra completions install ")));let r=W.spinner();r.start(z.cyan(`Detecting shell: ${t}...`));try{let n=null,o=null,i=null;if(t==="bash"?(n=Ie(Fe(),".bashrc"),o=Ie(Fe(),".bash_completion.d"),i="source ~/.bash_completion.d/nebutra"):t==="zsh"?(n=Ie(Fe(),".zshrc"),o=Ie(Fe(),".zsh/completions"),i="fpath=(~/.zsh/completions $fpath)"):t==="fish"?(o=Ie(Fe(),".config/fish/completions"),i="# Completions installed to ~/.config/fish/completions/nebutra.fish"):(r.stop(),W.log.warn(z.yellow(`Warning: Unsupported shell '${t}'. Please install completions manually.`)),jr("bash"),W.outro(z.cyan("Run 'nebutra completions bash' (or zsh/fish) to generate completions for your shell.")),process.exit(c.SUCCESS)),o){(await import("fs")).mkdirSync(o,{recursive:!0});let l=Ie(o,t==="fish"?"nebutra.fish":"nebutra"),u=t==="bash"?Tr():t==="zsh"?Ir():$r();Xa(l,u),r.stop(z.green(`Completion script installed to ${l}`))}n&&i&&t!=="fish"&&(!Ha(n)||!Ja(n,"utf8").includes("nebutra"))&&(Ya(n,(t==="bash"?`
367
+ `}function Nr(e){let r={bash:Ir,zsh:$r,fish:jr}[e.toLowerCase()];r||(console.error(z.red(`Error: Unknown shell '${e}'. Supported: bash, zsh, fish`)),process.exit(c.INVALID_ARGS)),console.log(r())}async function ii(){let t=(process.env.SHELL||"/bin/bash").split("/").pop()||"bash";W.intro(z.bgCyan(z.black(" nebutra completions install ")));let r=W.spinner();r.start(z.cyan(`Detecting shell: ${t}...`));try{let n=null,o=null,i=null;if(t==="bash"?(n=Ie(Fe(),".bashrc"),o=Ie(Fe(),".bash_completion.d"),i="source ~/.bash_completion.d/nebutra"):t==="zsh"?(n=Ie(Fe(),".zshrc"),o=Ie(Fe(),".zsh/completions"),i="fpath=(~/.zsh/completions $fpath)"):t==="fish"?(o=Ie(Fe(),".config/fish/completions"),i="# Completions installed to ~/.config/fish/completions/nebutra.fish"):(r.stop(),W.log.warn(z.yellow(`Warning: Unsupported shell '${t}'. Please install completions manually.`)),Nr("bash"),W.outro(z.cyan("Run 'nebutra completions bash' (or zsh/fish) to generate completions for your shell.")),process.exit(c.SUCCESS)),o){(await import("fs")).mkdirSync(o,{recursive:!0});let l=Ie(o,t==="fish"?"nebutra.fish":"nebutra"),u=t==="bash"?Ir():t==="zsh"?$r():jr();Za(l,u),r.stop(z.green(`Completion script installed to ${l}`))}n&&i&&t!=="fish"&&(!Xa(n)||!Qa(n,"utf8").includes("nebutra"))&&(Ja(n,(t==="bash"?`
368
368
  # nebutra completions
369
369
  [[ -f ~/.bash_completion.d/nebutra ]] && source ~/.bash_completion.d/nebutra`:`
370
370
  # nebutra completions
371
371
  fpath=(~/.zsh/completions $fpath)
372
372
  autoload -Uz compinit && compinit`)+`
373
- `),W.log.info(z.green(`Added nebutra completions to ${n}`))),W.log.info(z.cyan("Completions installed! Restart your shell or run:")),W.log.info(z.dim(` source "${t==="bash"?"~/.bashrc":"~/.zshrc"}"`)),W.outro(z.green("Installation complete!"))}catch(n){r.stop(),W.log.error(z.red("Error installing completions. You can manually add them by running:")),W.log.info(z.cyan(` nebutra completions ${t} >> ~/.${t}rc`)),n instanceof Error&&console.error(z.dim(n.message)),process.exit(c.ERROR)}}function Nr(e){e.command("completions [shell]").description("Generate or install shell completions").action(async t=>{!t||t==="install"?await oi():jr(t)})}import{spawn as ai}from"child_process";import{dirname as ii,resolve as si}from"path";import{fileURLToPath as ci}from"url";import*as ve from"@clack/prompts";import Ve from"picocolors";var li=ii(ci(import.meta.url));function di(){let e=[()=>si(li,"../../../create-sailor/dist/index.js")];for(let t of e)try{return t()}catch(r){a.debug("create-sailor binary resolution strategy failed",{error:r})}return"create-sailor"}function Ur(e){e.command("create [dir]").description("Scaffold a new Nebutra-Sailor project").allowUnknownOption(!0).action(async(t,r,n)=>{ve.intro(Ve.bgCyan(Ve.black(" nebutra create ")));try{let o=di(),i=t?[t]:[];if(n.args&&n.args.length>(t?1:0)){let u=n.args.slice(t?1:0);i.push(...u)}let s=ve.spinner();s.start(Ve.cyan(`Launching create-sailor${t?` in ${t}`:""}...`));let l=ai(process.execPath,[o,...i],{stdio:"inherit",env:{...process.env}});l.on("close",u=>{s.stop(),u===0&&ve.outro(Ve.green("Project created successfully! Run 'npm install && npm run dev' to get started.")),process.exit(u??0)}),l.on("error",u=>{s.stop(),a.error(`
373
+ `),W.log.info(z.green(`Added nebutra completions to ${n}`))),W.log.info(z.cyan("Completions installed! Restart your shell or run:")),W.log.info(z.dim(` source "${t==="bash"?"~/.bashrc":"~/.zshrc"}"`)),W.outro(z.green("Installation complete!"))}catch(n){r.stop(),W.log.error(z.red("Error installing completions. You can manually add them by running:")),W.log.info(z.cyan(` nebutra completions ${t} >> ~/.${t}rc`)),n instanceof Error&&console.error(z.dim(n.message)),process.exit(c.ERROR)}}function Ur(e){e.command("completions [shell]").description("Generate or install shell completions").action(async t=>{!t||t==="install"?await ii():Nr(t)})}import{spawn as si}from"child_process";import{dirname as ci,resolve as li}from"path";import{fileURLToPath as di}from"url";import*as ve from"@clack/prompts";import Ve from"picocolors";var ui=ci(di(import.meta.url));function mi(){let e=[()=>li(ui,"../../../create-sailor/dist/index.js")];for(let t of e)try{return t()}catch(r){a.debug("create-sailor binary resolution strategy failed",{error:r})}return"create-sailor"}function Lr(e){e.command("create [dir]").description("Scaffold a new Nebutra-Sailor project").allowUnknownOption(!0).action(async(t,r,n)=>{ve.intro(Ve.bgCyan(Ve.black(" nebutra create ")));try{let o=mi(),i=t?[t]:[];if(n.args&&n.args.length>(t?1:0)){let u=n.args.slice(t?1:0);i.push(...u)}let s=ve.spinner();s.start(Ve.cyan(`Launching create-sailor${t?` in ${t}`:""}...`));let l=si(process.execPath,[o,...i],{stdio:"inherit",env:{...process.env}});l.on("close",u=>{s.stop(),u===0&&ve.outro(Ve.green("Project created successfully! Run 'npm install && npm run dev' to get started.")),process.exit(u??0)}),l.on("error",u=>{s.stop(),a.error(`
374
374
  Failed to launch create-sailor: ${u.message}`),u.code==="ENOENT"&&(a.warn(`
375
- Tip: Ensure create-sailor is installed or available in your PATH.`),a.info(" Install globally: npm install -g create-sailor"),process.exit(c.NOT_FOUND)),process.exit(c.ERROR)})}catch(o){ve.log.error(Ve.red("Error: Unable to start create-sailor. Ensure it is properly installed.")),o instanceof Error&&a.error(o.message),process.exit(c.ERROR)}})}import*as st from"@clack/prompts";async function ui(e){d("Generating Prisma client"+"...","info");let r=await me("generate",{dryRun:e.dryRun,interactive:!e.dryRun});r.exitCode===0?d("Prisma client generated successfully","success"):(d("Failed to generate Prisma client","error"),process.exit(r.exitCode||1))}async function Nt(e,t){let r=t||{};if(e){d(`Creating migration: ${e}`,"info");let n=await me("migrate",{args:["dev","--name",e],dryRun:r.dryRun,interactive:!r.dryRun});n.exitCode===0?d(`Migration '${e}' created successfully`,"success"):(d(`Failed to create migration '${e}'`,"error"),process.exit(n.exitCode||1))}else{d("Running pending migrations...","info");let n=await me("migrate",{args:["deploy"],dryRun:r.dryRun,interactive:!r.dryRun});n.exitCode===0?d("All pending migrations completed","success"):(d("Migration deployment failed","error"),process.exit(n.exitCode||1))}}async function mi(e){d("Pushing schema to database...","info");let t=await me("db",{args:["push"],dryRun:e.dryRun,interactive:!e.dryRun});t.exitCode===0?d("Schema pushed successfully","success"):(d("Failed to push schema","error"),process.exit(t.exitCode||1))}async function pi(e){d("Seeding database...","info");let t=await me("db",{args:["seed"],dryRun:e.dryRun,interactive:!e.dryRun});t.exitCode===0?d("Database seeded successfully","success"):(d("Failed to seed database","error"),process.exit(t.exitCode||1))}async function fi(e){d("Launching Prisma Studio...","info");let t=await me("studio",{dryRun:e.dryRun,interactive:!0});t.exitCode!==0&&(d("Failed to launch Prisma Studio","error"),process.exit(t.exitCode||1))}async function gi(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let n=await st.confirm({message:"Reset database? This will delete all data.",initialValue:!1});(st.isCancel(n)||!n)&&(d("Reset cancelled","warn"),process.exit(c.CANCELLED))}else d("Database reset requires explicit --yes confirmation (use: nebutra db reset --yes)","error"),process.exit(c.INVALID_ARGS);d("Resetting database...","warn");let r=await me("migrate",{args:["reset",...e.yes?["--force"]:[]],dryRun:e.dryRun,interactive:!e.dryRun});r.exitCode===0?d("Database reset successfully","success"):(d("Failed to reset database","error"),process.exit(r.exitCode||1))}async function yi(e){d("Checking migration status...","info");let t=await me("migrate",{args:["status"],dryRun:e.dryRun,interactive:!e.dryRun});if(t.exitCode===0){if(e.format==="json")try{let r=JSON.parse(t.stdout);process.stdout.write(JSON.stringify(r,null,2)+`
376
- `)}catch{process.stdout.write(t.stdout)}}else d("Failed to check migration status","error"),process.exit(t.exitCode||1)}function Lr(e){e.command("db <verb> [args...]").description("Manage database schema, migrations, and state").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations (especially for reset)").option("--format <type>","Output format: json, plain","plain").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format};try{switch(r){case"generate":await ui(s);break;case"migrate":n.length>0?n[0]==="create"&&n[1]?await Nt(n[1],s):await Nt(n[0],s):await Nt(void 0,s);break;case"push":await mi(s);break;case"seed":await pi(s);break;case"studio":await fi(s);break;case"reset":await gi(s);break;case"status":await yi(s);break;default:d(`Unknown db subcommand: ${r}. Valid commands: generate, migrate, migrate create, push, seed, studio, reset, status`,"error"),process.exit(c.INVALID_ARGS)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Database command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
375
+ Tip: Ensure create-sailor is installed or available in your PATH.`),a.info(" Install globally: npm install -g create-sailor"),process.exit(c.NOT_FOUND)),process.exit(c.ERROR)})}catch(o){ve.log.error(Ve.red("Error: Unable to start create-sailor. Ensure it is properly installed.")),o instanceof Error&&a.error(o.message),process.exit(c.ERROR)}})}import*as st from"@clack/prompts";async function pi(e){d("Generating Prisma client"+"...","info");let r=await me("generate",{dryRun:e.dryRun,interactive:!e.dryRun});r.exitCode===0?d("Prisma client generated successfully","success"):(d("Failed to generate Prisma client","error"),process.exit(r.exitCode||1))}async function Nt(e,t){let r=t||{};if(e){d(`Creating migration: ${e}`,"info");let n=await me("migrate",{args:["dev","--name",e],dryRun:r.dryRun,interactive:!r.dryRun});n.exitCode===0?d(`Migration '${e}' created successfully`,"success"):(d(`Failed to create migration '${e}'`,"error"),process.exit(n.exitCode||1))}else{d("Running pending migrations...","info");let n=await me("migrate",{args:["deploy"],dryRun:r.dryRun,interactive:!r.dryRun});n.exitCode===0?d("All pending migrations completed","success"):(d("Migration deployment failed","error"),process.exit(n.exitCode||1))}}async function fi(e){d("Pushing schema to database...","info");let t=await me("db",{args:["push"],dryRun:e.dryRun,interactive:!e.dryRun});t.exitCode===0?d("Schema pushed successfully","success"):(d("Failed to push schema","error"),process.exit(t.exitCode||1))}async function gi(e){d("Seeding database...","info");let t=await me("db",{args:["seed"],dryRun:e.dryRun,interactive:!e.dryRun});t.exitCode===0?d("Database seeded successfully","success"):(d("Failed to seed database","error"),process.exit(t.exitCode||1))}async function yi(e){d("Launching Prisma Studio...","info");let t=await me("studio",{dryRun:e.dryRun,interactive:!0});t.exitCode!==0&&(d("Failed to launch Prisma Studio","error"),process.exit(t.exitCode||1))}async function hi(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let n=await st.confirm({message:"Reset database? This will delete all data.",initialValue:!1});(st.isCancel(n)||!n)&&(d("Reset cancelled","warn"),process.exit(c.CANCELLED))}else d("Database reset requires explicit --yes confirmation (use: nebutra db reset --yes)","error"),process.exit(c.INVALID_ARGS);d("Resetting database...","warn");let r=await me("migrate",{args:["reset",...e.yes?["--force"]:[]],dryRun:e.dryRun,interactive:!e.dryRun});r.exitCode===0?d("Database reset successfully","success"):(d("Failed to reset database","error"),process.exit(r.exitCode||1))}async function bi(e){d("Checking migration status...","info");let t=await me("migrate",{args:["status"],dryRun:e.dryRun,interactive:!e.dryRun});if(t.exitCode===0){if(e.format==="json")try{let r=JSON.parse(t.stdout);process.stdout.write(JSON.stringify(r,null,2)+`
376
+ `)}catch{process.stdout.write(t.stdout)}}else d("Failed to check migration status","error"),process.exit(t.exitCode||1)}function Dr(e){e.command("db <verb> [args...]").description("Manage database schema, migrations, and state").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations (especially for reset)").option("--format <type>","Output format: json, plain","plain").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format};try{switch(r){case"generate":await pi(s);break;case"migrate":n.length>0?n[0]==="create"&&n[1]?await Nt(n[1],s):await Nt(n[0],s):await Nt(void 0,s);break;case"push":await fi(s);break;case"seed":await gi(s);break;case"studio":await yi(s);break;case"reset":await hi(s);break;case"status":await bi(s);break;default:d(`Unknown db subcommand: ${r}. Valid commands: generate, migrate, migrate create, push, seed, studio, reset, status`,"error"),process.exit(c.INVALID_ARGS)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Database command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
377
377
  Examples:
378
378
  nebutra db generate Generate Prisma client
379
379
  nebutra db migrate Run all pending migrations
@@ -389,52 +389,52 @@ Flags:
389
389
  --yes Skip confirmations
390
390
  --format <type> Output format: json, plain (default: plain)
391
391
  `)}import*as _ from"@clack/prompts";import E from"picocolors";var $e=["landing-page","web","storybook","design-docs","sailor-docs","studio","docs","idp","mail-preview","gateway"];function ct(e){let t=`@nebutra/${e}`;if(!$e.includes(e)){let r=E.yellow(`Valid apps: ${$e.join(", ")}`);throw new Error(`Invalid app: ${E.red(e)}
392
- ${r}`)}return t}async function hi(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"dev",options:{app:e.app},task:e.app?"turbo dev":"turbo dev (all apps)"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app){ct(e.app);let r=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Starting dev server for ${E.bold(r)}...`));let n=await ge("dev",{filter:r});process.exit(n.exitCode)}e.quiet||_.log.info(E.cyan("Starting dev servers for all apps..."));let t=await ge("dev");process.exit(t.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}async function bi(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"build",options:{app:e.app,strict:e.strict},task:e.strict?"pnpm build:strict":"pnpm build"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app&&e.strict&&(_.log.error(E.red("Cannot use --strict with --app filter")),process.exit(c.INVALID_ARGS)),e.app){ct(e.app);let n=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Building ${E.bold(n)}...`));let o=await ge("build",{filter:n});process.exit(o.exitCode)}let t=e.strict?"build:strict":"build";if(!e.quiet){let n=e.strict?"Running strict build (with UI governance verification)...":"Building all apps...";_.log.info(E.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}async function vi(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"lint",options:{app:e.app,fix:e.fix},task:e.fix?"pnpm lint:fix":"pnpm lint"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app&&e.fix&&(_.log.error(E.red("Cannot use --fix with --app filter (lint:fix is global only)")),process.exit(c.INVALID_ARGS)),e.app){ct(e.app);let n=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Linting ${E.bold(n)}...`));let o=await x({command:"turbo",args:["run","lint","--filter",n],interactive:!0,label:`turbo lint --filter ${n}`,dryRun:e.dryRun});process.exit(o.exitCode)}let t=e.fix?"lint:fix":"lint";if(!e.quiet){let n=e.fix?"Fixing linting issues...":"Linting codebase...";_.log.info(E.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}async function wi(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"typecheck",options:{app:e.app},task:"turbo typecheck"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app){ct(e.app);let r=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Type-checking ${E.bold(r)}...`));let n=await ge("typecheck",{filter:r});process.exit(n.exitCode)}e.quiet||_.log.info(E.cyan("Type-checking all packages..."));let t=await ge("typecheck");process.exit(t.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}function Dr(e){e.command("dev").description("Start development servers (turbo dev)").option("--app <name>",`App to run: ${$e.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await hi({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})}),e.command("build").description("Build all apps (pnpm build or turbo build)").option("--app <name>",`App to build: ${$e.join(", ")}`).option("--strict","Run strict build with UI governance verification (pnpm build:strict)").option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await bi({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})}),e.command("lint").description("Lint with Biome (pnpm lint or pnpm lint:fix)").option("--app <name>",`App to lint: ${$e.join(", ")}`).option("--fix","Fix linting issues automatically").option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await vi({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})}),e.command("typecheck").description("Type-check with TypeScript (turbo typecheck)").option("--app <name>",`App to typecheck: ${$e.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await wi({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})})}import Fr from"fs";import Vr from"path";import Ut from"picocolors";var Lt=["smoke","golden","sleptons"],Si={smoke:{config:"e2e/playwright.config.ts",suiteDir:"e2e/smoke"},golden:{config:"e2e/playwright.golden.config.ts",suiteDir:"e2e/golden"},sleptons:{config:"e2e/playwright.sleptons.config.ts",suiteDir:"e2e/sleptons"}};async function Ri(e,t={}){Lt.includes(e)||(a.error(`Invalid suite: ${Ut.red(e)}. Valid: ${Lt.join(", ")}`),process.exit(c.INVALID_ARGS));let r=b(),{config:n,suiteDir:o}=Si[e],i=Vr.join(r,n),s=Vr.join(r,o);(!Fr.existsSync(s)||!Fr.existsSync(i))&&(a.error(`Suite ${Ut.red(e)} not found at ${o}.
392
+ ${r}`)}return t}async function vi(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"dev",options:{app:e.app},task:e.app?"turbo dev":"turbo dev (all apps)"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app){ct(e.app);let r=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Starting dev server for ${E.bold(r)}...`));let n=await ge("dev",{filter:r});process.exit(n.exitCode)}e.quiet||_.log.info(E.cyan("Starting dev servers for all apps..."));let t=await ge("dev");process.exit(t.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}async function wi(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"build",options:{app:e.app,strict:e.strict},task:e.strict?"pnpm build:strict":"pnpm build"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app&&e.strict&&(_.log.error(E.red("Cannot use --strict with --app filter")),process.exit(c.INVALID_ARGS)),e.app){ct(e.app);let n=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Building ${E.bold(n)}...`));let o=await ge("build",{filter:n});process.exit(o.exitCode)}let t=e.strict?"build:strict":"build";if(!e.quiet){let n=e.strict?"Running strict build (with UI governance verification)...":"Building all apps...";_.log.info(E.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Si(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"lint",options:{app:e.app,fix:e.fix},task:e.fix?"pnpm lint:fix":"pnpm lint"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app&&e.fix&&(_.log.error(E.red("Cannot use --fix with --app filter (lint:fix is global only)")),process.exit(c.INVALID_ARGS)),e.app){ct(e.app);let n=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Linting ${E.bold(n)}...`));let o=await x({command:"turbo",args:["run","lint","--filter",n],interactive:!0,label:`turbo lint --filter ${n}`,dryRun:e.dryRun});process.exit(o.exitCode)}let t=e.fix?"lint:fix":"lint";if(!e.quiet){let n=e.fix?"Fixing linting issues...":"Linting codebase...";_.log.info(E.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Ri(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"typecheck",options:{app:e.app},task:"turbo typecheck"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app){ct(e.app);let r=`@nebutra/${e.app}`;e.quiet||_.log.info(E.cyan(`Type-checking ${E.bold(r)}...`));let n=await ge("typecheck",{filter:r});process.exit(n.exitCode)}e.quiet||_.log.info(E.cyan("Type-checking all packages..."));let t=await ge("typecheck");process.exit(t.exitCode)}catch(t){t instanceof Error?_.log.error(E.red(t.message)):_.log.error(E.red("Unknown error occurred")),process.exit(c.ERROR)}}function Fr(e){e.command("dev").description("Start development servers (turbo dev)").option("--app <name>",`App to run: ${$e.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await vi({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})}),e.command("build").description("Build all apps (pnpm build or turbo build)").option("--app <name>",`App to build: ${$e.join(", ")}`).option("--strict","Run strict build with UI governance verification (pnpm build:strict)").option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await wi({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})}),e.command("lint").description("Lint with Biome (pnpm lint or pnpm lint:fix)").option("--app <name>",`App to lint: ${$e.join(", ")}`).option("--fix","Fix linting issues automatically").option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await Si({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})}),e.command("typecheck").description("Type-check with TypeScript (turbo typecheck)").option("--app <name>",`App to typecheck: ${$e.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await Ri({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})})}import Vr from"fs";import Mr from"path";import Ut from"picocolors";var Lt=["smoke","golden","sleptons"],ki={smoke:{config:"e2e/playwright.config.ts",suiteDir:"e2e/smoke"},golden:{config:"e2e/playwright.golden.config.ts",suiteDir:"e2e/golden"},sleptons:{config:"e2e/playwright.sleptons.config.ts",suiteDir:"e2e/sleptons"}};async function Ei(e,t={}){Lt.includes(e)||(a.error(`Invalid suite: ${Ut.red(e)}. Valid: ${Lt.join(", ")}`),process.exit(c.INVALID_ARGS));let r=b(),{config:n,suiteDir:o}=ki[e],i=Mr.join(r,n),s=Mr.join(r,o);(!Vr.existsSync(s)||!Vr.existsSync(i))&&(a.error(`Suite ${Ut.red(e)} not found at ${o}.
393
393
  Expected config: ${n}
394
394
  Remediation: scaffold the suite (analogous to 'nebutra workflow init <provider>')
395
- or restore the directory from git.`),process.exit(c.NOT_FOUND)),t.dryRun&&(O({mode:"dry-run",command:`e2e ${e}`,task:`pnpm exec playwright test --config ${n}`}),process.exit(c.DRY_RUN_OK)),t.quiet||a.info(`Running Playwright suite: ${Ut.bold(e)}`);let l=await x({command:"pnpm",args:["exec","playwright","test","--config",n],interactive:!0,label:`playwright ${e}`});process.exit(l.exitCode)}function Mr(e){e.command("e2e <suite>").description(`Run a Playwright suite (${Lt.join(" | ")})`).option("--dry-run","Preview the command that would run (exit code 10)").action(async(t,r)=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await Ri(t,{dryRun:r.dryRun||!1,quiet:n.quiet||!1})})}import g from"picocolors";var ki=process.env.NEBUTRA_ECOSYSTEM_URL||"https://api.nebutra.com/ecosystem",Br=process.env.NEBUTRA_ECOSYSTEM_TOKEN||"";async function P(e,t={}){let{method:r="GET",body:n,dryRun:o=!1,token:i=Br}=t,s=`${ki}${e}`;if(o)return d(`[DRY RUN] ${r} ${s}`),n&&d(`Body: ${JSON.stringify(n)}`),O({mode:"dry-run",method:r,url:s,...n&&{body:n}}),{ok:!0,status:200,json:async()=>({dryRun:!0})};let l={"Content-Type":"application/json"};i&&(l.Authorization=`Bearer ${i}`);try{let u=await fetch(s,{method:r,headers:l,...n&&{body:JSON.stringify(n)}});if(!u.ok){let m=await u.text();throw new Error(`${u.status}: ${m}`)}return u}catch(u){throw a.error(`Ecosystem API error: ${u}`),u}}function Ei(e={}){let t=[{name:"README.md exists",pass:!0},{name:"License file exists",pass:!0},{name:"package.json has description",pass:!0},{name:"No security vulnerabilities",pass:!0},{name:"TypeScript passes",pass:!0}];return e.skipChecks?{valid:!0,checks:t}:{valid:t.every(n=>n.pass),checks:t}}async function Ci(e){a.info(g.cyan(`\u{1F4CA} Ecosystem Status Dashboard
396
- `));try{let r=await(await P("/status")).json();return e.format,c.SUCCESS}catch(t){return a.error(`Failed to fetch ecosystem status: ${t}`),c.ERROR}}async function Ai(e){a.info(g.cyan(`\u{1F517} Connect to Nebutra Ecosystem
397
- `));let t=e.token||Br;!t&&!e.yes&&(a.warn(`No NEBUTRA_ECOSYSTEM_TOKEN found. Starting OAuth flow...
395
+ or restore the directory from git.`),process.exit(c.NOT_FOUND)),t.dryRun&&(O({mode:"dry-run",command:`e2e ${e}`,task:`pnpm exec playwright test --config ${n}`}),process.exit(c.DRY_RUN_OK)),t.quiet||a.info(`Running Playwright suite: ${Ut.bold(e)}`);let l=await x({command:"pnpm",args:["exec","playwright","test","--config",n],interactive:!0,label:`playwright ${e}`});process.exit(l.exitCode)}function Br(e){e.command("e2e <suite>").description(`Run a Playwright suite (${Lt.join(" | ")})`).option("--dry-run","Preview the command that would run (exit code 10)").action(async(t,r)=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await Ei(t,{dryRun:r.dryRun||!1,quiet:n.quiet||!1})})}import g from"picocolors";var Ci=process.env.NEBUTRA_ECOSYSTEM_URL||"https://api.nebutra.com/ecosystem",Gr=process.env.NEBUTRA_ECOSYSTEM_TOKEN||"";async function P(e,t={}){let{method:r="GET",body:n,dryRun:o=!1,token:i=Gr}=t,s=`${Ci}${e}`;if(o)return d(`[DRY RUN] ${r} ${s}`),n&&d(`Body: ${JSON.stringify(n)}`),O({mode:"dry-run",method:r,url:s,...n&&{body:n}}),{ok:!0,status:200,json:async()=>({dryRun:!0})};let l={"Content-Type":"application/json"};i&&(l.Authorization=`Bearer ${i}`);try{let u=await fetch(s,{method:r,headers:l,...n&&{body:JSON.stringify(n)}});if(!u.ok){let m=await u.text();throw new Error(`${u.status}: ${m}`)}return u}catch(u){throw a.error(`Ecosystem API error: ${u}`),u}}function Ai(e={}){let t=[{name:"README.md exists",pass:!0},{name:"License file exists",pass:!0},{name:"package.json has description",pass:!0},{name:"No security vulnerabilities",pass:!0},{name:"TypeScript passes",pass:!0}];return e.skipChecks?{valid:!0,checks:t}:{valid:t.every(n=>n.pass),checks:t}}async function xi(e){a.info(g.cyan(`\u{1F4CA} Ecosystem Status Dashboard
396
+ `));try{let r=await(await P("/status")).json();return e.format,c.SUCCESS}catch(t){return a.error(`Failed to fetch ecosystem status: ${t}`),c.ERROR}}async function Oi(e){a.info(g.cyan(`\u{1F517} Connect to Nebutra Ecosystem
397
+ `));let t=e.token||Gr;!t&&!e.yes&&(a.warn(`No NEBUTRA_ECOSYSTEM_TOKEN found. Starting OAuth flow...
398
398
  `),a.info("Visit: "+g.blue("https://nebutra.com/oauth/authorize?scope=ecosystem")),a.info("Then paste your token below:"),t="token_example_"+Math.random().toString(36).slice(2));let r=e.org||"org_default";try{let o=await(await P("/projects/connect",{method:"POST",body:{projectName:"My Project",repository:"https://github.com/user/project",orgId:r},dryRun:e.dryRun,token:t})).json();return e.dryRun?(d("[DRY RUN] Would connect project to ecosystem","success"),c.SUCCESS):(a.success(`\u2713 Connected to Nebutra Ecosystem
399
399
  `),a.info(`Project ID: ${g.cyan(o.projectId)}`),a.info(`Organization: ${g.cyan(r)}`),a.info(`Ecosystem Config: ${g.cyan(".nebutra/ecosystem.json")}
400
- `),a.info(`Next steps: Run ${g.yellow("nebutra ecosystem publish")} to share your project`),c.SUCCESS)}catch(n){return a.error(`Connection failed: ${n}`),c.ERROR}}async function xi(e){a.info(g.cyan(`\u{1F4E4} Publish to Ecosystem Marketplace
401
- `));let t=e.tag||"latest",r=e.visibility||"public",n=Ei();a.info(`${g.bold("Pre-Publish Checklist")}
400
+ `),a.info(`Next steps: Run ${g.yellow("nebutra ecosystem publish")} to share your project`),c.SUCCESS)}catch(n){return a.error(`Connection failed: ${n}`),c.ERROR}}async function _i(e){a.info(g.cyan(`\u{1F4E4} Publish to Ecosystem Marketplace
401
+ `));let t=e.tag||"latest",r=e.visibility||"public",n=Ai();a.info(`${g.bold("Pre-Publish Checklist")}
402
402
  `);for(let o of n.checks){let i=o.pass?g.green("\u2713"):g.red("\u2717")}if(!n.valid)return a.error(`
403
403
  Fix the checks above before publishing`),c.ERROR;if(r==="public"&&!e.yes&&(a.info(`This project will be ${g.yellow("publicly listed")} in the ecosystem`),a.info(`Continue? Run with ${g.yellow("--yes")} to skip confirmation`),!e.yes))return c.CANCELLED;try{let i=await(await P("/projects/publish",{method:"POST",body:{projectName:"My Template",description:"A production-ready SaaS template",repository:"https://github.com/user/project",tags:["saas","nextjs","ai"],tag:t,visibility:r},dryRun:e.dryRun})).json();return e.dryRun?(d("[DRY RUN] Would publish to ecosystem","success"),c.SUCCESS):(a.success(`\u2713 Published successfully!
404
404
  `),a.info(`Marketplace URL: ${g.blue(`https://nebutra.com/templates/${i.projectId}`)}`),a.info(`Visibility: ${r}`),a.info(`Tag: ${t}
405
- `),c.SUCCESS)}catch(o){return a.error(`Publish failed: ${o}`),c.ERROR}}async function Oi(e){a.info(g.cyan(`\u{1F4DA} Template Marketplace
406
- `));try{let r=await(await P(`/templates?category=${e.category||""}&sort=${e.sort||"downloads"}`)).json();return e.format==="json"||a.info(`Run ${g.yellow("nebutra ecosystem templates info <id>")} for details`),c.SUCCESS}catch(t){return a.error(`Failed to list templates: ${t}`),c.ERROR}}async function _i(e,t){a.info(g.cyan(`\u{1F50D} Searching templates for "${e}"
407
- `));try{let n=await(await P(`/templates/search?q=${encodeURIComponent(e)}`)).json();return t.format,c.SUCCESS}catch(r){return a.error(`Search failed: ${r}`),c.ERROR}}async function Pi(e){a.info(g.cyan(`\u{1F4D6} Template Details
408
- `));try{let r=await(await P(`/templates/${e}`)).json();return a.info(`Install: ${g.yellow("nebutra ecosystem templates install multi-tenant-saas")}`),c.SUCCESS}catch(t){return a.error(`Failed to fetch template info: ${t}`),c.ERROR}}async function Ti(e,t){a.info(g.cyan(`\u2B07\uFE0F Installing template "${e}"
405
+ `),c.SUCCESS)}catch(o){return a.error(`Publish failed: ${o}`),c.ERROR}}async function Pi(e){a.info(g.cyan(`\u{1F4DA} Template Marketplace
406
+ `));try{let r=await(await P(`/templates?category=${e.category||""}&sort=${e.sort||"downloads"}`)).json();return e.format==="json"||a.info(`Run ${g.yellow("nebutra ecosystem templates info <id>")} for details`),c.SUCCESS}catch(t){return a.error(`Failed to list templates: ${t}`),c.ERROR}}async function Ti(e,t){a.info(g.cyan(`\u{1F50D} Searching templates for "${e}"
407
+ `));try{let n=await(await P(`/templates/search?q=${encodeURIComponent(e)}`)).json();return t.format,c.SUCCESS}catch(r){return a.error(`Search failed: ${r}`),c.ERROR}}async function Ii(e){a.info(g.cyan(`\u{1F4D6} Template Details
408
+ `));try{let r=await(await P(`/templates/${e}`)).json();return a.info(`Install: ${g.yellow("nebutra ecosystem templates install multi-tenant-saas")}`),c.SUCCESS}catch(t){return a.error(`Failed to fetch template info: ${t}`),c.ERROR}}async function $i(e,t){a.info(g.cyan(`\u2B07\uFE0F Installing template "${e}"
409
409
  `));try{let r=await P(`/templates/${e}/install`,{method:"POST",body:{projectName:"my-saas"},dryRun:t.dryRun});return t.dryRun?(d("[DRY RUN] Would install template","success"),c.SUCCESS):(a.success(`\u2713 Template installed!
410
- `),a.info("Project: ./my-saas"),a.info(`Next: ${g.yellow("cd my-saas && pnpm install && pnpm dev")}`),c.SUCCESS)}catch(r){return a.error(`Installation failed: ${r}`),c.ERROR}}async function Ii(e){a.info(g.cyan(`\u{1F4A1} Ideas Marketplace
411
- `));try{let r=await(await P(`/ideas?status=${e.status||""}&sort=${e.sort||"recent"}`)).json();return e.format==="json"||(a.info(`Vote: ${g.yellow("nebutra ecosystem ideas vote <id>")}`),a.info(`Claim: ${g.yellow("nebutra ecosystem ideas claim <id>")}`)),c.SUCCESS}catch(t){return a.error(`Failed to list ideas: ${t}`),c.ERROR}}async function $i(e){if(a.info(g.cyan(`\u2728 Submit New Idea
410
+ `),a.info("Project: ./my-saas"),a.info(`Next: ${g.yellow("cd my-saas && pnpm install && pnpm dev")}`),c.SUCCESS)}catch(r){return a.error(`Installation failed: ${r}`),c.ERROR}}async function ji(e){a.info(g.cyan(`\u{1F4A1} Ideas Marketplace
411
+ `));try{let r=await(await P(`/ideas?status=${e.status||""}&sort=${e.sort||"recent"}`)).json();return e.format==="json"||(a.info(`Vote: ${g.yellow("nebutra ecosystem ideas vote <id>")}`),a.info(`Claim: ${g.yellow("nebutra ecosystem ideas claim <id>")}`)),c.SUCCESS}catch(t){return a.error(`Failed to list ideas: ${t}`),c.ERROR}}async function Ni(e){if(a.info(g.cyan(`\u2728 Submit New Idea
412
412
  `)),!e.title||!e.description)return a.error("Missing required fields: --title and --description"),c.INVALID_ARGS;try{let r=await(await P("/ideas",{method:"POST",body:{title:e.title,description:e.description,tags:e.tags?.split(",")||[],authorId:"user_current"},dryRun:e.dryRun})).json();return e.dryRun?(d("[DRY RUN] Would submit idea","success"),c.SUCCESS):(a.success(`\u2713 Idea submitted!
413
413
  `),a.info(`Idea URL: ${g.blue(`https://nebutra.com/ideas/${r.ideaId}`)}`),a.info(`Start voting and discussing! Community will help shape it.
414
- `),c.SUCCESS)}catch(t){return a.error(`Submission failed: ${t}`),c.ERROR}}async function ji(e,t){a.info(g.cyan(`\u{1F44D} Voting on idea "${e}"
414
+ `),c.SUCCESS)}catch(t){return a.error(`Submission failed: ${t}`),c.ERROR}}async function Ui(e,t){a.info(g.cyan(`\u{1F44D} Voting on idea "${e}"
415
415
  `));try{let r=await P(`/ideas/${e}/vote`,{method:"POST",body:{action:"upvote"},dryRun:t.dryRun});return t.dryRun?(d("[DRY RUN] Would upvote idea","success"),c.SUCCESS):(a.success(`\u2713 Vote recorded! This idea now has more momentum.
416
- `),c.SUCCESS)}catch(r){return a.error(`Vote failed: ${r}`),c.ERROR}}async function Ni(e,t){a.info(g.cyan(`\u{1F3AF} Claiming idea "${e}"
416
+ `),c.SUCCESS)}catch(r){return a.error(`Vote failed: ${r}`),c.ERROR}}async function Li(e,t){a.info(g.cyan(`\u{1F3AF} Claiming idea "${e}"
417
417
  `));try{let r=await P(`/ideas/${e}/claim`,{method:"POST",body:{claimerId:"user_current",status:"in-progress"},dryRun:t.dryRun});return t.dryRun?(d("[DRY RUN] Would claim idea","success"),c.SUCCESS):(a.success(`\u2713 Idea claimed! You're now working on this.
418
- `),a.info("Post updates in the comments to keep the community informed."),c.SUCCESS)}catch(r){return a.error(`Claim failed: ${r}`),c.ERROR}}async function Ui(e,t){if(a.info(g.cyan(`\u{1F4AC} Adding comment to idea "${e}"
418
+ `),a.info("Post updates in the comments to keep the community informed."),c.SUCCESS)}catch(r){return a.error(`Claim failed: ${r}`),c.ERROR}}async function Di(e,t){if(a.info(g.cyan(`\u{1F4AC} Adding comment to idea "${e}"
419
419
  `)),!t.message)return a.error("Missing --message parameter"),c.INVALID_ARGS;try{let r=await P(`/ideas/${e}/comments`,{method:"POST",body:{authorId:"user_current",message:t.message},dryRun:t.dryRun});return t.dryRun?(d("[DRY RUN] Would post comment","success"),c.SUCCESS):(a.success(`\u2713 Comment posted!
420
- `),c.SUCCESS)}catch(r){return a.error(`Comment failed: ${r}`),c.ERROR}}async function Li(e){a.info(g.cyan(`\u{1F465} Legacy Member Directory
421
- `));try{let r=await(await P(`/opc?skill=${e.skill||""}&industry=${e.industry||""}&sort=${e.sort||"active"}`)).json();return e.format==="json"||(a.info(`View profile: ${g.yellow("nebutra ecosystem opc profile <handle>")}`),a.info(`Register: ${g.yellow("nebutra ecosystem opc register")}`)),c.SUCCESS}catch(t){return a.error(`Failed to list members: ${t}`),c.ERROR}}async function Di(){a.info(g.cyan(`\u{1F464} Legacy Member Profile
422
- `));try{let t=await(await P("/opc/me")).json();return a.info(`Edit profile: ${g.yellow("nebutra ecosystem opc register")}`),c.SUCCESS}catch(e){return a.error(`Failed to load profile: ${e}`),c.ERROR}}async function Fi(e){a.info(g.cyan(`\u{1F4DD} Register Legacy Member Profile
420
+ `),c.SUCCESS)}catch(r){return a.error(`Comment failed: ${r}`),c.ERROR}}async function Fi(e){a.info(g.cyan(`\u{1F465} Legacy Member Directory
421
+ `));try{let r=await(await P(`/opc?skill=${e.skill||""}&industry=${e.industry||""}&sort=${e.sort||"active"}`)).json();return e.format==="json"||(a.info(`View profile: ${g.yellow("nebutra ecosystem opc profile <handle>")}`),a.info(`Register: ${g.yellow("nebutra ecosystem opc register")}`)),c.SUCCESS}catch(t){return a.error(`Failed to list members: ${t}`),c.ERROR}}async function Vi(){a.info(g.cyan(`\u{1F464} Legacy Member Profile
422
+ `));try{let t=await(await P("/opc/me")).json();return a.info(`Edit profile: ${g.yellow("nebutra ecosystem opc register")}`),c.SUCCESS}catch(e){return a.error(`Failed to load profile: ${e}`),c.ERROR}}async function Mi(e){a.info(g.cyan(`\u{1F4DD} Register Legacy Member Profile
423
423
  `));let t={name:"Your Name",handle:"your-handle",bio:"Building amazing products",skills:["nextjs","ai","devtools"],industry:"startup"};if(e.dryRun)return a.info(`[DRY RUN] Would register profile:
424
424
  `),c.SUCCESS;if(!e.yes)return a.info("This will create your public legacy member profile."),a.info(`Run with ${g.yellow("--yes")} to confirm`),c.CANCELLED;try{let r=await P("/opc/register",{method:"POST",body:t});return a.success(`\u2713 Legacy member profile created!
425
- `),a.info(`View at: ${g.blue("https://nebutra.com/members/your-handle")}`),a.info(`Compatibility command: ${g.yellow("nebutra ecosystem opc profile --share")}`),c.SUCCESS}catch(r){return a.error(`Registration failed: ${r}`),c.ERROR}}async function Vi(e){a.info(g.cyan(`\u2B50 Project Showcase
426
- `));try{let r=await(await P(`/showcase?category=${e.category||""}&featured=${e.featured?"true":""}`)).json();return e.format==="json"||(a.info(`Vote: ${g.yellow("nebutra ecosystem showcase vote <id>")}`),a.info(`Submit yours: ${g.yellow("nebutra ecosystem showcase submit")}`)),c.SUCCESS}catch(t){return a.error(`Failed to list showcase: ${t}`),c.ERROR}}async function Mi(e){a.info(g.cyan(`\u{1F389} Submit Project to Showcase
425
+ `),a.info(`View at: ${g.blue("https://nebutra.com/members/your-handle")}`),a.info(`Compatibility command: ${g.yellow("nebutra ecosystem opc profile --share")}`),c.SUCCESS}catch(r){return a.error(`Registration failed: ${r}`),c.ERROR}}async function Bi(e){a.info(g.cyan(`\u2B50 Project Showcase
426
+ `));try{let r=await(await P(`/showcase?category=${e.category||""}&featured=${e.featured?"true":""}`)).json();return e.format==="json"||(a.info(`Vote: ${g.yellow("nebutra ecosystem showcase vote <id>")}`),a.info(`Submit yours: ${g.yellow("nebutra ecosystem showcase submit")}`)),c.SUCCESS}catch(t){return a.error(`Failed to list showcase: ${t}`),c.ERROR}}async function Gi(e){a.info(g.cyan(`\u{1F389} Submit Project to Showcase
427
427
  `));let t={projectName:"My Awesome Project",url:"https://example.com",description:"A production product built with Nebutra",monthlyVisitors:1e4,builtWith:["nextjs","tailwind","prisma"]};if(!e.yes)return a.info("This will add your project to the public showcase."),a.info(`Run with ${g.yellow("--yes")} to confirm`),c.CANCELLED;try{let r=await P("/showcase/submit",{method:"POST",body:t,dryRun:e.dryRun});return e.dryRun?(d("[DRY RUN] Would submit to showcase","success"),c.SUCCESS):(a.success(`\u2713 Project added to showcase!
428
- `),a.info(`View at: ${g.blue("https://nebutra.com/showcase/my-project")}`),a.info("Community can now discover your work!"),c.SUCCESS)}catch(r){return a.error(`Submission failed: ${r}`),c.ERROR}}async function Bi(e,t){a.info(g.cyan(`\u{1F44D} Voting on showcase project "${e}"
428
+ `),a.info(`View at: ${g.blue("https://nebutra.com/showcase/my-project")}`),a.info("Community can now discover your work!"),c.SUCCESS)}catch(r){return a.error(`Submission failed: ${r}`),c.ERROR}}async function qi(e,t){a.info(g.cyan(`\u{1F44D} Voting on showcase project "${e}"
429
429
  `));try{let r=await P(`/showcase/${e}/vote`,{method:"POST",body:{action:"upvote"},dryRun:t.dryRun});return t.dryRun?(d("[DRY RUN] Would upvote project","success"),c.SUCCESS):(a.success(`\u2713 Vote recorded! You're supporting this project.
430
- `),c.SUCCESS)}catch(r){return a.error(`Vote failed: ${r}`),c.ERROR}}async function Gi(e){a.info(g.cyan(`\u{1F504} Sync with Ecosystem
430
+ `),c.SUCCESS)}catch(r){return a.error(`Vote failed: ${r}`),c.ERROR}}async function Ki(e){a.info(g.cyan(`\u{1F504} Sync with Ecosystem
431
431
  `));let t=!e.push,r=e.push?"push":"pull";try{let n=await P("/sync",{method:"POST",body:{direction:r,timestamp:new Date().toISOString()},dryRun:e.dryRun});return e.dryRun?(a.info(g.green(`\u2713 [DRY RUN] Would sync (${r})
432
432
  `)),c.SUCCESS):(a.success(`\u2713 Synced!
433
- `),t?a.info("Downloaded: ecosystem config, stats, badges"):a.info("Uploaded: project updates, metrics"),c.SUCCESS)}catch(n){return a.error(`Sync failed: ${n}`),c.ERROR}}function Gr(e){let t=e.command("ecosystem").description("Nebutra ecosystem marketplace, ideas, showcase, and sync workflows");t.command("status").description("Ecosystem overview dashboard").option("--format <format>","Output format: json","text").action(async s=>{await Ci(s)}),t.command("connect").description("Connect local project to Nebutra ecosystem").option("--token <token>","Ecosystem API token").option("--org <orgId>","Organization ID").option("--dry-run","Preview without making changes").option("--yes","Skip confirmations").action(async s=>{await Ai(s)}),t.command("publish").description("Publish project/template to ecosystem marketplace").option("--tag <tag>","Release tag: latest|beta|canary","latest").option("--visibility <visibility>","Project visibility: public|private|unlisted","public").option("--dry-run","Preview without making changes").option("--yes","Skip confirmations").action(async s=>{await xi(s)});let r=t.command("templates").description("Template marketplace");r.command("list").description("Browse available templates").option("--category <category>","Filter by category").option("--sort <sort>","Sort by: stars|downloads|recent","downloads").option("--format <format>","Output format","text").action(async s=>{await Oi(s)}),r.command("search <query>").description("Search templates").option("--format <format>","Output format","text").action(async(s,l)=>{await _i(s,l)}),r.command("info <id>").description("Template details").action(async s=>{await Pi(s)}),r.command("install <id>").description("Install/fork a template").option("--dry-run","Preview without making changes").action(async(s,l)=>{await Ti(s,l)});let n=t.command("ideas").description("Ideas marketplace");n.command("list").description("Browse ideas").option("--status <status>","Filter by status").option("--sort <sort>","Sort by: votes|recent|trending","recent").option("--format <format>","Output format","text").action(async s=>{await Ii(s)}),n.command("submit").description("Submit new idea").option("--title <title>","Idea title").option("--description <description>","Idea description").option("--tags <tags>","Comma-separated tags").option("--dry-run","Preview without making changes").action(async s=>{await $i(s)}),n.command("vote <id>").description("Upvote an idea").option("--dry-run","Preview without making changes").action(async(s,l)=>{await ji(s,l)}),n.command("claim <id>").description("Claim an idea to work on").option("--dry-run","Preview without making changes").action(async(s,l)=>{await Ni(s,l)}),n.command("comment <id>").description("Comment on an idea").option("--message <message>","Comment text").option("--dry-run","Preview without making changes").action(async(s,l)=>{await Ui(s,l)});let o=t.command("opc",{hidden:!0}).description("Legacy member directory");o.command("list").description("Browse legacy member profiles").option("--skill <skill>","Filter by skill tag").option("--industry <industry>","Filter by industry").option("--sort <sort>","Sort by: active|joined","active").option("--format <format>","Output format","text").action(async s=>{await Li(s)}),o.command("profile").description("View/edit your legacy member profile").action(async()=>{await Di()}),o.command("register").description("Register a legacy member profile").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async s=>{await Fi(s)});let i=t.command("showcase").description("Project showcase");i.command("list").description("Browse showcased projects").option("--category <category>","Filter by category").option("--featured","Show featured only").option("--format <format>","Output format","text").action(async s=>{await Vi(s)}),i.command("submit").description("Submit your project to showcase").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async s=>{await Mi(s)}),i.command("vote <id>").description("Upvote a project (Product Hunt style)").option("--dry-run","Preview without making changes").action(async(s,l)=>{await Bi(s,l)}),t.command("sync").description("Sync local project with ecosystem").option("--pull","Pull remote changes").option("--push","Push local changes").option("--dry-run","Preview without making changes").action(async s=>{await Gi(s)})}import{existsSync as lt,readFileSync as qr,writeFileSync as qi}from"fs";import{resolve as dt}from"path";import*as Ce from"@clack/prompts";import Ki from"picocolors";function ut(e){let t=dt(e,".env.example");if(!lt(t))throw new Error(`.env.example not found at ${t}`);let r=qr(t,"utf-8"),n={};for(let o of r.split(`
434
- `)){if(o.trim().startsWith("#")||!o.trim())continue;let i=o.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(i){let[,s,l]=i;n[s]=l.replace(/^["'](.*)["']$/,"$1")}}return n}function Dt(e){let t=dt(e,".env.local"),r=dt(e,".env"),n=lt(t)?t:r;if(!lt(n))return{};let o=qr(n,"utf-8"),i={};for(let s of o.split(`
435
- `)){if(s.trim().startsWith("#")||!s.trim())continue;let l=s.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(l){let[,u,m]=l;i[u]=m.replace(/^["'](.*)["']$/,"$1")}}return i}function zi(e,t){return["SECRET","KEY","TOKEN","PASSWORD"].some(o=>e.toUpperCase().includes(o))&&t.length>0}function Wi(e){return e.length<=8?"*".repeat(Math.max(e.length,4)):e.substring(0,4)+"*".repeat(e.length-8)+e.substring(e.length-4)}async function Yi(e){d("Validating environment variables...","info");let t=b(),r=ut(t),n=Dt(t),o=process.env,i={},s=!0;for(let l of Object.keys(r)){let u=l in n||l in o;i[l]=u,u||(s=!1)}if(e.format==="json")k({valid:s,checked:Object.keys(r).length,missing:Object.entries(i).filter(([,l])=>!l).map(([l])=>l)},{format:"json"});else{tt("Environment Validation");let l=Object.entries(i).filter(([,u])=>!u).map(([u])=>u);if(l.length===0)d("All required environment variables are set","success");else{d(`${l.length} missing environment variable(s):`,"warn");for(let u of l)d(` - ${u}`,"warn")}}s||process.exit(c.CONFIG_ERROR)}async function Hi(e){let t=b(),r=ut(t),n=dt(t,".env.local");if(lt(n)&&!e.yes&&!e.dryRun){let u=await Ce.confirm({message:".env.local already exists. Overwrite?",initialValue:!1});(Ce.isCancel(u)||!u)&&(d("Template generation cancelled","warn"),process.exit(c.CANCELLED))}d("Generating .env.local from template...","info");let o={},i=0,s=Object.keys(r).length;for(let[u,m]of Object.entries(r))if(i++,e.yes)o[u]=m;else if(process.stdin.isTTY===!0){let f=`[${i}/${s}] ${u}`,y=await Ce.text({message:f,defaultValue:m});Ce.isCancel(y)&&(d("Template generation cancelled","warn"),process.exit(c.CANCELLED)),o[u]=y}else o[u]=m;let l=Object.entries(o).map(([u,m])=>{let y=/[\s=]/.test(m)?`"${m}"`:m;return`${u}=${y}`}).join(`
436
- `);e.dryRun?(d("Dry-run: would write .env.local","info"),k(l,{format:"plain"})):(qi(n,l+`
437
- `),d(`Environment template written to ${n}`,"success"))}async function Ji(e){d("Comparing environment variables...","info");let t=b(),r=ut(t),n=Dt(t),o=[],i=[],s=[];for(let l of Object.keys(r))l in n?s.push(l):o.push(l);for(let l of Object.keys(n))l in r||i.push(l);if(e.format==="json")k({matching:s.length,missing:o.length,extra:i.length,missing_vars:o,extra_vars:i},{format:"json"});else{if(tt("Environment Diff"),s.length>0&&d(`Matching (${s.length}): ${s.join(", ")}`,"success"),o.length>0){d(`Missing (${o.length}):`,"warn");for(let l of o)d(` - ${l}`,"warn")}if(i.length>0){d(`Extra (${i.length}):`,"info");for(let l of i)d(` - ${l}`,"info")}}}async function Xi(e){d("Reading environment variables...","info");let t=b(),r=Dt(t),n=ut(t),o={};for(let i of Object.keys(n))if(i in r){let s=r[i];o[i]=zi(i,s)?Wi(s):s||"(empty)"}else o[i]="(not set)";if(e.format==="json"){let i={};for(let[s,l]of Object.entries(o))i[s]=l;k(i,{format:"json"})}else{tt("Current Environment Variables");let i=Object.entries(o).map(([s,l])=>({Variable:Ki.cyan(s),Value:l}));k(i,{format:"table"}),d("Note: Sensitive values (KEY, TOKEN, SECRET, PASSWORD) are masked","info")}}function Kr(e){e.command("env <verb>").description("Manage environment variables and configuration").option("--dry-run","Show what would be done without making changes").option("--yes","Skip confirmations and use defaults").option("--format <type>","Output format: json, plain","plain").action(async(r,n)=>{let o=n.optsWithGlobals?.(),i={dryRun:n.dryRun||o?.dryRun,yes:n.yes||o?.yes,format:n.format||o?.format};try{switch(r){case"validate":await Yi(i);break;case"template":await Hi(i);break;case"diff":await Ji(i);break;case"show":await Xi(i);break;default:d(`Unknown env subcommand: ${r}. Valid commands: validate, template, diff, show`,"error"),process.exit(c.INVALID_ARGS)}}catch(s){let l=s instanceof Error?s.message:String(s);d(`Environment command failed: ${l}`,"error"),A("Full error",{error:s}),process.exit(c.ERROR)}}).addHelpText("after",`
433
+ `),t?a.info("Downloaded: ecosystem config, stats, badges"):a.info("Uploaded: project updates, metrics"),c.SUCCESS)}catch(n){return a.error(`Sync failed: ${n}`),c.ERROR}}function qr(e){let t=e.command("ecosystem").description("Nebutra ecosystem marketplace, ideas, showcase, and sync workflows");t.command("status").description("Ecosystem overview dashboard").option("--format <format>","Output format: json","text").action(async s=>{await xi(s)}),t.command("connect").description("Connect local project to Nebutra ecosystem").option("--token <token>","Ecosystem API token").option("--org <orgId>","Organization ID").option("--dry-run","Preview without making changes").option("--yes","Skip confirmations").action(async s=>{await Oi(s)}),t.command("publish").description("Publish project/template to ecosystem marketplace").option("--tag <tag>","Release tag: latest|beta|canary","latest").option("--visibility <visibility>","Project visibility: public|private|unlisted","public").option("--dry-run","Preview without making changes").option("--yes","Skip confirmations").action(async s=>{await _i(s)});let r=t.command("templates").description("Template marketplace");r.command("list").description("Browse available templates").option("--category <category>","Filter by category").option("--sort <sort>","Sort by: stars|downloads|recent","downloads").option("--format <format>","Output format","text").action(async s=>{await Pi(s)}),r.command("search <query>").description("Search templates").option("--format <format>","Output format","text").action(async(s,l)=>{await Ti(s,l)}),r.command("info <id>").description("Template details").action(async s=>{await Ii(s)}),r.command("install <id>").description("Install/fork a template").option("--dry-run","Preview without making changes").action(async(s,l)=>{await $i(s,l)});let n=t.command("ideas").description("Ideas marketplace");n.command("list").description("Browse ideas").option("--status <status>","Filter by status").option("--sort <sort>","Sort by: votes|recent|trending","recent").option("--format <format>","Output format","text").action(async s=>{await ji(s)}),n.command("submit").description("Submit new idea").option("--title <title>","Idea title").option("--description <description>","Idea description").option("--tags <tags>","Comma-separated tags").option("--dry-run","Preview without making changes").action(async s=>{await Ni(s)}),n.command("vote <id>").description("Upvote an idea").option("--dry-run","Preview without making changes").action(async(s,l)=>{await Ui(s,l)}),n.command("claim <id>").description("Claim an idea to work on").option("--dry-run","Preview without making changes").action(async(s,l)=>{await Li(s,l)}),n.command("comment <id>").description("Comment on an idea").option("--message <message>","Comment text").option("--dry-run","Preview without making changes").action(async(s,l)=>{await Di(s,l)});let o=t.command("opc",{hidden:!0}).description("Legacy member directory");o.command("list").description("Browse legacy member profiles").option("--skill <skill>","Filter by skill tag").option("--industry <industry>","Filter by industry").option("--sort <sort>","Sort by: active|joined","active").option("--format <format>","Output format","text").action(async s=>{await Fi(s)}),o.command("profile").description("View/edit your legacy member profile").action(async()=>{await Vi()}),o.command("register").description("Register a legacy member profile").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async s=>{await Mi(s)});let i=t.command("showcase").description("Project showcase");i.command("list").description("Browse showcased projects").option("--category <category>","Filter by category").option("--featured","Show featured only").option("--format <format>","Output format","text").action(async s=>{await Bi(s)}),i.command("submit").description("Submit your project to showcase").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async s=>{await Gi(s)}),i.command("vote <id>").description("Upvote a project (Product Hunt style)").option("--dry-run","Preview without making changes").action(async(s,l)=>{await qi(s,l)}),t.command("sync").description("Sync local project with ecosystem").option("--pull","Pull remote changes").option("--push","Push local changes").option("--dry-run","Preview without making changes").action(async s=>{await Ki(s)})}import{existsSync as lt,readFileSync as Kr,writeFileSync as zi}from"fs";import{resolve as dt}from"path";import*as Ce from"@clack/prompts";import Wi from"picocolors";function ut(e){let t=dt(e,".env.example");if(!lt(t))throw new Error(`.env.example not found at ${t}`);let r=Kr(t,"utf-8"),n={};for(let o of r.split(`
434
+ `)){if(o.trim().startsWith("#")||!o.trim())continue;let i=o.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(i){let[,s,l]=i;n[s]=l.replace(/^["'](.*)["']$/,"$1")}}return n}function Dt(e){let t=dt(e,".env.local"),r=dt(e,".env"),n=lt(t)?t:r;if(!lt(n))return{};let o=Kr(n,"utf-8"),i={};for(let s of o.split(`
435
+ `)){if(s.trim().startsWith("#")||!s.trim())continue;let l=s.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(l){let[,u,m]=l;i[u]=m.replace(/^["'](.*)["']$/,"$1")}}return i}function Yi(e,t){return["SECRET","KEY","TOKEN","PASSWORD"].some(o=>e.toUpperCase().includes(o))&&t.length>0}function Hi(e){return e.length<=8?"*".repeat(Math.max(e.length,4)):e.substring(0,4)+"*".repeat(e.length-8)+e.substring(e.length-4)}async function Ji(e){d("Validating environment variables...","info");let t=b(),r=ut(t),n=Dt(t),o=process.env,i={},s=!0;for(let l of Object.keys(r)){let u=l in n||l in o;i[l]=u,u||(s=!1)}if(e.format==="json")k({valid:s,checked:Object.keys(r).length,missing:Object.entries(i).filter(([,l])=>!l).map(([l])=>l)},{format:"json"});else{tt("Environment Validation");let l=Object.entries(i).filter(([,u])=>!u).map(([u])=>u);if(l.length===0)d("All required environment variables are set","success");else{d(`${l.length} missing environment variable(s):`,"warn");for(let u of l)d(` - ${u}`,"warn")}}s||process.exit(c.CONFIG_ERROR)}async function Xi(e){let t=b(),r=ut(t),n=dt(t,".env.local");if(lt(n)&&!e.yes&&!e.dryRun){let u=await Ce.confirm({message:".env.local already exists. Overwrite?",initialValue:!1});(Ce.isCancel(u)||!u)&&(d("Template generation cancelled","warn"),process.exit(c.CANCELLED))}d("Generating .env.local from template...","info");let o={},i=0,s=Object.keys(r).length;for(let[u,m]of Object.entries(r))if(i++,e.yes)o[u]=m;else if(process.stdin.isTTY===!0){let f=`[${i}/${s}] ${u}`,y=await Ce.text({message:f,defaultValue:m});Ce.isCancel(y)&&(d("Template generation cancelled","warn"),process.exit(c.CANCELLED)),o[u]=y}else o[u]=m;let l=Object.entries(o).map(([u,m])=>{let y=/[\s=]/.test(m)?`"${m}"`:m;return`${u}=${y}`}).join(`
436
+ `);e.dryRun?(d("Dry-run: would write .env.local","info"),k(l,{format:"plain"})):(zi(n,l+`
437
+ `),d(`Environment template written to ${n}`,"success"))}async function Qi(e){d("Comparing environment variables...","info");let t=b(),r=ut(t),n=Dt(t),o=[],i=[],s=[];for(let l of Object.keys(r))l in n?s.push(l):o.push(l);for(let l of Object.keys(n))l in r||i.push(l);if(e.format==="json")k({matching:s.length,missing:o.length,extra:i.length,missing_vars:o,extra_vars:i},{format:"json"});else{if(tt("Environment Diff"),s.length>0&&d(`Matching (${s.length}): ${s.join(", ")}`,"success"),o.length>0){d(`Missing (${o.length}):`,"warn");for(let l of o)d(` - ${l}`,"warn")}if(i.length>0){d(`Extra (${i.length}):`,"info");for(let l of i)d(` - ${l}`,"info")}}}async function Zi(e){d("Reading environment variables...","info");let t=b(),r=Dt(t),n=ut(t),o={};for(let i of Object.keys(n))if(i in r){let s=r[i];o[i]=Yi(i,s)?Hi(s):s||"(empty)"}else o[i]="(not set)";if(e.format==="json"){let i={};for(let[s,l]of Object.entries(o))i[s]=l;k(i,{format:"json"})}else{tt("Current Environment Variables");let i=Object.entries(o).map(([s,l])=>({Variable:Wi.cyan(s),Value:l}));k(i,{format:"table"}),d("Note: Sensitive values (KEY, TOKEN, SECRET, PASSWORD) are masked","info")}}function zr(e){e.command("env <verb>").description("Manage environment variables and configuration").option("--dry-run","Show what would be done without making changes").option("--yes","Skip confirmations and use defaults").option("--format <type>","Output format: json, plain","plain").action(async(r,n)=>{let o=n.optsWithGlobals?.(),i={dryRun:n.dryRun||o?.dryRun,yes:n.yes||o?.yes,format:n.format||o?.format};try{switch(r){case"validate":await Ji(i);break;case"template":await Xi(i);break;case"diff":await Qi(i);break;case"show":await Zi(i);break;default:d(`Unknown env subcommand: ${r}. Valid commands: validate, template, diff, show`,"error"),process.exit(c.INVALID_ARGS)}}catch(s){let l=s instanceof Error?s.message:String(s);d(`Environment command failed: ${l}`,"error"),A("Full error",{error:s}),process.exit(c.ERROR)}}).addHelpText("after",`
438
438
  Examples:
439
439
  nebutra env validate Check all required vars are set
440
440
  nebutra env template Generate .env.local from .env.example with prompts
@@ -451,7 +451,7 @@ Flags:
451
451
  Sensitive Variables:
452
452
  Variables with KEY, TOKEN, SECRET, PASSWORD in their names are masked in output.
453
453
  This prevents accidental exposure of credentials.
454
- `)}import{promises as zr}from"fs";import{join as Ae}from"path";import*as Be from"@clack/prompts";import U from"picocolors";var Me=["design","iam","commerce","integrations","platform","ops","ai"];function Qi(e){return Me.includes(e)}function Ft(e,t){if(!t)throw new Error(`--category is required. Valid categories: ${Me.join(", ")}. Example: nebutra generate package ${e} --category iam`);if(!Qi(t))throw new Error(`Unknown category "${t}". Valid categories: ${Me.join(", ")}.`);return`packages/${t}/${e}`}function Wr(e){let t=e.split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("");return{"package.json":`{
454
+ `)}import{promises as Wr}from"fs";import{join as Ae}from"path";import*as Be from"@clack/prompts";import U from"picocolors";var Me=["design","iam","commerce","integrations","platform","ops","ai"];function es(e){return Me.includes(e)}function Ft(e,t){if(!t)throw new Error(`--category is required. Valid categories: ${Me.join(", ")}. Example: nebutra generate package ${e} --category iam`);if(!es(t))throw new Error(`Unknown category "${t}". Valid categories: ${Me.join(", ")}.`);return`packages/${t}/${e}`}function Yr(e){let t=e.split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("");return{"package.json":`{
455
455
  "name": "@nebutra/${e}",
456
456
  "version": "0.0.0",
457
457
  "private": true,
@@ -536,7 +536,7 @@ export default function RootLayout({
536
536
 
537
537
  @theme {
538
538
  --color-*: var(--neutral-*);
539
- }`}}function Yr(e){return{"package.json":`{
539
+ }`}}function Hr(e){return{"package.json":`{
540
540
  "name": "@nebutra/${e}",
541
541
  "version": "0.0.0",
542
542
  "type": "module",
@@ -573,7 +573,7 @@ export default function RootLayout({
573
573
 
574
574
  export function hello(name: string): string {
575
575
  return \`Hello, \${name}!\`;
576
- }`}}function Hr(e){let t=e.replace(/\//g,"_").replace(/-/g,"_");return{[`src/routes/${e}.ts`]:`import { Hono } from "hono";
576
+ }`}}function Jr(e){let t=e.replace(/\//g,"_").replace(/-/g,"_");return{[`src/routes/${e}.ts`]:`import { Hono } from "hono";
577
577
  import { z } from "zod";
578
578
 
579
579
  type Env = {
@@ -624,7 +624,7 @@ app.post("/", async (c) => {
624
624
  );
625
625
  });
626
626
 
627
- export default app;`}}function Jr(e){let t=e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),r=e.split("-").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("");return{[`src/components/${t}.tsx`]:`import { cva, type VariantProps } from "class-variance-authority";
627
+ export default app;`}}function Xr(e){let t=e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),r=e.split("-").map(n=>n.charAt(0).toUpperCase()+n.slice(1)).join("");return{[`src/components/${t}.tsx`]:`import { cva, type VariantProps } from "class-variance-authority";
628
628
  import { cn } from "@nebutra/ui/utils";
629
629
 
630
630
  const ${t}Variants = cva(
@@ -698,13 +698,13 @@ export const AllSizes: Story = {
698
698
  <${r} size="lg">Large</\${pascalCase}>
699
699
  </div>
700
700
  ),
701
- };`}}async function mt(e,t,r){let n=b(),o=[],i={};switch(e){case"app":i=Wr(t);break;case"package":i=Yr(t);break;case"route":i=Hr(t);break;case"component":i=Jr(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let s=e==="package"?Ft(t,r.category):void 0;for(let[l,u]of Object.entries(i)){let m=e==="app"?Ae(n,"apps",t,l):e==="package"?Ae(n,s??`packages/${t}`,l):Ae(n,"backends/gateway",l);o.push({path:m,size:Buffer.byteLength(u)})}return o}async function pt(e,t,r={}){let n=b(),o=[],i={};switch(e){case"app":i=Wr(t);break;case"package":i=Yr(t);break;case"route":i=Hr(t);break;case"component":i=Jr(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let s=e==="package"?Ft(t,r.category):void 0;for(let[l,u]of Object.entries(i)){let m;e==="app"?m=Ae(n,"apps",t,l):e==="package"?m=Ae(n,s??`packages/${t}`,l):e==="component"?m=Ae(n,"packages/design/ui",l):m=Ae(n,"backends/gateway",l);let f=m.substring(0,m.lastIndexOf("/"));await zr.mkdir(f,{recursive:!0}),await zr.writeFile(m,u,"utf-8"),o.push(m)}return o}async function Zi(e,t){if(t.dryRun){let n=await mt("app",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"app",name:e,location:`apps/${e}`,files:n.map(i=>({path:i.path,sizeBytes:i.size})),instructions:[`cd apps/${e}`,"pnpm install","pnpm run dev"]};process.stdout.write(JSON.stringify(o,null,2)+`
702
- `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate app ")));let r=a.spinner();try{r.start(`Generating app ${U.cyan(e)}...`);let n=await pt("app",e);r.stop(`Created app ${U.cyan(e)}`,0),a.success(`App created with ${n.length} files`),a.info("Next steps:"),a.info(` cd apps/${e}`),a.info(" pnpm install"),a.info(" pnpm run dev"),process.exit(c.SUCCESS)}catch(n){r.stop(`Failed to generate app: ${n instanceof Error?n.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function es(e,t){let r;try{r=Ft(e,t.category)}catch(o){a.error(o instanceof Error?o.message:String(o)),process.exit(c.INVALID_ARGS)}if(t.dryRun){let o=await mt("package",e,t),i={mode:"dry-run",timestamp:new Date().toISOString(),type:"package",name:e,category:t.category,location:r,files:o.map(s=>({path:s.path,sizeBytes:s.size}))};process.stdout.write(JSON.stringify(i,null,2)+`
703
- `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate package ")));let n=a.spinner();try{n.start(`Generating package ${U.cyan(e)} in ${U.dim(r)}...`);let o=await pt("package",e,{category:t.category});n.stop(`Created package ${U.cyan(e)}`,0),a.success(`Package created with ${o.length} files`),a.info("Next steps:"),a.info(` Edit ${r}/src/index.ts`),a.info(` Run: pnpm --filter @nebutra/${e} build`),process.exit(c.SUCCESS)}catch(o){n.stop(`Failed to generate package: ${o instanceof Error?o.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function ts(e,t){if(t.dryRun){let n=await mt("route",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"route",path:e,location:`backends/gateway/src/routes/${e}.ts`,files:n.map(i=>({path:i.path,sizeBytes:i.size}))};process.stdout.write(JSON.stringify(o,null,2)+`
704
- `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate route ")));let r=a.spinner();try{r.start(`Generating route ${U.cyan(e)}...`);let n=await pt("route",e);r.stop(`Created route ${U.cyan(e)}`,0),a.success(`Route created with ${n.length} files`),a.info(`File: backends/gateway/src/routes/${e}.ts`),a.info(`Add to your main app.ts: app.route("/${e}", routes)`),process.exit(c.SUCCESS)}catch(n){r.stop(`Failed to generate route: ${n instanceof Error?n.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function rs(e,t){if(t.dryRun){let n=await mt("component",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"component",name:e,location:"packages/design/ui/src/components/",files:n.map(i=>({path:i.path,sizeBytes:i.size})),nextSteps:["Add export to packages/design/ui/src/components/index.ts","Run: pnpm --filter @nebutra/ui typecheck","View in Storybook: pnpm --filter @nebutra/storybook dev"]};process.stdout.write(JSON.stringify(o,null,2)+`
705
- `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate component ")));let r=a.spinner();try{r.start(`Generating component ${U.cyan(e)}...`);let n=await pt("component",e);r.stop(`Created component ${U.cyan(e)}`,0),a.success(`Component created with ${n.length} files`),a.info("Files created in packages/design/ui/src/components/"),a.info("Next steps:"),a.info(" 1. Add export to packages/design/ui/src/components/index.ts"),a.info(" 2. pnpm --filter @nebutra/ui typecheck"),a.info(" 3. pnpm --filter @nebutra/storybook dev"),process.exit(c.SUCCESS)}catch(n){r.stop(`Failed to generate component: ${n instanceof Error?n.message:"Unknown error"}`,1),process.exit(c.ERROR)}}function Xr(e){let t=e.command("generate").description("Scaffold a new app, package, route, or component").alias("gen");t.command("app <name>").description("Scaffold a new Next.js app (Next.js 16 + Tailwind v4)").option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").option("--template <type>","App template (default: nextjs)","nextjs").option("--port <number>","Dev server port","3000").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await Zi(r,{...n,dryRun:n.dryRun||!1,yes:o.yes||!1,interactive:process.stdin.isTTY})}),t.command("package <name>").description(`Scaffold a new categorized package (@nebutra/<name>). Categories: ${Me.join(", ")}`).requiredOption("--category <category>",`Package category: ${Me.join(" | ")}`).option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await es(r,{...n,category:n.category,dryRun:n.dryRun||!1,yes:o.yes||!1})}),t.command("route <path>").description("Scaffold a Hono API route in backends/gateway").option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await ts(r,{...n,dryRun:n.dryRun||!1,yes:o.yes||!1})}),t.command("component <name>").description("Scaffold a UI component with Storybook story").option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").option("--variants <list>","Comma-separated variant names (e.g., 'primary,secondary')").option("--sizes <list>","Comma-separated size names (e.g., 'sm,md,lg')").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await rs(r,{...n,dryRun:n.dryRun||!1,yes:o.yes||!1,variants:n.variants,sizes:n.sizes})})}import je from"picocolors";async function Y(e,t){let r=await b(),n=new URL(e,"http://localhost:3000/api/growth");t?.query&&Object.entries(t.query).forEach(([i,s])=>{n.searchParams.set(i,s)});let o=await fetch(n,{method:t?.method||"GET",headers:{"Content-Type":"application/json"},body:t?.body?JSON.stringify(t.body):void 0});if(!o.ok)throw new Error(`Growth API error (${o.status}): ${await o.text()}`);return o.json()}async function ns(e){try{let t=e.period||"7d",r=e.compare;a.info(`Fetching growth metrics for ${t}...`);let n=await Y("/summary",{query:{period:t,compare:r?"true":"false"}});return c.SUCCESS}catch(t){return a.error(`Dashboard error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function os(e){try{let t=e.period||"7d",r=e.segment||"all";a.info(`Fetching funnel data for ${t} (${r})...`);let n=await Y("/funnel",{query:{period:t,segment:r}});return n.forEach((i,s)=>{let l="\u2588".repeat(Math.ceil(i.rate*20)),u="\u2591".repeat(20-Math.ceil(i.rate*20)),m=s<n.length-1?je.red(`\u2193 ${(i.dropoff_rate*100).toFixed(1)}% drop`):""}),n.reduce((i,s)=>s.dropoff_rate>i.dropoff_rate?s:i).dropoff_rate>.2,c.SUCCESS}catch(t){return a.error(`Funnel error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function as(e){try{let t=e.period||"weekly",r=parseInt(e.cohorts,10)||8;a.info(`Fetching ${t} cohort data (${r} cohorts)...`);let n=await Y("/cohort",{query:{period:t,cohorts:String(r)}});if(n.length===0)return c.SUCCESS;let o=Object.keys(n[0]).slice(1);return n.forEach(i=>{let l=String(i.cohort).padEnd(15);o.forEach(u=>{let m=i[u];if(typeof m=="number"){let f=m/100,y=String(Math.round(m)).padEnd(8);f>=.7?y=je.green(y):f>=.4?y=je.yellow(y):y=je.red(y),l+=y+" "}})}),c.SUCCESS}catch(t){return a.error(`Cohort error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function is(e,t){try{if(e==="stats"){a.info("Fetching newsletter stats...");let r=await Y("/newsletter/stats");return c.SUCCESS}if(e==="subscribers"){let r=parseInt(t.limit,10)||10,n=parseInt(t.offset,10)||0;return a.info(`Fetching ${r} newsletter subscribers (offset ${n})...`),(await Y("/newsletter/subscribers",{query:{limit:String(r),offset:String(n)}})).forEach(i=>{}),c.SUCCESS}if(e==="send"){let r=t.template;return r?t.yes?(a.info(`Sending newsletter with template: ${r}`),await Y("/newsletter/send",{method:"POST",body:{template_id:r}}),c.SUCCESS):(a.warn("Use --yes to confirm newsletter send"),c.ERROR):(a.error("--template is required"),c.ERROR)}return a.error(`Unknown newsletter subcommand: ${e}`),c.ERROR}catch(r){return a.error(`Newsletter error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function ss(e,t){try{if(e==="status"){a.info("Fetching referral program status...");let r=await Y("/referral/status");return c.SUCCESS}if(e==="config"){a.info("Fetching referral config...");let r=await Y("/referral/config");return Object.entries(r).forEach(([n,o])=>{}),c.SUCCESS}return e==="leaderboard"?(a.info("Fetching referral leaderboard..."),(await Y("/referral/leaderboard")).forEach(n=>{let o=n.rank===1?"\u{1F947}":n.rank===2?"\u{1F948}":"\u{1F949}"}),c.SUCCESS):(a.error(`Unknown referral subcommand: ${e}`),c.ERROR)}catch(r){return a.error(`Referral error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function cs(e,t){try{if(e==="list"){a.info("Fetching active experiments...");let r=await Y("/experiment");return r.length===0?c.SUCCESS:(r.forEach(n=>{let o=n.status==="running"?je.yellow("\u25CF"):je.green("\u2713")}),c.SUCCESS)}if(e==="create"){let r=t.name,n=t.variants?.split(","),o=t.metric;if(!r||!n||!o)return a.error("Required: --name <name> --variants <A,B> --metric <metric>"),c.ERROR;a.info(`Creating experiment: ${r}`);let i=await Y("/experiment",{method:"POST",body:{name:r,variants:n,metric:o}});return c.SUCCESS}if(e==="results"){let r=t.id;if(!r)return a.error("--id is required"),c.ERROR;a.info(`Fetching results for experiment ${r}...`);let n=await Y(`/experiment/${r}`);return n.winner,n.significance,c.SUCCESS}if(e==="conclude"){let r=t.id,n=t.winner;return!r||!n?(a.error("Required: --id <id> --winner <variant>"),c.ERROR):t.yes?(a.info(`Concluding experiment ${r} with winner: ${n}`),await Y(`/experiment/${r}`,{method:"POST",body:{action:"conclude",winner:n}}),c.SUCCESS):(a.warn("Use --yes to confirm experiment conclusion"),c.ERROR)}return a.error(`Unknown experiment subcommand: ${e}`),c.ERROR}catch(r){return a.error(`Experiment error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function ls(e){try{let t=e.focus||"activation",r=e.depth||"quick";a.info(`Generating growth insights (focus: ${t}, depth: ${r})...`);let n=await Y("/pulse",{query:{focus:t,depth:r}});return n.insights.forEach(o=>{}),n.recommendations.forEach(o=>{}),c.SUCCESS}catch(t){return a.error(`Pulse error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}function Qr(e){let t=e.command("growth").description("Growth engine operations \u2014 metrics, funnel, cohorts, AI insights");t.command("dashboard").description("Growth metrics overview").option("--period <7d|30d|90d>","Time period","7d").option("--compare","Show period-over-period deltas").action(async i=>{process.exit(await ns(i))}),t.command("funnel").description("Conversion funnel analysis").option("--period <7d|30d|90d>","Time period","7d").option("--segment <organic|paid|referral>","Traffic segment","all").action(async i=>{process.exit(await os(i))}),t.command("cohort").description("Cohort retention analysis").option("--period <weekly|monthly>","Cohort period","weekly").option("--cohorts <n>","Number of cohorts","8").action(async i=>{process.exit(await as(i))}),t.command("newsletter <subcommand>").description("Newsletter management").action(async(i,s)=>{process.exit(await is(i,s))}),t.command("referral <subcommand>").description("Referral program management").action(async(i,s)=>{process.exit(await ss(i,s))}),t.command("experiment <subcommand>").description("A/B testing and experiment management").option("--id <id>","Experiment ID").option("--name <name>","Experiment name").option("--variants <A,B>","Comma-separated variants").option("--metric <metric>","Success metric").option("--winner <variant>","Winning variant").action(async(i,s)=>{process.exit(await cs(i,s))}),t.command("pulse").description("AI-generated growth insights (AARRR: Acquisition, Activation, Retention, Revenue, Referral)").option("--focus <aarrr>","Focus area (acquisition|activation|retention|revenue|referral)","activation").option("--depth <quick|deep>","Analysis depth","quick").action(async i=>{process.exit(await ls(i))}),t.option("--dry-run","Preview changes without applying them").option("--format <json|text>","Output format","text").option("--yes","Skip confirmation prompts")}import Vt,{lstatSync as ds,readdirSync as Mt,readFileSync as us,writeFileSync as ms}from"fs";import de from"path";import{fileURLToPath as ps}from"url";import X from"picocolors";var fs=de.dirname(ps(import.meta.url));function Bt(){let e=new Map,t=de.join(fs,"../../../apps");if(!Vt.existsSync(t))return e;try{let r=Mt(t);for(let n of r){let o=de.join(t,n),i=de.join(o,"messages");Vt.existsSync(i)&&ds(i).isDirectory()&&e.set(n,i)}}catch(r){a.debug(`Error scanning apps directory: ${r instanceof Error?r.message:String(r)}`)}return e}function Ge(e,t=""){let r=new Set;for(let[n,o]of Object.entries(e)){let i=t?`${t}.${n}`:n;if(typeof o=="object"&&o!==null&&!Array.isArray(o)){let s=Ge(o,i);for(let l of s)r.add(l)}else r.add(i)}return r}function qe(e){try{let t=us(e,"utf-8");return JSON.parse(t)}catch(t){return a.debug(`Failed to parse ${e}: ${t instanceof Error?t.message:String(t)}`),null}}async function gs(e){if(a.info("Syncing language files across the project..."),(await K("translate",{filter:"landing-page",dryRun:e.dryRun,interactive:e.interactive??!0})).exitCode!==0){a.warn("Landing page translate script not found or failed. Trying sync-lang.mjs...");let r=await x({command:"node",args:["scripts/sync-lang.mjs"],dryRun:e.dryRun,interactive:e.interactive??!0,label:"Sync language files"});r.exitCode!==0&&(a.error("Failed to sync language files"),process.exit(r.exitCode)),e.format==="json"?console.log(JSON.stringify({command:"i18n:sync",exitCode:0,success:!0},null,2)):e.dryRun||a.success("Language files synced successfully")}else e.format==="json"?console.log(JSON.stringify({command:"i18n:sync",exitCode:0,success:!0},null,2)):e.dryRun||a.success("Language files synced successfully")}async function ys(e){a.info("Validating translation files...");let t=Bt();t.size===0&&(a.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let r=new Map,n=!1;for(let[o,i]of t){let s=[];try{let l=Mt(i).filter(y=>y.endsWith(".json"));if(l.length===0)continue;let u=de.join(i,"en.json"),m=qe(u);if(!m){a.warn(`Could not load reference locale en.json from ${o}`);continue}let f=Ge(m);for(let y of l){if(y==="en.json")continue;let C=y.replace(".json",""),L=de.join(i,y),D=qe(L);if(!D){a.debug(`Could not parse ${y}`);continue}let q=Ge(D),ue=Array.from(f).filter(p=>!q.has(p)),ie=Array.from(q).filter(p=>!f.has(p)),Re=f.size>0?(f.size-ue.length)/f.size*100:100;(ue.length>0||ie.length>0)&&(n=!0),s.push({locale:C,totalKeys:f.size,missingKeys:ue,extraKeys:ie,coverage:Math.round(Re*100)/100})}s.length>0&&r.set(o,s)}catch(l){a.debug(`Error validating ${o}: ${l instanceof Error?l.message:String(l)}`)}}if(e.format==="json"){let o={command:"i18n:validate",success:!n,results:Array.from(r.entries()).reduce((i,[s,l])=>(i[s]=l,i),{})};console.log(JSON.stringify(o,null,2))}else for(let[o,i]of r){a.info(`${X.bold(o)}:`);for(let s of i){let u=(s.coverage>=100?X.green:s.coverage>=80?X.yellow:X.red)(`${s.coverage}%`);a.info(` ${X.cyan(s.locale.padEnd(5))} ${u.padEnd(20)} [${s.totalKeys} keys]`),s.missingKeys.length>0&&a.warn(` Missing: ${s.missingKeys.slice(0,5).join(", ")}${s.missingKeys.length>5?` (+ ${s.missingKeys.length-5} more)`:""}`),s.extraKeys.length>0&&a.warn(` Extra: ${s.extraKeys.slice(0,5).join(", ")}${s.extraKeys.length>5?` (+ ${s.extraKeys.length-5} more)`:""}`)}}n&&process.exit(c.CONFLICT)}async function hs(e,t){/^[a-z]{2}(-[A-Z]{2})?$/.test(e)||(a.error(`Invalid locale format: ${e}. Use 'en', 'es', 'zh-CN', etc.`),process.exit(c.INVALID_ARGS));let r=Bt();r.size===0&&(a.error("No message directories found in the project"),process.exit(c.NOT_FOUND));let n=[],o=!1;for(let[s,l]of r){let u=de.join(l,`${e}.json`);if(Vt.existsSync(u)){a.warn(`Locale ${e} already exists in ${s}`);continue}try{let C=function(L){for(let D in L)typeof L[D]=="string"?L[D]="":typeof L[D]=="object"&&L[D]!==null&&C(L[D])};var i=C;let m=de.join(l,"en.json"),f=qe(m);if(!f){a.warn(`Could not load reference en.json from ${s}, skipping...`);continue}let y=JSON.parse(JSON.stringify(f));C(y),t.dryRun?a.info(`Would create ${e} locale in ${s}`):(ms(u,JSON.stringify(y,null,2)+`
706
- `),n.push({app:s,path:u}),a.success(`Created ${e} locale in ${s}`))}catch(m){a.error(`Failed to create locale in ${s}: ${m instanceof Error?m.message:String(m)}`),o=!0}}t.format==="json"?console.log(JSON.stringify({command:"i18n:add",locale:e,dryRun:t.dryRun||!1,created:n,success:!o},null,2)):t.dryRun||a.success(`Locale '${e}' added to ${n.length} app(s)`),o&&process.exit(c.ERROR)}async function bs(e){a.info("Checking translation coverage...");let t=Bt();t.size===0&&(a.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let r=new Map,n=0,o=0;for(let[i,s]of t){let l=[];try{let u=Mt(s).filter(C=>C.endsWith(".json"));if(u.length===0)continue;let m=de.join(s,"en.json"),f=qe(m);if(!f){a.debug(`Could not load reference locale from ${i}`);continue}let y=Ge(f);for(let C of u){let L=C.replace(".json",""),D=de.join(s,C),q=qe(D);if(!q)continue;let ue=Ge(q),ie=Array.from(ue).filter(F=>{let _e=q[F.split(".")[0]];return _e!==void 0&&_e!==""}).length,Re=y.size-ie,p=y.size>0?ie/y.size*100:0;l.push({locale:L,coverage:Math.round(p*100)/100,totalKeys:y.size,translatedKeys:ie,missingKeys:Re})}l.length>0&&(r.set(i,l),o++,n+=l.reduce((C,L)=>C+L.coverage,0)/l.length)}catch(u){a.debug(`Error checking status for ${i}: ${u instanceof Error?u.message:String(u)}`)}}if(e.format==="json"){let i={command:"i18n:status",averageCoverage:o>0?Math.round(n/o*100)/100:0,results:Array.from(r.entries()).reduce((s,[l,u])=>(s[l]=u,s),{})};console.log(JSON.stringify(i,null,2))}else{for(let[i,s]of r){a.info(`${X.bold(i)}:`);for(let l of s){let u="",f=Math.round(l.coverage/100*20);u="\u2588".repeat(f)+"\u2591".repeat(20-f);let C=(l.coverage>=100?X.green:l.coverage>=80?X.yellow:X.red)(`${l.coverage.toFixed(1)}%`);a.info(` ${X.cyan(l.locale.padEnd(5))} [${u}] ${C}`),a.info(` ${l.translatedKeys}/${l.totalKeys} keys (${l.missingKeys} missing)`)}}if(o>0){let i=n/o,s=i>=100?X.green:i>=80?X.yellow:X.red;a.info(`
707
- Average coverage: ${s(i.toFixed(1)+"%")}`)}}}function Zr(e){let t=e.command("i18n").description("Manage internationalization and translations");t.command("sync").description("Synchronize language translations across the project").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await gs({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("validate").description("Validate all locale files for missing or extra keys").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await ys({format:r.format||n.format,interactive:n.yes!==!0})}),t.command("add <locale>").description("Add a new locale with template files (e.g. 'en', 'es', 'zh-CN')").option("--dry-run","Preview what would be created without writing files").option("--format <type>","Output format: json or plain").action(async(r,n)=>{let o=n.optsWithGlobals?.()||n;await hs(r,{dryRun:n.dryRun||!1,format:n.format||o.format,interactive:o.yes!==!0})}),t.command("status").description("Show translation coverage per locale and app").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await bs({format:r.format||n.format,interactive:n.yes!==!0})})}import*as ft from"@clack/prompts";async function vs(e){let t=e.lite?"docker-compose.lite.yml":void 0,r=e.lite?"Starting lite stack (PostgreSQL + Redis)":"Starting full stack";d(r+"...","info");let n=await Pe("up -d",{file:t,profile:e.profile,dryRun:e.dryRun});n.exitCode===0?d("Infrastructure stack started successfully","success"):(d("Failed to start infrastructure stack","error"),A("Docker compose output",{stderr:n.stderr}),process.exit(n.exitCode||1))}async function ws(e){d("Stopping infrastructure stack...","info");let t=await Pe("down",{dryRun:e.dryRun});t.exitCode===0?d("Infrastructure stack stopped","success"):(d("Failed to stop infrastructure stack","error"),A("Docker compose output",{stderr:t.stderr}),process.exit(t.exitCode||1))}async function Ss(e){d("Checking infrastructure status...","info");let t=await Pe("ps --format json",{dryRun:e.dryRun});if(t.exitCode===0)try{let r=JSON.parse(t.stdout);if(e.format==="json")k(r,{format:"json"});else{let n=r.map(o=>({name:o.Name,status:o.Status,ports:o.Ports||"-"}));k(n,{format:"table"})}}catch{k(t.stdout,{format:"plain"})}else d("Failed to check infrastructure status","error"),A("Docker compose output",{stderr:t.stderr}),process.exit(t.exitCode||1)}async function Rs(e,t){let r=t||{},n=e?`Fetching logs for ${e}...`:"Fetching infrastructure logs...";d(n,"info");let o=["logs","--tail","50"];e&&o.push(e);let i=await Pe(o.join(" "),{dryRun:r.dryRun});i.exitCode===0?k(i.stdout,{format:"plain"}):(d("Failed to fetch logs","error"),A("Docker compose output",{stderr:i.stderr}),process.exit(i.exitCode||1))}async function ks(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let n=await ft.confirm({message:"Reset infrastructure? This will remove all containers and volumes.",initialValue:!1});(ft.isCancel(n)||!n)&&(d("Reset cancelled","warn"),process.exit(c.CANCELLED))}else d("Infrastructure reset requires explicit --yes confirmation (use: nebutra infra reset --yes)","error"),process.exit(c.INVALID_ARGS);d("Resetting infrastructure stack...","warn");let r=await Pe("down -v",{dryRun:e.dryRun});r.exitCode===0?d("Infrastructure reset successfully","success"):(d("Failed to reset infrastructure","error"),A("Docker compose output",{stderr:r.stderr}),process.exit(r.exitCode||1))}function en(e){e.command("infra <verb> [service]").description("Manage Docker Compose infrastructure (PostgreSQL, Redis, Meilisearch, etc.)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations (especially for reset)").option("--lite","Use lite stack (PostgreSQL + Redis only)").option("--profile <name>","Docker Compose profile to use (e.g., search)").option("--format <type>","Output format: json, plain","plain").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,lite:o.lite||!1,profile:o.profile};try{switch(r){case"up":await vs(s);break;case"down":await ws(s);break;case"status":await Ss(s);break;case"logs":await Rs(n,s);break;case"reset":await ks(s);break;default:d(`Unknown infra subcommand: ${r}. Valid commands: up, down, status, logs, reset`,"error"),process.exit(c.INVALID_ARGS)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Infrastructure command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
701
+ };`}}async function mt(e,t,r){let n=b(),o=[],i={};switch(e){case"app":i=Yr(t);break;case"package":i=Hr(t);break;case"route":i=Jr(t);break;case"component":i=Xr(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let s=e==="package"?Ft(t,r.category):void 0;for(let[l,u]of Object.entries(i)){let m=e==="app"?Ae(n,"apps",t,l):e==="package"?Ae(n,s??`packages/${t}`,l):Ae(n,"backends/gateway",l);o.push({path:m,size:Buffer.byteLength(u)})}return o}async function pt(e,t,r={}){let n=b(),o=[],i={};switch(e){case"app":i=Yr(t);break;case"package":i=Hr(t);break;case"route":i=Jr(t);break;case"component":i=Xr(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let s=e==="package"?Ft(t,r.category):void 0;for(let[l,u]of Object.entries(i)){let m;e==="app"?m=Ae(n,"apps",t,l):e==="package"?m=Ae(n,s??`packages/${t}`,l):e==="component"?m=Ae(n,"packages/design/ui",l):m=Ae(n,"backends/gateway",l);let f=m.substring(0,m.lastIndexOf("/"));await Wr.mkdir(f,{recursive:!0}),await Wr.writeFile(m,u,"utf-8"),o.push(m)}return o}async function ts(e,t){if(t.dryRun){let n=await mt("app",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"app",name:e,location:`apps/${e}`,files:n.map(i=>({path:i.path,sizeBytes:i.size})),instructions:[`cd apps/${e}`,"pnpm install","pnpm run dev"]};process.stdout.write(JSON.stringify(o,null,2)+`
702
+ `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate app ")));let r=a.spinner();try{r.start(`Generating app ${U.cyan(e)}...`);let n=await pt("app",e);r.stop(`Created app ${U.cyan(e)}`,0),a.success(`App created with ${n.length} files`),a.info("Next steps:"),a.info(` cd apps/${e}`),a.info(" pnpm install"),a.info(" pnpm run dev"),process.exit(c.SUCCESS)}catch(n){r.stop(`Failed to generate app: ${n instanceof Error?n.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function rs(e,t){let r;try{r=Ft(e,t.category)}catch(o){a.error(o instanceof Error?o.message:String(o)),process.exit(c.INVALID_ARGS)}if(t.dryRun){let o=await mt("package",e,t),i={mode:"dry-run",timestamp:new Date().toISOString(),type:"package",name:e,category:t.category,location:r,files:o.map(s=>({path:s.path,sizeBytes:s.size}))};process.stdout.write(JSON.stringify(i,null,2)+`
703
+ `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate package ")));let n=a.spinner();try{n.start(`Generating package ${U.cyan(e)} in ${U.dim(r)}...`);let o=await pt("package",e,{category:t.category});n.stop(`Created package ${U.cyan(e)}`,0),a.success(`Package created with ${o.length} files`),a.info("Next steps:"),a.info(` Edit ${r}/src/index.ts`),a.info(` Run: pnpm --filter @nebutra/${e} build`),process.exit(c.SUCCESS)}catch(o){n.stop(`Failed to generate package: ${o instanceof Error?o.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function ns(e,t){if(t.dryRun){let n=await mt("route",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"route",path:e,location:`backends/gateway/src/routes/${e}.ts`,files:n.map(i=>({path:i.path,sizeBytes:i.size}))};process.stdout.write(JSON.stringify(o,null,2)+`
704
+ `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate route ")));let r=a.spinner();try{r.start(`Generating route ${U.cyan(e)}...`);let n=await pt("route",e);r.stop(`Created route ${U.cyan(e)}`,0),a.success(`Route created with ${n.length} files`),a.info(`File: backends/gateway/src/routes/${e}.ts`),a.info(`Add to your main app.ts: app.route("/${e}", routes)`),process.exit(c.SUCCESS)}catch(n){r.stop(`Failed to generate route: ${n instanceof Error?n.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function os(e,t){if(t.dryRun){let n=await mt("component",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"component",name:e,location:"packages/design/ui/src/components/",files:n.map(i=>({path:i.path,sizeBytes:i.size})),nextSteps:["Add export to packages/design/ui/src/components/index.ts","Run: pnpm --filter @nebutra/ui typecheck","View in Storybook: pnpm --filter @nebutra/storybook dev"]};process.stdout.write(JSON.stringify(o,null,2)+`
705
+ `),process.exit(c.DRY_RUN_OK)}Be.intro(U.bgCyan(U.black(" nebutra generate component ")));let r=a.spinner();try{r.start(`Generating component ${U.cyan(e)}...`);let n=await pt("component",e);r.stop(`Created component ${U.cyan(e)}`,0),a.success(`Component created with ${n.length} files`),a.info("Files created in packages/design/ui/src/components/"),a.info("Next steps:"),a.info(" 1. Add export to packages/design/ui/src/components/index.ts"),a.info(" 2. pnpm --filter @nebutra/ui typecheck"),a.info(" 3. pnpm --filter @nebutra/storybook dev"),process.exit(c.SUCCESS)}catch(n){r.stop(`Failed to generate component: ${n instanceof Error?n.message:"Unknown error"}`,1),process.exit(c.ERROR)}}function Qr(e){let t=e.command("generate").description("Scaffold a new app, package, route, or component").alias("gen");t.command("app <name>").description("Scaffold a new Next.js app (Next.js 16 + Tailwind v4)").option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").option("--template <type>","App template (default: nextjs)","nextjs").option("--port <number>","Dev server port","3000").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await ts(r,{...n,dryRun:n.dryRun||!1,yes:o.yes||!1,interactive:process.stdin.isTTY})}),t.command("package <name>").description(`Scaffold a new categorized package (@nebutra/<name>). Categories: ${Me.join(", ")}`).requiredOption("--category <category>",`Package category: ${Me.join(" | ")}`).option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await rs(r,{...n,category:n.category,dryRun:n.dryRun||!1,yes:o.yes||!1})}),t.command("route <path>").description("Scaffold a Hono API route in backends/gateway").option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await ns(r,{...n,dryRun:n.dryRun||!1,yes:o.yes||!1})}),t.command("component <name>").description("Scaffold a UI component with Storybook story").option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").option("--variants <list>","Comma-separated variant names (e.g., 'primary,secondary')").option("--sizes <list>","Comma-separated size names (e.g., 'sm,md,lg')").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await os(r,{...n,dryRun:n.dryRun||!1,yes:o.yes||!1,variants:n.variants,sizes:n.sizes})})}import je from"picocolors";async function Y(e,t){let r=await b(),n=new URL(e,"http://localhost:3000/api/growth");t?.query&&Object.entries(t.query).forEach(([i,s])=>{n.searchParams.set(i,s)});let o=await fetch(n,{method:t?.method||"GET",headers:{"Content-Type":"application/json"},body:t?.body?JSON.stringify(t.body):void 0});if(!o.ok)throw new Error(`Growth API error (${o.status}): ${await o.text()}`);return o.json()}async function as(e){try{let t=e.period||"7d",r=e.compare;a.info(`Fetching growth metrics for ${t}...`);let n=await Y("/summary",{query:{period:t,compare:r?"true":"false"}});return c.SUCCESS}catch(t){return a.error(`Dashboard error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function is(e){try{let t=e.period||"7d",r=e.segment||"all";a.info(`Fetching funnel data for ${t} (${r})...`);let n=await Y("/funnel",{query:{period:t,segment:r}});return n.forEach((i,s)=>{let l="\u2588".repeat(Math.ceil(i.rate*20)),u="\u2591".repeat(20-Math.ceil(i.rate*20)),m=s<n.length-1?je.red(`\u2193 ${(i.dropoff_rate*100).toFixed(1)}% drop`):""}),n.reduce((i,s)=>s.dropoff_rate>i.dropoff_rate?s:i).dropoff_rate>.2,c.SUCCESS}catch(t){return a.error(`Funnel error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function ss(e){try{let t=e.period||"weekly",r=parseInt(e.cohorts,10)||8;a.info(`Fetching ${t} cohort data (${r} cohorts)...`);let n=await Y("/cohort",{query:{period:t,cohorts:String(r)}});if(n.length===0)return c.SUCCESS;let o=Object.keys(n[0]).slice(1);return n.forEach(i=>{let l=String(i.cohort).padEnd(15);o.forEach(u=>{let m=i[u];if(typeof m=="number"){let f=m/100,y=String(Math.round(m)).padEnd(8);f>=.7?y=je.green(y):f>=.4?y=je.yellow(y):y=je.red(y),l+=y+" "}})}),c.SUCCESS}catch(t){return a.error(`Cohort error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function cs(e,t){try{if(e==="stats"){a.info("Fetching newsletter stats...");let r=await Y("/newsletter/stats");return c.SUCCESS}if(e==="subscribers"){let r=parseInt(t.limit,10)||10,n=parseInt(t.offset,10)||0;return a.info(`Fetching ${r} newsletter subscribers (offset ${n})...`),(await Y("/newsletter/subscribers",{query:{limit:String(r),offset:String(n)}})).forEach(i=>{}),c.SUCCESS}if(e==="send"){let r=t.template;return r?t.yes?(a.info(`Sending newsletter with template: ${r}`),await Y("/newsletter/send",{method:"POST",body:{template_id:r}}),c.SUCCESS):(a.warn("Use --yes to confirm newsletter send"),c.ERROR):(a.error("--template is required"),c.ERROR)}return a.error(`Unknown newsletter subcommand: ${e}`),c.ERROR}catch(r){return a.error(`Newsletter error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function ls(e,t){try{if(e==="status"){a.info("Fetching referral program status...");let r=await Y("/referral/status");return c.SUCCESS}if(e==="config"){a.info("Fetching referral config...");let r=await Y("/referral/config");return Object.entries(r).forEach(([n,o])=>{}),c.SUCCESS}return e==="leaderboard"?(a.info("Fetching referral leaderboard..."),(await Y("/referral/leaderboard")).forEach(n=>{let o=n.rank===1?"\u{1F947}":n.rank===2?"\u{1F948}":"\u{1F949}"}),c.SUCCESS):(a.error(`Unknown referral subcommand: ${e}`),c.ERROR)}catch(r){return a.error(`Referral error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function ds(e,t){try{if(e==="list"){a.info("Fetching active experiments...");let r=await Y("/experiment");return r.length===0?c.SUCCESS:(r.forEach(n=>{let o=n.status==="running"?je.yellow("\u25CF"):je.green("\u2713")}),c.SUCCESS)}if(e==="create"){let r=t.name,n=t.variants?.split(","),o=t.metric;if(!r||!n||!o)return a.error("Required: --name <name> --variants <A,B> --metric <metric>"),c.ERROR;a.info(`Creating experiment: ${r}`);let i=await Y("/experiment",{method:"POST",body:{name:r,variants:n,metric:o}});return c.SUCCESS}if(e==="results"){let r=t.id;if(!r)return a.error("--id is required"),c.ERROR;a.info(`Fetching results for experiment ${r}...`);let n=await Y(`/experiment/${r}`);return n.winner,n.significance,c.SUCCESS}if(e==="conclude"){let r=t.id,n=t.winner;return!r||!n?(a.error("Required: --id <id> --winner <variant>"),c.ERROR):t.yes?(a.info(`Concluding experiment ${r} with winner: ${n}`),await Y(`/experiment/${r}`,{method:"POST",body:{action:"conclude",winner:n}}),c.SUCCESS):(a.warn("Use --yes to confirm experiment conclusion"),c.ERROR)}return a.error(`Unknown experiment subcommand: ${e}`),c.ERROR}catch(r){return a.error(`Experiment error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function us(e){try{let t=e.focus||"activation",r=e.depth||"quick";a.info(`Generating growth insights (focus: ${t}, depth: ${r})...`);let n=await Y("/pulse",{query:{focus:t,depth:r}});return n.insights.forEach(o=>{}),n.recommendations.forEach(o=>{}),c.SUCCESS}catch(t){return a.error(`Pulse error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}function Zr(e){let t=e.command("growth").description("Growth engine operations \u2014 metrics, funnel, cohorts, AI insights");t.command("dashboard").description("Growth metrics overview").option("--period <7d|30d|90d>","Time period","7d").option("--compare","Show period-over-period deltas").action(async i=>{process.exit(await as(i))}),t.command("funnel").description("Conversion funnel analysis").option("--period <7d|30d|90d>","Time period","7d").option("--segment <organic|paid|referral>","Traffic segment","all").action(async i=>{process.exit(await is(i))}),t.command("cohort").description("Cohort retention analysis").option("--period <weekly|monthly>","Cohort period","weekly").option("--cohorts <n>","Number of cohorts","8").action(async i=>{process.exit(await ss(i))}),t.command("newsletter <subcommand>").description("Newsletter management").action(async(i,s)=>{process.exit(await cs(i,s))}),t.command("referral <subcommand>").description("Referral program management").action(async(i,s)=>{process.exit(await ls(i,s))}),t.command("experiment <subcommand>").description("A/B testing and experiment management").option("--id <id>","Experiment ID").option("--name <name>","Experiment name").option("--variants <A,B>","Comma-separated variants").option("--metric <metric>","Success metric").option("--winner <variant>","Winning variant").action(async(i,s)=>{process.exit(await ds(i,s))}),t.command("pulse").description("AI-generated growth insights (AARRR: Acquisition, Activation, Retention, Revenue, Referral)").option("--focus <aarrr>","Focus area (acquisition|activation|retention|revenue|referral)","activation").option("--depth <quick|deep>","Analysis depth","quick").action(async i=>{process.exit(await us(i))}),t.option("--dry-run","Preview changes without applying them").option("--format <json|text>","Output format","text").option("--yes","Skip confirmation prompts")}import Vt,{lstatSync as ms,readdirSync as Mt,readFileSync as ps,writeFileSync as fs}from"fs";import de from"path";import{fileURLToPath as gs}from"url";import X from"picocolors";var ys=de.dirname(gs(import.meta.url));function Bt(){let e=new Map,t=de.join(ys,"../../../apps");if(!Vt.existsSync(t))return e;try{let r=Mt(t);for(let n of r){let o=de.join(t,n),i=de.join(o,"messages");Vt.existsSync(i)&&ms(i).isDirectory()&&e.set(n,i)}}catch(r){a.debug(`Error scanning apps directory: ${r instanceof Error?r.message:String(r)}`)}return e}function Ge(e,t=""){let r=new Set;for(let[n,o]of Object.entries(e)){let i=t?`${t}.${n}`:n;if(typeof o=="object"&&o!==null&&!Array.isArray(o)){let s=Ge(o,i);for(let l of s)r.add(l)}else r.add(i)}return r}function qe(e){try{let t=ps(e,"utf-8");return JSON.parse(t)}catch(t){return a.debug(`Failed to parse ${e}: ${t instanceof Error?t.message:String(t)}`),null}}async function hs(e){if(a.info("Syncing language files across the project..."),(await K("translate",{filter:"landing-page",dryRun:e.dryRun,interactive:e.interactive??!0})).exitCode!==0){a.warn("Landing page translate script not found or failed. Trying sync-lang.mjs...");let r=await x({command:"node",args:["scripts/sync-lang.mjs"],dryRun:e.dryRun,interactive:e.interactive??!0,label:"Sync language files"});r.exitCode!==0&&(a.error("Failed to sync language files"),process.exit(r.exitCode)),e.format==="json"?console.log(JSON.stringify({command:"i18n:sync",exitCode:0,success:!0},null,2)):e.dryRun||a.success("Language files synced successfully")}else e.format==="json"?console.log(JSON.stringify({command:"i18n:sync",exitCode:0,success:!0},null,2)):e.dryRun||a.success("Language files synced successfully")}async function bs(e){a.info("Validating translation files...");let t=Bt();t.size===0&&(a.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let r=new Map,n=!1;for(let[o,i]of t){let s=[];try{let l=Mt(i).filter(y=>y.endsWith(".json"));if(l.length===0)continue;let u=de.join(i,"en.json"),m=qe(u);if(!m){a.warn(`Could not load reference locale en.json from ${o}`);continue}let f=Ge(m);for(let y of l){if(y==="en.json")continue;let C=y.replace(".json",""),L=de.join(i,y),D=qe(L);if(!D){a.debug(`Could not parse ${y}`);continue}let q=Ge(D),ue=Array.from(f).filter(p=>!q.has(p)),ie=Array.from(q).filter(p=>!f.has(p)),Re=f.size>0?(f.size-ue.length)/f.size*100:100;(ue.length>0||ie.length>0)&&(n=!0),s.push({locale:C,totalKeys:f.size,missingKeys:ue,extraKeys:ie,coverage:Math.round(Re*100)/100})}s.length>0&&r.set(o,s)}catch(l){a.debug(`Error validating ${o}: ${l instanceof Error?l.message:String(l)}`)}}if(e.format==="json"){let o={command:"i18n:validate",success:!n,results:Array.from(r.entries()).reduce((i,[s,l])=>(i[s]=l,i),{})};console.log(JSON.stringify(o,null,2))}else for(let[o,i]of r){a.info(`${X.bold(o)}:`);for(let s of i){let u=(s.coverage>=100?X.green:s.coverage>=80?X.yellow:X.red)(`${s.coverage}%`);a.info(` ${X.cyan(s.locale.padEnd(5))} ${u.padEnd(20)} [${s.totalKeys} keys]`),s.missingKeys.length>0&&a.warn(` Missing: ${s.missingKeys.slice(0,5).join(", ")}${s.missingKeys.length>5?` (+ ${s.missingKeys.length-5} more)`:""}`),s.extraKeys.length>0&&a.warn(` Extra: ${s.extraKeys.slice(0,5).join(", ")}${s.extraKeys.length>5?` (+ ${s.extraKeys.length-5} more)`:""}`)}}n&&process.exit(c.CONFLICT)}async function vs(e,t){/^[a-z]{2}(-[A-Z]{2})?$/.test(e)||(a.error(`Invalid locale format: ${e}. Use 'en', 'es', 'zh-CN', etc.`),process.exit(c.INVALID_ARGS));let r=Bt();r.size===0&&(a.error("No message directories found in the project"),process.exit(c.NOT_FOUND));let n=[],o=!1;for(let[s,l]of r){let u=de.join(l,`${e}.json`);if(Vt.existsSync(u)){a.warn(`Locale ${e} already exists in ${s}`);continue}try{let C=function(L){for(let D in L)typeof L[D]=="string"?L[D]="":typeof L[D]=="object"&&L[D]!==null&&C(L[D])};var i=C;let m=de.join(l,"en.json"),f=qe(m);if(!f){a.warn(`Could not load reference en.json from ${s}, skipping...`);continue}let y=JSON.parse(JSON.stringify(f));C(y),t.dryRun?a.info(`Would create ${e} locale in ${s}`):(fs(u,JSON.stringify(y,null,2)+`
706
+ `),n.push({app:s,path:u}),a.success(`Created ${e} locale in ${s}`))}catch(m){a.error(`Failed to create locale in ${s}: ${m instanceof Error?m.message:String(m)}`),o=!0}}t.format==="json"?console.log(JSON.stringify({command:"i18n:add",locale:e,dryRun:t.dryRun||!1,created:n,success:!o},null,2)):t.dryRun||a.success(`Locale '${e}' added to ${n.length} app(s)`),o&&process.exit(c.ERROR)}async function ws(e){a.info("Checking translation coverage...");let t=Bt();t.size===0&&(a.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let r=new Map,n=0,o=0;for(let[i,s]of t){let l=[];try{let u=Mt(s).filter(C=>C.endsWith(".json"));if(u.length===0)continue;let m=de.join(s,"en.json"),f=qe(m);if(!f){a.debug(`Could not load reference locale from ${i}`);continue}let y=Ge(f);for(let C of u){let L=C.replace(".json",""),D=de.join(s,C),q=qe(D);if(!q)continue;let ue=Ge(q),ie=Array.from(ue).filter(F=>{let _e=q[F.split(".")[0]];return _e!==void 0&&_e!==""}).length,Re=y.size-ie,p=y.size>0?ie/y.size*100:0;l.push({locale:L,coverage:Math.round(p*100)/100,totalKeys:y.size,translatedKeys:ie,missingKeys:Re})}l.length>0&&(r.set(i,l),o++,n+=l.reduce((C,L)=>C+L.coverage,0)/l.length)}catch(u){a.debug(`Error checking status for ${i}: ${u instanceof Error?u.message:String(u)}`)}}if(e.format==="json"){let i={command:"i18n:status",averageCoverage:o>0?Math.round(n/o*100)/100:0,results:Array.from(r.entries()).reduce((s,[l,u])=>(s[l]=u,s),{})};console.log(JSON.stringify(i,null,2))}else{for(let[i,s]of r){a.info(`${X.bold(i)}:`);for(let l of s){let u="",f=Math.round(l.coverage/100*20);u="\u2588".repeat(f)+"\u2591".repeat(20-f);let C=(l.coverage>=100?X.green:l.coverage>=80?X.yellow:X.red)(`${l.coverage.toFixed(1)}%`);a.info(` ${X.cyan(l.locale.padEnd(5))} [${u}] ${C}`),a.info(` ${l.translatedKeys}/${l.totalKeys} keys (${l.missingKeys} missing)`)}}if(o>0){let i=n/o,s=i>=100?X.green:i>=80?X.yellow:X.red;a.info(`
707
+ Average coverage: ${s(i.toFixed(1)+"%")}`)}}}function en(e){let t=e.command("i18n").description("Manage internationalization and translations");t.command("sync").description("Synchronize language translations across the project").option("--dry-run","Preview changes without executing").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await hs({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})}),t.command("validate").description("Validate all locale files for missing or extra keys").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await bs({format:r.format||n.format,interactive:n.yes!==!0})}),t.command("add <locale>").description("Add a new locale with template files (e.g. 'en', 'es', 'zh-CN')").option("--dry-run","Preview what would be created without writing files").option("--format <type>","Output format: json or plain").action(async(r,n)=>{let o=n.optsWithGlobals?.()||n;await vs(r,{dryRun:n.dryRun||!1,format:n.format||o.format,interactive:o.yes!==!0})}),t.command("status").description("Show translation coverage per locale and app").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await ws({format:r.format||n.format,interactive:n.yes!==!0})})}import*as ft from"@clack/prompts";async function Ss(e){let t=e.lite?"docker-compose.lite.yml":void 0,r=e.lite?"Starting lite stack (PostgreSQL + Redis)":"Starting full stack";d(r+"...","info");let n=await Pe("up -d",{file:t,profile:e.profile,dryRun:e.dryRun});n.exitCode===0?d("Infrastructure stack started successfully","success"):(d("Failed to start infrastructure stack","error"),A("Docker compose output",{stderr:n.stderr}),process.exit(n.exitCode||1))}async function Rs(e){d("Stopping infrastructure stack...","info");let t=await Pe("down",{dryRun:e.dryRun});t.exitCode===0?d("Infrastructure stack stopped","success"):(d("Failed to stop infrastructure stack","error"),A("Docker compose output",{stderr:t.stderr}),process.exit(t.exitCode||1))}async function ks(e){d("Checking infrastructure status...","info");let t=await Pe("ps --format json",{dryRun:e.dryRun});if(t.exitCode===0)try{let r=JSON.parse(t.stdout);if(e.format==="json")k(r,{format:"json"});else{let n=r.map(o=>({name:o.Name,status:o.Status,ports:o.Ports||"-"}));k(n,{format:"table"})}}catch{k(t.stdout,{format:"plain"})}else d("Failed to check infrastructure status","error"),A("Docker compose output",{stderr:t.stderr}),process.exit(t.exitCode||1)}async function Es(e,t){let r=t||{},n=e?`Fetching logs for ${e}...`:"Fetching infrastructure logs...";d(n,"info");let o=["logs","--tail","50"];e&&o.push(e);let i=await Pe(o.join(" "),{dryRun:r.dryRun});i.exitCode===0?k(i.stdout,{format:"plain"}):(d("Failed to fetch logs","error"),A("Docker compose output",{stderr:i.stderr}),process.exit(i.exitCode||1))}async function Cs(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let n=await ft.confirm({message:"Reset infrastructure? This will remove all containers and volumes.",initialValue:!1});(ft.isCancel(n)||!n)&&(d("Reset cancelled","warn"),process.exit(c.CANCELLED))}else d("Infrastructure reset requires explicit --yes confirmation (use: nebutra infra reset --yes)","error"),process.exit(c.INVALID_ARGS);d("Resetting infrastructure stack...","warn");let r=await Pe("down -v",{dryRun:e.dryRun});r.exitCode===0?d("Infrastructure reset successfully","success"):(d("Failed to reset infrastructure","error"),A("Docker compose output",{stderr:r.stderr}),process.exit(r.exitCode||1))}function tn(e){e.command("infra <verb> [service]").description("Manage Docker Compose infrastructure (PostgreSQL, Redis, Meilisearch, etc.)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations (especially for reset)").option("--lite","Use lite stack (PostgreSQL + Redis only)").option("--profile <name>","Docker Compose profile to use (e.g., search)").option("--format <type>","Output format: json, plain","plain").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,lite:o.lite||!1,profile:o.profile};try{switch(r){case"up":await Ss(s);break;case"down":await Rs(s);break;case"status":await ks(s);break;case"logs":await Es(n,s);break;case"reset":await Cs(s);break;default:d(`Unknown infra subcommand: ${r}. Valid commands: up, down, status, logs, reset`,"error"),process.exit(c.INVALID_ARGS)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Infrastructure command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
708
708
  Examples:
709
709
  nebutra infra up Start full stack
710
710
  nebutra infra up --lite Start lite stack (PostgreSQL + Redis)
@@ -721,24 +721,24 @@ Flags:
721
721
  --lite Use docker-compose.lite.yml (PostgreSQL + Redis only)
722
722
  --profile <name> Enable Docker Compose profile (search, notifications, etc.)
723
723
  --format <type> Output format: json, plain (default: plain, auto-json in non-TTY)
724
- `)}import Gt from"fs";import Es from"path";import*as Z from"@clack/prompts";import gt from"picocolors";var Cs={$schema:"https://nebutra.com/schema.json",componentsDirectory:"packages/design/ui/src/components",tailwind:{config:"tailwind.config.ts",css:"packages/design/tokens/styles.css",baseColor:"slate",cssVariables:!0},aliases:{components:"@nebutra/ui",utils:"@nebutra/ui/utils"}};function As(){return process.stdout.isTTY===!0}function xs(e){return e.yes===!0||e.dryRun===!0||!As()}function Os(e,t,r){return{operation:r?"update":"create",path:e,...r&&{before:r},after:t}}async function tn(e={}){let t=process.cwd(),r=Es.join(t,"nebutra.config.json"),n=Gt.existsSync(r);e.ifNotExists&&n&&(a.info("nebutra.config.json already exists, skipping initialization."),process.exit(c.SUCCESS));let o=xs(e);o||Z.intro(gt.bgCyan(gt.black(" nebutra init "))),n&&!o&&(Z.log.warn("nebutra.config.json already exists in this directory."),await Z.confirm({message:"Do you want to overwrite it?",initialValue:!1})||(Z.outro("Operation aborted."),process.exit(c.CANCELLED)));let i={...Cs};if(e.dryRun){let s=n?JSON.parse(Gt.readFileSync(r,"utf-8")):void 0,l=Os(r,i,s);O(l),d("Dry-run completed. No changes made."),process.exit(c.DRY_RUN_OK)}o?a.info("Initializing Nebutra CLI configuration..."):Z.spinner().start("Initializing Nebutra CLI configuration..."),Gt.writeFileSync(r,JSON.stringify(i,null,2)+`
725
- `),o?(a.success("Configuration saved to nebutra.config.json"),a.info('Initialization complete! You can now use "nebutra add" to start injecting components.')):(await new Promise(s=>setTimeout(s,800)),Z.spinner().stop(gt.green("Configuration saved to nebutra.config.json")),Z.outro(gt.cyan('Initialization complete! You can now use "nebutra add" to start injecting components.'))),process.exit(c.SUCCESS)}import bt from"fs/promises";import Ls from"os";import Ke from"path";import*as T from"@clack/prompts";import R from"picocolors";var _s="https://analytics.nebutra.com";function Ps(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function Ts(){return process.env.npm_package_version??"0.0.0-dev"}function yt(e,t={}){Ps(t)||(async()=>{try{let r=await import("./dist-RKQ2VFAN.js");if(typeof r.createProductAnalyticsClient!="function")return;let n=r.createProductAnalyticsClient({posthog:{apiKey:process.env.POSTHOG_KEY??process.env.NEXT_PUBLIC_POSTHOG_KEY??process.env.NEBUTRA_POSTHOG_KEY??"",host:process.env.POSTHOG_HOST??process.env.NEXT_PUBLIC_POSTHOG_HOST??process.env.NEBUTRA_POSTHOG_HOST??_s},onError:()=>{}});if(typeof n?.track!="function")return;let o=n.track("license.cli",{action:e.action,cli_version:Ts(),...e.tier?{license_tier:e.tier}:{},...e.type?{license_type:e.type}:{},...e.error_code?{error_code:e.error_code}:{}});o&&typeof o.then=="function"&&await o.catch(()=>{})}catch{}})()}import{createHmac as Is}from"crypto";var $s=[{id:"v1",key:"nebutra-sailor:scaffold-marker:v1"}],js="v1";function Ns(e){if(e)return $s.find(t=>t.id===e)}function Us(e,t){let r=`${e.cliVersion}|${e.scaffoldedAt}|${e.projectName}|${e.nonce}`;return Is("sha256",t).update(r).digest("hex")}function rn(e){if(!e)return{valid:!1,reason:"missing_meta"};if(e.schemaVersion!==1)return{valid:!1,reason:"schema_mismatch"};if(typeof e.cliVersion!="string"||typeof e.scaffoldedAt!="string"||typeof e.projectName!="string"||typeof e.nonce!="string"||typeof e.signature!="string")return{valid:!1,reason:"schema_mismatch"};let t=e.signingKeyId??js,r=Ns(t);return r?Us({cliVersion:e.cliVersion,scaffoldedAt:e.scaffoldedAt,projectName:e.projectName,nonce:e.nonce},r.key)!==e.signature?{valid:!1,reason:"signature_mismatch"}:{valid:!0,reason:"ok"}:{valid:!1,reason:"unknown_signing_key"}}var ht={ok:"valid",missing_meta:".nebutra/scaffold-meta.json not found",schema_mismatch:"scaffold-meta.json schema mismatch (corrupt or future format)",unknown_signing_key:"signed with an unknown key \u2014 upgrade `nebutra` to a newer release that recognises it",signature_mismatch:"signature does not match \u2014 file has been tampered with or hand-edited"};var nn=process.env.NEBUTRA_LICENSE_API_URL??"https://nebutra.com";async function on(){let e=Ls.homedir(),t=Ke.join(e,".config","nebutra");try{await bt.mkdir(t,{recursive:!0})}catch{}return t}async function Ds(e){let t=`${nn}/api/license/validate?key=${encodeURIComponent(e)}`,r;try{r=await fetch(t,{signal:AbortSignal.timeout(1e4)})}catch{throw new Error(`Could not reach the Nebutra license server (${nn}). Check your internet connection or set NEBUTRA_LICENSE_API_URL.`)}if(r.status===404)throw new Error("License key not found. Please check the key and try again.");if(r.status===410)throw new Error("License key has expired. Please renew your license at nebutra.com.");if(!r.ok)throw new Error(`License validation failed (HTTP ${r.status}). Please try again later.`);let n=await r.json();if(!n.valid)throw new Error("License key is not valid. Please check the key and try again.");return{tier:n.tier??"UNKNOWN",type:n.type??"UNKNOWN"}}function Fs(e){let t=e instanceof Error?e.message:String(e);return/Invalid license key format/i.test(t)?"invalid_format":/license server/i.test(t)?"network_error":/not found/i.test(t)?"not_found":/expired/i.test(t)?"expired":/not valid/i.test(t)?"invalid_key":/HTTP \d+/i.test(t)?"http_error":"unknown"}async function Vs(e,t){let r=t.quiet===!0;r||T.intro(R.bgCyan(R.black(" Nebutra License Activation "))),yt({action:"activate_attempted"});try{if(e.length<10)throw new Error("Invalid license key format.");r||T.log.step("Validating license key with Nebutra...");let{tier:n,type:o}=await Ds(e),i=await on(),s=Ke.join(i,"license.json");await bt.writeFile(s,JSON.stringify({licenseKey:e,tier:n,type:o,activatedAt:new Date().toISOString()},null,2),"utf-8"),r||(T.log.success(R.green(`${n} license activated and saved to ${s}`)),T.outro(R.cyan("Premium CLI capabilities are now unlocked!"))),yt({action:"activated",tier:n,type:o})}catch(n){yt({action:"failed",error_code:Fs(n)}),r||(T.log.error(R.red("Activation failed")),a.error(n instanceof Error?n.message:String(n)),T.outro("Please check your key and try again.")),process.exit(c.ERROR)}}async function Ms(e){let t=e.quiet===!0;t||T.intro(R.bgCyan(R.black(" Nebutra License Status ")));try{let r=await on(),n=Ke.join(r,"license.json"),o=await bt.readFile(n,"utf-8"),i=JSON.parse(o);if(i.licenseKey)t||(T.log.success(R.green("License is active!")),T.log.info(`Key: ${i.licenseKey.substring(0,8)}...`),i.tier&&T.log.info(`Tier: ${R.bold(i.tier)}`),i.type&&T.log.info(`Type: ${i.type}`),T.log.info(`Activated: ${new Date(i.activatedAt).toLocaleString()}`),T.outro(R.cyan("You are ready to use premium features.")));else throw new Error("License key not found in config.")}catch{t||(T.log.warn(R.yellow("No active license found locally.")),T.log.message(R.dim("Run `nebutra license activate <key>` to unlock premium features.")),T.outro("")),process.exit(c.NOT_FOUND)}}async function Bs(e,t){let r=t.format==="json",n=t.quiet===!0,o=e?Ke.resolve(process.cwd(),e):process.cwd(),i=Ke.join(o,".nebutra","scaffold-meta.json"),s;try{s=await bt.readFile(i,"utf-8")}catch{let y={valid:!1,tier:null,cliVersion:null,scaffoldedAt:null,projectName:null,reason:"missing_meta",reasonText:ht.missing_meta,path:i};r?process.stdout.write(`${JSON.stringify(y,null,2)}
724
+ `)}import Gt from"fs";import As from"path";import*as Z from"@clack/prompts";import gt from"picocolors";var xs={$schema:"https://nebutra.com/schema.json",componentsDirectory:"packages/design/ui/src/components",tailwind:{config:"tailwind.config.ts",css:"packages/design/tokens/styles.css",baseColor:"slate",cssVariables:!0},aliases:{components:"@nebutra/ui",utils:"@nebutra/ui/utils"}};function Os(){return process.stdout.isTTY===!0}function _s(e){return e.yes===!0||e.dryRun===!0||!Os()}function Ps(e,t,r){return{operation:r?"update":"create",path:e,...r&&{before:r},after:t}}async function rn(e={}){let t=process.cwd(),r=As.join(t,"nebutra.config.json"),n=Gt.existsSync(r);e.ifNotExists&&n&&(a.info("nebutra.config.json already exists, skipping initialization."),process.exit(c.SUCCESS));let o=_s(e);o||Z.intro(gt.bgCyan(gt.black(" nebutra init "))),n&&!o&&(Z.log.warn("nebutra.config.json already exists in this directory."),await Z.confirm({message:"Do you want to overwrite it?",initialValue:!1})||(Z.outro("Operation aborted."),process.exit(c.CANCELLED)));let i={...xs};if(e.dryRun){let s=n?JSON.parse(Gt.readFileSync(r,"utf-8")):void 0,l=Ps(r,i,s);O(l),d("Dry-run completed. No changes made."),process.exit(c.DRY_RUN_OK)}o?a.info("Initializing Nebutra CLI configuration..."):Z.spinner().start("Initializing Nebutra CLI configuration..."),Gt.writeFileSync(r,JSON.stringify(i,null,2)+`
725
+ `),o?(a.success("Configuration saved to nebutra.config.json"),a.info('Initialization complete! You can now use "nebutra add" to start injecting components.')):(await new Promise(s=>setTimeout(s,800)),Z.spinner().stop(gt.green("Configuration saved to nebutra.config.json")),Z.outro(gt.cyan('Initialization complete! You can now use "nebutra add" to start injecting components.'))),process.exit(c.SUCCESS)}import bt from"fs/promises";import Fs from"os";import Ke from"path";import*as T from"@clack/prompts";import R from"picocolors";var Ts="https://analytics.nebutra.com";function Is(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function $s(){return process.env.npm_package_version??"0.0.0-dev"}function yt(e,t={}){Is(t)||(async()=>{try{let r=await import("./dist-RKQ2VFAN.js");if(typeof r.createProductAnalyticsClient!="function")return;let n=r.createProductAnalyticsClient({posthog:{apiKey:process.env.POSTHOG_KEY??process.env.NEXT_PUBLIC_POSTHOG_KEY??process.env.NEBUTRA_POSTHOG_KEY??"",host:process.env.POSTHOG_HOST??process.env.NEXT_PUBLIC_POSTHOG_HOST??process.env.NEBUTRA_POSTHOG_HOST??Ts},onError:()=>{}});if(typeof n?.track!="function")return;let o=n.track("license.cli",{action:e.action,cli_version:$s(),...e.tier?{license_tier:e.tier}:{},...e.type?{license_type:e.type}:{},...e.error_code?{error_code:e.error_code}:{}});o&&typeof o.then=="function"&&await o.catch(()=>{})}catch{}})()}import{createHmac as js}from"crypto";var Ns=[{id:"v1",key:"nebutra-sailor:scaffold-marker:v1"}],Us="v1";function Ls(e){if(e)return Ns.find(t=>t.id===e)}function Ds(e,t){let r=`${e.cliVersion}|${e.scaffoldedAt}|${e.projectName}|${e.nonce}`;return js("sha256",t).update(r).digest("hex")}function nn(e){if(!e)return{valid:!1,reason:"missing_meta"};if(e.schemaVersion!==1)return{valid:!1,reason:"schema_mismatch"};if(typeof e.cliVersion!="string"||typeof e.scaffoldedAt!="string"||typeof e.projectName!="string"||typeof e.nonce!="string"||typeof e.signature!="string")return{valid:!1,reason:"schema_mismatch"};let t=e.signingKeyId??Us,r=Ls(t);return r?Ds({cliVersion:e.cliVersion,scaffoldedAt:e.scaffoldedAt,projectName:e.projectName,nonce:e.nonce},r.key)!==e.signature?{valid:!1,reason:"signature_mismatch"}:{valid:!0,reason:"ok"}:{valid:!1,reason:"unknown_signing_key"}}var ht={ok:"valid",missing_meta:".nebutra/scaffold-meta.json not found",schema_mismatch:"scaffold-meta.json schema mismatch (corrupt or future format)",unknown_signing_key:"signed with an unknown key \u2014 upgrade `nebutra` to a newer release that recognises it",signature_mismatch:"signature does not match \u2014 file has been tampered with or hand-edited"};var on=process.env.NEBUTRA_LICENSE_API_URL??"https://nebutra.com";async function an(){let e=Fs.homedir(),t=Ke.join(e,".config","nebutra");try{await bt.mkdir(t,{recursive:!0})}catch{}return t}async function Vs(e){let t=`${on}/api/license/validate?key=${encodeURIComponent(e)}`,r;try{r=await fetch(t,{signal:AbortSignal.timeout(1e4)})}catch{throw new Error(`Could not reach the Nebutra license server (${on}). Check your internet connection or set NEBUTRA_LICENSE_API_URL.`)}if(r.status===404)throw new Error("License key not found. Please check the key and try again.");if(r.status===410)throw new Error("License key has expired. Please renew your license at nebutra.com.");if(!r.ok)throw new Error(`License validation failed (HTTP ${r.status}). Please try again later.`);let n=await r.json();if(!n.valid)throw new Error("License key is not valid. Please check the key and try again.");return{tier:n.tier??"UNKNOWN",type:n.type??"UNKNOWN"}}function Ms(e){let t=e instanceof Error?e.message:String(e);return/Invalid license key format/i.test(t)?"invalid_format":/license server/i.test(t)?"network_error":/not found/i.test(t)?"not_found":/expired/i.test(t)?"expired":/not valid/i.test(t)?"invalid_key":/HTTP \d+/i.test(t)?"http_error":"unknown"}async function Bs(e,t){let r=t.quiet===!0;r||T.intro(R.bgCyan(R.black(" Nebutra License Activation "))),yt({action:"activate_attempted"});try{if(e.length<10)throw new Error("Invalid license key format.");r||T.log.step("Validating license key with Nebutra...");let{tier:n,type:o}=await Vs(e),i=await an(),s=Ke.join(i,"license.json");await bt.writeFile(s,JSON.stringify({licenseKey:e,tier:n,type:o,activatedAt:new Date().toISOString()},null,2),"utf-8"),r||(T.log.success(R.green(`${n} license activated and saved to ${s}`)),T.outro(R.cyan("Premium CLI capabilities are now unlocked!"))),yt({action:"activated",tier:n,type:o})}catch(n){yt({action:"failed",error_code:Ms(n)}),r||(T.log.error(R.red("Activation failed")),a.error(n instanceof Error?n.message:String(n)),T.outro("Please check your key and try again.")),process.exit(c.ERROR)}}async function Gs(e){let t=e.quiet===!0;t||T.intro(R.bgCyan(R.black(" Nebutra License Status ")));try{let r=await an(),n=Ke.join(r,"license.json"),o=await bt.readFile(n,"utf-8"),i=JSON.parse(o);if(i.licenseKey)t||(T.log.success(R.green("License is active!")),T.log.info(`Key: ${i.licenseKey.substring(0,8)}...`),i.tier&&T.log.info(`Tier: ${R.bold(i.tier)}`),i.type&&T.log.info(`Type: ${i.type}`),T.log.info(`Activated: ${new Date(i.activatedAt).toLocaleString()}`),T.outro(R.cyan("You are ready to use premium features.")));else throw new Error("License key not found in config.")}catch{t||(T.log.warn(R.yellow("No active license found locally.")),T.log.message(R.dim("Run `nebutra license activate <key>` to unlock premium features.")),T.outro("")),process.exit(c.NOT_FOUND)}}async function qs(e,t){let r=t.format==="json",n=t.quiet===!0,o=e?Ke.resolve(process.cwd(),e):process.cwd(),i=Ke.join(o,".nebutra","scaffold-meta.json"),s;try{s=await bt.readFile(i,"utf-8")}catch{let y={valid:!1,tier:null,cliVersion:null,scaffoldedAt:null,projectName:null,reason:"missing_meta",reasonText:ht.missing_meta,path:i};r?process.stdout.write(`${JSON.stringify(y,null,2)}
726
726
  `):n||process.stderr.write(`${R.red("\u2718")} No scaffold marker found at ${R.dim(i)}.
727
727
  This project does not appear to be scaffolded by ${R.bold("create-sailor")}.
728
728
  Run ${R.cyan("npm create sailor@latest")} to scaffold a licensed project.
729
- `),process.exit(c.NOT_FOUND)}let l=null;try{l=JSON.parse(s)}catch{}let u=rn(l),m={valid:u.valid,tier:l?.license?.tier??null,cliVersion:l?.cliVersion??null,scaffoldedAt:l?.scaffoldedAt??null,projectName:l?.projectName??null,signingKeyId:l?.signingKeyId??null,reason:u.reason,reasonText:ht[u.reason],path:i};if(r&&(process.stdout.write(`${JSON.stringify(m,null,2)}
729
+ `),process.exit(c.NOT_FOUND)}let l=null;try{l=JSON.parse(s)}catch{}let u=nn(l),m={valid:u.valid,tier:l?.license?.tier??null,cliVersion:l?.cliVersion??null,scaffoldedAt:l?.scaffoldedAt??null,projectName:l?.projectName??null,signingKeyId:l?.signingKeyId??null,reason:u.reason,reasonText:ht[u.reason],path:i};if(r&&(process.stdout.write(`${JSON.stringify(m,null,2)}
730
730
  `),process.exit(u.valid?c.SUCCESS:c.INCOMPATIBLE)),!n)if(u.valid&&l){let f=new Date(l.scaffoldedAt).toLocaleDateString("en-US",{year:"numeric",month:"short",day:"numeric"}),y=[`${R.green("\u2713")} Project "${R.bold(l.projectName)}" scaffolded with ${R.cyan(`create-sailor@${l.cliVersion}`)} on ${f}`,` Signing key: ${R.dim(l.signingKeyId??"v1 (legacy, no keyId)")}`,` Tier: ${R.bold(l.license?.tier??"independent")}`,` ${R.green("Independent Developer License valid.")}`];process.stderr.write(`${y.join(`
731
731
  `)}
732
732
  `)}else{let f=ht[u.reason];process.stderr.write(`${R.red("\u2718")} Invalid scaffold marker.
733
733
  Reason: ${R.yellow(f)}
734
734
  File: ${R.dim(i)}
735
- `)}process.exit(u.valid?c.SUCCESS:c.INCOMPATIBLE)}function an(e){let t=e.command("license").description("Manage your Nebutra-Sailor commercial license");t.command("activate <key>").description("Activate a commercial license key for local development").option("--quiet","Suppress output").action(async(r,n)=>{await Vs(r,n)}),t.command("status").description("Check the locally configured license status").option("--quiet","Suppress output").action(async r=>{await Ms(r)}),t.command("verify [path]").description("Verify the scaffold-meta HMAC signature in a create-sailor project (defaults to cwd)").option("--format <type>","Output format: json | plain (default: plain)").option("--quiet","Suppress non-essential output").action(async function(r,n,o){let i=o&&typeof o.optsWithGlobals=="function"?o.optsWithGlobals()??{}:{...n},s=typeof n?.format=="string"?n.format:typeof i.format=="string"?i.format:void 0,l=!!n?.quiet||!!i.quiet;await Bs(r,{format:s,quiet:l})})}import{existsSync as sn,readFileSync as Gs,writeFileSync as qs}from"fs";import{dirname as Ks,join as cn,parse as zs}from"path";import*as vt from"@clack/prompts";function Ws(e){let t=e,{root:r}=zs(t);for(;;){if(sn(cn(t,"package.json")))return t;if(t===r)return null;let n=Ks(t);if(n===t)return null;t=n}}function Ys(e){if(!sn(e))return{};try{return JSON.parse(Gs(e,"utf-8"))}catch{return{}}}function Hs(e,t){qs(e,JSON.stringify(t,null,2)+`
736
- `)}async function Js(e,t){let r=t.format==="json",n=Ws(process.cwd());n||(r?console.log(JSON.stringify({command:"link",success:!1,error:"No package.json found upstream"},null,2)):a.error("No package.json found in current or parent directories."),process.exit(c.NOT_FOUND));let o=e;if(!o){t.yes&&(r?console.log(JSON.stringify({command:"link",success:!1,error:"project-id required in --yes mode"},null,2)):a.error("project-id is required when running with --yes / non-interactive."),process.exit(c.INVALID_ARGS));let u=await vt.text({message:"Project ID to link to:",placeholder:"proj_abc123",validate:m=>m&&m.trim().length>0?void 0:"Project ID cannot be empty"});vt.isCancel(u)&&(a.warn("Cancelled"),process.exit(c.CANCELLED)),o=String(u).trim()}let i=cn(n,"nebutra.config.json"),l={...Ys(i),projectId:o};Hs(i,l),r?console.log(JSON.stringify({command:"link",success:!0,projectId:o,configPath:i},null,2)):a.success(`Linked to project: ${o}`)}function ln(e){e.command("link [project-id]").description("Link the current project to a Nebutra project id").option("--format <type>","Output format: json or plain").action(async(t,r,n)=>{let o=n?.optsWithGlobals?.()||r;await Js(t,{yes:o.yes||!1,format:r.format||o.format})})}import{existsSync as dn,rmSync as Xs,unlinkSync as Qs}from"fs";import{homedir as un,platform as Zs}from"os";import{join as ze}from"path";function ec(){if(Zs()==="win32"){let t=process.env.LOCALAPPDATA||ze(un(),"AppData","Local");return ze(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?ze(e,"nebutra"):ze(un(),".config","nebutra")}var tc=["auth.json","session.json","token","credentials.json"];async function rc(e){let t=ec(),r=e.format==="json",n=0,o=[];if(e.all){if(dn(t))try{Xs(t,{recursive:!0,force:!0}),n=1,o.push(t)}catch(i){let s=i instanceof Error?i.message:String(i);r?console.log(JSON.stringify({command:"logout",success:!1,error:s},null,2)):a.error(`Failed to clear config directory: ${s}`),process.exit(c.PERMISSION_DENIED)}}else for(let i of tc){let s=ze(t,i);if(dn(s))try{Qs(s),n++,o.push(s)}catch{}}n===0&&(r?console.log(JSON.stringify({command:"logout",success:!0,alreadyLoggedOut:!0,removed:[]},null,2)):a.info("Already logged out"),process.exit(c.SUCCESS)),r?console.log(JSON.stringify({command:"logout",success:!0,removed:o,clearedAll:!!e.all},null,2)):a.success(e.all?"Cleared all nebutra config":"Logged out of nebutra.com")}function mn(e){e.command("logout").description("Clear stored authentication credentials").option("--all","Clear ALL local config, not just auth tokens").option("--format <type>","Output format: json or plain").action(async(t,r)=>{let n=r?.optsWithGlobals?.()||t;await rc({all:t.all||!1,format:t.format||n.format})})}import{spawn as nc}from"child_process";import{dirname as oc,resolve as ac}from"path";import{fileURLToPath as ic}from"url";import*as ae from"@clack/prompts";import fe from"picocolors";var sc=oc(ic(import.meta.url));function cc(){let e=[()=>ac(sc,"../../../mcp/dist/server/contextServer.js")];for(let t of e)try{return t()}catch(r){a.debug("MCP server binary resolution strategy failed",{error:r})}return"nebutra-mcp"}function pn(e){e.command("mcp").description("Start the Nebutra MCP server for Cursor/Windsurf").option("--stdio","Use stdio transport (default)",!0).action(async t=>{ae.intro(fe.bgCyan(fe.black(" nebutra mcp ")));try{let r=cc();ae.log.info(fe.cyan("Starting Nebutra MCP server for Cursor/Windsurf integration...")),ae.log.info(fe.dim(`Press Ctrl+C to stop the server.
737
- `));let n=nc(process.execPath,[r],{stdio:"inherit",env:{...process.env}});n.on("close",o=>{o===0?ae.outro(fe.green("MCP server stopped gracefully.")):o===null&&ae.outro(fe.yellow("MCP server terminated.")),process.exit(o??0)}),n.on("error",o=>{a.error(`
735
+ `)}process.exit(u.valid?c.SUCCESS:c.INCOMPATIBLE)}function sn(e){let t=e.command("license").description("Manage your Nebutra-Sailor commercial license");t.command("activate <key>").description("Activate a commercial license key for local development").option("--quiet","Suppress output").action(async(r,n)=>{await Bs(r,n)}),t.command("status").description("Check the locally configured license status").option("--quiet","Suppress output").action(async r=>{await Gs(r)}),t.command("verify [path]").description("Verify the scaffold-meta HMAC signature in a create-sailor project (defaults to cwd)").option("--format <type>","Output format: json | plain (default: plain)").option("--quiet","Suppress non-essential output").action(async function(r,n,o){let i=o&&typeof o.optsWithGlobals=="function"?o.optsWithGlobals()??{}:{...n},s=typeof n?.format=="string"?n.format:typeof i.format=="string"?i.format:void 0,l=!!n?.quiet||!!i.quiet;await qs(r,{format:s,quiet:l})})}import{existsSync as cn,readFileSync as Ks,writeFileSync as zs}from"fs";import{dirname as Ws,join as ln,parse as Ys}from"path";import*as vt from"@clack/prompts";function Hs(e){let t=e,{root:r}=Ys(t);for(;;){if(cn(ln(t,"package.json")))return t;if(t===r)return null;let n=Ws(t);if(n===t)return null;t=n}}function Js(e){if(!cn(e))return{};try{return JSON.parse(Ks(e,"utf-8"))}catch{return{}}}function Xs(e,t){zs(e,JSON.stringify(t,null,2)+`
736
+ `)}async function Qs(e,t){let r=t.format==="json",n=Hs(process.cwd());n||(r?console.log(JSON.stringify({command:"link",success:!1,error:"No package.json found upstream"},null,2)):a.error("No package.json found in current or parent directories."),process.exit(c.NOT_FOUND));let o=e;if(!o){t.yes&&(r?console.log(JSON.stringify({command:"link",success:!1,error:"project-id required in --yes mode"},null,2)):a.error("project-id is required when running with --yes / non-interactive."),process.exit(c.INVALID_ARGS));let u=await vt.text({message:"Project ID to link to:",placeholder:"proj_abc123",validate:m=>m&&m.trim().length>0?void 0:"Project ID cannot be empty"});vt.isCancel(u)&&(a.warn("Cancelled"),process.exit(c.CANCELLED)),o=String(u).trim()}let i=ln(n,"nebutra.config.json"),l={...Js(i),projectId:o};Xs(i,l),r?console.log(JSON.stringify({command:"link",success:!0,projectId:o,configPath:i},null,2)):a.success(`Linked to project: ${o}`)}function dn(e){e.command("link [project-id]").description("Link the current project to a Nebutra project id").option("--format <type>","Output format: json or plain").action(async(t,r,n)=>{let o=n?.optsWithGlobals?.()||r;await Qs(t,{yes:o.yes||!1,format:r.format||o.format})})}import{existsSync as un,rmSync as Zs,unlinkSync as ec}from"fs";import{homedir as mn,platform as tc}from"os";import{join as ze}from"path";function rc(){if(tc()==="win32"){let t=process.env.LOCALAPPDATA||ze(mn(),"AppData","Local");return ze(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?ze(e,"nebutra"):ze(mn(),".config","nebutra")}var nc=["auth.json","session.json","token","credentials.json"];async function oc(e){let t=rc(),r=e.format==="json",n=0,o=[];if(e.all){if(un(t))try{Zs(t,{recursive:!0,force:!0}),n=1,o.push(t)}catch(i){let s=i instanceof Error?i.message:String(i);r?console.log(JSON.stringify({command:"logout",success:!1,error:s},null,2)):a.error(`Failed to clear config directory: ${s}`),process.exit(c.PERMISSION_DENIED)}}else for(let i of nc){let s=ze(t,i);if(un(s))try{ec(s),n++,o.push(s)}catch{}}n===0&&(r?console.log(JSON.stringify({command:"logout",success:!0,alreadyLoggedOut:!0,removed:[]},null,2)):a.info("Already logged out"),process.exit(c.SUCCESS)),r?console.log(JSON.stringify({command:"logout",success:!0,removed:o,clearedAll:!!e.all},null,2)):a.success(e.all?"Cleared all nebutra config":"Logged out of nebutra.com")}function pn(e){e.command("logout").description("Clear stored authentication credentials").option("--all","Clear ALL local config, not just auth tokens").option("--format <type>","Output format: json or plain").action(async(t,r)=>{let n=r?.optsWithGlobals?.()||t;await oc({all:t.all||!1,format:t.format||n.format})})}import{spawn as ac}from"child_process";import{dirname as ic,resolve as sc}from"path";import{fileURLToPath as cc}from"url";import*as ae from"@clack/prompts";import fe from"picocolors";var lc=ic(cc(import.meta.url));function dc(){let e=[()=>sc(lc,"../../../mcp/dist/server/contextServer.js")];for(let t of e)try{return t()}catch(r){a.debug("MCP server binary resolution strategy failed",{error:r})}return"nebutra-mcp"}function fn(e){e.command("mcp").description("Start the Nebutra MCP server for Cursor/Windsurf").option("--stdio","Use stdio transport (default)",!0).action(async t=>{ae.intro(fe.bgCyan(fe.black(" nebutra mcp ")));try{let r=dc();ae.log.info(fe.cyan("Starting Nebutra MCP server for Cursor/Windsurf integration...")),ae.log.info(fe.dim(`Press Ctrl+C to stop the server.
737
+ `));let n=ac(process.execPath,[r],{stdio:"inherit",env:{...process.env}});n.on("close",o=>{o===0?ae.outro(fe.green("MCP server stopped gracefully.")):o===null&&ae.outro(fe.yellow("MCP server terminated.")),process.exit(o??0)}),n.on("error",o=>{a.error(`
738
738
  Failed to start MCP server: ${o.message}`),o.code==="ENOENT"&&(a.warn(`
739
739
  Tip: Ensure @nebutra/mcp is installed or available in your PATH.`),a.info(" Install globally: npm install -g @nebutra/mcp"),process.exit(c.NOT_FOUND)),process.exit(c.ERROR)}),process.on("SIGINT",()=>{ae.log.info(fe.yellow(`
740
- Shutting down MCP server...`)),n.kill("SIGINT")}),process.on("SIGTERM",()=>{ae.log.info(fe.yellow("Terminating MCP server...")),n.kill("SIGTERM")})}catch(r){ae.log.error(fe.red("Error: Unable to start MCP server. Ensure @nebutra/mcp is properly installed.")),r instanceof Error&&a.error(r.message),process.exit(c.ERROR)}})}import*as V from"@clack/prompts";import ee from"picocolors";var gn=Object.fromEntries(Object.entries(Qt).map(([e,t])=>[e,t]));function yn(e){return typeof e=="boolean"?"boolean":"string"}function lc(){let e=nr().map(r=>({name:r.name,description:r.description,envFile:r.envFile??".env.local",providers:(r.providers??[]).map(n=>({id:n.id,description:n.description,dependencies:n.dependencies??[],devDependencies:n.devDependencies??[],env:n.env??[]})),files:(r.files??[]).map(n=>n.path)})),t=Array.from(new Set(e.flatMap(r=>r.providers.map(n=>n.id))));return{localFeatures:e,valueDomains:{components:e.map(r=>r.name),provider:t}}}function dc(e){let t=e.arguments.map(i=>i.name==="components"?{...i,description:"Local feature names to install from the Nebutra registry"}:i),n=e.options.some(i=>i.flags.includes("--provider"))?e.options:[...e.options,{flags:"--provider <id>",description:"Specify a provider for a local feature install",required:!1,type:"string"}],o=[{command:"nebutra add queue --provider upstash",description:"Install the local queue feature starter with the Upstash provider"},{command:"nebutra add search --provider meilisearch --dry-run",description:"Preview the local search feature install plan as JSON"},...e.examples.filter(i=>i.command.includes("--21st")||i.command.includes("--v0"))];return{...e,arguments:t,options:n,examples:o,extensions:lc()}}function uc(e){return{...e,extensions:{valueDomains:h,aliases:{storage:{supabase:"supabase-storage"},payment:{lemonsqueezy:"lemon"}}}}}function hn(e){let t={name:e.name,description:e.description,usage:e.usage,arguments:e.arguments||[],options:(e.options||[]).map(r=>({flags:r.flags,description:r.description,default:r.default,required:!1,type:yn(r.default)})),examples:e.examples||[]};return e.name==="add"?dc(t):e.name==="create"?uc(t):t}function mc(e){let r=(ce.subcommands||[]).find(n=>n.name===e);return r?hn(r):null}function pc(){return(ce.options??[]).map(e=>({flags:e.flags,description:e.description,required:!1,type:yn(e.default)}))}function fc(e){let t=ce.subcommands||[];return{name:ce.name,version:e,description:ce.description,usage:ce.usage||"nebutra [command] [options]",globalOptions:pc(),commands:t.map(hn),exitCodes:gn,timestamp:new Date().toISOString()}}function fn(){return(ce.subcommands||[]).map(t=>t.name)}function wt(e){process.stdout.write(`${JSON.stringify(e,null,2)}
741
- `)}function gc(e){return e instanceof Error&&e.message.startsWith("EXIT:")}async function yc(e,t){let r=t.quiet===!0,n="0.1.0";try{if(t.all===!0&&(wt(fc(n)),process.exit(0)),t.list===!0&&(wt(fn()),process.exit(0)),(t.exitCodes===!0||t["exit-codes"]===!0)&&(wt(gn),process.exit(0)),e){let o=mc(e);o||(r||(a.error(`Unknown command '${e}'`),a.info(`Available commands: ${fn().join(", ")}`)),process.exit(c.NOT_FOUND)),wt(o),process.exit(0)}r||(V.intro(ee.bgCyan(ee.black(" nebutra schema "))),V.log.info(ee.cyan("Agent-friendly introspection of CLI commands, arguments, and value domains.")),V.log.message(""),V.log.info(ee.bold("Usage:")),V.log.message(ee.dim(" nebutra schema --all Show full command tree as JSON")),V.log.message(ee.dim(" nebutra schema <command> Show schema for a specific command")),V.log.message(ee.dim(" nebutra schema --list List available command names")),V.log.message(ee.dim(" nebutra schema --exit-codes Show exit codes reference")),V.log.message(""),V.log.info(ee.bold("Example:")),V.log.message(ee.dim(" nebutra schema add")),V.log.message(ee.dim(" nebutra schema --all | jq '.commands[0]'")),V.outro(ee.cyan("All output is JSON for easy parsing by agents and automation tools."))),process.exit(0)}catch(o){if(gc(o))throw o;r||a.error(o instanceof Error?o.message:String(o)),process.exit(c.ERROR)}}function bn(e){e.command("schema [command]").description("Show command schema and argument documentation (Agent-friendly JSON output)").option("--all","Show full schema for all commands").option("--list","List all available command names").option("--exit-codes","Show exit codes reference").action(async(t,r)=>{await yc(t,r)})}import*as St from"@clack/prompts";import te from"picocolors";function We(){let e=process.env.MEILISEARCH_URL,t=process.env.TYPESENSE_URL,r=process.env.ALGOLIA_APP_ID;return e?{type:"meilisearch",url:e,health:!0,message:"Meilisearch configured"}:t?{type:"typesense",url:t,health:!0,message:"Typesense configured"}:r?{type:"algolia",health:!0,message:"Algolia configured"}:{type:"none",health:!1,message:"No search provider configured"}}async function hc(e){d("Detecting search provider...","info");let t=We();t.type==="none"&&(d("No search provider is configured","warn"),d("Set one of: MEILISEARCH_URL, TYPESENSE_URL, or ALGOLIA_APP_ID","info"),process.exit(0));let r={provider:t.type,configured:!0,url:t.url||"managed",health:t.health,message:t.message};e.format==="json"?k(r,{format:"json"}):(d(`Search Provider: ${te.cyan(t.type.toUpperCase())}`,"success"),d(`Status: ${t.health?te.green("Healthy"):te.red("Unhealthy")}`,t.health?"success":"error"),t.url&&d(`URL: ${t.url}`,"info"))}async function bc(e){d("Fetching search indexes...","info"),We().type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let r=[{name:"products",documentCount:15420,size:"2.4 MB",lastUpdated:"2 hours ago"},{name:"articles",documentCount:3240,size:"1.1 MB",lastUpdated:"1 day ago"},{name:"users",documentCount:8900,size:"0.8 MB",lastUpdated:"30 minutes ago"}];if(e.format==="json")k(r,{format:"json"});else{d("Search Indexes","info");for(let n of r)d(`${te.cyan(n.name)}: ${n.documentCount} documents (${n.size})`,"info")}}async function vn(e,t){let r=t||{},n=We();n.type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let o=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e&&!r.force&&!r.dryRun&&o){let s=await St.confirm({message:"Reindex ALL indexes? This will recreate all indexes from scratch.",initialValue:!1});(St.isCancel(s)||!s)&&(d("Reindex cancelled","warn"),process.exit(c.CANCELLED))}!r.yes&&!r.dryRun&&!e&&(d("Full reindex requires --yes confirmation","error"),process.exit(c.INVALID_ARGS));let i=e||"all";if(d(`Reindexing ${te.cyan(i)}...`,"info"),r.dryRun){d(`Would reindex ${i} with provider ${n.type}`,"info");return}d(`Reindexing ${i} on ${n.type}...`,"info"),d(`Index ${te.cyan(i)} reindexed successfully`,"success")}async function vc(e,t,r){d(`Querying ${te.cyan(e)} for "${te.yellow(t)}"...`,"info");let n=We();n.type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let o=[{id:"1",title:"Sample Result 1",score:.95,_formatted:{title:"Sample <mark>Result</mark> 1",content:"Contains search term..."}},{id:"2",title:"Another Result",score:.87,_formatted:{title:"Another <mark>Result</mark>",content:"Also matches search..."}}],i={index:e,query:t,provider:n.type,hits:o.length,limit:r.limit||10,results:o};if(r.format==="json")k(i,{format:"json"});else{d(`Found ${te.cyan(String(o.length))} results for "${t}"`,"success");for(let s of o)d(`${te.dim(String(s.score))}: ${s.title}`,"info")}}async function wc(e){d("Fetching search statistics...","info");let t=We();t.type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let r={provider:t.type,indexes:[{name:"products",documents:15420,size:24e5,lastUpdated:"2024-03-30T14:22:00Z"},{name:"articles",documents:3240,size:11e5,lastUpdated:"2024-03-29T08:15:00Z"},{name:"users",documents:8900,size:8e5,lastUpdated:"2024-03-30T14:52:00Z"}],totalDocuments:27560,totalSize:43e5};if(e.format==="json")k(r,{format:"json"});else{d("Search Statistics","info"),d(`Provider: ${te.cyan(r.provider)}`,"info"),d(`Total Indexes: ${r.indexes.length}`,"info"),d(`Total Documents: ${r.totalDocuments.toLocaleString()}`,"info"),d(`Total Size: ${(r.totalSize/1024/1024).toFixed(2)} MB`,"info"),d("Index Breakdown:","info");for(let n of r.indexes)d(` ${te.cyan(n.name)}: ${n.documents.toLocaleString()} docs (${(n.size/1024/1024).toFixed(2)} MB)`,"info")}}function wn(e){e.command("search <verb> [args...]").description("Manage search engine (Meilisearch, Typesense, or Algolia)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations").option("--format <type>","Output format: json, plain, table","plain").option("--force","Force operation (e.g., recreate index)").option("--limit <n>","Result limit for queries").option("--filters <json>","Filters for search query (JSON)").option("--tenant <id>","Tenant ID for multi-tenant queries").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,force:o.force||!1,limit:o.limit??10,filters:o.filters,tenant:o.tenant};try{switch(r){case"status":await hc(s);break;case"indexes":await bc(s);break;case"reindex":n.length>0?await vn(n[0],s):await vn(void 0,s);break;case"query":n.length<2&&(d("query requires an index and search term: nebutra search query <index> <query>","error"),process.exit(c.INVALID_ARGS)),await vc(n[0],n.slice(1).join(" "),s);break;case"stats":await wc(s);break;default:d(`Unknown search subcommand: ${r}. Valid commands: status, indexes, reindex, query, stats`,"error"),process.exit(c.ERROR)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Search command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
740
+ Shutting down MCP server...`)),n.kill("SIGINT")}),process.on("SIGTERM",()=>{ae.log.info(fe.yellow("Terminating MCP server...")),n.kill("SIGTERM")})}catch(r){ae.log.error(fe.red("Error: Unable to start MCP server. Ensure @nebutra/mcp is properly installed.")),r instanceof Error&&a.error(r.message),process.exit(c.ERROR)}})}import*as V from"@clack/prompts";import ee from"picocolors";var yn=Object.fromEntries(Object.entries(Zt).map(([e,t])=>[e,t]));function hn(e){return typeof e=="boolean"?"boolean":"string"}function uc(){let e=or().map(r=>({name:r.name,description:r.description,envFile:r.envFile??".env.local",providers:(r.providers??[]).map(n=>({id:n.id,description:n.description,dependencies:n.dependencies??[],devDependencies:n.devDependencies??[],env:n.env??[]})),files:(r.files??[]).map(n=>n.path)})),t=Array.from(new Set(e.flatMap(r=>r.providers.map(n=>n.id))));return{localFeatures:e,valueDomains:{components:e.map(r=>r.name),provider:t}}}function mc(e){let t=e.arguments.map(i=>i.name==="components"?{...i,description:"Local feature names to install from the Nebutra registry"}:i),n=e.options.some(i=>i.flags.includes("--provider"))?e.options:[...e.options,{flags:"--provider <id>",description:"Specify a provider for a local feature install",required:!1,type:"string"}],o=[{command:"nebutra add queue --provider upstash",description:"Install the local queue feature starter with the Upstash provider"},{command:"nebutra add search --provider meilisearch --dry-run",description:"Preview the local search feature install plan as JSON"},...e.examples.filter(i=>i.command.includes("--21st")||i.command.includes("--v0"))];return{...e,arguments:t,options:n,examples:o,extensions:uc()}}function pc(e){return{...e,extensions:{valueDomains:h,aliases:{storage:{supabase:"supabase-storage"},payment:{lemonsqueezy:"lemon"}}}}}function bn(e){let t={name:e.name,description:e.description,usage:e.usage,arguments:e.arguments||[],options:(e.options||[]).map(r=>({flags:r.flags,description:r.description,default:r.default,required:!1,type:hn(r.default)})),examples:e.examples||[]};return e.name==="add"?mc(t):e.name==="create"?pc(t):t}function fc(e){let r=(ce.subcommands||[]).find(n=>n.name===e);return r?bn(r):null}function gc(){return(ce.options??[]).map(e=>({flags:e.flags,description:e.description,required:!1,type:hn(e.default)}))}function yc(e){let t=ce.subcommands||[];return{name:ce.name,version:e,description:ce.description,usage:ce.usage||"nebutra [command] [options]",globalOptions:gc(),commands:t.map(bn),exitCodes:yn,timestamp:new Date().toISOString()}}function gn(){return(ce.subcommands||[]).map(t=>t.name)}function wt(e){process.stdout.write(`${JSON.stringify(e,null,2)}
741
+ `)}function hc(e){return e instanceof Error&&e.message.startsWith("EXIT:")}async function bc(e,t){let r=t.quiet===!0,n="0.1.0";try{if(t.all===!0&&(wt(yc(n)),process.exit(0)),t.list===!0&&(wt(gn()),process.exit(0)),(t.exitCodes===!0||t["exit-codes"]===!0)&&(wt(yn),process.exit(0)),e){let o=fc(e);o||(r||(a.error(`Unknown command '${e}'`),a.info(`Available commands: ${gn().join(", ")}`)),process.exit(c.NOT_FOUND)),wt(o),process.exit(0)}r||(V.intro(ee.bgCyan(ee.black(" nebutra schema "))),V.log.info(ee.cyan("Agent-friendly introspection of CLI commands, arguments, and value domains.")),V.log.message(""),V.log.info(ee.bold("Usage:")),V.log.message(ee.dim(" nebutra schema --all Show full command tree as JSON")),V.log.message(ee.dim(" nebutra schema <command> Show schema for a specific command")),V.log.message(ee.dim(" nebutra schema --list List available command names")),V.log.message(ee.dim(" nebutra schema --exit-codes Show exit codes reference")),V.log.message(""),V.log.info(ee.bold("Example:")),V.log.message(ee.dim(" nebutra schema add")),V.log.message(ee.dim(" nebutra schema --all | jq '.commands[0]'")),V.outro(ee.cyan("All output is JSON for easy parsing by agents and automation tools."))),process.exit(0)}catch(o){if(hc(o))throw o;r||a.error(o instanceof Error?o.message:String(o)),process.exit(c.ERROR)}}function vn(e){e.command("schema [command]").description("Show command schema and argument documentation (Agent-friendly JSON output)").option("--all","Show full schema for all commands").option("--list","List all available command names").option("--exit-codes","Show exit codes reference").action(async(t,r)=>{await bc(t,r)})}import*as St from"@clack/prompts";import te from"picocolors";function We(){let e=process.env.MEILISEARCH_URL,t=process.env.TYPESENSE_URL,r=process.env.ALGOLIA_APP_ID;return e?{type:"meilisearch",url:e,health:!0,message:"Meilisearch configured"}:t?{type:"typesense",url:t,health:!0,message:"Typesense configured"}:r?{type:"algolia",health:!0,message:"Algolia configured"}:{type:"none",health:!1,message:"No search provider configured"}}async function vc(e){d("Detecting search provider...","info");let t=We();t.type==="none"&&(d("No search provider is configured","warn"),d("Set one of: MEILISEARCH_URL, TYPESENSE_URL, or ALGOLIA_APP_ID","info"),process.exit(0));let r={provider:t.type,configured:!0,url:t.url||"managed",health:t.health,message:t.message};e.format==="json"?k(r,{format:"json"}):(d(`Search Provider: ${te.cyan(t.type.toUpperCase())}`,"success"),d(`Status: ${t.health?te.green("Healthy"):te.red("Unhealthy")}`,t.health?"success":"error"),t.url&&d(`URL: ${t.url}`,"info"))}async function wc(e){d("Fetching search indexes...","info"),We().type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let r=[{name:"products",documentCount:15420,size:"2.4 MB",lastUpdated:"2 hours ago"},{name:"articles",documentCount:3240,size:"1.1 MB",lastUpdated:"1 day ago"},{name:"users",documentCount:8900,size:"0.8 MB",lastUpdated:"30 minutes ago"}];if(e.format==="json")k(r,{format:"json"});else{d("Search Indexes","info");for(let n of r)d(`${te.cyan(n.name)}: ${n.documentCount} documents (${n.size})`,"info")}}async function wn(e,t){let r=t||{},n=We();n.type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let o=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e&&!r.force&&!r.dryRun&&o){let s=await St.confirm({message:"Reindex ALL indexes? This will recreate all indexes from scratch.",initialValue:!1});(St.isCancel(s)||!s)&&(d("Reindex cancelled","warn"),process.exit(c.CANCELLED))}!r.yes&&!r.dryRun&&!e&&(d("Full reindex requires --yes confirmation","error"),process.exit(c.INVALID_ARGS));let i=e||"all";if(d(`Reindexing ${te.cyan(i)}...`,"info"),r.dryRun){d(`Would reindex ${i} with provider ${n.type}`,"info");return}d(`Reindexing ${i} on ${n.type}...`,"info"),d(`Index ${te.cyan(i)} reindexed successfully`,"success")}async function Sc(e,t,r){d(`Querying ${te.cyan(e)} for "${te.yellow(t)}"...`,"info");let n=We();n.type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let o=[{id:"1",title:"Sample Result 1",score:.95,_formatted:{title:"Sample <mark>Result</mark> 1",content:"Contains search term..."}},{id:"2",title:"Another Result",score:.87,_formatted:{title:"Another <mark>Result</mark>",content:"Also matches search..."}}],i={index:e,query:t,provider:n.type,hits:o.length,limit:r.limit||10,results:o};if(r.format==="json")k(i,{format:"json"});else{d(`Found ${te.cyan(String(o.length))} results for "${t}"`,"success");for(let s of o)d(`${te.dim(String(s.score))}: ${s.title}`,"info")}}async function Rc(e){d("Fetching search statistics...","info");let t=We();t.type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let r={provider:t.type,indexes:[{name:"products",documents:15420,size:24e5,lastUpdated:"2024-03-30T14:22:00Z"},{name:"articles",documents:3240,size:11e5,lastUpdated:"2024-03-29T08:15:00Z"},{name:"users",documents:8900,size:8e5,lastUpdated:"2024-03-30T14:52:00Z"}],totalDocuments:27560,totalSize:43e5};if(e.format==="json")k(r,{format:"json"});else{d("Search Statistics","info"),d(`Provider: ${te.cyan(r.provider)}`,"info"),d(`Total Indexes: ${r.indexes.length}`,"info"),d(`Total Documents: ${r.totalDocuments.toLocaleString()}`,"info"),d(`Total Size: ${(r.totalSize/1024/1024).toFixed(2)} MB`,"info"),d("Index Breakdown:","info");for(let n of r.indexes)d(` ${te.cyan(n.name)}: ${n.documents.toLocaleString()} docs (${(n.size/1024/1024).toFixed(2)} MB)`,"info")}}function Sn(e){e.command("search <verb> [args...]").description("Manage search engine (Meilisearch, Typesense, or Algolia)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations").option("--format <type>","Output format: json, plain, table","plain").option("--force","Force operation (e.g., recreate index)").option("--limit <n>","Result limit for queries").option("--filters <json>","Filters for search query (JSON)").option("--tenant <id>","Tenant ID for multi-tenant queries").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,force:o.force||!1,limit:o.limit??10,filters:o.filters,tenant:o.tenant};try{switch(r){case"status":await vc(s);break;case"indexes":await wc(s);break;case"reindex":n.length>0?await wn(n[0],s):await wn(void 0,s);break;case"query":n.length<2&&(d("query requires an index and search term: nebutra search query <index> <query>","error"),process.exit(c.INVALID_ARGS)),await Sc(n[0],n.slice(1).join(" "),s);break;case"stats":await Rc(s);break;default:d(`Unknown search subcommand: ${r}. Valid commands: status, indexes, reindex, query, stats`,"error"),process.exit(c.ERROR)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Search command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
742
742
  Examples:
743
743
  nebutra search status Show search provider status
744
744
  nebutra search indexes List all indexes
@@ -761,7 +761,7 @@ Flags:
761
761
  --limit <n> Result limit for queries (default: 10)
762
762
  --filters <json> Filters for search query
763
763
  --tenant <id> Tenant ID for multi-tenant searches
764
- `)}import{stdin as Ye}from"process";import*as Rt from"@clack/prompts";import I from"picocolors";async function Sc(){return new Promise((e,t)=>{let r="";Ye.setEncoding("utf8"),Ye.on("readable",()=>{let n;for(;(n=Ye.read())!==null;)r+=n}),Ye.on("end",()=>{e(r.trim())}),Ye.on("error",t)})}async function Rc(e){d("Fetching secret metadata...","info");let t=[{key:"openai_key",tenant:e.tenant||"org_123",createdAt:"2024-03-15T10:30:00Z",updatedAt:"2024-03-30T14:22:00Z",description:"OpenAI API key for embeddings",masked:!0},{key:"stripe_sk",tenant:e.tenant||"org_123",createdAt:"2024-03-10T08:15:00Z",updatedAt:"2024-03-25T09:45:00Z",description:"Stripe secret key",masked:!0},{key:"github_token",tenant:e.tenant||"org_123",createdAt:"2024-03-20T16:30:00Z",updatedAt:"2024-03-29T11:20:00Z",description:"GitHub API token",masked:!0}];if(e.format==="json")k(t,{format:"json"});else{d("Secrets for tenant: "+(e.tenant||"org_123"),"info");for(let r of t){let n=r.description?` \u2014 ${r.description}`:"";d(`${I.cyan(r.key)}${I.gray(n)}`,"info"),d(` Updated: ${r.updatedAt}`,"info")}}}async function kc(e,t){e||(d("Secret key is required: nebutra secrets set <key>","error"),process.exit(c.INVALID_ARGS));let r;if(t.value)d("WARNING: Using --value flag exposes secret in shell history. Prefer stdin.","warn"),r=t.value;else{d("Enter secret value (will not echo). Press Ctrl+D when done:","info");try{r=await Sc()}catch{d("Failed to read secret from stdin","error"),process.exit(c.ERROR)}}if(r||(d("Secret value cannot be empty","error"),process.exit(c.INVALID_ARGS)),d(`Setting secret ${I.cyan(e)}...`,"info"),t.dryRun){d(`Would encrypt and store secret ${e} for tenant ${t.tenant||"org_123"}`,"info");return}d(`Secret ${I.cyan(e)} encrypted and stored successfully`,"success"),t.description&&d(`Description: ${t.description}`,"info")}async function Ec(e,t){e||(d("Secret key is required: nebutra secrets get <key>","error"),process.exit(c.INVALID_ARGS)),d(`Retrieving secret ${I.cyan(e)}...`,"info");let n=t.unmask?"sk_live_abc123xyz789...":"***masked***";t.unmask||d(`Secret value is ${I.yellow("masked")}. Use --unmask to display.`,"warn");let o={key:e,tenant:t.tenant||"org_123",value:n,encrypted:!0};t.format==="json"?k(o,{format:"json"}):d(`${I.cyan(e)}: ${n}`,"info")}async function Cc(e,t){e||(d("Secret key is required: nebutra secrets rotate <key>","error"),process.exit(c.INVALID_ARGS));let r=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!t.yes&&!t.dryRun&&r){let n=await Rt.confirm({message:`Rotate encryption key for ${I.cyan(e)}? This will re-encrypt with new key material.`,initialValue:!1});(Rt.isCancel(n)||!n)&&(d("Rotation cancelled","warn"),process.exit(c.CANCELLED))}if(!t.yes&&!t.dryRun&&!r&&(d("Key rotation requires --yes confirmation","error"),process.exit(c.INVALID_ARGS)),d(`Rotating encryption key for ${I.cyan(e)}...`,"info"),t.dryRun){d(`Would rotate encryption key for ${e}`,"info");return}d(`Encryption key for ${I.cyan(e)} rotated successfully`,"success"),d(`New key version: ${I.dim("v2")}`,"info")}async function Ac(e){d("Fetching audit log...","info");let r=[{timestamp:"2024-03-30T14:52:00Z",action:"read",key:"openai_key",actor:"api_service",success:!0},{timestamp:"2024-03-30T14:22:00Z",action:"write",key:"openai_key",actor:"claude_user",success:!0},{timestamp:"2024-03-30T13:45:00Z",action:"read",key:"stripe_sk",actor:"billing_worker",success:!0},{timestamp:"2024-03-30T11:30:00Z",action:"rotate",key:"github_token",actor:"admin_user",success:!0},{timestamp:"2024-03-30T10:15:00Z",action:"read",key:"unknown_key",actor:"unauthorized_service",success:!1,message:"Key not found"}];if(e.limit&&(r=r.slice(0,e.limit)),e.format==="json")k(r,{format:"json"});else{d("Secret Access Audit Log","info");for(let n of r){let o=n.success?I.green("\u2713"):I.red("\u2716");d(`${o} ${n.timestamp} ${I.cyan(n.action)} ${n.key}`,n.success?"success":"error"),d(` Actor: ${n.actor}${n.message?` \u2014 ${n.message}`:""}`,"info")}}}async function xc(e){d("Verifying vault configuration...","info");let t=[];if(t.push({name:"KMS Connectivity",healthy:!0,message:"Connected to AWS KMS"}),t.push({name:"Master Key",healthy:!0,message:"Master encryption key available"}),t.push({name:"Envelope Encryption",healthy:!0,message:"HKDF envelope encryption configured"}),t.push({name:"Storage Backend",healthy:!0,message:"PostgreSQL backend healthy"}),e.format==="json")k(t,{format:"json"});else{d("Vault Configuration Check","info");for(let n of t){let o=n.healthy?I.green("\u2713"):I.red("\u2716");d(`${o} ${n.name}: ${n.message}`,n.healthy?"success":"error")}let r=t.every(n=>n.healthy);d(`Overall: ${r?I.green("HEALTHY"):I.red("UNHEALTHY")}`,r?"success":"error")}}function Sn(e){e.command("secrets <verb> [args...]").description("Manage encrypted secrets via @nebutra/vault (AWS KMS + HKDF envelope encryption)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations").option("--format <type>","Output format: json, plain, table","plain").option("--tenant <id>","Tenant ID for multi-tenant access").option("--unmask","Unmask secret values (required to view)").option("--description <text>","Description for secret").option("--value <text>","Secret value (prefer stdin for security)").option("--since <date>","Audit log start date (ISO 8601)").option("--limit <n>","Maximum audit log entries (default: 50)").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,tenant:o.tenant||i?.tenant,unmask:o.unmask||!1,description:o.description,value:o.value,since:o.since,limit:o.limit??50};try{switch(r){case"list":await Rc(s);break;case"set":n.length===0&&(d("set requires a secret key: nebutra secrets set <key>","error"),process.exit(c.INVALID_ARGS)),await kc(n[0],s);break;case"get":n.length===0&&(d("get requires a secret key: nebutra secrets get <key>","error"),process.exit(c.INVALID_ARGS)),await Ec(n[0],s);break;case"rotate":n.length===0&&(d("rotate requires a secret key: nebutra secrets rotate <key>","error"),process.exit(c.INVALID_ARGS)),await Cc(n[0],s);break;case"audit":await Ac(s);break;case"verify":await xc(s);break;default:d(`Unknown secrets subcommand: ${r}. Valid commands: list, set, get, rotate, audit, verify`,"error"),process.exit(c.ERROR)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Secrets command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
764
+ `)}import{stdin as Ye}from"process";import*as Rt from"@clack/prompts";import I from"picocolors";async function kc(){return new Promise((e,t)=>{let r="";Ye.setEncoding("utf8"),Ye.on("readable",()=>{let n;for(;(n=Ye.read())!==null;)r+=n}),Ye.on("end",()=>{e(r.trim())}),Ye.on("error",t)})}async function Ec(e){d("Fetching secret metadata...","info");let t=[{key:"openai_key",tenant:e.tenant||"org_123",createdAt:"2024-03-15T10:30:00Z",updatedAt:"2024-03-30T14:22:00Z",description:"OpenAI API key for embeddings",masked:!0},{key:"stripe_sk",tenant:e.tenant||"org_123",createdAt:"2024-03-10T08:15:00Z",updatedAt:"2024-03-25T09:45:00Z",description:"Stripe secret key",masked:!0},{key:"github_token",tenant:e.tenant||"org_123",createdAt:"2024-03-20T16:30:00Z",updatedAt:"2024-03-29T11:20:00Z",description:"GitHub API token",masked:!0}];if(e.format==="json")k(t,{format:"json"});else{d("Secrets for tenant: "+(e.tenant||"org_123"),"info");for(let r of t){let n=r.description?` \u2014 ${r.description}`:"";d(`${I.cyan(r.key)}${I.gray(n)}`,"info"),d(` Updated: ${r.updatedAt}`,"info")}}}async function Cc(e,t){e||(d("Secret key is required: nebutra secrets set <key>","error"),process.exit(c.INVALID_ARGS));let r;if(t.value)d("WARNING: Using --value flag exposes secret in shell history. Prefer stdin.","warn"),r=t.value;else{d("Enter secret value (will not echo). Press Ctrl+D when done:","info");try{r=await kc()}catch{d("Failed to read secret from stdin","error"),process.exit(c.ERROR)}}if(r||(d("Secret value cannot be empty","error"),process.exit(c.INVALID_ARGS)),d(`Setting secret ${I.cyan(e)}...`,"info"),t.dryRun){d(`Would encrypt and store secret ${e} for tenant ${t.tenant||"org_123"}`,"info");return}d(`Secret ${I.cyan(e)} encrypted and stored successfully`,"success"),t.description&&d(`Description: ${t.description}`,"info")}async function Ac(e,t){e||(d("Secret key is required: nebutra secrets get <key>","error"),process.exit(c.INVALID_ARGS)),d(`Retrieving secret ${I.cyan(e)}...`,"info");let n=t.unmask?"sk_live_abc123xyz789...":"***masked***";t.unmask||d(`Secret value is ${I.yellow("masked")}. Use --unmask to display.`,"warn");let o={key:e,tenant:t.tenant||"org_123",value:n,encrypted:!0};t.format==="json"?k(o,{format:"json"}):d(`${I.cyan(e)}: ${n}`,"info")}async function xc(e,t){e||(d("Secret key is required: nebutra secrets rotate <key>","error"),process.exit(c.INVALID_ARGS));let r=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!t.yes&&!t.dryRun&&r){let n=await Rt.confirm({message:`Rotate encryption key for ${I.cyan(e)}? This will re-encrypt with new key material.`,initialValue:!1});(Rt.isCancel(n)||!n)&&(d("Rotation cancelled","warn"),process.exit(c.CANCELLED))}if(!t.yes&&!t.dryRun&&!r&&(d("Key rotation requires --yes confirmation","error"),process.exit(c.INVALID_ARGS)),d(`Rotating encryption key for ${I.cyan(e)}...`,"info"),t.dryRun){d(`Would rotate encryption key for ${e}`,"info");return}d(`Encryption key for ${I.cyan(e)} rotated successfully`,"success"),d(`New key version: ${I.dim("v2")}`,"info")}async function Oc(e){d("Fetching audit log...","info");let r=[{timestamp:"2024-03-30T14:52:00Z",action:"read",key:"openai_key",actor:"api_service",success:!0},{timestamp:"2024-03-30T14:22:00Z",action:"write",key:"openai_key",actor:"claude_user",success:!0},{timestamp:"2024-03-30T13:45:00Z",action:"read",key:"stripe_sk",actor:"billing_worker",success:!0},{timestamp:"2024-03-30T11:30:00Z",action:"rotate",key:"github_token",actor:"admin_user",success:!0},{timestamp:"2024-03-30T10:15:00Z",action:"read",key:"unknown_key",actor:"unauthorized_service",success:!1,message:"Key not found"}];if(e.limit&&(r=r.slice(0,e.limit)),e.format==="json")k(r,{format:"json"});else{d("Secret Access Audit Log","info");for(let n of r){let o=n.success?I.green("\u2713"):I.red("\u2716");d(`${o} ${n.timestamp} ${I.cyan(n.action)} ${n.key}`,n.success?"success":"error"),d(` Actor: ${n.actor}${n.message?` \u2014 ${n.message}`:""}`,"info")}}}async function _c(e){d("Verifying vault configuration...","info");let t=[];if(t.push({name:"KMS Connectivity",healthy:!0,message:"Connected to AWS KMS"}),t.push({name:"Master Key",healthy:!0,message:"Master encryption key available"}),t.push({name:"Envelope Encryption",healthy:!0,message:"HKDF envelope encryption configured"}),t.push({name:"Storage Backend",healthy:!0,message:"PostgreSQL backend healthy"}),e.format==="json")k(t,{format:"json"});else{d("Vault Configuration Check","info");for(let n of t){let o=n.healthy?I.green("\u2713"):I.red("\u2716");d(`${o} ${n.name}: ${n.message}`,n.healthy?"success":"error")}let r=t.every(n=>n.healthy);d(`Overall: ${r?I.green("HEALTHY"):I.red("UNHEALTHY")}`,r?"success":"error")}}function Rn(e){e.command("secrets <verb> [args...]").description("Manage encrypted secrets via @nebutra/vault (AWS KMS + HKDF envelope encryption)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations").option("--format <type>","Output format: json, plain, table","plain").option("--tenant <id>","Tenant ID for multi-tenant access").option("--unmask","Unmask secret values (required to view)").option("--description <text>","Description for secret").option("--value <text>","Secret value (prefer stdin for security)").option("--since <date>","Audit log start date (ISO 8601)").option("--limit <n>","Maximum audit log entries (default: 50)").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,tenant:o.tenant||i?.tenant,unmask:o.unmask||!1,description:o.description,value:o.value,since:o.since,limit:o.limit??50};try{switch(r){case"list":await Ec(s);break;case"set":n.length===0&&(d("set requires a secret key: nebutra secrets set <key>","error"),process.exit(c.INVALID_ARGS)),await Cc(n[0],s);break;case"get":n.length===0&&(d("get requires a secret key: nebutra secrets get <key>","error"),process.exit(c.INVALID_ARGS)),await Ac(n[0],s);break;case"rotate":n.length===0&&(d("rotate requires a secret key: nebutra secrets rotate <key>","error"),process.exit(c.INVALID_ARGS)),await xc(n[0],s);break;case"audit":await Oc(s);break;case"verify":await _c(s);break;default:d(`Unknown secrets subcommand: ${r}. Valid commands: list, set, get, rotate, audit, verify`,"error"),process.exit(c.ERROR)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Secrets command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
765
765
  Examples:
766
766
  nebutra secrets list List all secrets (metadata only)
767
767
  nebutra secrets list --tenant org_456 List secrets for specific tenant
@@ -796,7 +796,7 @@ Security Notes:
796
796
  - Never use --value in production (visible in shell history)
797
797
  - Always use --unmask when viewing secrets in scripts
798
798
  - Audit log tracks all access and modifications
799
- `)}import*as kt from"@clack/prompts";import M from"picocolors";function Rn(e){switch(e.toLowerCase()){case"running":return"running";case"exited":return"exited";case"restarting":return"restarting";case"paused":return"paused";default:return"exited"}}function Oc(e){switch(e){case"running":return M.green("\u25CF");case"exited":return M.red("\u25CF");case"restarting":return M.yellow("\u25CF");case"paused":return M.gray("\u25CF");default:return M.gray("\u25CF")}}async function _c(e){d("Checking service status...","info");let t=await x({command:"docker",args:["compose","ps","--format","json"],cwd:b(),interactive:!1,label:"Docker Compose PS",dryRun:e.dryRun});t.exitCode!==0&&(d("Failed to fetch service status","error"),A("Docker error",{stderr:t.stderr}),process.exit(c.ERROR));try{let r=JSON.parse(t.stdout);if(e.format==="json"){let n=r.map(o=>({name:o.Name,status:Rn(o.State),exitCode:o.ExitCode}));k(n,{format:"json"})}else{d("Service Status","info");let n=r.map(o=>({Service:Oc(Rn(o.State))+" "+o.Name,Status:o.State,"Exit Code":o.ExitCode||"\u2014"}));for(let o of n)d(`${o.Service} (${o.Status})`,"info")}}catch(r){d("Failed to parse service status","error"),A("Parse error",{error:String(r)}),process.exit(c.ERROR)}}async function Pc(e,t){d(`Streaming logs for ${M.cyan(e)}...`,"info");let r=["compose","logs"];t.tail?r.push("--tail",String(t.tail)):r.push("--tail","100"),t.since&&r.push("--since",t.since),r.push("-f",e),(await x({command:"docker",args:r,cwd:b(),interactive:!0,label:`Docker Compose Logs (${e})`,dryRun:t.dryRun})).exitCode!==0&&(d(`Failed to stream logs for ${e}`,"error"),process.exit(c.ERROR))}async function Tc(e,t){let r=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!t.yes&&!t.dryRun&&r){let i=await kt.confirm({message:`Restart service ${M.cyan(e)}?`,initialValue:!1});(kt.isCancel(i)||!i)&&(d("Restart cancelled","warn"),process.exit(c.CANCELLED))}d(`Restarting service ${M.cyan(e)}...`,"info");let n=["compose","restart"];t.timeout&&n.push("--timeout",String(t.timeout)),n.push(e);let o=await x({command:"docker",args:n,cwd:b(),interactive:!1,label:`Docker Compose Restart (${e})`,dryRun:t.dryRun});o.exitCode===0?d(`Service ${M.cyan(e)} restarted successfully`,"success"):(d(`Failed to restart service ${e}`,"error"),A("Docker error",{stderr:o.stderr}),process.exit(c.ERROR))}async function Ic(e){d("Running deep health check...","info");let t=[],r=await x({command:"docker",args:["compose","exec","-T","postgres","pg_isready"],cwd:b(),interactive:!1,label:"PostgreSQL Health",dryRun:e.dryRun});t.push({service:"PostgreSQL",healthy:r.exitCode===0,message:r.exitCode===0?"Ready":"Not responding"});let n=await x({command:"docker",args:["compose","exec","-T","redis","redis-cli","ping"],cwd:b(),interactive:!1,label:"Redis Health",dryRun:e.dryRun});t.push({service:"Redis",healthy:n.exitCode===0,message:n.exitCode===0?"Ready":"Not responding"});let o=await x({command:"docker",args:["compose","exec","-T","clickhouse","curl","-s","http://localhost:8123/ping"],cwd:b(),interactive:!1,label:"ClickHouse Health",dryRun:e.dryRun});t.push({service:"ClickHouse",healthy:o.exitCode===0,message:o.exitCode===0?"Ready":"Not responding"});let i=await x({command:"docker",args:["compose","exec","-T","meilisearch","curl","-s","http://localhost:7700/health"],cwd:b(),interactive:!1,label:"Meilisearch Health",dryRun:e.dryRun});if(t.push({service:"Meilisearch",healthy:i.exitCode===0,message:i.exitCode===0?"Healthy":"Not responding"}),e.format==="json")k(t,{format:"json"});else{for(let l of t){let u=l.healthy?M.green("\u2713"):M.red("\u2716");d(`${u} ${l.service}: ${l.message}`,l.healthy?"success":"error")}let s=t.every(l=>l.healthy);d(`Overall health: ${s?M.green("HEALTHY"):M.red("UNHEALTHY")}`,s?"success":"error")}}async function $c(e,t,r){let n=parseInt(t,10);(Number.isNaN(n)||n<0)&&(d("Invalid replica count (must be a non-negative number)","error"),process.exit(c.INVALID_ARGS)),d(`Scaling ${M.cyan(e)} to ${M.cyan(String(n))} replicas...`,"info");let o=await x({command:"docker",args:["compose","up","-d","--scale",`${e}=${n}`],cwd:b(),interactive:!1,label:`Docker Compose Scale (${e})`,dryRun:r.dryRun});o.exitCode===0?d(`Service ${M.cyan(e)} scaled to ${n} replicas`,"success"):(d(`Failed to scale service ${e}`,"error"),A("Docker error",{stderr:o.stderr}),process.exit(c.ERROR))}function kn(e){e.command("services <verb> [args...]").description("Manage Docker Compose microservices (postgres, redis, clickhouse, meilisearch, novu, openfga, etc.)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations").option("--format <type>","Output format: json, plain, table","plain").option("--tail <n>","Number of log lines to show (default: 100)").option("--since <duration>","Show logs since duration (e.g., 10m, 1h)").option("--timeout <seconds>","Timeout for service restart").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,tail:o.tail??100,since:o.since,timeout:o.timeout};try{switch(r){case"status":await _c(s);break;case"logs":n.length===0&&(d("logs requires a service name: nebutra services logs <service>","error"),process.exit(c.INVALID_ARGS)),await Pc(n[0],s);break;case"restart":n.length===0&&(d("restart requires a service name: nebutra services restart <service>","error"),process.exit(c.INVALID_ARGS)),await Tc(n[0],s);break;case"health":await Ic(s);break;case"scale":n.length<2&&(d("scale requires a service name and replica count: nebutra services scale <service> <count>","error"),process.exit(c.INVALID_ARGS)),await $c(n[0],n[1],s);break;default:d(`Unknown services subcommand: ${r}. Valid commands: status, logs, restart, health, scale`,"error"),process.exit(c.ERROR)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Services command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
799
+ `)}import*as kt from"@clack/prompts";import M from"picocolors";function kn(e){switch(e.toLowerCase()){case"running":return"running";case"exited":return"exited";case"restarting":return"restarting";case"paused":return"paused";default:return"exited"}}function Pc(e){switch(e){case"running":return M.green("\u25CF");case"exited":return M.red("\u25CF");case"restarting":return M.yellow("\u25CF");case"paused":return M.gray("\u25CF");default:return M.gray("\u25CF")}}async function Tc(e){d("Checking service status...","info");let t=await x({command:"docker",args:["compose","ps","--format","json"],cwd:b(),interactive:!1,label:"Docker Compose PS",dryRun:e.dryRun});t.exitCode!==0&&(d("Failed to fetch service status","error"),A("Docker error",{stderr:t.stderr}),process.exit(c.ERROR));try{let r=JSON.parse(t.stdout);if(e.format==="json"){let n=r.map(o=>({name:o.Name,status:kn(o.State),exitCode:o.ExitCode}));k(n,{format:"json"})}else{d("Service Status","info");let n=r.map(o=>({Service:Pc(kn(o.State))+" "+o.Name,Status:o.State,"Exit Code":o.ExitCode||"\u2014"}));for(let o of n)d(`${o.Service} (${o.Status})`,"info")}}catch(r){d("Failed to parse service status","error"),A("Parse error",{error:String(r)}),process.exit(c.ERROR)}}async function Ic(e,t){d(`Streaming logs for ${M.cyan(e)}...`,"info");let r=["compose","logs"];t.tail?r.push("--tail",String(t.tail)):r.push("--tail","100"),t.since&&r.push("--since",t.since),r.push("-f",e),(await x({command:"docker",args:r,cwd:b(),interactive:!0,label:`Docker Compose Logs (${e})`,dryRun:t.dryRun})).exitCode!==0&&(d(`Failed to stream logs for ${e}`,"error"),process.exit(c.ERROR))}async function $c(e,t){let r=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!t.yes&&!t.dryRun&&r){let i=await kt.confirm({message:`Restart service ${M.cyan(e)}?`,initialValue:!1});(kt.isCancel(i)||!i)&&(d("Restart cancelled","warn"),process.exit(c.CANCELLED))}d(`Restarting service ${M.cyan(e)}...`,"info");let n=["compose","restart"];t.timeout&&n.push("--timeout",String(t.timeout)),n.push(e);let o=await x({command:"docker",args:n,cwd:b(),interactive:!1,label:`Docker Compose Restart (${e})`,dryRun:t.dryRun});o.exitCode===0?d(`Service ${M.cyan(e)} restarted successfully`,"success"):(d(`Failed to restart service ${e}`,"error"),A("Docker error",{stderr:o.stderr}),process.exit(c.ERROR))}async function jc(e){d("Running deep health check...","info");let t=[],r=await x({command:"docker",args:["compose","exec","-T","postgres","pg_isready"],cwd:b(),interactive:!1,label:"PostgreSQL Health",dryRun:e.dryRun});t.push({service:"PostgreSQL",healthy:r.exitCode===0,message:r.exitCode===0?"Ready":"Not responding"});let n=await x({command:"docker",args:["compose","exec","-T","redis","redis-cli","ping"],cwd:b(),interactive:!1,label:"Redis Health",dryRun:e.dryRun});t.push({service:"Redis",healthy:n.exitCode===0,message:n.exitCode===0?"Ready":"Not responding"});let o=await x({command:"docker",args:["compose","exec","-T","clickhouse","curl","-s","http://localhost:8123/ping"],cwd:b(),interactive:!1,label:"ClickHouse Health",dryRun:e.dryRun});t.push({service:"ClickHouse",healthy:o.exitCode===0,message:o.exitCode===0?"Ready":"Not responding"});let i=await x({command:"docker",args:["compose","exec","-T","meilisearch","curl","-s","http://localhost:7700/health"],cwd:b(),interactive:!1,label:"Meilisearch Health",dryRun:e.dryRun});if(t.push({service:"Meilisearch",healthy:i.exitCode===0,message:i.exitCode===0?"Healthy":"Not responding"}),e.format==="json")k(t,{format:"json"});else{for(let l of t){let u=l.healthy?M.green("\u2713"):M.red("\u2716");d(`${u} ${l.service}: ${l.message}`,l.healthy?"success":"error")}let s=t.every(l=>l.healthy);d(`Overall health: ${s?M.green("HEALTHY"):M.red("UNHEALTHY")}`,s?"success":"error")}}async function Nc(e,t,r){let n=parseInt(t,10);(Number.isNaN(n)||n<0)&&(d("Invalid replica count (must be a non-negative number)","error"),process.exit(c.INVALID_ARGS)),d(`Scaling ${M.cyan(e)} to ${M.cyan(String(n))} replicas...`,"info");let o=await x({command:"docker",args:["compose","up","-d","--scale",`${e}=${n}`],cwd:b(),interactive:!1,label:`Docker Compose Scale (${e})`,dryRun:r.dryRun});o.exitCode===0?d(`Service ${M.cyan(e)} scaled to ${n} replicas`,"success"):(d(`Failed to scale service ${e}`,"error"),A("Docker error",{stderr:o.stderr}),process.exit(c.ERROR))}function En(e){e.command("services <verb> [args...]").description("Manage Docker Compose microservices (postgres, redis, clickhouse, meilisearch, novu, openfga, etc.)").option("--dry-run","Show what would be run without executing").option("--yes","Skip confirmations").option("--format <type>","Output format: json, plain, table","plain").option("--tail <n>","Number of log lines to show (default: 100)").option("--since <duration>","Show logs since duration (e.g., 10m, 1h)").option("--timeout <seconds>","Timeout for service restart").action(async(r,n,o)=>{let i=o.optsWithGlobals?.(),s={dryRun:o.dryRun||i?.dryRun,yes:o.yes||i?.yes,format:o.format||i?.format,tail:o.tail??100,since:o.since,timeout:o.timeout};try{switch(r){case"status":await Tc(s);break;case"logs":n.length===0&&(d("logs requires a service name: nebutra services logs <service>","error"),process.exit(c.INVALID_ARGS)),await Ic(n[0],s);break;case"restart":n.length===0&&(d("restart requires a service name: nebutra services restart <service>","error"),process.exit(c.INVALID_ARGS)),await $c(n[0],s);break;case"health":await jc(s);break;case"scale":n.length<2&&(d("scale requires a service name and replica count: nebutra services scale <service> <count>","error"),process.exit(c.INVALID_ARGS)),await Nc(n[0],n[1],s);break;default:d(`Unknown services subcommand: ${r}. Valid commands: status, logs, restart, health, scale`,"error"),process.exit(c.ERROR)}}catch(l){let u=l instanceof Error?l.message:String(l);d(`Services command failed: ${u}`,"error"),A("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
800
800
  Examples:
801
801
  nebutra services status Show all service status
802
802
  nebutra services logs postgres Stream postgres logs
@@ -817,15 +817,15 @@ Flags:
817
817
  --tail <n> Log lines to show (default: 100)
818
818
  --since <duration> Show logs since (e.g., 10m, 1h)
819
819
  --timeout <seconds> Timeout for restart
820
- `)}import{existsSync as Q,readdirSync as He,readFileSync as En}from"fs";import{resolve as B}from"path";import Ne from"picocolors";function xe(e,t,r){if(t==="json"){let n={command:r||"stats",...e};console.log(JSON.stringify(n,null,2))}else e.stdout&&(console.log(e.stdout),delete e.stdout),Object.keys(e).length>0&&console.log(JSON.stringify(e,null,2))}function Cn(e){try{let t=En(B(e,"package.json"),"utf-8");return JSON.parse(t)}catch{return{}}}function An(e){try{return He(e,{recursive:!0}).length}catch{return 0}}async function jc(e){a.info("Gathering monorepo statistics...");let t=b(),r=B(t,"packages"),n=B(t,"apps"),o=[],i=[],s=0,l="unknown";try{Q(r)&&(o=He(r).filter(f=>!f.startsWith(".")&&Q(B(r,f,"package.json")))),Q(n)&&(i=He(n).filter(f=>!f.startsWith(".")&&Q(B(n,f,"package.json"))));let m=B(t,"nebutra.config.ts");if(Q(m)){let y=En(m,"utf-8").match(/preset:\s*["']([^"']+)["']/);y&&(l=y[1])}}catch(m){a.warn(`Failed to read monorepo structure: ${m instanceof Error?m.message:String(m)}`)}let u={monorepo:{root:t,packages:o.length,apps:i.length,preset:l},statistics:{totalWorkspaces:o.length+i.length,packageCount:o.length,appCount:i.length}};e.dryRun||(a.success(`Found ${u.statistics.totalWorkspaces} workspaces`),a.info(`Packages: ${u.statistics.packageCount}, Apps: ${u.statistics.appCount}`),a.info(`Preset: ${l}`)),xe(u,e.format,"stats")}async function Nc(e){a.info("Analyzing bundle and dependency sizes...");let t=await x({command:"pnpm",args:["size"],interactive:!1,label:"Analyze package sizes",dryRun:e.dryRun}),r={analysis:"pnpm size",exitCode:t.exitCode,...t.stdout&&{stdout:t.stdout},...t.stderr&&{stderr:t.stderr}};t.exitCode!==0&&a.warn("Size analysis failed. Ensure your project is built."),xe(r,e.format,"stats:size")}async function Uc(e){a.info("Analyzing dependencies...");let t=await x({command:"npx",args:["knip","--no-progress"],interactive:!1,label:"Analyze dependencies",dryRun:e.dryRun}),r={analysis:"knip (unused dependencies)",exitCode:t.exitCode,command:"npx knip",...t.stdout&&{stdout:t.stdout.substring(0,500)}};e.dryRun||(t.exitCode===0?a.success("No unused dependencies detected"):a.info("Run 'npx knip' to see detailed dependency analysis")),xe(r,e.format,"stats:deps")}async function Lc(e){a.info("Listing packages...");let t=b(),r=B(t,"packages"),n=[];try{Q(r)&&(n=He(r).filter(s=>!s.startsWith(".")&&Q(B(r,s,"package.json"))).map(s=>{let l=B(r,s),u=Cn(l);return{name:u.name||s,version:u.version,description:u.description,files:An(l)}}))}catch(i){a.error(`Failed to list packages: ${i instanceof Error?i.message:String(i)}`),process.exit(c.ERROR)}let o={packages:n,total:n.length};e.dryRun||e.format==="json"?xe(o,e.format,"stats:packages"):(console.log(`
820
+ `)}import{existsSync as Q,readdirSync as He,readFileSync as Cn}from"fs";import{resolve as B}from"path";import Ne from"picocolors";function xe(e,t,r){if(t==="json"){let n={command:r||"stats",...e};console.log(JSON.stringify(n,null,2))}else e.stdout&&(console.log(e.stdout),delete e.stdout),Object.keys(e).length>0&&console.log(JSON.stringify(e,null,2))}function An(e){try{let t=Cn(B(e,"package.json"),"utf-8");return JSON.parse(t)}catch{return{}}}function xn(e){try{return He(e,{recursive:!0}).length}catch{return 0}}async function Uc(e){a.info("Gathering monorepo statistics...");let t=b(),r=B(t,"packages"),n=B(t,"apps"),o=[],i=[],s=0,l="unknown";try{Q(r)&&(o=He(r).filter(f=>!f.startsWith(".")&&Q(B(r,f,"package.json")))),Q(n)&&(i=He(n).filter(f=>!f.startsWith(".")&&Q(B(n,f,"package.json"))));let m=B(t,"nebutra.config.ts");if(Q(m)){let y=Cn(m,"utf-8").match(/preset:\s*["']([^"']+)["']/);y&&(l=y[1])}}catch(m){a.warn(`Failed to read monorepo structure: ${m instanceof Error?m.message:String(m)}`)}let u={monorepo:{root:t,packages:o.length,apps:i.length,preset:l},statistics:{totalWorkspaces:o.length+i.length,packageCount:o.length,appCount:i.length}};e.dryRun||(a.success(`Found ${u.statistics.totalWorkspaces} workspaces`),a.info(`Packages: ${u.statistics.packageCount}, Apps: ${u.statistics.appCount}`),a.info(`Preset: ${l}`)),xe(u,e.format,"stats")}async function Lc(e){a.info("Analyzing bundle and dependency sizes...");let t=await x({command:"pnpm",args:["size"],interactive:!1,label:"Analyze package sizes",dryRun:e.dryRun}),r={analysis:"pnpm size",exitCode:t.exitCode,...t.stdout&&{stdout:t.stdout},...t.stderr&&{stderr:t.stderr}};t.exitCode!==0&&a.warn("Size analysis failed. Ensure your project is built."),xe(r,e.format,"stats:size")}async function Dc(e){a.info("Analyzing dependencies...");let t=await x({command:"npx",args:["knip","--no-progress"],interactive:!1,label:"Analyze dependencies",dryRun:e.dryRun}),r={analysis:"knip (unused dependencies)",exitCode:t.exitCode,command:"npx knip",...t.stdout&&{stdout:t.stdout.substring(0,500)}};e.dryRun||(t.exitCode===0?a.success("No unused dependencies detected"):a.info("Run 'npx knip' to see detailed dependency analysis")),xe(r,e.format,"stats:deps")}async function Fc(e){a.info("Listing packages...");let t=b(),r=B(t,"packages"),n=[];try{Q(r)&&(n=He(r).filter(s=>!s.startsWith(".")&&Q(B(r,s,"package.json"))).map(s=>{let l=B(r,s),u=An(l);return{name:u.name||s,version:u.version,description:u.description,files:xn(l)}}))}catch(i){a.error(`Failed to list packages: ${i instanceof Error?i.message:String(i)}`),process.exit(c.ERROR)}let o={packages:n,total:n.length};e.dryRun||e.format==="json"?xe(o,e.format,"stats:packages"):(console.log(`
821
821
  ${Ne.cyan("Packages")} (${n.length} total)
822
- `),n.forEach(i=>{console.log(` ${Ne.blue(i.name)}`),i.version&&console.log(` version: ${i.version}`),i.description&&console.log(` ${i.description}`),console.log(` files: ${i.files}`)}),console.log(""))}async function Dc(e){a.info("Listing apps...");let t=b(),r=B(t,"apps"),n=[];try{Q(r)&&(n=He(r).filter(s=>!s.startsWith(".")&&Q(B(r,s,"package.json"))).map(s=>{let l=B(r,s),u=Cn(l),m=Q(B(l,"next.config.ts"))||Q(B(l,"next.config.js")),f=Q(B(l,"server.ts"))||Q(B(l,"server.js"));return{name:u.name||s,version:u.version,description:u.description,files:An(l),status:m||f?"ready":"unknown"}}))}catch(i){a.error(`Failed to list apps: ${i instanceof Error?i.message:String(i)}`),process.exit(c.ERROR)}let o={apps:n,total:n.length,ready:n.filter(i=>i.status==="ready").length};e.dryRun||e.format==="json"?xe(o,e.format,"stats:apps"):(console.log(`
822
+ `),n.forEach(i=>{console.log(` ${Ne.blue(i.name)}`),i.version&&console.log(` version: ${i.version}`),i.description&&console.log(` ${i.description}`),console.log(` files: ${i.files}`)}),console.log(""))}async function Vc(e){a.info("Listing apps...");let t=b(),r=B(t,"apps"),n=[];try{Q(r)&&(n=He(r).filter(s=>!s.startsWith(".")&&Q(B(r,s,"package.json"))).map(s=>{let l=B(r,s),u=An(l),m=Q(B(l,"next.config.ts"))||Q(B(l,"next.config.js")),f=Q(B(l,"server.ts"))||Q(B(l,"server.js"));return{name:u.name||s,version:u.version,description:u.description,files:xn(l),status:m||f?"ready":"unknown"}}))}catch(i){a.error(`Failed to list apps: ${i instanceof Error?i.message:String(i)}`),process.exit(c.ERROR)}let o={apps:n,total:n.length,ready:n.filter(i=>i.status==="ready").length};e.dryRun||e.format==="json"?xe(o,e.format,"stats:apps"):(console.log(`
823
823
  ${Ne.cyan("Apps")} (${n.length} total, ${o.ready} ready)
824
- `),n.forEach(i=>{let s=i.status==="ready"?Ne.green("\u2713"):Ne.gray("\u25CB");console.log(` ${s} ${Ne.blue(i.name)}`),i.version&&console.log(` version: ${i.version}`),i.description&&console.log(` ${i.description}`),console.log(` files: ${i.files}`)}),console.log(""))}function xn(e){let t=e.command("stats").description("Project statistics and health checks");t.command("*",{isDefault:!0}).description("Show monorepo overview").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await jc({format:r.format||n.format})}),t.command("size").description("Analyze bundle and package sizes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Nc({format:r.format||n.format})}),t.command("deps").description("Analyze dependencies (unused, missing, duplicate)").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Uc({format:r.format||n.format})}),t.command("packages").description("List all packages with metadata").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Lc({format:r.format||n.format})}),t.command("apps").description("List all apps with status").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Dc({format:r.format||n.format})})}import*as G from"@clack/prompts";import $ from"picocolors";var qt=["landing-page","web","storybook","backends/gateway","design-docs","studio","docs","ui","tokens","brand","theme","icons","preset","queue","search","notifications","permissions","webhooks","metering","uploads","vault","tenant"];function Fc(e){let t=`@nebutra/${e}`;if(!qt.includes(e)){let r=$.yellow(`Valid apps: ${qt.join(", ")}`);throw new Error(`Invalid app: ${$.red(e)}
825
- ${r}`)}return t}async function Vc(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test",options:{app:e.app,watch:e.watch,coverage:e.coverage},task:e.coverage?"pnpm test:coverage":e.watch?"pnpm test:watch":"pnpm test"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app&&(e.watch||e.coverage)&&(G.log.error($.red("Cannot use --watch or --coverage with --app filter (app-level tests use turbo)")),process.exit(c.INVALID_ARGS)),e.app){Fc(e.app);let n=`@nebutra/${e.app}`;e.quiet||G.log.info($.cyan(`Running tests for ${$.bold(n)}...`));let o=await ge("test",{filter:n});process.exit(o.exitCode)}let t="test";if(e.coverage?t="test:coverage":e.watch&&(t="test:watch"),!e.quiet){let n=t==="test:coverage"?"Running tests with coverage...":t==="test:watch"?"Running tests in watch mode...":"Running tests...";G.log.info($.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}async function On(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test e2e",options:{ui:e.ui,ci:e.ci},task:e.ci?"pnpm e2e:ci":e.ui?"pnpm e2e:ui":"pnpm e2e"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{e.ui&&e.ci&&(G.log.error($.red("Cannot use --ui and --ci together")),process.exit(c.INVALID_ARGS));let t="e2e";if(e.ci?t="e2e:ci":e.ui&&(t="e2e:ui"),!e.quiet){let n=t==="e2e:ci"?"Running E2E tests (CI mode)...":t==="e2e:ui"?"Opening E2E tests in UI mode...":"Running E2E tests...";G.log.info($.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}async function _n(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test size",options:{why:e.why},task:e.why?"pnpm size:why":"pnpm size"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{let t=e.why?"size:why":"size";if(!e.quiet){let n=e.why?"Analyzing bundle size (showing largest assets)...":"Checking bundle size...";G.log.info($.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Pn(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test arch",task:"pnpm test:arch"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{e.quiet||G.log.info($.cyan("Running architecture tests..."));let t=await K("test:arch",{interactive:!0});process.exit(t.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}function Tn(e){let t=e.command("test [subcommand]").description("Run tests (Vitest, Playwright, bundle size, architecture)").option("--watch","Run tests in watch mode (unit tests only)").option("--coverage","Generate coverage report (unit tests only)").option("--app <name>",`Run tests for specific app: ${qt.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;r==="e2e"?await On({ui:n.ui||!1,ci:n.ci||!1,dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):r==="size"?await _n({why:n.why||!1,dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):r==="arch"?await Pn({dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):await Vc({...n,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format})});t.command("e2e").description("Run end-to-end tests (Playwright)").option("--ui","Open interactive UI mode").option("--ci","Run in CI mode with strict options").option("--dry-run","Preview what would run (exit code 10)").action(async r=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await On({...r,quiet:n.quiet||!1,verbose:n.verbose||!1,format:n.format})}),t.command("size").description("Check bundle size (analyze largest assets)").option("--why","Show breakdown of largest bundle assets").option("--dry-run","Preview what would run (exit code 10)").action(async r=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await _n({...r,quiet:n.quiet||!1,verbose:n.verbose||!1,format:n.format})}),t.command("arch").description("Run architecture tests (verify design layer isolation)").option("--dry-run","Preview what would run (exit code 10)").action(async r=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await Pn({dryRun:r.dryRun||!1,quiet:n.quiet||!1,verbose:n.verbose||!1,format:n.format})})}var In={$schema:"https://nebutra.com/schemas/theme-registry.json",version:"2026.05",defaultTheme:"nebutra",themes:[{id:"nebutra",name:"Nebutra",category:"ai-native",mood:"Official Nebutra brand \u2014 \u4E91\u6BD3\u84DD \u2192 \u4E91\u6BD3\u9752, AI-native default",tokenPath:"tokens/themes/nebutra.json",install:{command:"nebutra theme add nebutra",registryUrl:"https://ui.nebutra.com/themes/nebutra.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"dark-dense",name:"Dark Dense",category:"pro-tools",mood:"Dense operator surfaces - dark, compact, low distraction",tokenPath:"tokens/themes/dark-dense.json",install:{command:"nebutra theme add dark-dense",registryUrl:"https://ui.nebutra.com/themes/dark-dense.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"minimal",name:"Minimal",category:"productivity",mood:"Document and workspace apps - neutral, calm, readable",tokenPath:"tokens/themes/minimal.json",install:{command:"nebutra theme add minimal",registryUrl:"https://ui.nebutra.com/themes/minimal.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"vibrant",name:"Vibrant",category:"creative",mood:"Creator and consumer surfaces - saturated, expressive, energetic",tokenPath:"tokens/themes/vibrant.json",install:{command:"nebutra theme add vibrant",registryUrl:"https://ui.nebutra.com/themes/vibrant.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"ocean",name:"Ocean",category:"enterprise",mood:"B2B infrastructure and finance - cool, stable, trustworthy",tokenPath:"tokens/themes/ocean.json",install:{command:"nebutra theme add ocean",registryUrl:"https://ui.nebutra.com/themes/ocean.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid",name:"Coral Bloom",category:"community",mood:"Hot coral-rose on white \u2014 lively, welcoming, approachable",tokenPath:"tokens/themes/crimson-light-vivid.json",install:{command:"nebutra theme add crimson-light-vivid",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-muted",name:"Maritime",category:"community",mood:"Deep navy on white \u2014 nautical precision, calm authority",tokenPath:"tokens/themes/cyan-light-muted.json",install:{command:"nebutra theme add cyan-light-muted",registryUrl:"https://ui.nebutra.com/themes/cyan-light-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid",name:"Blueprint",category:"community",mood:"Classic azure on white \u2014 architectural, clear-purpose",tokenPath:"tokens/themes/cyan-light-vivid.json",install:{command:"nebutra theme add cyan-light-vivid",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"amber-light-vivid",name:"Sunstruck",category:"community",mood:"Electric gold on charcoal \u2014 warm, high-energy, confident",tokenPath:"tokens/themes/amber-light-vivid.json",install:{command:"nebutra theme add amber-light-vivid",registryUrl:"https://ui.nebutra.com/themes/amber-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted",name:"Void",category:"community",mood:"Pure white on black \u2014 maximum contrast, zero distraction",tokenPath:"tokens/themes/crimson-dark-muted.json",install:{command:"nebutra theme add crimson-dark-muted",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-2",name:"Cobalt Dusk",category:"community",mood:"Medium cobalt on white \u2014 grounded, reliable, focused",tokenPath:"tokens/themes/cyan-light-vivid-2.json",install:{command:"nebutra theme add cyan-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-2",name:"Obsidian",category:"community",mood:"White on deep black \u2014 high-contrast, stark monochrome",tokenPath:"tokens/themes/crimson-dark-muted-2.json",install:{command:"nebutra theme add crimson-dark-muted-2",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted",name:"Graphite",category:"community",mood:"Near-black on clean white \u2014 direct, no-nonsense",tokenPath:"tokens/themes/crimson-light-muted.json",install:{command:"nebutra theme add crimson-light-muted",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid",name:"Sandstone",category:"community",mood:"Warm terracotta on cream \u2014 organic, considered, sun-baked",tokenPath:"tokens/themes/rose-light-vivid.json",install:{command:"nebutra theme add rose-light-vivid",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-2",name:"Parchment",category:"community",mood:"Deep ink on warm parchment \u2014 warm, literary, timeless",tokenPath:"tokens/themes/crimson-light-muted-2.json",install:{command:"nebutra theme add crimson-light-muted-2",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"gold-dark-vivid",name:"Neon Citrus",category:"community",mood:"Neon yellow-gold on near-black \u2014 maximum energy, studio glow",tokenPath:"tokens/themes/gold-dark-vivid.json",install:{command:"nebutra theme add gold-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/gold-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-muted",name:"Raven",category:"community",mood:"Carbon charcoal on white \u2014 stark, editorial clarity",tokenPath:"tokens/themes/azure-light-muted.json",install:{command:"nebutra theme add azure-light-muted",registryUrl:"https://ui.nebutra.com/themes/azure-light-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-3",name:"Ultraviolet",category:"community",mood:"Deep electric blue on white \u2014 bold, digital, forward",tokenPath:"tokens/themes/cyan-light-vivid-3.json",install:{command:"nebutra theme add cyan-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-dark-vivid",name:"Royal Linen",category:"community",mood:"Deep royal blue on bright linen \u2014 classic, structured, formal",tokenPath:"tokens/themes/azure-dark-vivid.json",install:{command:"nebutra theme add azure-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/azure-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-2",name:"Tangerine",category:"community",mood:"Deep orange on near-white \u2014 warm, energetic, bold",tokenPath:"tokens/themes/rose-light-vivid-2.json",install:{command:"nebutra theme add rose-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-2",name:"Scarlet",category:"community",mood:"Vivid scarlet on white \u2014 assertive, expressive, electric",tokenPath:"tokens/themes/crimson-light-vivid-2.json",install:{command:"nebutra theme add crimson-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-3",name:"Pumice",category:"community",mood:"Warm dark on light gray \u2014 subtle, refined surface",tokenPath:"tokens/themes/crimson-light-muted-3.json",install:{command:"nebutra theme add crimson-light-muted-3",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-4",name:"Flint",category:"community",mood:"Black on white \u2014 pure editorial, zero tonal interference",tokenPath:"tokens/themes/crimson-light-muted-4.json",install:{command:"nebutra theme add crimson-light-muted-4",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-vivid",name:"Ember",category:"community",mood:"Deep ember red on dark charcoal \u2014 intense, dramatic warmth",tokenPath:"tokens/themes/crimson-dark-vivid.json",install:{command:"nebutra theme add crimson-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-5",name:"Chalk Veil",category:"community",mood:"Black on soft white \u2014 gentle clarity, editorial calm",tokenPath:"tokens/themes/crimson-light-muted-5.json",install:{command:"nebutra theme add crimson-light-muted-5",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-3",name:"Inkwell",category:"community",mood:"Bright white on inky dark \u2014 typographic, print-inspired",tokenPath:"tokens/themes/crimson-dark-muted-3.json",install:{command:"nebutra theme add crimson-dark-muted-3",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-4",name:"Ivory Press",category:"community",mood:"Black ink on near-white \u2014 newspaper clarity, old-school type",tokenPath:"tokens/themes/crimson-dark-muted-4.json",install:{command:"nebutra theme add crimson-dark-muted-4",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-4",name:"Lapis",category:"community",mood:"Deep lapis blue on white \u2014 timeless, authoritative",tokenPath:"tokens/themes/cyan-light-vivid-4.json",install:{command:"nebutra theme add cyan-light-vivid-4",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-5",name:"Cerulean",category:"community",mood:"Cerulean on white \u2014 open sky, systematic clarity",tokenPath:"tokens/themes/cyan-light-vivid-5.json",install:{command:"nebutra theme add cyan-light-vivid-5",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-6",name:"Atelier",category:"community",mood:"Dark ink on warm cream \u2014 handcrafted, studio-warm aesthetic",tokenPath:"tokens/themes/crimson-light-muted-6.json",install:{command:"nebutra theme add crimson-light-muted-6",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-6.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"indigo-dim-vivid",name:"Aubergine",category:"community",mood:"Electric violet on near-black \u2014 rich, complex, dark luxury",tokenPath:"tokens/themes/indigo-dim-vivid.json",install:{command:"nebutra theme add indigo-dim-vivid",registryUrl:"https://ui.nebutra.com/themes/indigo-dim-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"amber-light-vivid-2",name:"Harvest Noir",category:"community",mood:"Deep amber on near-black \u2014 bold, harvested warmth in darkness",tokenPath:"tokens/themes/amber-light-vivid-2.json",install:{command:"nebutra theme add amber-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/amber-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-dark-vivid-2",name:"Periwinkle Void",category:"community",mood:"Dusky periwinkle on true black \u2014 calm intelligence",tokenPath:"tokens/themes/azure-dark-vivid-2.json",install:{command:"nebutra theme add azure-dark-vivid-2",registryUrl:"https://ui.nebutra.com/themes/azure-dark-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-6",name:"Cornflower",category:"community",mood:"Cornflower blue on warm canvas \u2014 friendly, accessible",tokenPath:"tokens/themes/cyan-light-vivid-6.json",install:{command:"nebutra theme add cyan-light-vivid-6",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-6.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-vivid-2",name:"Lacquer",category:"community",mood:"Bold lacquer red on dark ground \u2014 assertive, polished",tokenPath:"tokens/themes/crimson-dark-vivid-2.json",install:{command:"nebutra theme add crimson-dark-vivid-2",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-7",name:"Horizon",category:"community",mood:"Deep sky blue on white \u2014 expansive, clear, optimistic",tokenPath:"tokens/themes/cyan-light-vivid-7.json",install:{command:"nebutra theme add cyan-light-vivid-7",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-7.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-7",name:"Carbon",category:"community",mood:"Carbon black on white \u2014 precision engineering aesthetic",tokenPath:"tokens/themes/crimson-light-muted-7.json",install:{command:"nebutra theme add crimson-light-muted-7",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-7.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-8",name:"Jet",category:"community",mood:"Jet black on pure white \u2014 crisp, high-definition",tokenPath:"tokens/themes/crimson-light-muted-8.json",install:{command:"nebutra theme add crimson-light-muted-8",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-8.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-muted-2",name:"Monolith",category:"community",mood:"Near-black primary on pure white \u2014 minimal, decisive, uncluttered",tokenPath:"tokens/themes/azure-light-muted-2.json",install:{command:"nebutra theme add azure-light-muted-2",registryUrl:"https://ui.nebutra.com/themes/azure-light-muted-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-3",name:"Blaze",category:"community",mood:"Vivid orange on white \u2014 bright, bold, full-spectrum warmth",tokenPath:"tokens/themes/rose-light-vivid-3.json",install:{command:"nebutra theme add rose-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-light-vivid",name:"Acid Mint",category:"community",mood:"Neon mint on dark canvas \u2014 raw energy, dev-tool edge",tokenPath:"tokens/themes/emerald-light-vivid.json",install:{command:"nebutra theme add emerald-light-vivid",registryUrl:"https://ui.nebutra.com/themes/emerald-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-9",name:"Slate Fog",category:"community",mood:"Soft dark on white \u2014 cool and composed, low-key depth",tokenPath:"tokens/themes/crimson-light-muted-9.json",install:{command:"nebutra theme add crimson-light-muted-9",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-9.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-vivid",name:"Amethyst Chalk",category:"community",mood:"Strong violet-blue on chalk \u2014 artful, composed, airy",tokenPath:"tokens/themes/azure-light-vivid.json",install:{command:"nebutra theme add azure-light-vivid",registryUrl:"https://ui.nebutra.com/themes/azure-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"lime-light-vivid",name:"Viridian",category:"community",mood:"Saturated tech-lime on white \u2014 charged, technical freshness",tokenPath:"tokens/themes/lime-light-vivid.json",install:{command:"nebutra theme add lime-light-vivid",registryUrl:"https://ui.nebutra.com/themes/lime-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-10",name:"Noir Blanc",category:"community",mood:"Pure black on white \u2014 photographic, stripped back",tokenPath:"tokens/themes/crimson-light-muted-10.json",install:{command:"nebutra theme add crimson-light-muted-10",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-10.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-11",name:"Birch",category:"community",mood:"Warm dark on near-white \u2014 gentle, organic, Scandinavian",tokenPath:"tokens/themes/crimson-light-muted-11.json",install:{command:"nebutra theme add crimson-light-muted-11",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-11.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-3",name:"Signal Red",category:"community",mood:"Pure signal red on white \u2014 urgent, direct, unmissable",tokenPath:"tokens/themes/crimson-light-vivid-3.json",install:{command:"nebutra theme add crimson-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-8",name:"Cobalt Night",category:"community",mood:"Vivid cobalt on deep dark \u2014 bold night mode energy",tokenPath:"tokens/themes/cyan-light-vivid-8.json",install:{command:"nebutra theme add cyan-light-vivid-8",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-8.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-4",name:"Marigold Noir",category:"community",mood:"Golden amber on deep dark \u2014 warm accent, dramatic contrast",tokenPath:"tokens/themes/rose-light-vivid-4.json",install:{command:"nebutra theme add rose-light-vivid-4",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-12",name:"Anthracite",category:"community",mood:"White on deep anthracite \u2014 modern, architectural",tokenPath:"tokens/themes/crimson-light-muted-12.json",install:{command:"nebutra theme add crimson-light-muted-12",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-12.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"amber-light-vivid-3",name:"Voltage",category:"community",mood:"Neon yellow on dark canvas \u2014 electric, alert, studio-bright",tokenPath:"tokens/themes/amber-light-vivid-3.json",install:{command:"nebutra theme add amber-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/amber-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-4",name:"Cinnabar",category:"community",mood:"Deep cinnabar on warm off-white \u2014 rich, earthy intensity",tokenPath:"tokens/themes/crimson-light-vivid-4.json",install:{command:"nebutra theme add crimson-light-vivid-4",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-dark-muted",name:"Moonbeam",category:"community",mood:"Pale silver-white on black \u2014 cool night, lunar glow",tokenPath:"tokens/themes/cyan-dark-muted.json",install:{command:"nebutra theme add cyan-dark-muted",registryUrl:"https://ui.nebutra.com/themes/cyan-dark-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-vivid-2",name:"Cobalt Vault",category:"community",mood:"Vivid cobalt on deep slate \u2014 sharp, technical, midnight engineering",tokenPath:"tokens/themes/azure-light-vivid-2.json",install:{command:"nebutra theme add azure-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/azure-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-5",name:"Bone Script",category:"community",mood:"Soft near-black on bone white \u2014 considered, understated",tokenPath:"tokens/themes/crimson-dark-muted-5.json",install:{command:"nebutra theme add crimson-dark-muted-5",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-vivid-3",name:"Terracotta Noir",category:"community",mood:"Warm terracotta on charcoal night \u2014 earthy, expressive",tokenPath:"tokens/themes/crimson-dark-vivid-3.json",install:{command:"nebutra theme add crimson-dark-vivid-3",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"indigo-light",name:"Dusk Veil",category:"community",mood:"Deep midnight violet on pale lilac \u2014 contemplative dusk",tokenPath:"tokens/themes/indigo-light.json",install:{command:"nebutra theme add indigo-light",registryUrl:"https://ui.nebutra.com/themes/indigo-light.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-13",name:"Quartz Dawn",category:"community",mood:"Black on quartz-white \u2014 clean surfaces, morning clarity",tokenPath:"tokens/themes/crimson-light-muted-13.json",install:{command:"nebutra theme add crimson-light-muted-13",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-13.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"violet-light-vivid",name:"Plum",category:"community",mood:"Deep plum on white \u2014 rich, intentional, confident",tokenPath:"tokens/themes/violet-light-vivid.json",install:{command:"nebutra theme add violet-light-vivid",registryUrl:"https://ui.nebutra.com/themes/violet-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-14",name:"Alabaster",category:"community",mood:"Black on alabaster \u2014 minimal, interior-design cool",tokenPath:"tokens/themes/crimson-light-muted-14.json",install:{command:"nebutra theme add crimson-light-muted-14",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-14.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-dark-vivid",name:"Neon Grove",category:"community",mood:"Electric emerald on charcoal \u2014 vibrant, playful, alive",tokenPath:"tokens/themes/emerald-dark-vivid.json",install:{command:"nebutra theme add emerald-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/emerald-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-dark-vivid-2",name:"Forest Vault",category:"community",mood:"Deep forest green on dark \u2014 grounded, organic, premium",tokenPath:"tokens/themes/emerald-dark-vivid-2.json",install:{command:"nebutra theme add emerald-dark-vivid-2",registryUrl:"https://ui.nebutra.com/themes/emerald-dark-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-vivid-3",name:"Iris Flash",category:"community",mood:"Electric iris on bright white \u2014 bold, creative, wide-open",tokenPath:"tokens/themes/azure-light-vivid-3.json",install:{command:"nebutra theme add azure-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/azure-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-light-vivid-2",name:"Lagoon",category:"community",mood:"Bright sea-green on deep dark \u2014 tropical, refreshing",tokenPath:"tokens/themes/emerald-light-vivid-2.json",install:{command:"nebutra theme add emerald-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/emerald-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light",name:"Midnight Quill",category:"community",mood:"Midnight indigo on white \u2014 considered, literary, precise",tokenPath:"tokens/themes/azure-light.json",install:{command:"nebutra theme add azure-light",registryUrl:"https://ui.nebutra.com/themes/azure-light.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-dim-vivid",name:"Sapphire Mist",category:"community",mood:"Vivid sapphire on pale mist \u2014 clear, open, airy",tokenPath:"tokens/themes/cyan-dim-vivid.json",install:{command:"nebutra theme add cyan-dim-vivid",registryUrl:"https://ui.nebutra.com/themes/cyan-dim-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"teal-light-vivid",name:"Glacial",category:"community",mood:"Electric teal-mint on deep dark \u2014 Arctic clarity, crisp",tokenPath:"tokens/themes/teal-light-vivid.json",install:{command:"nebutra theme add teal-light-vivid",registryUrl:"https://ui.nebutra.com/themes/teal-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-15",name:"Stencil",category:"community",mood:"Black on white \u2014 bold cutout, typographic",tokenPath:"tokens/themes/crimson-light-muted-15.json",install:{command:"nebutra theme add crimson-light-muted-15",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-15.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-16",name:"Porcelain",category:"community",mood:"Soft black on porcelain white \u2014 refined, glaze-like surface",tokenPath:"tokens/themes/crimson-light-muted-16.json",install:{command:"nebutra theme add crimson-light-muted-16",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-16.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-17",name:"Pewter",category:"community",mood:"Pewter dark on white \u2014 understated, functional elegance",tokenPath:"tokens/themes/crimson-light-muted-17.json",install:{command:"nebutra theme add crimson-light-muted-17",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-17.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-5",name:"Flux Red",category:"community",mood:"Electric red on white \u2014 charged, high-stakes, decisive",tokenPath:"tokens/themes/crimson-light-vivid-5.json",install:{command:"nebutra theme add crimson-light-vivid-5",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-dark-vivid-3",name:"Jade Noir",category:"community",mood:"Vivid jade on near-black \u2014 lush, technical, distinctive",tokenPath:"tokens/themes/emerald-dark-vivid-3.json",install:{command:"nebutra theme add emerald-dark-vivid-3",registryUrl:"https://ui.nebutra.com/themes/emerald-dark-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-dark-muted",name:"Truffle",category:"community",mood:"Warm cream on espresso brown \u2014 cozy, warm, editorial",tokenPath:"tokens/themes/rose-dark-muted.json",install:{command:"nebutra theme add rose-dark-muted",registryUrl:"https://ui.nebutra.com/themes/rose-dark-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-18",name:"Basalt",category:"community",mood:"Deep basalt on white \u2014 volcanic, grounded, decisive",tokenPath:"tokens/themes/crimson-light-muted-18.json",install:{command:"nebutra theme add crimson-light-muted-18",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-18.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-19",name:"Tundra",category:"community",mood:"Black on white \u2014 vast, clear, utterly open",tokenPath:"tokens/themes/crimson-light-muted-19.json",install:{command:"nebutra theme add crimson-light-muted-19",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-19.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"lime-light-vivid-2",name:"Chartreuse Noir",category:"community",mood:"Bright chartreuse on dark \u2014 bold, unconventional, vivid",tokenPath:"tokens/themes/lime-light-vivid-2.json",install:{command:"nebutra theme add lime-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/lime-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-6",name:"Pitch",category:"community",mood:"Clean white on near-black \u2014 dark mode minimalism",tokenPath:"tokens/themes/crimson-dark-muted-6.json",install:{command:"nebutra theme add crimson-dark-muted-6",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-6.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-5",name:"Vermilion",category:"community",mood:"Deep vermilion on off-white \u2014 earthy, vivid, painterly",tokenPath:"tokens/themes/rose-light-vivid-5.json",install:{command:"nebutra theme add rose-light-vivid-5",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}}]};var we=In,lp=we.themes.map(e=>e.id);var dp=we.defaultTheme;function $n(e){return we.themes.find(t=>t.id===e)}function jn(e){let t=e.opts?e.opts():e,r=e.optsWithGlobals?e.optsWithGlobals():e;return t.format??r.format??Bc()}function Bc(){let e=process.argv.find(r=>r.startsWith("--format="));if(e)return e.slice(9);let t=process.argv.indexOf("--format");if(t>=0)return process.argv[t+1]}function Gc(e){return{id:e.id,name:e.name,category:e.category,mood:e.mood,tokenPath:e.tokenPath,installCommand:e.install.command,registryUrl:e.install.registryUrl,wcag:e.governance.wcag,visualSuites:e.governance.visualSuites}}function qc(e="table"){let t=we.themes.map(Gc);return e==="json"?JSON.stringify({version:we.version,defaultTheme:we.defaultTheme,count:t.length,themes:t},null,2):[`Nebutra themes (${t.length})`,`Default: ${we.defaultTheme}`,"",...t.map(n=>`${n.id.padEnd(12)} ${n.category.padEnd(14)} ${n.tokenPath.padEnd(34)} ${n.mood}`)].join(`
826
- `)}function Kc(e,t="table"){let r=$n(e);if(r)return t==="json"?JSON.stringify(r,null,2):[`${r.name} (${r.id})`,`Category: ${r.category}`,`Mood: ${r.mood}`,`Token path: ${r.tokenPath}`,`Install: ${r.install.command}`,`Registry: ${r.install.registryUrl}`,`WCAG: ${r.governance.wcag}`,`Visual suites: ${r.governance.visualSuites.join(", ")}`,`Required tokens: ${r.governance.requiredTokens.join(", ")}`].join(`
827
- `)}function Nn(e){let t=e.command("theme").description("Inspect registry-backed Nebutra themes and governance metadata");t.command("list").description("List built-in themes from the shared theme registry").option("--format <type>","Output format: json or table").action(r=>{console.log(qc(jn(r)))}),t.command("inspect <id>").description("Show governance metadata for one theme").option("--format <type>","Output format: json or table").action((r,n)=>{let o=Kc(r,jn(n));o||(a.error(`Theme '${r}' was not found in the Nebutra theme registry.`),process.exit(c.NOT_FOUND)),console.log(o)})}import{existsSync as Un,readFileSync as zc,unlinkSync as Wc,writeFileSync as Yc}from"fs";import{dirname as Hc,join as Ln,parse as Jc}from"path";function Xc(e){let t=e,{root:r}=Jc(t);for(;;){if(Un(Ln(t,"package.json")))return t;if(t===r)return null;let n=Hc(t);if(n===t)return null;t=n}}async function Qc(e){let t=e.format==="json",r=Xc(process.cwd())??process.cwd(),n=Ln(r,"nebutra.config.json");if(Un(n)||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):a.info("Already unlinked"),process.exit(c.SUCCESS)),e.force){try{Wc(n)}catch(l){let u=l instanceof Error?l.message:String(l);t?console.log(JSON.stringify({command:"unlink",success:!1,error:u},null,2)):a.error(`Failed to delete config: ${u}`),process.exit(c.PERMISSION_DENIED)}t?console.log(JSON.stringify({command:"unlink",success:!0,deletedConfig:!0,configPath:n},null,2)):a.success("Removed nebutra.config.json");return}let o={};try{o=JSON.parse(zc(n,"utf-8"))}catch{o={}}"projectId"in o||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):a.info("Already unlinked"),process.exit(c.SUCCESS));let{projectId:i,...s}=o;Yc(n,JSON.stringify(s,null,2)+`
828
- `),t?console.log(JSON.stringify({command:"unlink",success:!0,configPath:n},null,2)):a.success("Unlinked from project")}function Dn(e){e.command("unlink").description("Remove the project link from nebutra.config.json").option("--force","Delete the entire nebutra.config.json").option("--format <type>","Output format: json or plain").action(async(t,r)=>{let n=r?.optsWithGlobals?.()||t;await Qc({force:t.force||!1,format:t.format||n.format})})}import{spawnSync as dl}from"child_process";import{promises as Et}from"fs";import{homedir as Zc}from"os";import{join as Vn}from"path";import el from"p-timeout";import Se from"picocolors";var tl=1440*60*1e3,Mn=Vn(Zc(),".nebutra"),Kt=Vn(Mn,"update-check.json"),rl="https://registry.npmjs.org/nebutra",nl=5e3;async function ol(){try{await Et.mkdir(Mn,{recursive:!0})}catch{}}async function al(){try{let e=await Et.readFile(Kt,"utf-8"),t=JSON.parse(e);return Date.now()-t.timestamp<tl?t:(await Et.unlink(Kt).catch(n=>{a.debug("Failed to remove expired update cache file",{error:n})}),null)}catch{return null}}async function il(e){try{await ol();let t={timestamp:Date.now(),latestVersion:e};await Et.writeFile(Kt,JSON.stringify(t,null,2),"utf-8")}catch{}}async function sl(){try{let e=new AbortController,t=await el(fetch(rl,{signal:e.signal,headers:{Accept:"application/json"}}),{milliseconds:nl,fallback:()=>(e.abort(),null)});if(!t?.ok)return null;let n=(await t.json())["dist-tags"];return!n||typeof n.latest!="string"?null:n.latest}catch{return null}}function Fn(e){return e.split(".").map(t=>parseInt(t.replace(/[^0-9]/g,""),10)||0).slice(0,3)}function cl(e,t){let r=Fn(e),n=Fn(t);for(let o=0;o<3;o++){let i=r[o]??0,s=n[o]??0;if(s>i)return!0;if(s<i)return!1}return!1}async function zt(e){let t=await al(),r=null;return t?r=t.latestVersion:(r=await sl(),r&&await il(r)),!r||!cl(e,r)?null:{currentVersion:e,latestVersion:r,isUpdate:!0}}function ll(e){let r=`Update available: ${e.currentVersion} \u2192 ${e.latestVersion}`,n="Run `npm i -g nebutra` to update",o=" ".repeat((43-r.length)/2),i=" ".repeat((43-n.length)/2),s=[Se.cyan("\u256D"+"\u2500".repeat(41)+"\u256E"),Se.cyan("\u2502")+Se.yellow(o+r+o)+Se.cyan("\u2502"),Se.cyan("\u2502")+Se.gray(i+n+i)+Se.cyan("\u2502"),Se.cyan("\u2570"+"\u2500".repeat(41)+"\u256F")]}async function Bn(e){let t=null;return zt(e).then(r=>{t=r}),async()=>{!process.stdout.isTTY||process.env.CI||(t||await new Promise(r=>setTimeout(r,100)),t&&ll(t))}}function ul(){let t=(process.argv[1]||"").toLowerCase();if(t.includes("/homebrew/")||t.includes("/cellar/"))return"brew";if(t.includes("/.bun/")||t.includes("/bun/"))return"bun";if(t.includes("/pnpm/")||t.includes("/.pnpm/"))return"pnpm";if(t.includes("/yarn/")||t.includes("/.yarn/"))return"yarn";if(t.includes("/npm/")||t.includes("/node_modules/"))return"npm";let r=process.env.npm_config_user_agent||"";return r.startsWith("pnpm")?"pnpm":r.startsWith("yarn")?"yarn":r.startsWith("bun")?"bun":r.startsWith("npm")?"npm":"unknown"}function ml(e){switch(e){case"pnpm":return"pnpm add -g nebutra@latest";case"yarn":return"yarn global add nebutra@latest";case"bun":return"bun add -g nebutra@latest";case"brew":return"brew upgrade nebutra";case"npm":return"npm i -g nebutra@latest";default:return"npm i -g nebutra@latest"}}var Oe="0.1.0";async function pl(e){let t=ul(),r=ml(t),n=e.format==="json",o=await zt(Oe),i=o?.latestVersion??null,s=!!o?.isUpdate;e.dryRun&&(n?console.log(JSON.stringify({command:"upgrade",dryRun:!0,installer:t,command_to_run:r,currentVersion:Oe,latestVersion:i,hasUpdate:s},null,2)):(a.info(`Detected installer: ${t}`),a.info(`Current: ${Oe}${i?` \u2192 Latest: ${i}`:""}`),a.info(`Upgrade command: ${r}`)),process.exit(c.DRY_RUN_OK)),!s&&i&&(n?console.log(JSON.stringify({command:"upgrade",success:!0,alreadyLatest:!0,version:Oe},null,2)):a.success(`Already on the latest version (${Oe})`),process.exit(c.SUCCESS)),e.yes||(n?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,command_to_run:r,currentVersion:Oe,latestVersion:i,requiresConfirmation:!0},null,2)):(a.info(`Current: ${Oe}${i?` \u2192 Latest: ${i}`:""}`),a.info("To upgrade, run:"),a.info(` ${r}`),a.info("Or re-run this command with --yes to execute it now.")),process.exit(c.SUCCESS));let[l,...u]=r.split(" ");n||a.info(`Running: ${r}`);let m=dl(l,u,{stdio:n?"pipe":"inherit"});m.status===0&&(n?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,ran:r},null,2)):a.success("Upgrade complete"),process.exit(c.SUCCESS));let f=m.stderr?.toString()||`Upgrade failed (exit ${m.status})`;n?console.log(JSON.stringify({command:"upgrade",success:!1,installer:t,ran:r,error:f},null,2)):a.error(f),process.exit(c.ERROR)}function Gn(e){let t=(r,n)=>{let o=n?.optsWithGlobals?.()||r;return pl({yes:r.yes||o.yes||!1,dryRun:r.dryRun||!1,format:r.format||o.format})};e.command("upgrade").alias("self-update").description("Upgrade the nebutra CLI to the latest version").option("--yes","Execute the upgrade command without confirmation").option("--dry-run","Show the upgrade command without executing (exit 10)").option("--format <type>","Output format: json or plain").action(t)}import Wt from"fs";import Yt from"path";import fl from"picocolors";var Ht=["inngest","n8n","pusher"],gl=`import { Inngest } from "inngest";
824
+ `),n.forEach(i=>{let s=i.status==="ready"?Ne.green("\u2713"):Ne.gray("\u25CB");console.log(` ${s} ${Ne.blue(i.name)}`),i.version&&console.log(` version: ${i.version}`),i.description&&console.log(` ${i.description}`),console.log(` files: ${i.files}`)}),console.log(""))}function On(e){let t=e.command("stats").description("Project statistics and health checks");t.command("*",{isDefault:!0}).description("Show monorepo overview").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Uc({format:r.format||n.format})}),t.command("size").description("Analyze bundle and package sizes").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Lc({format:r.format||n.format})}),t.command("deps").description("Analyze dependencies (unused, missing, duplicate)").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Dc({format:r.format||n.format})}),t.command("packages").description("List all packages with metadata").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Fc({format:r.format||n.format})}),t.command("apps").description("List all apps with status").option("--format <type>","Output format: json or plain").action(async r=>{let n=r.optsWithGlobals?.()||r;await Vc({format:r.format||n.format})})}import*as G from"@clack/prompts";import $ from"picocolors";var qt=["landing-page","web","storybook","backends/gateway","design-docs","studio","docs","ui","tokens","brand","theme","icons","preset","queue","search","notifications","permissions","webhooks","metering","uploads","vault","tenant"];function Mc(e){let t=`@nebutra/${e}`;if(!qt.includes(e)){let r=$.yellow(`Valid apps: ${qt.join(", ")}`);throw new Error(`Invalid app: ${$.red(e)}
825
+ ${r}`)}return t}async function Bc(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test",options:{app:e.app,watch:e.watch,coverage:e.coverage},task:e.coverage?"pnpm test:coverage":e.watch?"pnpm test:watch":"pnpm test"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{if(e.app&&(e.watch||e.coverage)&&(G.log.error($.red("Cannot use --watch or --coverage with --app filter (app-level tests use turbo)")),process.exit(c.INVALID_ARGS)),e.app){Mc(e.app);let n=`@nebutra/${e.app}`;e.quiet||G.log.info($.cyan(`Running tests for ${$.bold(n)}...`));let o=await ge("test",{filter:n});process.exit(o.exitCode)}let t="test";if(e.coverage?t="test:coverage":e.watch&&(t="test:watch"),!e.quiet){let n=t==="test:coverage"?"Running tests with coverage...":t==="test:watch"?"Running tests in watch mode...":"Running tests...";G.log.info($.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}async function _n(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test e2e",options:{ui:e.ui,ci:e.ci},task:e.ci?"pnpm e2e:ci":e.ui?"pnpm e2e:ui":"pnpm e2e"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{e.ui&&e.ci&&(G.log.error($.red("Cannot use --ui and --ci together")),process.exit(c.INVALID_ARGS));let t="e2e";if(e.ci?t="e2e:ci":e.ui&&(t="e2e:ui"),!e.quiet){let n=t==="e2e:ci"?"Running E2E tests (CI mode)...":t==="e2e:ui"?"Opening E2E tests in UI mode...":"Running E2E tests...";G.log.info($.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Pn(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test size",options:{why:e.why},task:e.why?"pnpm size:why":"pnpm size"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{let t=e.why?"size:why":"size";if(!e.quiet){let n=e.why?"Analyzing bundle size (showing largest assets)...":"Checking bundle size...";G.log.info($.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Tn(e){e.dryRun&&(O({mode:"dry-run",timestamp:new Date().toISOString(),command:"test arch",task:"pnpm test:arch"},{format:e.format}),process.exit(c.DRY_RUN_OK));try{e.quiet||G.log.info($.cyan("Running architecture tests..."));let t=await K("test:arch",{interactive:!0});process.exit(t.exitCode)}catch(t){t instanceof Error?G.log.error($.red(t.message)):G.log.error($.red("Unknown error occurred")),process.exit(c.ERROR)}}function In(e){let t=e.command("test [subcommand]").description("Run tests (Vitest, Playwright, bundle size, architecture)").option("--watch","Run tests in watch mode (unit tests only)").option("--coverage","Generate coverage report (unit tests only)").option("--app <name>",`Run tests for specific app: ${qt.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;r==="e2e"?await _n({ui:n.ui||!1,ci:n.ci||!1,dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):r==="size"?await Pn({why:n.why||!1,dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):r==="arch"?await Tn({dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):await Bc({...n,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format})});t.command("e2e").description("Run end-to-end tests (Playwright)").option("--ui","Open interactive UI mode").option("--ci","Run in CI mode with strict options").option("--dry-run","Preview what would run (exit code 10)").action(async r=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await _n({...r,quiet:n.quiet||!1,verbose:n.verbose||!1,format:n.format})}),t.command("size").description("Check bundle size (analyze largest assets)").option("--why","Show breakdown of largest bundle assets").option("--dry-run","Preview what would run (exit code 10)").action(async r=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await Pn({...r,quiet:n.quiet||!1,verbose:n.verbose||!1,format:n.format})}),t.command("arch").description("Run architecture tests (verify design layer isolation)").option("--dry-run","Preview what would run (exit code 10)").action(async r=>{let n=r.optsWithGlobals?r.optsWithGlobals():r;await Tn({dryRun:r.dryRun||!1,quiet:n.quiet||!1,verbose:n.verbose||!1,format:n.format})})}var $n={$schema:"https://nebutra.com/schemas/theme-registry.json",version:"2026.05",defaultTheme:"nebutra",themes:[{id:"nebutra",name:"Nebutra",category:"ai-native",mood:"Official Nebutra brand \u2014 \u4E91\u6BD3\u84DD \u2192 \u4E91\u6BD3\u9752, AI-native default",tokenPath:"tokens/themes/nebutra.json",install:{command:"nebutra theme add nebutra",registryUrl:"https://ui.nebutra.com/themes/nebutra.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"dark-dense",name:"Dark Dense",category:"pro-tools",mood:"Dense operator surfaces - dark, compact, low distraction",tokenPath:"tokens/themes/dark-dense.json",install:{command:"nebutra theme add dark-dense",registryUrl:"https://ui.nebutra.com/themes/dark-dense.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"minimal",name:"Minimal",category:"productivity",mood:"Document and workspace apps - neutral, calm, readable",tokenPath:"tokens/themes/minimal.json",install:{command:"nebutra theme add minimal",registryUrl:"https://ui.nebutra.com/themes/minimal.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"vibrant",name:"Vibrant",category:"creative",mood:"Creator and consumer surfaces - saturated, expressive, energetic",tokenPath:"tokens/themes/vibrant.json",install:{command:"nebutra theme add vibrant",registryUrl:"https://ui.nebutra.com/themes/vibrant.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"ocean",name:"Ocean",category:"enterprise",mood:"B2B infrastructure and finance - cool, stable, trustworthy",tokenPath:"tokens/themes/ocean.json",install:{command:"nebutra theme add ocean",registryUrl:"https://ui.nebutra.com/themes/ocean.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid",name:"Coral Bloom",category:"community",mood:"Hot coral-rose on white \u2014 lively, welcoming, approachable",tokenPath:"tokens/themes/crimson-light-vivid.json",install:{command:"nebutra theme add crimson-light-vivid",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-muted",name:"Maritime",category:"community",mood:"Deep navy on white \u2014 nautical precision, calm authority",tokenPath:"tokens/themes/cyan-light-muted.json",install:{command:"nebutra theme add cyan-light-muted",registryUrl:"https://ui.nebutra.com/themes/cyan-light-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid",name:"Blueprint",category:"community",mood:"Classic azure on white \u2014 architectural, clear-purpose",tokenPath:"tokens/themes/cyan-light-vivid.json",install:{command:"nebutra theme add cyan-light-vivid",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"amber-light-vivid",name:"Sunstruck",category:"community",mood:"Electric gold on charcoal \u2014 warm, high-energy, confident",tokenPath:"tokens/themes/amber-light-vivid.json",install:{command:"nebutra theme add amber-light-vivid",registryUrl:"https://ui.nebutra.com/themes/amber-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted",name:"Void",category:"community",mood:"Pure white on black \u2014 maximum contrast, zero distraction",tokenPath:"tokens/themes/crimson-dark-muted.json",install:{command:"nebutra theme add crimson-dark-muted",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-2",name:"Cobalt Dusk",category:"community",mood:"Medium cobalt on white \u2014 grounded, reliable, focused",tokenPath:"tokens/themes/cyan-light-vivid-2.json",install:{command:"nebutra theme add cyan-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-2",name:"Obsidian",category:"community",mood:"White on deep black \u2014 high-contrast, stark monochrome",tokenPath:"tokens/themes/crimson-dark-muted-2.json",install:{command:"nebutra theme add crimson-dark-muted-2",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted",name:"Graphite",category:"community",mood:"Near-black on clean white \u2014 direct, no-nonsense",tokenPath:"tokens/themes/crimson-light-muted.json",install:{command:"nebutra theme add crimson-light-muted",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid",name:"Sandstone",category:"community",mood:"Warm terracotta on cream \u2014 organic, considered, sun-baked",tokenPath:"tokens/themes/rose-light-vivid.json",install:{command:"nebutra theme add rose-light-vivid",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-2",name:"Parchment",category:"community",mood:"Deep ink on warm parchment \u2014 warm, literary, timeless",tokenPath:"tokens/themes/crimson-light-muted-2.json",install:{command:"nebutra theme add crimson-light-muted-2",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"gold-dark-vivid",name:"Neon Citrus",category:"community",mood:"Neon yellow-gold on near-black \u2014 maximum energy, studio glow",tokenPath:"tokens/themes/gold-dark-vivid.json",install:{command:"nebutra theme add gold-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/gold-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-muted",name:"Raven",category:"community",mood:"Carbon charcoal on white \u2014 stark, editorial clarity",tokenPath:"tokens/themes/azure-light-muted.json",install:{command:"nebutra theme add azure-light-muted",registryUrl:"https://ui.nebutra.com/themes/azure-light-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-3",name:"Ultraviolet",category:"community",mood:"Deep electric blue on white \u2014 bold, digital, forward",tokenPath:"tokens/themes/cyan-light-vivid-3.json",install:{command:"nebutra theme add cyan-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-dark-vivid",name:"Royal Linen",category:"community",mood:"Deep royal blue on bright linen \u2014 classic, structured, formal",tokenPath:"tokens/themes/azure-dark-vivid.json",install:{command:"nebutra theme add azure-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/azure-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-2",name:"Tangerine",category:"community",mood:"Deep orange on near-white \u2014 warm, energetic, bold",tokenPath:"tokens/themes/rose-light-vivid-2.json",install:{command:"nebutra theme add rose-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-2",name:"Scarlet",category:"community",mood:"Vivid scarlet on white \u2014 assertive, expressive, electric",tokenPath:"tokens/themes/crimson-light-vivid-2.json",install:{command:"nebutra theme add crimson-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-3",name:"Pumice",category:"community",mood:"Warm dark on light gray \u2014 subtle, refined surface",tokenPath:"tokens/themes/crimson-light-muted-3.json",install:{command:"nebutra theme add crimson-light-muted-3",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-4",name:"Flint",category:"community",mood:"Black on white \u2014 pure editorial, zero tonal interference",tokenPath:"tokens/themes/crimson-light-muted-4.json",install:{command:"nebutra theme add crimson-light-muted-4",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-vivid",name:"Ember",category:"community",mood:"Deep ember red on dark charcoal \u2014 intense, dramatic warmth",tokenPath:"tokens/themes/crimson-dark-vivid.json",install:{command:"nebutra theme add crimson-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-5",name:"Chalk Veil",category:"community",mood:"Black on soft white \u2014 gentle clarity, editorial calm",tokenPath:"tokens/themes/crimson-light-muted-5.json",install:{command:"nebutra theme add crimson-light-muted-5",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-3",name:"Inkwell",category:"community",mood:"Bright white on inky dark \u2014 typographic, print-inspired",tokenPath:"tokens/themes/crimson-dark-muted-3.json",install:{command:"nebutra theme add crimson-dark-muted-3",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-4",name:"Ivory Press",category:"community",mood:"Black ink on near-white \u2014 newspaper clarity, old-school type",tokenPath:"tokens/themes/crimson-dark-muted-4.json",install:{command:"nebutra theme add crimson-dark-muted-4",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-4",name:"Lapis",category:"community",mood:"Deep lapis blue on white \u2014 timeless, authoritative",tokenPath:"tokens/themes/cyan-light-vivid-4.json",install:{command:"nebutra theme add cyan-light-vivid-4",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-5",name:"Cerulean",category:"community",mood:"Cerulean on white \u2014 open sky, systematic clarity",tokenPath:"tokens/themes/cyan-light-vivid-5.json",install:{command:"nebutra theme add cyan-light-vivid-5",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-6",name:"Atelier",category:"community",mood:"Dark ink on warm cream \u2014 handcrafted, studio-warm aesthetic",tokenPath:"tokens/themes/crimson-light-muted-6.json",install:{command:"nebutra theme add crimson-light-muted-6",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-6.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"indigo-dim-vivid",name:"Aubergine",category:"community",mood:"Electric violet on near-black \u2014 rich, complex, dark luxury",tokenPath:"tokens/themes/indigo-dim-vivid.json",install:{command:"nebutra theme add indigo-dim-vivid",registryUrl:"https://ui.nebutra.com/themes/indigo-dim-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"amber-light-vivid-2",name:"Harvest Noir",category:"community",mood:"Deep amber on near-black \u2014 bold, harvested warmth in darkness",tokenPath:"tokens/themes/amber-light-vivid-2.json",install:{command:"nebutra theme add amber-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/amber-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-dark-vivid-2",name:"Periwinkle Void",category:"community",mood:"Dusky periwinkle on true black \u2014 calm intelligence",tokenPath:"tokens/themes/azure-dark-vivid-2.json",install:{command:"nebutra theme add azure-dark-vivid-2",registryUrl:"https://ui.nebutra.com/themes/azure-dark-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-6",name:"Cornflower",category:"community",mood:"Cornflower blue on warm canvas \u2014 friendly, accessible",tokenPath:"tokens/themes/cyan-light-vivid-6.json",install:{command:"nebutra theme add cyan-light-vivid-6",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-6.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-vivid-2",name:"Lacquer",category:"community",mood:"Bold lacquer red on dark ground \u2014 assertive, polished",tokenPath:"tokens/themes/crimson-dark-vivid-2.json",install:{command:"nebutra theme add crimson-dark-vivid-2",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-7",name:"Horizon",category:"community",mood:"Deep sky blue on white \u2014 expansive, clear, optimistic",tokenPath:"tokens/themes/cyan-light-vivid-7.json",install:{command:"nebutra theme add cyan-light-vivid-7",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-7.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-7",name:"Carbon",category:"community",mood:"Carbon black on white \u2014 precision engineering aesthetic",tokenPath:"tokens/themes/crimson-light-muted-7.json",install:{command:"nebutra theme add crimson-light-muted-7",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-7.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-8",name:"Jet",category:"community",mood:"Jet black on pure white \u2014 crisp, high-definition",tokenPath:"tokens/themes/crimson-light-muted-8.json",install:{command:"nebutra theme add crimson-light-muted-8",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-8.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-muted-2",name:"Monolith",category:"community",mood:"Near-black primary on pure white \u2014 minimal, decisive, uncluttered",tokenPath:"tokens/themes/azure-light-muted-2.json",install:{command:"nebutra theme add azure-light-muted-2",registryUrl:"https://ui.nebutra.com/themes/azure-light-muted-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-3",name:"Blaze",category:"community",mood:"Vivid orange on white \u2014 bright, bold, full-spectrum warmth",tokenPath:"tokens/themes/rose-light-vivid-3.json",install:{command:"nebutra theme add rose-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-light-vivid",name:"Acid Mint",category:"community",mood:"Neon mint on dark canvas \u2014 raw energy, dev-tool edge",tokenPath:"tokens/themes/emerald-light-vivid.json",install:{command:"nebutra theme add emerald-light-vivid",registryUrl:"https://ui.nebutra.com/themes/emerald-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-9",name:"Slate Fog",category:"community",mood:"Soft dark on white \u2014 cool and composed, low-key depth",tokenPath:"tokens/themes/crimson-light-muted-9.json",install:{command:"nebutra theme add crimson-light-muted-9",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-9.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-vivid",name:"Amethyst Chalk",category:"community",mood:"Strong violet-blue on chalk \u2014 artful, composed, airy",tokenPath:"tokens/themes/azure-light-vivid.json",install:{command:"nebutra theme add azure-light-vivid",registryUrl:"https://ui.nebutra.com/themes/azure-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"lime-light-vivid",name:"Viridian",category:"community",mood:"Saturated tech-lime on white \u2014 charged, technical freshness",tokenPath:"tokens/themes/lime-light-vivid.json",install:{command:"nebutra theme add lime-light-vivid",registryUrl:"https://ui.nebutra.com/themes/lime-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-10",name:"Noir Blanc",category:"community",mood:"Pure black on white \u2014 photographic, stripped back",tokenPath:"tokens/themes/crimson-light-muted-10.json",install:{command:"nebutra theme add crimson-light-muted-10",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-10.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-11",name:"Birch",category:"community",mood:"Warm dark on near-white \u2014 gentle, organic, Scandinavian",tokenPath:"tokens/themes/crimson-light-muted-11.json",install:{command:"nebutra theme add crimson-light-muted-11",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-11.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-3",name:"Signal Red",category:"community",mood:"Pure signal red on white \u2014 urgent, direct, unmissable",tokenPath:"tokens/themes/crimson-light-vivid-3.json",install:{command:"nebutra theme add crimson-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-light-vivid-8",name:"Cobalt Night",category:"community",mood:"Vivid cobalt on deep dark \u2014 bold night mode energy",tokenPath:"tokens/themes/cyan-light-vivid-8.json",install:{command:"nebutra theme add cyan-light-vivid-8",registryUrl:"https://ui.nebutra.com/themes/cyan-light-vivid-8.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-4",name:"Marigold Noir",category:"community",mood:"Golden amber on deep dark \u2014 warm accent, dramatic contrast",tokenPath:"tokens/themes/rose-light-vivid-4.json",install:{command:"nebutra theme add rose-light-vivid-4",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-12",name:"Anthracite",category:"community",mood:"White on deep anthracite \u2014 modern, architectural",tokenPath:"tokens/themes/crimson-light-muted-12.json",install:{command:"nebutra theme add crimson-light-muted-12",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-12.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"amber-light-vivid-3",name:"Voltage",category:"community",mood:"Neon yellow on dark canvas \u2014 electric, alert, studio-bright",tokenPath:"tokens/themes/amber-light-vivid-3.json",install:{command:"nebutra theme add amber-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/amber-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-4",name:"Cinnabar",category:"community",mood:"Deep cinnabar on warm off-white \u2014 rich, earthy intensity",tokenPath:"tokens/themes/crimson-light-vivid-4.json",install:{command:"nebutra theme add crimson-light-vivid-4",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-4.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-dark-muted",name:"Moonbeam",category:"community",mood:"Pale silver-white on black \u2014 cool night, lunar glow",tokenPath:"tokens/themes/cyan-dark-muted.json",install:{command:"nebutra theme add cyan-dark-muted",registryUrl:"https://ui.nebutra.com/themes/cyan-dark-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-vivid-2",name:"Cobalt Vault",category:"community",mood:"Vivid cobalt on deep slate \u2014 sharp, technical, midnight engineering",tokenPath:"tokens/themes/azure-light-vivid-2.json",install:{command:"nebutra theme add azure-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/azure-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-5",name:"Bone Script",category:"community",mood:"Soft near-black on bone white \u2014 considered, understated",tokenPath:"tokens/themes/crimson-dark-muted-5.json",install:{command:"nebutra theme add crimson-dark-muted-5",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-vivid-3",name:"Terracotta Noir",category:"community",mood:"Warm terracotta on charcoal night \u2014 earthy, expressive",tokenPath:"tokens/themes/crimson-dark-vivid-3.json",install:{command:"nebutra theme add crimson-dark-vivid-3",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"indigo-light",name:"Dusk Veil",category:"community",mood:"Deep midnight violet on pale lilac \u2014 contemplative dusk",tokenPath:"tokens/themes/indigo-light.json",install:{command:"nebutra theme add indigo-light",registryUrl:"https://ui.nebutra.com/themes/indigo-light.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-13",name:"Quartz Dawn",category:"community",mood:"Black on quartz-white \u2014 clean surfaces, morning clarity",tokenPath:"tokens/themes/crimson-light-muted-13.json",install:{command:"nebutra theme add crimson-light-muted-13",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-13.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"violet-light-vivid",name:"Plum",category:"community",mood:"Deep plum on white \u2014 rich, intentional, confident",tokenPath:"tokens/themes/violet-light-vivid.json",install:{command:"nebutra theme add violet-light-vivid",registryUrl:"https://ui.nebutra.com/themes/violet-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-14",name:"Alabaster",category:"community",mood:"Black on alabaster \u2014 minimal, interior-design cool",tokenPath:"tokens/themes/crimson-light-muted-14.json",install:{command:"nebutra theme add crimson-light-muted-14",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-14.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-dark-vivid",name:"Neon Grove",category:"community",mood:"Electric emerald on charcoal \u2014 vibrant, playful, alive",tokenPath:"tokens/themes/emerald-dark-vivid.json",install:{command:"nebutra theme add emerald-dark-vivid",registryUrl:"https://ui.nebutra.com/themes/emerald-dark-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-dark-vivid-2",name:"Forest Vault",category:"community",mood:"Deep forest green on dark \u2014 grounded, organic, premium",tokenPath:"tokens/themes/emerald-dark-vivid-2.json",install:{command:"nebutra theme add emerald-dark-vivid-2",registryUrl:"https://ui.nebutra.com/themes/emerald-dark-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light-vivid-3",name:"Iris Flash",category:"community",mood:"Electric iris on bright white \u2014 bold, creative, wide-open",tokenPath:"tokens/themes/azure-light-vivid-3.json",install:{command:"nebutra theme add azure-light-vivid-3",registryUrl:"https://ui.nebutra.com/themes/azure-light-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-light-vivid-2",name:"Lagoon",category:"community",mood:"Bright sea-green on deep dark \u2014 tropical, refreshing",tokenPath:"tokens/themes/emerald-light-vivid-2.json",install:{command:"nebutra theme add emerald-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/emerald-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"azure-light",name:"Midnight Quill",category:"community",mood:"Midnight indigo on white \u2014 considered, literary, precise",tokenPath:"tokens/themes/azure-light.json",install:{command:"nebutra theme add azure-light",registryUrl:"https://ui.nebutra.com/themes/azure-light.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"cyan-dim-vivid",name:"Sapphire Mist",category:"community",mood:"Vivid sapphire on pale mist \u2014 clear, open, airy",tokenPath:"tokens/themes/cyan-dim-vivid.json",install:{command:"nebutra theme add cyan-dim-vivid",registryUrl:"https://ui.nebutra.com/themes/cyan-dim-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"teal-light-vivid",name:"Glacial",category:"community",mood:"Electric teal-mint on deep dark \u2014 Arctic clarity, crisp",tokenPath:"tokens/themes/teal-light-vivid.json",install:{command:"nebutra theme add teal-light-vivid",registryUrl:"https://ui.nebutra.com/themes/teal-light-vivid.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-15",name:"Stencil",category:"community",mood:"Black on white \u2014 bold cutout, typographic",tokenPath:"tokens/themes/crimson-light-muted-15.json",install:{command:"nebutra theme add crimson-light-muted-15",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-15.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-16",name:"Porcelain",category:"community",mood:"Soft black on porcelain white \u2014 refined, glaze-like surface",tokenPath:"tokens/themes/crimson-light-muted-16.json",install:{command:"nebutra theme add crimson-light-muted-16",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-16.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-17",name:"Pewter",category:"community",mood:"Pewter dark on white \u2014 understated, functional elegance",tokenPath:"tokens/themes/crimson-light-muted-17.json",install:{command:"nebutra theme add crimson-light-muted-17",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-17.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-vivid-5",name:"Flux Red",category:"community",mood:"Electric red on white \u2014 charged, high-stakes, decisive",tokenPath:"tokens/themes/crimson-light-vivid-5.json",install:{command:"nebutra theme add crimson-light-vivid-5",registryUrl:"https://ui.nebutra.com/themes/crimson-light-vivid-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"emerald-dark-vivid-3",name:"Jade Noir",category:"community",mood:"Vivid jade on near-black \u2014 lush, technical, distinctive",tokenPath:"tokens/themes/emerald-dark-vivid-3.json",install:{command:"nebutra theme add emerald-dark-vivid-3",registryUrl:"https://ui.nebutra.com/themes/emerald-dark-vivid-3.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-dark-muted",name:"Truffle",category:"community",mood:"Warm cream on espresso brown \u2014 cozy, warm, editorial",tokenPath:"tokens/themes/rose-dark-muted.json",install:{command:"nebutra theme add rose-dark-muted",registryUrl:"https://ui.nebutra.com/themes/rose-dark-muted.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-18",name:"Basalt",category:"community",mood:"Deep basalt on white \u2014 volcanic, grounded, decisive",tokenPath:"tokens/themes/crimson-light-muted-18.json",install:{command:"nebutra theme add crimson-light-muted-18",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-18.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-light-muted-19",name:"Tundra",category:"community",mood:"Black on white \u2014 vast, clear, utterly open",tokenPath:"tokens/themes/crimson-light-muted-19.json",install:{command:"nebutra theme add crimson-light-muted-19",registryUrl:"https://ui.nebutra.com/themes/crimson-light-muted-19.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"lime-light-vivid-2",name:"Chartreuse Noir",category:"community",mood:"Bright chartreuse on dark \u2014 bold, unconventional, vivid",tokenPath:"tokens/themes/lime-light-vivid-2.json",install:{command:"nebutra theme add lime-light-vivid-2",registryUrl:"https://ui.nebutra.com/themes/lime-light-vivid-2.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"crimson-dark-muted-6",name:"Pitch",category:"community",mood:"Clean white on near-black \u2014 dark mode minimalism",tokenPath:"tokens/themes/crimson-dark-muted-6.json",install:{command:"nebutra theme add crimson-dark-muted-6",registryUrl:"https://ui.nebutra.com/themes/crimson-dark-muted-6.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}},{id:"rose-light-vivid-5",name:"Vermilion",category:"community",mood:"Deep vermilion on off-white \u2014 earthy, vivid, painterly",tokenPath:"tokens/themes/rose-light-vivid-5.json",install:{command:"nebutra theme add rose-light-vivid-5",registryUrl:"https://ui.nebutra.com/themes/rose-light-vivid-5.json"},compatibility:{tailwind:"4",cssVariables:!0,figmaVariables:!0,shadcnRegistry:!0},governance:{wcag:"AA",requiredTokens:["color.primary","color.primary-foreground","color.background","color.foreground","color.card","color.border","color.ring","radius.md","fontFamily.sans"],visualSuites:["forms","pricing","dashboard","ai-chat","charts"]}}]};var we=$n,up=we.themes.map(e=>e.id);var mp=we.defaultTheme;function jn(e){return we.themes.find(t=>t.id===e)}function Nn(e){let t=e.opts?e.opts():e,r=e.optsWithGlobals?e.optsWithGlobals():e;return t.format??r.format??qc()}function qc(){let e=process.argv.find(r=>r.startsWith("--format="));if(e)return e.slice(9);let t=process.argv.indexOf("--format");if(t>=0)return process.argv[t+1]}function Kc(e){return{id:e.id,name:e.name,category:e.category,mood:e.mood,tokenPath:e.tokenPath,installCommand:e.install.command,registryUrl:e.install.registryUrl,wcag:e.governance.wcag,visualSuites:e.governance.visualSuites}}function zc(e="table"){let t=we.themes.map(Kc);return e==="json"?JSON.stringify({version:we.version,defaultTheme:we.defaultTheme,count:t.length,themes:t},null,2):[`Nebutra themes (${t.length})`,`Default: ${we.defaultTheme}`,"",...t.map(n=>`${n.id.padEnd(12)} ${n.category.padEnd(14)} ${n.tokenPath.padEnd(34)} ${n.mood}`)].join(`
826
+ `)}function Wc(e,t="table"){let r=jn(e);if(r)return t==="json"?JSON.stringify(r,null,2):[`${r.name} (${r.id})`,`Category: ${r.category}`,`Mood: ${r.mood}`,`Token path: ${r.tokenPath}`,`Install: ${r.install.command}`,`Registry: ${r.install.registryUrl}`,`WCAG: ${r.governance.wcag}`,`Visual suites: ${r.governance.visualSuites.join(", ")}`,`Required tokens: ${r.governance.requiredTokens.join(", ")}`].join(`
827
+ `)}function Un(e){let t=e.command("theme").description("Inspect registry-backed Nebutra themes and governance metadata");t.command("list").description("List built-in themes from the shared theme registry").option("--format <type>","Output format: json or table").action(r=>{console.log(zc(Nn(r)))}),t.command("inspect <id>").description("Show governance metadata for one theme").option("--format <type>","Output format: json or table").action((r,n)=>{let o=Wc(r,Nn(n));o||(a.error(`Theme '${r}' was not found in the Nebutra theme registry.`),process.exit(c.NOT_FOUND)),console.log(o)})}import{existsSync as Ln,readFileSync as Yc,unlinkSync as Hc,writeFileSync as Jc}from"fs";import{dirname as Xc,join as Dn,parse as Qc}from"path";function Zc(e){let t=e,{root:r}=Qc(t);for(;;){if(Ln(Dn(t,"package.json")))return t;if(t===r)return null;let n=Xc(t);if(n===t)return null;t=n}}async function el(e){let t=e.format==="json",r=Zc(process.cwd())??process.cwd(),n=Dn(r,"nebutra.config.json");if(Ln(n)||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):a.info("Already unlinked"),process.exit(c.SUCCESS)),e.force){try{Hc(n)}catch(l){let u=l instanceof Error?l.message:String(l);t?console.log(JSON.stringify({command:"unlink",success:!1,error:u},null,2)):a.error(`Failed to delete config: ${u}`),process.exit(c.PERMISSION_DENIED)}t?console.log(JSON.stringify({command:"unlink",success:!0,deletedConfig:!0,configPath:n},null,2)):a.success("Removed nebutra.config.json");return}let o={};try{o=JSON.parse(Yc(n,"utf-8"))}catch{o={}}"projectId"in o||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):a.info("Already unlinked"),process.exit(c.SUCCESS));let{projectId:i,...s}=o;Jc(n,JSON.stringify(s,null,2)+`
828
+ `),t?console.log(JSON.stringify({command:"unlink",success:!0,configPath:n},null,2)):a.success("Unlinked from project")}function Fn(e){e.command("unlink").description("Remove the project link from nebutra.config.json").option("--force","Delete the entire nebutra.config.json").option("--format <type>","Output format: json or plain").action(async(t,r)=>{let n=r?.optsWithGlobals?.()||t;await el({force:t.force||!1,format:t.format||n.format})})}import{spawnSync as ml}from"child_process";import{promises as Et}from"fs";import{homedir as tl}from"os";import{join as Mn}from"path";import rl from"p-timeout";import Se from"picocolors";var nl=1440*60*1e3,Bn=Mn(tl(),".nebutra"),Kt=Mn(Bn,"update-check.json"),ol="https://registry.npmjs.org/nebutra",al=5e3;async function il(){try{await Et.mkdir(Bn,{recursive:!0})}catch{}}async function sl(){try{let e=await Et.readFile(Kt,"utf-8"),t=JSON.parse(e);return Date.now()-t.timestamp<nl?t:(await Et.unlink(Kt).catch(n=>{a.debug("Failed to remove expired update cache file",{error:n})}),null)}catch{return null}}async function cl(e){try{await il();let t={timestamp:Date.now(),latestVersion:e};await Et.writeFile(Kt,JSON.stringify(t,null,2),"utf-8")}catch{}}async function ll(){try{let e=new AbortController,t=await rl(fetch(ol,{signal:e.signal,headers:{Accept:"application/json"}}),{milliseconds:al,fallback:()=>(e.abort(),null)});if(!t?.ok)return null;let n=(await t.json())["dist-tags"];return!n||typeof n.latest!="string"?null:n.latest}catch{return null}}function Vn(e){return e.split(".").map(t=>parseInt(t.replace(/[^0-9]/g,""),10)||0).slice(0,3)}function dl(e,t){let r=Vn(e),n=Vn(t);for(let o=0;o<3;o++){let i=r[o]??0,s=n[o]??0;if(s>i)return!0;if(s<i)return!1}return!1}async function zt(e){let t=await sl(),r=null;return t?r=t.latestVersion:(r=await ll(),r&&await cl(r)),!r||!dl(e,r)?null:{currentVersion:e,latestVersion:r,isUpdate:!0}}function ul(e){let r=`Update available: ${e.currentVersion} \u2192 ${e.latestVersion}`,n="Run `npm i -g nebutra` to update",o=" ".repeat((43-r.length)/2),i=" ".repeat((43-n.length)/2),s=[Se.cyan("\u256D"+"\u2500".repeat(41)+"\u256E"),Se.cyan("\u2502")+Se.yellow(o+r+o)+Se.cyan("\u2502"),Se.cyan("\u2502")+Se.gray(i+n+i)+Se.cyan("\u2502"),Se.cyan("\u2570"+"\u2500".repeat(41)+"\u256F")]}async function Gn(e){let t=null;return zt(e).then(r=>{t=r}),async()=>{!process.stdout.isTTY||process.env.CI||(t||await new Promise(r=>setTimeout(r,100)),t&&ul(t))}}function pl(){let t=(process.argv[1]||"").toLowerCase();if(t.includes("/homebrew/")||t.includes("/cellar/"))return"brew";if(t.includes("/.bun/")||t.includes("/bun/"))return"bun";if(t.includes("/pnpm/")||t.includes("/.pnpm/"))return"pnpm";if(t.includes("/yarn/")||t.includes("/.yarn/"))return"yarn";if(t.includes("/npm/")||t.includes("/node_modules/"))return"npm";let r=process.env.npm_config_user_agent||"";return r.startsWith("pnpm")?"pnpm":r.startsWith("yarn")?"yarn":r.startsWith("bun")?"bun":r.startsWith("npm")?"npm":"unknown"}function fl(e){switch(e){case"pnpm":return"pnpm add -g nebutra@latest";case"yarn":return"yarn global add nebutra@latest";case"bun":return"bun add -g nebutra@latest";case"brew":return"brew upgrade nebutra";case"npm":return"npm i -g nebutra@latest";default:return"npm i -g nebutra@latest"}}var Oe="0.1.0";async function gl(e){let t=pl(),r=fl(t),n=e.format==="json",o=await zt(Oe),i=o?.latestVersion??null,s=!!o?.isUpdate;e.dryRun&&(n?console.log(JSON.stringify({command:"upgrade",dryRun:!0,installer:t,command_to_run:r,currentVersion:Oe,latestVersion:i,hasUpdate:s},null,2)):(a.info(`Detected installer: ${t}`),a.info(`Current: ${Oe}${i?` \u2192 Latest: ${i}`:""}`),a.info(`Upgrade command: ${r}`)),process.exit(c.DRY_RUN_OK)),!s&&i&&(n?console.log(JSON.stringify({command:"upgrade",success:!0,alreadyLatest:!0,version:Oe},null,2)):a.success(`Already on the latest version (${Oe})`),process.exit(c.SUCCESS)),e.yes||(n?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,command_to_run:r,currentVersion:Oe,latestVersion:i,requiresConfirmation:!0},null,2)):(a.info(`Current: ${Oe}${i?` \u2192 Latest: ${i}`:""}`),a.info("To upgrade, run:"),a.info(` ${r}`),a.info("Or re-run this command with --yes to execute it now.")),process.exit(c.SUCCESS));let[l,...u]=r.split(" ");n||a.info(`Running: ${r}`);let m=ml(l,u,{stdio:n?"pipe":"inherit"});m.status===0&&(n?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,ran:r},null,2)):a.success("Upgrade complete"),process.exit(c.SUCCESS));let f=m.stderr?.toString()||`Upgrade failed (exit ${m.status})`;n?console.log(JSON.stringify({command:"upgrade",success:!1,installer:t,ran:r,error:f},null,2)):a.error(f),process.exit(c.ERROR)}function qn(e){let t=(r,n)=>{let o=n?.optsWithGlobals?.()||r;return gl({yes:r.yes||o.yes||!1,dryRun:r.dryRun||!1,format:r.format||o.format})};e.command("upgrade").alias("self-update").description("Upgrade the nebutra CLI to the latest version").option("--yes","Execute the upgrade command without confirmation").option("--dry-run","Show the upgrade command without executing (exit 10)").option("--format <type>","Output format: json or plain").action(t)}import Wt from"fs";import Yt from"path";import yl from"picocolors";var Ht=["inngest","n8n","pusher"],hl=`import { Inngest } from "inngest";
829
829
 
830
830
  export const inngest = new Inngest({ id: "nebutra-sailor" });
831
831
 
@@ -839,7 +839,7 @@ export const exampleFn = inngest.createFunction(
839
839
  return { status: "completed" };
840
840
  },
841
841
  );
842
- `,yl=`# n8n Workflows (Self-hosted Convention)
842
+ `,bl=`# n8n Workflows (Self-hosted Convention)
843
843
 
844
844
  Nebutra Sailor uses n8n in self-hosted mode for visual workflow orchestration.
845
845
 
@@ -863,7 +863,7 @@ docker run -it --rm \\
863
863
  ## Webhook endpoints
864
864
 
865
865
  Production webhooks route through \`backends/gateway\` (see \`packages/integrations/webhooks\`).
866
- `,hl=`{
866
+ `,vl=`{
867
867
  "name": "example-workflow",
868
868
  "nodes": [
869
869
  {
@@ -879,7 +879,7 @@ Production webhooks route through \`backends/gateway\` (see \`packages/integrati
879
879
  "settings": {},
880
880
  "tags": []
881
881
  }
882
- `,bl=`import Pusher from "pusher";
882
+ `,wl=`import Pusher from "pusher";
883
883
 
884
884
  export const pusher = new Pusher({
885
885
  appId: process.env.PUSHER_APP_ID ?? "",
@@ -895,8 +895,8 @@ export async function publishExample(channel: string, event: string, data: unkno
895
895
  }
896
896
  return pusher.trigger(channel, event, data);
897
897
  }
898
- `;function vl(e){switch(e){case"inngest":return[{relPath:"workflows/inngest/example.ts",content:gl}];case"n8n":return[{relPath:"workflows/n8n/README.md",content:yl},{relPath:"workflows/n8n/example.json",content:hl}];case"pusher":return[{relPath:"workflows/pusher/example.ts",content:bl}]}}async function wl(e,t={}){Ht.includes(e)||(a.error(`Invalid provider: ${fl.red(e)}. Valid: ${Ht.join(", ")}`),process.exit(c.INVALID_ARGS));let r=b(),n=vl(e);t.dryRun&&(O({mode:"dry-run",command:`workflow init ${e}`,files:n.map(s=>({path:Yt.join(r,s.relPath)}))}),process.exit(c.DRY_RUN_OK));let o=0,i=0;for(let s of n){let l=Yt.join(r,s.relPath);if(Wt.existsSync(l)){a.warn(`Skipping ${s.relPath} \u2014 already exists.`),i++;continue}Wt.mkdirSync(Yt.dirname(l),{recursive:!0}),Wt.writeFileSync(l,s.content),t.quiet||a.success(`Created ${s.relPath}`),o++}o===0&&i>0&&(a.info(`No files created \u2014 ${e} scaffold already present.`),process.exit(c.CONFLICT)),process.exit(c.SUCCESS)}function qn(e){e.command("workflow").description("Manage workflow provider scaffolding (inngest | n8n | pusher)").command("init <provider>").description(`Scaffold a starter workflow file for a provider (${Ht.join(" | ")})`).option("--dry-run","Preview files that would be created (exit code 10)").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await wl(r,{dryRun:n.dryRun||!1,quiet:o.quiet||!1})})}import{existsSync as Sl,mkdirSync as Kn,writeFileSync as zn}from"fs";import{homedir as Wn,platform as Rl}from"os";import{join as Je}from"path";function kl(){if(Rl()==="win32"){let t=process.env.LOCALAPPDATA||Je(Wn(),"AppData","Local");return Je(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?Je(e,"nebutra"):Je(Wn(),".config","nebutra")}function El(){let e=process.env.NEBUTRA_TELEMETRY;return e==="0"||e==="false"||e==="no"}function Yn(){if(!process.stderr.isTTY||!process.stdin.isTTY||process.env.CI)return;let e=kl(),t=Je(e,"first-run-acked");try{if(Sl(t))return}catch{return}if(El()){try{Kn(e,{recursive:!0}),zn(t,"")}catch{}return}let r=["\x1B[36m\u2139\x1B[0m Nebutra collects anonymous usage analytics to improve the CLI."," Opt out at any time: export NEBUTRA_TELEMETRY=0"," Privacy policy: https://nebutra.com/legal/cli-analytics",""];try{process.stderr.write(r.join(`
899
- `))}catch{}try{Kn(e,{recursive:!0}),zn(t,"")}catch{}}var Pl=xl(Al(Jn(import.meta.url)),"..","package.json"),Hn=JSON.parse(Cl(Pl,"utf8")).version;function Tl(e){let t=new _l,r=e.isInteractive??(process.stdin.isTTY!==!1&&process.stdout.isTTY!==!1);return t.name("nebutra").description("Nebutra \u2014 governance-first CLI for topology scaffolding, registry features, and platform operations").version(e.version).option("--verbose","Enable verbose output").option("--quiet","Suppress non-essential output").option("--format <type>","Output format: json, table, plain").option("--yes","Skip all interactive prompts (Agent mode)").option("--no-interactive","Alias for --yes").option("--no-color","Disable colored output"),t.command("init").description("Initialize a Nebutra project and create nebutra.config.json").option("--dry-run","Preview changes without writing files (exits with code 10)").option("--if-not-exists","Skip initialization if nebutra.config.json already exists").action(async n=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await tn({dryRun:n.dryRun||!1,yes:o.yes||!1,ifNotExists:n.ifNotExists||!1})}),t.command("add [components...]").description("Add a registry-backed platform feature or external UI component").option("--21st <id>","Fetch and install a component from 21st.dev").option("--v0 <url>","Fetch and install a component from v0.dev").option("--provider <id>","Specify a backend provider for a system feature (e.g. upstash)").option("--dry-run","Preview what would be installed without making changes (exit code 10)").option("--yes","Skip all interactive prompts and use defaults (Agent mode)").option("--if-not-exists","Skip installation if component already exists").action(async(n,o)=>{let i=o.optsWithGlobals?o.optsWithGlobals():o;await ur(n,{...o,yes:i.yes||!r})}),Ur(t),pn(t),bn(t),Or(t),Zr(t),en(t),Kr(t),an(t),wr(t),Sr(t),Ar(t),xn(t),Lr(t),Xr(t),Dr(t),Tn(t),qn(t),Cr(t),Mr(t),Nn(t),gr(t),_r(t),Qr(t),Gr(t),kn(t),wn(t),Sn(t),Nr(t),mn(t),Gn(t),ln(t),Dn(t),t.command("doctor").description("Check your Nebutra project setup for common issues").action(async()=>{let{logger:n}=await import("./logger-LKYUI2MJ.js"),{findMonorepoRoot:o}=await import("./delegate-AT4FVWBK.js"),i=await import("fs"),s=await import("path");n.info("Running project health check...");let l=!1,u=o(),m=process.version;parseInt(m.replace("v","").split(".")[0]??"0",10)<22?(n.error(`Node.js >= 22 required, found ${m}`),l=!0):n.success(`Node.js version OK (${m})`),i.existsSync(s.join(u,"nebutra.config.json"))?n.success("nebutra.config.json found"):n.warn("nebutra.config.json missing. Try running 'nebutra init'"),i.existsSync(s.join(u,"package.json"))?n.success("package.json found"):(n.error("No package.json found in root directory"),l=!0),i.existsSync(s.join(u,".env"))||i.existsSync(s.join(u,".env.local"))?n.success("Environment variables configured"):n.warn("No .env or .env.local found. Some features may not work properly.");let C=s.join(u,"apps/api-gateway");i.existsSync(C)&&n.warn("Legacy `apps/api-gateway/` present. Expected `backends/gateway/` \u2014 see CLAUDE.md for the W2.x restructure.");let L=s.join(u,"backends/gateway");i.existsSync(L)?n.success("backends/gateway/ present"):i.existsSync(s.join(u,"backends"));let D=s.join(u,"packages");if(i.existsSync(D)){let ie=new Set(["design","iam","commerce","integrations","platform","ops","ai"]);try{let Re=i.readdirSync(D,{withFileTypes:!0}),p=[];for(let F of Re){if(!F.isDirectory()||ie.has(F.name))continue;let _e=s.join(D,F.name,"package.json");i.existsSync(_e)&&p.push(F.name)}p.length>0?n.warn(`Found ${p.length} uncategorized package(s) under packages/: ${p.join(", ")}. Expected packages/<category>/<name>/ \u2014 see CLAUDE.md.`):n.success("Packages follow categorized layout")}catch{}}let q=s.join(u,".nebutra"),ue=s.join(q,"scaffold-meta.json");i.existsSync(ue)?n.success(".nebutra/scaffold-meta.json present (CLI-scaffolded project)"):i.existsSync(q)&&n.warn(".nebutra/ directory exists but scaffold-meta.json is missing. Run `nebutra license verify` for details."),l?(n.error("Doctor found critical issues that require your attention."),process.exit(c.CONFIG_ERROR)):n.success("Doctor is happy. Your project looks healthy!")}),t.hook("preAction",n=>{let o=n.optsWithGlobals();(!r||o.noInteractive)&&(o.yes=!0)}),t.addHelpText("after",`
898
+ `;function Sl(e){switch(e){case"inngest":return[{relPath:"workflows/inngest/example.ts",content:hl}];case"n8n":return[{relPath:"workflows/n8n/README.md",content:bl},{relPath:"workflows/n8n/example.json",content:vl}];case"pusher":return[{relPath:"workflows/pusher/example.ts",content:wl}]}}async function Rl(e,t={}){Ht.includes(e)||(a.error(`Invalid provider: ${yl.red(e)}. Valid: ${Ht.join(", ")}`),process.exit(c.INVALID_ARGS));let r=b(),n=Sl(e);t.dryRun&&(O({mode:"dry-run",command:`workflow init ${e}`,files:n.map(s=>({path:Yt.join(r,s.relPath)}))}),process.exit(c.DRY_RUN_OK));let o=0,i=0;for(let s of n){let l=Yt.join(r,s.relPath);if(Wt.existsSync(l)){a.warn(`Skipping ${s.relPath} \u2014 already exists.`),i++;continue}Wt.mkdirSync(Yt.dirname(l),{recursive:!0}),Wt.writeFileSync(l,s.content),t.quiet||a.success(`Created ${s.relPath}`),o++}o===0&&i>0&&(a.info(`No files created \u2014 ${e} scaffold already present.`),process.exit(c.CONFLICT)),process.exit(c.SUCCESS)}function Kn(e){e.command("workflow").description("Manage workflow provider scaffolding (inngest | n8n | pusher)").command("init <provider>").description(`Scaffold a starter workflow file for a provider (${Ht.join(" | ")})`).option("--dry-run","Preview files that would be created (exit code 10)").action(async(r,n)=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await Rl(r,{dryRun:n.dryRun||!1,quiet:o.quiet||!1})})}import{existsSync as kl,mkdirSync as zn,writeFileSync as Wn}from"fs";import{homedir as Yn,platform as El}from"os";import{join as Je}from"path";function Cl(){if(El()==="win32"){let t=process.env.LOCALAPPDATA||Je(Yn(),"AppData","Local");return Je(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?Je(e,"nebutra"):Je(Yn(),".config","nebutra")}function Al(){let e=process.env.NEBUTRA_TELEMETRY;return e==="0"||e==="false"||e==="no"}function Hn(){if(!process.stderr.isTTY||!process.stdin.isTTY||process.env.CI)return;let e=Cl(),t=Je(e,"first-run-acked");try{if(kl(t))return}catch{return}if(Al()){try{zn(e,{recursive:!0}),Wn(t,"")}catch{}return}let r=["\x1B[36m\u2139\x1B[0m Nebutra collects anonymous usage analytics to improve the CLI."," Opt out at any time: export NEBUTRA_TELEMETRY=0"," Privacy policy: https://nebutra.com/legal/cli-analytics",""];try{process.stderr.write(r.join(`
899
+ `))}catch{}try{zn(e,{recursive:!0}),Wn(t,"")}catch{}}var Tl=_l(Ol(Jt(import.meta.url)),"..","package.json"),Qn=JSON.parse(xl(Tl,"utf8")).version;function Il(e){let t=new Pl,r=e.isInteractive??(process.stdin.isTTY!==!1&&process.stdout.isTTY!==!1);return t.name("nebutra").description("Nebutra \u2014 governance-first CLI for topology scaffolding, registry features, and platform operations").version(e.version).option("--verbose","Enable verbose output").option("--quiet","Suppress non-essential output").option("--format <type>","Output format: json, table, plain").option("--yes","Skip all interactive prompts (Agent mode)").option("--no-interactive","Alias for --yes").option("--no-color","Disable colored output"),t.command("init").description("Initialize a Nebutra project and create nebutra.config.json").option("--dry-run","Preview changes without writing files (exits with code 10)").option("--if-not-exists","Skip initialization if nebutra.config.json already exists").action(async n=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await rn({dryRun:n.dryRun||!1,yes:o.yes||!1,ifNotExists:n.ifNotExists||!1})}),t.command("add [components...]").description("Add a registry-backed platform feature or external UI component").option("--21st <id>","Fetch and install a component from 21st.dev").option("--v0 <url>","Fetch and install a component from v0.dev").option("--provider <id>","Specify a backend provider for a system feature (e.g. upstash)").option("--dry-run","Preview what would be installed without making changes (exit code 10)").option("--yes","Skip all interactive prompts and use defaults (Agent mode)").option("--if-not-exists","Skip installation if component already exists").action(async(n,o)=>{let i=o.optsWithGlobals?o.optsWithGlobals():o;await mr(n,{...o,yes:i.yes||!r})}),Lr(t),fn(t),vn(t),_r(t),en(t),tn(t),zr(t),sn(t),Sr(t),Rr(t),xr(t),On(t),Dr(t),Qr(t),Fr(t),In(t),Kn(t),Ar(t),Br(t),Un(t),yr(t),Pr(t),Zr(t),qr(t),En(t),Sn(t),Rn(t),Ur(t),pn(t),qn(t),dn(t),Fn(t),t.command("doctor").description("Check your Nebutra project setup for common issues").action(async()=>{let{logger:n}=await import("./logger-LKYUI2MJ.js"),{findMonorepoRoot:o}=await import("./delegate-AT4FVWBK.js"),i=await import("fs"),s=await import("path");n.info("Running project health check...");let l=!1,u=o(),m=process.version;parseInt(m.replace("v","").split(".")[0]??"0",10)<22?(n.error(`Node.js >= 22 required, found ${m}`),l=!0):n.success(`Node.js version OK (${m})`),i.existsSync(s.join(u,"nebutra.config.json"))?n.success("nebutra.config.json found"):n.warn("nebutra.config.json missing. Try running 'nebutra init'"),i.existsSync(s.join(u,"package.json"))?n.success("package.json found"):(n.error("No package.json found in root directory"),l=!0),i.existsSync(s.join(u,".env"))||i.existsSync(s.join(u,".env.local"))?n.success("Environment variables configured"):n.warn("No .env or .env.local found. Some features may not work properly.");let C=s.join(u,"apps/api-gateway");i.existsSync(C)&&n.warn("Legacy `apps/api-gateway/` present. Expected `backends/gateway/` \u2014 see CLAUDE.md for the W2.x restructure.");let L=s.join(u,"backends/gateway");i.existsSync(L)?n.success("backends/gateway/ present"):i.existsSync(s.join(u,"backends"));let D=s.join(u,"packages");if(i.existsSync(D)){let ie=new Set(["design","iam","commerce","integrations","platform","ops","ai"]);try{let Re=i.readdirSync(D,{withFileTypes:!0}),p=[];for(let F of Re){if(!F.isDirectory()||ie.has(F.name))continue;let _e=s.join(D,F.name,"package.json");i.existsSync(_e)&&p.push(F.name)}p.length>0?n.warn(`Found ${p.length} uncategorized package(s) under packages/: ${p.join(", ")}. Expected packages/<category>/<name>/ \u2014 see CLAUDE.md.`):n.success("Packages follow categorized layout")}catch{}}let q=s.join(u,".nebutra"),ue=s.join(q,"scaffold-meta.json");i.existsSync(ue)?n.success(".nebutra/scaffold-meta.json present (CLI-scaffolded project)"):i.existsSync(q)&&n.warn(".nebutra/ directory exists but scaffold-meta.json is missing. Run `nebutra license verify` for details."),l?(n.error("Doctor found critical issues that require your attention."),process.exit(c.CONFIG_ERROR)):n.success("Doctor is happy. Your project looks healthy!")}),t.hook("preAction",n=>{let o=n.optsWithGlobals();(!r||o.noInteractive)&&(o.yes=!0)}),t.addHelpText("after",`
900
900
  Examples:
901
901
  $ nebutra init Initialize a new project
902
902
  $ nebutra add cache --provider upstash-redis --yes Install a registry feature
@@ -943,4 +943,4 @@ Environment:
943
943
  NEBUTRA_OUTPUT_FORMAT Output format (json|table|plain)
944
944
  NO_COLOR Disable colored output
945
945
  CI Auto-enable non-interactive mode
946
- `),t}async function Il(){Yn();let e=await Bn(Hn),t=Tl({version:Hn,isInteractive:process.stdin.isTTY!==!1&&process.stdout.isTTY!==!1});process.argv.length<=2&&(t.outputHelp(),process.exit(c.SUCCESS)),await t.parseAsync(process.argv),await e()}var $l=process.argv[1]?Jn(import.meta.url)===Ol(process.argv[1]):!1;$l&&Il().catch(e=>a.error(e instanceof Error?e.message:String(e)));export{Tl as buildProgram};
946
+ `),t}async function $l(){Hn();let e=await Gn(Qn),t=Il({version:Qn,isInteractive:process.stdin.isTTY!==!1&&process.stdout.isTTY!==!1});process.argv.length<=2&&(t.outputHelp(),process.exit(c.SUCCESS)),await t.parseAsync(process.argv),await e()}function jl(){if(!process.argv[1])return!1;try{return Jn(Jt(import.meta.url))===Jn(Xn(process.argv[1]))}catch{return Jt(import.meta.url)===Xn(process.argv[1])}}var Nl=jl();Nl&&$l().catch(e=>a.error(e instanceof Error?e.message:String(e)));export{Il as buildProgram};