nebutra 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{b as i}from"./chunk-JDX5NXDX.js";import{a as h,b as x,c as K,d as ge,e as Te,f as me}from"./chunk-LGUMYJ4Q.js";import{a as Eo}from"./chunk-IYWUY3VA.js";import{readFileSync as pd,realpathSync as wo}from"fs";import{dirname as fd,join as gd,resolve as So}from"path";import{fileURLToPath as lr}from"url";import{Command as yd}from"commander";import{execFileSync as It}from"child_process";import{promises as Ee}from"fs";import H from"path";import*as w from"@clack/prompts";import Le 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},mr={[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 Ao,readdirSync as gr,readFileSync as xo,statSync as Oo}from"fs";import{dirname as fr,join as Tt,parse as _o}from"path";import{fileURLToPath as Po}from"url";var Co={"@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 pr(e){return Co[e]??null}var To=`const featureEnvKeys = {{envKeysArray}} as const;
2
+ import{a as Sn}from"./chunk-PF57JMDL.js";import{b as s}from"./chunk-JDX5NXDX.js";import{a as h,b as O,c as z,d as we,e as De,f as he}from"./chunk-LGUMYJ4Q.js";import{a as Uo}from"./chunk-IYWUY3VA.js";import{readFileSync as bd,realpathSync as Io}from"fs";import{dirname as vd,join as wd,resolve as $o}from"path";import{fileURLToPath as vn}from"url";import{Command as Rd}from"commander";import{execFileSync as Bt}from"child_process";import{promises as Pe}from"fs";import X from"path";import*as w from"@clack/prompts";import qe 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},Cn={[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 Lo,readdirSync as xn,readFileSync as Do,statSync as Fo}from"fs";import{dirname as kn,join as Dt,parse as Bo}from"path";import{fileURLToPath as Mo}from"url";var jo={"@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 En(e){return jo[e]??null}var Go=`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
- `,$o=`# {{feature}} Feature
22
+ `,Ko=`# {{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
- `,Io="integrations";function $e(e,t=Io){let r=`packages/${t}/${e}`;return[{path:`${r}/src/index.ts`,content:To},{path:`${r}/README.md`,content:$o}]}var No={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
+ `,Vo="integrations";function Fe(e,t=Vo){let n=`packages/${t}/${e}`;return[{path:`${n}/src/index.ts`,content:Go},{path:`${n}/README.md`,content:Ko}]}var qo={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,32 +95,32 @@ 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:$e("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:$e("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:$e("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:$e("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:$e("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:$e("captcha","iam")}},jo=["iam","commerce","integrations","ai","design","platform","ops"];function Uo(){let e;try{e=fr(Po(import.meta.url))}catch{e=process.cwd()}for(;e&&e!==_o(e).root;){try{let t=gr(e);if(t.includes("pnpm-workspace.yaml")||t.includes("packages")){let r=Tt(e,"packages");if(Ao(r)&&Oo(r).isDirectory())return r}}catch{}e=fr(e)}return null}function Lo(e,t,r,n,o){let a=(t.env??[]).map(l=>({key:l,description:`${l} (declared by ${o})`})),s=pr(o)??"latest";return{name:e,description:t.summary??r.description??`${e} feature`,group:t.category??n,dependencies:[{name:o,version:s}],env:a,envFile:t.envFile??".env.local",files:[]}}var rt=null;function Do(){if(rt)return rt;let e={},t=Uo();if(!t)return rt=e,e;for(let r of jo){let n=Tt(t,r),o;try{o=gr(n)}catch{continue}for(let a of o){let s=Tt(n,a,"package.json"),l;try{l=xo(s,"utf-8")}catch{continue}let u;try{u=JSON.parse(l)}catch{continue}let m=u.nebutra,p=m?.featureId;!m||!p||!u.name||(e[p]=Lo(p,m,u,r,u.name))}}return rt=e,e}function yr(){return{...Do(),...No}}function hr(){return Object.values(yr())}async function br(e){return yr()[e]??null}function $t(e){return e instanceof Error&&e.message.startsWith("EXIT:")}function vr(e){try{return It("npm",["list",e],{stdio:"pipe"}),!0}catch{return!1}}function wr(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&&i.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 Rr(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 Vo(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 nt(e){try{return await Ee.readFile(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Mo(e,t){if(t)return H.join(e,t);let r=[".env.local",".env"];for(let n of r)try{return await Ee.access(H.join(e,n)),H.join(e,n)}catch{}return H.join(e,".env.local")}function Bo(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 Go(e){return e?Object.fromEntries(Object.entries(e).sort(([t],[r])=>t.localeCompare(r))):{}}function kr(e,t){if(!(!e.providers||e.providers.length===0))return t?e.providers.find(r=>r.id===t):e.providers[0]}async function qo(e,t,r){let n=H.join(t,"package.json"),o=await nt(n);if(!o)throw new Error(`No package.json found in ${t}. Run this command from a project root.`);let a=JSON.parse(o),s=Rr(e.flatMap(f=>[...f.descriptor.env??[],...f.provider?.env??[]])),l=await Mo(t,e[0]?.descriptor.envFile),u=await nt(l)??"",m=Bo(u),p=s.filter(f=>!m.has(f.key)),y=s.filter(f=>m.has(f.key)),C=[];for(let f of e){let F=Rr([...f.descriptor.env??[],...f.provider?.env??[]]),Pe={feature:f.name,provider:f.provider?.id,providerDescription:f.provider?.description,envFile:H.relative(t,l)||H.basename(l),envEntries:F};for(let _t of f.descriptor.files??[]){let Pt=H.join(t,_t.path),ko=H.relative(t,Pt)||_t.path,dr=Vo(_t.content,Pe),ur=await nt(Pt),et,tt;ur===null?(et="create",tt="file missing"):ur===dr?(et="skip",tt="already matches registry template"):(et="conflict",tt="file exists with different content"),C.push({type:"write-file",feature:f.name,path:Pt,relativePath:ko,status:et,reason:tt,content:dr})}}let L=Sr("dependencies",e.flatMap(f=>[...f.descriptor.dependencies??[],...f.provider?.dependencies??[]])),D=Sr("devDependencies",e.flatMap(f=>[...f.descriptor.devDependencies??[],...f.provider?.devDependencies??[]])),q=[];for(let f of L){let F=a.dependencies?.[f.name];q.push({section:"dependencies",name:f.name,action:F?F===f.version?"keep":"update":"add",from:F,to:f.version})}for(let f of D){let F=a.devDependencies?.[f.name];q.push({section:"devDependencies",name:f.name,action:F?F===f.version?"keep":"update":"add",from:F,to:f.version})}let ue={type:"merge-env",path:l,relativePath:H.relative(t,l)||H.basename(l),created:u.length===0,add:p,keep:y},ae={type:"update-package-json",path:n,relativePath:H.relative(t,n)||"package.json",changes:q},ke={create:C.filter(f=>f.status==="create").length,update:q.filter(f=>f.action==="add"||f.action==="update").length,append:p.length,skip:C.filter(f=>f.status==="skip").length+q.filter(f=>f.action==="keep").length+y.length,conflict:C.filter(f=>f.status==="conflict").length};return{mode:r,planType:"local-feature-install",cwd:t,timestamp:new Date().toISOString(),features:e.map(f=>({name:f.name,description:f.descriptor.description,provider:f.provider?.id,providerDescription:f.provider?.description})),operations:[...C,ue,ae],summary:ke}}function Er(e){return e.summary.create>0||e.summary.update>0||e.summary.append>0}function Ko(e){return e.summary.conflict>0}async function Wo(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 Ee.mkdir(H.dirname(o.path),{recursive:!0}),await Ee.writeFile(o.path,o.content,"utf8"));if(r&&r.add.length>0){let o=await nt(r.path)??"",a=r.add.map(u=>`# ${u.description}
100
- ${u.key}=`),s=o.trim().length>0?`
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:Fe("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:Fe("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:Fe("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:Fe("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:Fe("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:Fe("captcha","iam")}},zo=["iam","commerce","integrations","ai","design","platform","ops"];function Yo(){let e;try{e=kn(Mo(import.meta.url))}catch{e=process.cwd()}for(;e&&e!==Bo(e).root;){try{let t=xn(e);if(t.includes("pnpm-workspace.yaml")||t.includes("packages")){let n=Dt(e,"packages");if(Lo(n)&&Fo(n).isDirectory())return n}}catch{}e=kn(e)}return null}function Ho(e,t,n,r,o){let a=(t.env??[]).map(l=>({key:l,description:`${l} (declared by ${o})`})),i=En(o)??"latest";return{name:e,description:t.summary??n.description??`${e} feature`,group:t.category??r,dependencies:[{name:o,version:i}],env:a,envFile:t.envFile??".env.local",files:[]}}var ut=null;function Wo(){if(ut)return ut;let e={},t=Yo();if(!t)return ut=e,e;for(let n of zo){let r=Dt(t,n),o;try{o=xn(r)}catch{continue}for(let a of o){let i=Dt(r,a,"package.json"),l;try{l=Do(i,"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]=Ho(f,m,u,n,u.name))}}return ut=e,e}function On(){return{...Wo(),...qo}}function An(){return Object.values(On())}async function _n(e){return On()[e]??null}function Ft(e){return e instanceof Error&&e.message.startsWith("EXIT:")}function Pn(e){try{return Bt("npm",["list",e],{stdio:"pipe"}),!0}catch{return!1}}function In(e){process.stdout.write(`${JSON.stringify(e,null,2)}
99
+ `)}function Jo(e,t){let n=[];if(t["21st"]){let r=t["21st"],o=r.startsWith("http")?r:`https://21st.dev/r/${r}`;n.push({type:"run-command",source:"21st",component:r,resolvedUrl:o,command:`pnpm dlx shadcn@latest add "${o}"`})}return t.v0&&n.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&&s.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:n,summary:{execute:n.length}}}function $n(e,t){if(!t||t.length===0)return[];let n=new Map;for(let r of t)n.set(`${e}:${r.name}`,r);return Array.from(n.values())}function Nn(e){let t=new Map;for(let n of e)t.has(n.key)||t.set(n.key,n);return Array.from(t.values())}function Xo(e,t){let n=t.envEntries.map(r=>r.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}}",n.join(", ")).replaceAll("{{envKeysArray}}",JSON.stringify(n))}async function mt(e){try{return await Pe.readFile(e,"utf8")}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Qo(e,t){if(t)return X.join(e,t);let n=[".env.local",".env"];for(let r of n)try{return await Pe.access(X.join(e,r)),X.join(e,r)}catch{}return X.join(e,".env.local")}function Zo(e){let t=new Set;for(let n of e.matchAll(/^\s*([A-Za-z_][A-Za-z0-9_]*)\s*=/gm))n[1]&&t.add(n[1]);return t}function es(e){return e?Object.fromEntries(Object.entries(e).sort(([t],[n])=>t.localeCompare(n))):{}}function Tn(e,t){if(!(!e.providers||e.providers.length===0))return t?e.providers.find(n=>n.id===t):e.providers[0]}async function ts(e,t,n){let r=X.join(t,"package.json"),o=await mt(r);if(!o)throw new Error(`No package.json found in ${t}. Run this command from a project root.`);let a=JSON.parse(o),i=Nn(e.flatMap(p=>[...p.descriptor.env??[],...p.provider?.env??[]])),l=await Qo(t,e[0]?.descriptor.envFile),u=await mt(l)??"",m=Zo(u),f=i.filter(p=>!m.has(p.key)),y=i.filter(p=>m.has(p.key)),E=[];for(let p of e){let B=Nn([...p.descriptor.env??[],...p.provider?.env??[]]),Le={feature:p.name,provider:p.provider?.id,providerDescription:p.provider?.description,envFile:X.relative(t,l)||X.basename(l),envEntries:B};for(let jt of p.descriptor.files??[]){let Lt=X.join(t,jt.path),To=X.relative(t,Lt)||jt.path,wn=Xo(jt.content,Le),Rn=await mt(Lt),lt,dt;Rn===null?(lt="create",dt="file missing"):Rn===wn?(lt="skip",dt="already matches registry template"):(lt="conflict",dt="file exists with different content"),E.push({type:"write-file",feature:p.name,path:Lt,relativePath:To,status:lt,reason:dt,content:wn})}}let D=$n("dependencies",e.flatMap(p=>[...p.descriptor.dependencies??[],...p.provider?.dependencies??[]])),F=$n("devDependencies",e.flatMap(p=>[...p.descriptor.devDependencies??[],...p.provider?.devDependencies??[]])),q=[];for(let p of D){let B=a.dependencies?.[p.name];q.push({section:"dependencies",name:p.name,action:B?B===p.version?"keep":"update":"add",from:B,to:p.version})}for(let p of F){let B=a.devDependencies?.[p.name];q.push({section:"devDependencies",name:p.name,action:B?B===p.version?"keep":"update":"add",from:B,to:p.version})}let ye={type:"merge-env",path:l,relativePath:X.relative(t,l)||X.basename(l),created:u.length===0,add:f,keep:y},ue={type:"update-package-json",path:r,relativePath:X.relative(t,r)||"package.json",changes:q},_e={create:E.filter(p=>p.status==="create").length,update:q.filter(p=>p.action==="add"||p.action==="update").length,append:f.length,skip:E.filter(p=>p.status==="skip").length+q.filter(p=>p.action==="keep").length+y.length,conflict:E.filter(p=>p.status==="conflict").length};return{mode:n,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:[...E,ye,ue],summary:_e}}function Un(e){return e.summary.create>0||e.summary.update>0||e.summary.append>0}function ns(e){return e.summary.conflict>0}async function rs(e){let t=e.operations.find(o=>o.type==="update-package-json"),n=e.operations.find(o=>o.type==="merge-env"),r=e.operations.filter(o=>o.type==="write-file");for(let o of r)o.status==="create"&&(await Pe.mkdir(X.dirname(o.path),{recursive:!0}),await Pe.writeFile(o.path,o.content,"utf8"));if(n&&n.add.length>0){let o=await mt(n.path)??"",a=n.add.map(u=>`# ${u.description}
100
+ ${u.key}=`),i=o.trim().length>0?`
101
101
 
102
- `:"",l=`${o.replace(/\s+$/,"")}${s}${a.join(`
102
+ `:"",l=`${o.replace(/\s+$/,"")}${i}${a.join(`
103
103
 
104
104
  `)}
105
- `;await Ee.writeFile(r.path,l,"utf8")}if(t){let o=await Ee.readFile(t.path,"utf8"),a=JSON.parse(o);for(let s of t.changes){if(s.action==="keep")continue;let l=s.section==="dependencies"?"dependencies":"devDependencies";a[l]={...a[l]??{},[s.name]:s.to},a[l]=Go(a[l])}await Ee.writeFile(t.path,`${JSON.stringify(a,null,2)}
106
- `,"utf8")}}async function zo(e,t,r){let n=[];for(let o of e){let a=await br(o);a||(i.error(`Feature '${o}' not found in the local registry.`),i.info("Use one of the supported local features or choose --21st / --v0 for external UI installs."),process.exit(c.INVALID_ARGS));let s=kr(a,t.provider);if(t.provider&&!s&&(i.error(`Provider '${t.provider}' is not supported for feature '${o}'.`),process.exit(c.INVALID_ARGS)),!s&&a.providers&&a.providers.length>0)if(r)s=a.providers[0];else{let l=await w.select({message:`Select a provider for ${o}`,options:a.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=kr(a,String(l))}n.push({name:o,descriptor:a,provider:s})}return n}function Yo(e){w.log.info(Le.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 Cr(e,t){t.dryRun||w.intro(Le.bgCyan(Le.black(" nebutra add ")));let r=t.yes||!process.stdin.isTTY;if(e.length===0&&!t["21st"]&&!t.v0&&(t.dryRun?i.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)&&(wr(Fo(e,t)),process.exit(c.DRY_RUN_OK)),t.ifNotExists&&(t["21st"]||t.v0)&&(t["21st"]&&vr(t["21st"])||t.v0&&vr("shadcn-component"))&&(i.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(Le.cyan(`Invoking shadcn integration for 21st.dev component: ${t["21st"]}...`));try{let o=t["21st"],a=o.startsWith("http")?o:`https://21st.dev/r/${o}`;It("pnpm",["dlx","shadcn@latest","add",a],{stdio:"inherit"}),i.success(`Successfully installed ${o}`),process.exit(c.SUCCESS)}catch(o){if($t(o))throw o;i.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(Le.cyan(`Invoking shadcn integration for v0 URL: ${t.v0}...`));try{It("pnpm",["dlx","shadcn@latest","add",t.v0],{stdio:"inherit"}),i.success("Successfully installed v0 component"),process.exit(c.SUCCESS)}catch(o){if($t(o))throw o;i.error(`Failed to install component: ${o instanceof Error?o.message:"Unknown error"}`),process.exit(c.ERROR)}}try{let n=await zo(e,t,r),o=await qo(n,process.cwd(),t.dryRun?"dry-run":"apply");if(t.dryRun&&(wr(o),process.exit(c.DRY_RUN_OK)),Ko(o)){let s=o.operations.filter(l=>l.type==="write-file"&&l.status==="conflict").map(l=>l.relativePath);t.ifNotExists&&!Er(o)&&(i.info("Feature already appears to be installed. Skipping because --if-not-exists was set."),process.exit(c.SUCCESS)),i.error(`Refusing to overwrite existing files: ${s.join(", ")}`),process.exit(c.CONFLICT)}Er(o)||(i.info("Feature install already satisfied. No files, env keys, or dependencies needed changes."),process.exit(c.SUCCESS)),Yo(o);let a=r||await w.confirm({message:`Proceed with installing ${o.features.map(s=>s.name).join(", ")}?`,initialValue:!0});(w.isCancel(a)||!a)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),await Wo(o),i.success(`Installed ${o.features.map(s=>s.name).join(", ")} into ${o.cwd}`),process.exit(c.SUCCESS)}catch(n){if($t(n))throw n;i.error(n instanceof Error?n.message:String(n)),process.exit(c.CONFIG_ERROR)}}import N from"picocolors";import{stderr as ye,stdout as Ar}from"process";import se from"picocolors";function Ho(){return process.env.NEBUTRA_NON_TTY||process.env.CI||process.env.GITHUB_ACTIONS?!1:process.stderr.isTTY===!0}function xr(e){if(e)return e;let t=process.env.NEBUTRA_OUTPUT_FORMAT;return t&&["json","table","plain"].includes(t)?t:Ho()?"plain":"json"}function Jo(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(" | "),a=r.map(l=>"-".repeat(n[String(l)])).join("-+-"),s=[o,a];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 Xo(e){return JSON.stringify(e)}function Or(e){if(!Array.isArray(e))return Nt(e);if(e.length===0)return"(empty)";if(typeof e[0]!="object"||e[0]===null)return Nt(e);let t=Jo(e);return se.gray(t)}function Nt(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=xr(t?.format),n=t?.stream==="stderr"?ye:Ar,o;switch(r){case"json":o=Xo(e);break;case"table":o=Or(e);break;default:o=Nt(e);break}n.write(o+`
108
- `)}function O(e,t={}){let r=xr(t.format),n;switch(r){case"json":n=JSON.stringify(e);break;case"table":n=Or(e);break;default:n=JSON.stringify(e,null,2);break}Ar.write(n+`
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
- `)}function A(e,t){if(!(process.env.NEBUTRA_DEBUG||process.argv.includes("--debug")))return;let n=se.dim(`[debug] ${e}`);ye.write(n+`
111
- `),t&&Object.keys(t).length>0&&ye.write(se.dim(JSON.stringify(t,null,2))+`
112
- `)}function ot(e){ye.write(`
113
- `),ye.write(se.bold(se.cyan(e))+`
114
- `),ye.write(se.gray("-".repeat(e.length))+`
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(),a=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:a,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:a,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 Qo(e){i.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||(i.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"):(i.info(`Found ${o.total} tenant(s)`),o.tenants.length>0&&(console.log(`
117
- Tenants:`),o.tenants.forEach(a=>{console.log(` ${N.blue(a.id)} \u2014 ${a.name||"(unnamed)"}`),console.log(` Status: ${a.status}`),a.plan&&console.log(` Plan: ${a.plan}`)})))}async function Zo(e,t){i.info(`Fetching tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}`,{dryRun:t.dryRun});if(r.ok||(i.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;i.success(`Tenant ${N.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 ei(e,t){t.yes||(i.warn(`Suspending tenant ${e} will disable all operations`),i.info("Use --yes to confirm"),process.exit(c.CANCELLED)),i.info(`Suspending tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}/suspend`,{method:"POST",dryRun:t.dryRun});if(r.ok||(i.error(`Failed to suspend tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:suspend");return}i.success(`Tenant ${N.blue(e)} suspended`),t.format==="json"&&S({suspended:!0,tenantId:e},t.format,"admin:suspend")}async function ti(e,t){i.info(`Unsuspending tenant ${e}...`);let r=await J(`/api/v1/admin/tenants/${e}/unsuspend`,{method:"POST",dryRun:t.dryRun});if(r.ok||(i.error(`Failed to unsuspend tenant: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:unsuspend");return}i.success(`Tenant ${N.blue(e)} unsuspended`),t.format==="json"&&S({unsuspended:!0,tenantId:e},t.format,"admin:unsuspend")}async function ri(e){i.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||(i.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"):(i.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((a,s)=>{console.log(` ${s+1}. ${a.tenantName||a.tenantId} \u2014 ${a.usage}`)})))}async function ni(e){i.info("Fetching dead letter queue...");let t=await J("/api/v1/admin/dlq/list",{dryRun:e.dryRun});if(t.ok||(i.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"):(i.info(`Found ${r.count} message(s) in DLQ`),r.messages.length>0&&(console.log(`
119
- Messages:`),r.messages.forEach(n=>{console.log(` ${N.blue(n.id)}`),console.log(` Type: ${n.type}`),console.log(` Error: ${n.error}`),console.log(` Created: ${n.createdAt}`)})))}async function oi(e,t){i.info(`Replaying DLQ message ${e}...`);let r=await J(`/api/v1/admin/dlq/replay/${e}`,{method:"POST",dryRun:t.dryRun});if(r.ok||(i.error(`Failed to replay message: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:dlq:replay");return}i.success(`Message ${N.blue(e)} replayed`),t.format==="json"&&S({replayed:!0,messageId:e},t.format,"admin:dlq:replay")}async function ii(e){e.yes||(i.warn("This will permanently delete all messages in the DLQ"),i.info("Use --yes to confirm"),process.exit(c.CANCELLED)),i.info("Purging DLQ...");let t=await J("/api/v1/admin/dlq/purge",{method:"POST",dryRun:e.dryRun});if(t.ok||(i.error(`Failed to purge DLQ: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){S(t.data,e.format,"admin:dlq:purge");return}i.success("DLQ purged"),e.format==="json"&&S({purged:!0,count:t.data?.count},e.format,"admin:dlq:purge")}async function ai(e){i.info("Fetching feature flags...");let t=await J("/api/v1/admin/feature-flags",{dryRun:e.dryRun});if(t.ok||(i.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"):(i.info(`Found ${r.total} flag(s)`),r.flags.length>0&&(console.log(`
120
- Flags:`),r.flags.forEach(n=>{let o=n.override!==void 0?N.yellow(String(n.override)):N.gray(String(n.default));console.log(` ${N.blue(n.name)} = ${o}`)})))}async function si(e,t,r){i.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||(i.error(`Failed to set flag: ${o.error}`),process.exit(c.NETWORK_ERROR)),r.dryRun){S(o.data,r.format,"admin:flags:set");return}i.success(`Flag ${N.blue(e)} set to ${n}`),r.format==="json"&&S({flag:e,value:n},r.format,"admin:flags:set")}async function ci(e,t){i.info(`Unsetting flag ${e}...`);let r=await J(`/api/v1/admin/feature-flags/${e}`,{method:"DELETE",dryRun:t.dryRun});if(r.ok||(i.error(`Failed to unset flag: ${r.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){S(r.data,t.format,"admin:flags:unset");return}i.success(`Flag ${N.blue(e)} unset`),t.format==="json"&&S({flag:e,unset:!0},t.format,"admin:flags:unset")}async function li(e){i.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||(i.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"):(i.info(`Found ${o.total} audit log entries`),o.entries.length>0&&(console.log(`
121
- Audit entries:`),o.entries.forEach(a=>{console.log(` ${a.timestamp} \u2014 ${N.blue(a.action)} by ${a.actor}`),a.details&&console.log(` ${a.details}`)})))}async function di(e){i.info("Running platform health check...");let t=await J("/api/v1/system/status",{dryRun:e.dryRun});if(t.ok||(i.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"?N.green:r.status==="degraded"?N.yellow:N.red;i.info(`Platform status: ${n(r.status)}`),r.services&&Object.keys(r.services).length>0&&(console.log(`
122
- Services:`),Object.entries(r.services).forEach(([o,a])=>{let s=a.status==="healthy"?N.green("\u2713"):N.red("\u2717");console.log(` ${s} ${o}: ${a.status}`),a.latency&&console.log(` Latency: ${a.latency}ms`),a.error&&console.log(` Error: ${a.error}`)}))}}function _r(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 a=o.optsWithGlobals?.()||o;await Qo({limit:o.limit,offset:o.offset,status:o.status,format:o.format||a.format,dryRun:o.dryRun||a.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,a)=>{let s=a.optsWithGlobals?.()||a;await Zo(o,{format:a.format||s.format,dryRun:a.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,a)=>{let s=a.optsWithGlobals?.()||a;await ei(o,{yes:a.yes||s.yes,format:a.format||s.format,dryRun:a.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,a)=>{let s=a.optsWithGlobals?.()||a;await ti(o,{format:a.format||s.format,dryRun:a.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 a=o.optsWithGlobals?.()||o;await ri({period:o.period,top:o.top,format:o.format||a.format,dryRun:o.dryRun||a.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 a=o.optsWithGlobals?.()||o;await ni({format:o.format||a.format,dryRun:o.dryRun||a.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,a)=>{let s=a.optsWithGlobals?.()||a;await oi(o,{format:a.format||s.format,dryRun:a.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 a=o.optsWithGlobals?.()||o;await ii({yes:o.yes||a.yes,format:o.format||a.format,dryRun:o.dryRun||a.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 a=o.optsWithGlobals?.()||o;await ai({format:o.format||a.format,dryRun:o.dryRun||a.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,a,s)=>{let l=s.optsWithGlobals?.()||s;await si(o,a,{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,a)=>{let s=a.optsWithGlobals?.()||a;await ci(o,{format:a.format||s.format,dryRun:a.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 a=o.optsWithGlobals?.()||o;await li({actor:o.actor,action:o.action,since:o.since,limit:o.limit,format:o.format||a.format,dryRun:o.dryRun||a.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 a=o.optsWithGlobals?.()||o;await di({format:o.format||a.format,dryRun:o.dryRun||a.dryRun})})}import{existsSync as mi,readFileSync as pi,writeFileSync as fi}from"fs";import{resolve as jt}from"path";var b={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"]},ui=[{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:ui,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:"ui",description:"Search, inspect, validate, and plan migrations for @nebutra/ui components",usage:"nebutra ui [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 Tr="nebutra.config.json",gi=b.ai.filter(e=>e!=="none"),Pr={"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 yi(e){return e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function hi(e){return Pr[e]?Pr[e]:[`${e.replace(/-/g,"_").toUpperCase()}_API_KEY`]}function it(){return Object.fromEntries(gi.map(e=>[e,{id:e,name:yi(e),envVars:hi(e)}]))}function le(){return jt(process.cwd(),Tr)}function Ce(){let e=le();if(!mi(e))return{$schema:"https://nebutra.com/schema.json"};try{return JSON.parse(pi(e,"utf-8"))}catch(t){i.error(`Failed to parse ${Tr}: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}function at(e){fi(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 $r(e){let t=it(),r=[...new Set(e.map(o=>o.toLowerCase()))],n=r.filter(o=>!t[o]);return n.length>0&&(i.error(`Unknown AI provider(s): ${n.join(", ")}. Valid providers: ${Object.keys(t).join(", ")}`),process.exit(c.INVALID_ARGS)),r}function bi(e){let t=e?.split(",").map(n=>n.trim()).filter(Boolean)??[];t.length===0&&(i.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&&(i.error(`Invalid fallback target(s): ${r.join(", ")}. Expected provider:model.`),process.exit(c.INVALID_ARGS)),t}function Ir(e){let t=he(e),r=t.providers??{},n=t.routes??{},o=Object.entries(r).filter(([,a])=>a.enabled).map(([a])=>a);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??vi();return{...r,...t,...n?{format:n}:{}}}function vi(){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 De(e){return e?e.length<=8?"***":`${e.substring(0,8)}***`:"not set"}async function wi(e){e.format!=="json"&&i.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(a=>({name:a,value:De(process.env[a])}))})),configuredCount:Object.values(t).filter(n=>n.configured).length,totalProviders:Object.keys(t).length};e.dryRun||(r.configuredCount===0?i.warn("No AI providers configured. Set API keys to enable AI features."):i.success(`${r.configuredCount} AI provider(s) configured`)),ne(r,e.format,"ai:models")}async function Si(e){e.format!=="json"&&i.info("Scanning for available agents...");try{let t=jt(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?i.info("No agents configured. Create agents in backends/gateway/src/routes/agents/"):i.success(`Found ${n.count} agent(s)`)),ne(n,e.format,"ai:agents")}catch(t){i.error(`Failed to scan agents: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}async function Ri(e,t){(!e||e.trim().length===0)&&(i.error("Prompt cannot be empty"),process.exit(c.INVALID_ARGS)),t.format!=="json"&&(i.info("Testing AI prompt against default model..."),i.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||i.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 ki(e){e.format!=="json"&&i.info("Checking AI configuration...");let t={providers:{openai:{key:De(process.env.OPENAI_API_KEY),configured:!!process.env.OPENAI_API_KEY},anthropic:{key:De(process.env.ANTHROPIC_API_KEY),configured:!!process.env.ANTHROPIC_API_KEY},openrouter:{key:De(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=jt(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?i.warn("No AI providers configured. Set environment variables to enable AI features."):i.success(`Configuration loaded: ${r.join(", ")}`)),ne(t,e.format,"ai:config")}async function Ei(e){let t=Ce(),r=he(t),n=it(),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:De(process.env[u])}))}}),a={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?i.warn("No runtime AI providers enabled in nebutra.config.json."):i.success(`Enabled AI providers: ${s.map(l=>l.id).join(", ")}`)}ne(a,e.format,"ai:provider:list")}async function Ci(e,t){let r=$r(e),n=Ce(),o=he(n),a=it(),s=new Date().toISOString();for(let u of r)o.providers[u]={enabled:!0,envVars:a[u].envVars,enabledAt:o.providers?.[u]?.enabledAt??s};at(n);let l={configPath:le(),enabled:r,env:t.env===!0?r.flatMap(u=>a[u].envVars.map(m=>({provider:u,name:m,example:`${m}=`}))):void 0,ai:Ir(n)};if(t.format!=="json"&&(i.success(`Enabled AI provider(s): ${r.join(", ")}`),t.env)){i.info("Required environment variables:");for(let u of r)for(let m of a[u].envVars)console.log(`${m}=`)}ne(l,t.format,"ai:provider:enable")}async function Ai(e,t){let r=$r(e),n=Ce(),o=he(n),a=it(),s=new Date().toISOString();for(let u of r)o.providers[u]={enabled:!1,envVars:o.providers?.[u]?.envVars??a[u].envVars,disabledAt:s};at(n);let l={configPath:le(),disabled:r,ai:Ir(n)};t.format!=="json"&&i.success(`Disabled AI provider(s): ${r.join(", ")}`),ne(l,t.format,"ai:provider:disable")}async function xi(e){let t=Ce(),r=he(t),n=new Date().toISOString();r.gateway={enabled:!0,mode:"local",initializedAt:r.gateway?.initializedAt??n,updatedAt:n},at(t);let o={configPath:le(),gateway:r.gateway};e.format!=="json"&&i.success("AI gateway governance initialized in nebutra.config.json"),ne(o,e.format,"ai:gateway:init")}async function Oi(e){let t=Ce(),r=he(t),n={configPath:le(),gateway:r.gateway??null,initialized:r.gateway?.enabled===!0};e.format!=="json"&&(n.initialized?i.success("AI gateway governance is initialized"):i.warn("AI gateway governance is not initialized. Run: nebutra ai gateway init")),ne(n,e.format,"ai:gateway:status")}async function _i(e,t){(!e||e.trim().length===0)&&(i.error("Route name cannot be empty"),process.exit(c.INVALID_ARGS)),t.policy||(i.error("Route policy is required. Use --policy <policy>."),process.exit(c.INVALID_ARGS));let r=bi(t.fallback),n=Ce(),o=he(n);o.routes[e]={policy:t.policy,fallback:r,updatedAt:new Date().toISOString()},at(n);let a={configPath:le(),route:{name:e,...o.routes[e]},routes:o.routes};t.format!=="json"&&i.success(`AI route '${e}' set with policy '${t.policy}'`),ne(a,t.format,"ai:route:set")}async function Pi(e){let t=Ce(),r=he(t),n=Object.entries(r.routes??{}).map(([a,s])=>({name:a,...s})),o={configPath:le(),routes:n,count:n.length};e.format!=="json"&&(n.length===0?i.warn("No AI routes configured. Run: nebutra ai route set chat --policy cost-latency-balanced --fallback openai:gpt-5.4"):i.success(`Configured AI routes: ${n.map(a=>a.name).join(", ")}`)),ne(o,e.format,"ai:route:list")}function Nr(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 a=>{let s=re(a);await Ei({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(a,s)=>{let l=re(s);await Ci(a,{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(a,s)=>{let l=re(s);await Ai(a,{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 a=>{let s=re(a);await xi({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 a=>{let s=re(a);await Oi({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(a,s)=>{let l=re(s);await _i(a,{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 a=>{let s=re(a);await Pi({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 a=>{let s=re(a);await wi({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 a=>{let s=re(a);await Si({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(a,s)=>{let l=re(s);await Ri(a,{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 a=>{let s=re(a);await ki({dryRun:s.dryRun===!0,format:s.format,interactive:s.yes!==!0})})}import{resolve as Ti}from"path";function Ut(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 $i(){try{let e=Ti(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 Ii(e){i.info("Checking authentication configuration...");let t=$i(),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?i.success(`Auth provider configured: ${t}`):i.warn(`Auth provider ${t} is not fully configured`)),Ut(r,e.format,"auth:status")}async function Ni(e,t){let r=["clerk","better-auth","nextauth","supabase"];r.includes(e.toLowerCase())||(i.error(`Invalid provider: ${e}. Choose from: ${r.join(", ")}`),process.exit(c.INVALID_ARGS));let n=e.toLowerCase();i.info(`Setting up ${n} authentication...`),n==="clerk"?(i.info("Clerk setup requires:"),i.info("1. A Clerk account (https://clerk.com)"),i.info("2. A Clerk application created"),i.info("3. API keys from the Clerk dashboard"),i.info(""),i.info("To complete setup:"),i.info("1. Go to https://dashboard.clerk.com"),i.info("2. Copy your Secret Key and Publishable Key"),i.info("3. Add them to .env.local:"),i.info(' CLERK_SECRET_KEY="sk_..."'),i.info(' NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_..."'),i.info(""),i.info("Webhook setup (optional):"),i.info("1. In Clerk dashboard, go to Webhooks"),i.info("2. Create endpoint: https://yourdomain.com/api/webhooks/clerk"),i.info("3. Copy the signing secret to .env.local:"),i.info(' CLERK_WEBHOOK_SECRET="whsec_..."')):n==="better-auth"?(i.info("Better Auth setup requires:"),i.info("1. Database URL configured (DATABASE_URL env var)"),i.info("2. A generated auth secret"),i.info(""),i.info("To complete setup:"),i.info("1. Ensure DATABASE_URL is set in .env.local"),i.info("2. Generate a new secret:"),i.info(" openssl rand -base64 32"),i.info("3. Add to .env.local:"),i.info(' BETTER_AUTH_SECRET="<generated_secret>"'),i.info(' BETTER_AUTH_URL="http://localhost:3000"'),i.info(""),i.info("4. Run database migration:"),i.info(" pnpm --filter @nebutra/web db:push")):n==="nextauth"?(i.info("NextAuth / Auth.js setup requires:"),i.info("1. A generated Auth.js secret"),i.info("2. NEXTAUTH_URL or AUTH_URL pointing at the web app origin"),i.info("3. OAuth provider credentials for each enabled provider"),i.info(""),i.info("To complete setup:"),i.info("1. Generate a new secret:"),i.info(" openssl rand -base64 32"),i.info("2. Add to the production environment:"),i.info(' AUTH_PROVIDER="nextauth"'),i.info(' NEXT_PUBLIC_AUTH_PROVIDER="nextauth"'),i.info(' AUTH_SECRET="<generated_secret>"'),i.info(' NEXTAUTH_URL="https://app.nebutra.com"'),i.info(' GOOGLE_CLIENT_ID="..."'),i.info(' GOOGLE_CLIENT_SECRET="..."')):(i.info("Supabase Auth setup requires:"),i.info("1. Supabase project URL"),i.info("2. Public anon key for browser auth"),i.info("3. Service role key for server-side user/session validation"),i.info(""),i.info("To complete setup:"),i.info(' AUTH_PROVIDER="supabase"'),i.info(' NEXT_PUBLIC_AUTH_PROVIDER="supabase"'),i.info(' NEXT_PUBLIC_SUPABASE_URL="https://xxx.supabase.co"'),i.info(' NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),i.info(' NEXT_PUBLIC_SUPABASE_ANON_KEY="..."'),i.info(' SUPABASE_URL="https://xxx.supabase.co"'),i.info(' SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),i.info(' SUPABASE_ANON_KEY="..."'),i.info(' SUPABASE_SERVICE_ROLE_KEY="..."')),t.dryRun||i.success(`Setup instructions for ${n} displayed above`),Ut({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 ji(e){i.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,a=r.configured.nextAuth.secret&&r.configured.nextAuth.url,s=r.configured.supabase.url&&r.configured.supabase.publishableKey&&r.configured.supabase.serviceRole;!n&&!o&&!a&&!s?i.warn("No authentication keys configured"):(i.info("Auth keys status:"),n&&i.success("Clerk configured"),o&&i.success("Better Auth configured"),a&&i.success("NextAuth configured"),s&&i.success("Supabase configured"))}Ut(r,e.format,"auth:keys")}function jr(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 Ii({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 Ni(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 ji({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}import be from"fs";import oe from"path";import*as st from"@clack/prompts";import Dr from"picocolors";var Ur=["ts","py"],Ui=`{
105
+ `;await Pe.writeFile(n.path,l,"utf8")}if(t){let o=await Pe.readFile(t.path,"utf8"),a=JSON.parse(o);for(let i of t.changes){if(i.action==="keep")continue;let l=i.section==="dependencies"?"dependencies":"devDependencies";a[l]={...a[l]??{},[i.name]:i.to},a[l]=es(a[l])}await Pe.writeFile(t.path,`${JSON.stringify(a,null,2)}
106
+ `,"utf8")}}async function os(e,t,n){let r=[];for(let o of e){let a=await _n(o);a||(s.error(`Feature '${o}' not found in the local registry.`),s.info("Use one of the supported local features or choose --21st / --v0 for external UI installs."),process.exit(c.INVALID_ARGS));let i=Tn(a,t.provider);if(t.provider&&!i&&(s.error(`Provider '${t.provider}' is not supported for feature '${o}'.`),process.exit(c.INVALID_ARGS)),!i&&a.providers&&a.providers.length>0)if(n)i=a.providers[0];else{let l=await w.select({message:`Select a provider for ${o}`,options:a.providers.map(u=>({value:u.id,label:u.id,hint:u.description}))});w.isCancel(l)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),i=Tn(a,String(l))}r.push({name:o,descriptor:a,provider:i})}return r}function ss(e){w.log.info(qe.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(n=>n.key).join(", ")} to ${t.relativePath}`),t.type==="update-package-json"){let n=t.changes.filter(r=>r.action==="add"||r.action==="update");n.length>0&&w.log.message(` - UPDATE ${t.relativePath}: ${n.map(r=>`${r.name}@${r.to}`).join(", ")}`)}}async function jn(e,t){t.dryRun||w.intro(qe.bgCyan(qe.black(" nebutra add ")));let n=t.yes||!process.stdin.isTTY;if(e.length===0&&!t["21st"]&&!t.v0&&(t.dryRun?s.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)&&(In(Jo(e,t)),process.exit(c.DRY_RUN_OK)),t.ifNotExists&&(t["21st"]||t.v0)&&(t["21st"]&&Pn(t["21st"])||t.v0&&Pn("shadcn-component"))&&(s.info("Component already exists. Skipping installation."),process.exit(c.SUCCESS)),t["21st"]){let r=n||await w.confirm({message:`Install 21st.dev component: ${t["21st"]}?`,initialValue:!0});(w.isCancel(r)||!r)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),w.log.info(qe.cyan(`Invoking shadcn integration for 21st.dev component: ${t["21st"]}...`));try{let o=t["21st"],a=o.startsWith("http")?o:`https://21st.dev/r/${o}`;Bt("pnpm",["dlx","shadcn@latest","add",a],{stdio:"inherit"}),s.success(`Successfully installed ${o}`),process.exit(c.SUCCESS)}catch(o){if(Ft(o))throw o;s.error(`Failed to install component: ${o instanceof Error?o.message:"Unknown error"}`),process.exit(c.ERROR)}}if(t.v0){let r=n||await w.confirm({message:`Install v0 component from: ${t.v0}?`,initialValue:!0});(w.isCancel(r)||!r)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),w.log.info(qe.cyan(`Invoking shadcn integration for v0 URL: ${t.v0}...`));try{Bt("pnpm",["dlx","shadcn@latest","add",t.v0],{stdio:"inherit"}),s.success("Successfully installed v0 component"),process.exit(c.SUCCESS)}catch(o){if(Ft(o))throw o;s.error(`Failed to install component: ${o instanceof Error?o.message:"Unknown error"}`),process.exit(c.ERROR)}}try{let r=await os(e,t,n),o=await ts(r,process.cwd(),t.dryRun?"dry-run":"apply");if(t.dryRun&&(In(o),process.exit(c.DRY_RUN_OK)),ns(o)){let i=o.operations.filter(l=>l.type==="write-file"&&l.status==="conflict").map(l=>l.relativePath);t.ifNotExists&&!Un(o)&&(s.info("Feature already appears to be installed. Skipping because --if-not-exists was set."),process.exit(c.SUCCESS)),s.error(`Refusing to overwrite existing files: ${i.join(", ")}`),process.exit(c.CONFLICT)}Un(o)||(s.info("Feature install already satisfied. No files, env keys, or dependencies needed changes."),process.exit(c.SUCCESS)),ss(o);let a=n||await w.confirm({message:`Proceed with installing ${o.features.map(i=>i.name).join(", ")}?`,initialValue:!0});(w.isCancel(a)||!a)&&(w.log.info("Installation cancelled."),process.exit(c.CANCELLED)),await rs(o),s.success(`Installed ${o.features.map(i=>i.name).join(", ")} into ${o.cwd}`),process.exit(c.SUCCESS)}catch(r){if(Ft(r))throw r;s.error(r instanceof Error?r.message:String(r)),process.exit(c.CONFIG_ERROR)}}import T from"picocolors";import{stderr as Re,stdout as Ln}from"process";import me from"picocolors";function as(){return process.env.NEBUTRA_NON_TTY||process.env.CI||process.env.GITHUB_ACTIONS?!1:process.stderr.isTTY===!0}function Dn(e){if(e)return e;let t=process.env.NEBUTRA_OUTPUT_FORMAT;return t&&["json","table","plain"].includes(t)?t:as()?"plain":"json"}function is(e,t){if(e.length===0)return"";let n=t||Object.keys(e[0]),r={};for(let l of n){r[String(l)]=String(l).length;for(let u of e){let m=String(u[l]??"");r[String(l)]=Math.max(r[String(l)],m.length)}}let o=n.map(l=>String(l).padEnd(r[String(l)])).join(" | "),a=n.map(l=>"-".repeat(r[String(l)])).join("-+-"),i=[o,a];for(let l of e){let u=n.map(m=>String(l[m]??"").padEnd(r[String(m)])).join(" | ");i.push(u)}return i.join(`
107
+ `)}function cs(e){return JSON.stringify(e)}function Fn(e){if(!Array.isArray(e))return Mt(e);if(e.length===0)return"(empty)";if(typeof e[0]!="object"||e[0]===null)return Mt(e);let t=is(e);return me.gray(t)}function Mt(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 S(e,t){let n=Dn(t?.format),r=t?.stream==="stderr"?Re:Ln,o;switch(n){case"json":o=cs(e);break;case"table":o=Fn(e);break;default:o=Mt(e);break}r.write(o+`
108
+ `)}function A(e,t={}){let n=Dn(t.format),r;switch(n){case"json":r=JSON.stringify(e);break;case"table":r=Fn(e);break;default:r=JSON.stringify(e,null,2);break}Ln.write(r+`
109
+ `)}function d(e,t="info"){let n;switch(t){case"error":n=me.red("\u2716");break;case"warn":n=me.yellow("\u26A0");break;case"success":n=me.green("\u2713");break;default:n=me.blue("\u2139");break}let r=`${n} ${e}`;Re.write(r+`
110
+ `)}function k(e,t){if(!(process.env.NEBUTRA_DEBUG||process.argv.includes("--debug")))return;let r=me.dim(`[debug] ${e}`);Re.write(r+`
111
+ `),t&&Object.keys(t).length>0&&Re.write(me.dim(JSON.stringify(t,null,2))+`
112
+ `)}function pt(e){Re.write(`
113
+ `),Re.write(me.bold(me.cyan(e))+`
114
+ `),Re.write(me.gray("-".repeat(e.length))+`
115
+ `),Re.write(`
116
+ `)}function U(e){return e&&typeof e=="object"&&!Array.isArray(e)?e:{}}function Ye(e){return Array.isArray(e)?e:[]}function ze(e,t){return U(e)[t]}function Be(e,t,n=0){let r=ze(e,t);return typeof r=="number"?r:n}function R(e,t=""){return e==null?t:String(e)}async function Q(e,t={}){let n=process.env.NEBUTRA_API_URL||"http://localhost:3100",r=process.env.NEBUTRA_ADMIN_KEY;if(!r)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,n).toString(),a=t.method||"GET",i=t.body?JSON.stringify(t.body):void 0;if(t.dryRun){let l={mode:"dry-run",timestamp:new Date().toISOString(),method:a,url:o,...i&&{body:JSON.parse(i)},headers:{"X-Admin-Key":"***","Content-Type":"application/json"}};return A(l),{ok:!0,status:0,data:l}}try{let l=await fetch(o,{method:a,headers:{"X-Admin-Key":r,"Content-Type":"application/json"},...i&&{body:i}}),u=await l.json().catch(()=>null);if(!l.ok){let m=ze(u,"error");return{ok:!1,status:l.status,error:typeof m=="string"?m:`HTTP ${l.status}`}}return{ok:!0,status:l.status,data:u}}catch(l){return{ok:!1,status:0,error:`Network error: ${l instanceof Error?l.message:String(l)}`}}}function Y(e,t,n){if(t==="json"){let r={command:n||"admin",...e};console.log(JSON.stringify(r,null,2))}else console.log(JSON.stringify(e,null,2))}function Z(e,t,n){Y(U(e),t,n)}async function ls(e){s.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 n=`/api/v1/admin/tenants${t.toString()?`?${t.toString()}`:""}`,r=await Q(n,{dryRun:e.dryRun});if(r.ok||(s.error(`Failed to fetch tenants: ${r.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){Z(r.data,e.format,"admin:tenants");return}let o=U(r.data),a={tenants:Ye(o.tenants??o.data),total:Be(o,"total")||Be(o.meta,"total"),limit:o.limit??ze(o.meta,"limit"),offset:o.offset??ze(o.meta,"offset")};e.format==="json"?Y(a,e.format,"admin:tenants"):(s.info(`Found ${a.total} tenant(s)`),a.tenants.length>0&&(console.log(`
117
+ Tenants:`),a.tenants.forEach(i=>{let l=U(i);console.log(` ${T.blue(R(l.id))} \u2014 ${R(l.name,"(unnamed)")}`),console.log(` Status: ${R(l.status)}`),l.plan&&console.log(` Plan: ${R(l.plan)}`)})))}async function ds(e,t){s.info(`Fetching tenant ${e}...`);let n=await Q(`/api/v1/admin/tenants/${e}`,{dryRun:t.dryRun});if(n.ok||(s.error(`Failed to fetch tenant: ${n.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){Z(n.data,t.format,"admin:tenant");return}if(t.format==="json")Y({tenant:U(n.data)},t.format,"admin:tenant");else{let r=U(n.data);s.success(`Tenant ${T.blue(R(r.id))}`),console.log(` Name: ${R(r.name)}`),console.log(` Status: ${R(r.status)}`),console.log(` Plan: ${R(r.plan)}`),console.log(` Created: ${R(r.createdAt)}`),r.suspendedAt&&console.log(` Suspended: ${R(r.suspendedAt)}`)}}async function us(e,t){t.yes||(s.warn(`Suspending tenant ${e} will disable all operations`),s.info("Use --yes to confirm"),process.exit(c.CANCELLED)),s.info(`Suspending tenant ${e}...`);let n=await Q(`/api/v1/admin/tenants/${e}/suspend`,{method:"POST",dryRun:t.dryRun});if(n.ok||(s.error(`Failed to suspend tenant: ${n.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){Z(n.data,t.format,"admin:suspend");return}s.success(`Tenant ${T.blue(e)} suspended`),t.format==="json"&&Y({suspended:!0,tenantId:e},t.format,"admin:suspend")}async function ms(e,t){s.info(`Unsuspending tenant ${e}...`);let n=await Q(`/api/v1/admin/tenants/${e}/unsuspend`,{method:"POST",dryRun:t.dryRun});if(n.ok||(s.error(`Failed to unsuspend tenant: ${n.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){Z(n.data,t.format,"admin:unsuspend");return}s.success(`Tenant ${T.blue(e)} unsuspended`),t.format==="json"&&Y({unsuspended:!0,tenantId:e},t.format,"admin:unsuspend")}async function ps(e){s.info("Fetching usage report...");let t=new URLSearchParams;e.period&&t.append("period",e.period),e.top&&t.append("top",String(e.top));let n=`/api/v1/admin/usage/report${t.toString()?`?${t.toString()}`:""}`,r=await Q(n,{dryRun:e.dryRun});if(r.ok||(s.error(`Failed to fetch usage report: ${r.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){Z(r.data,e.format,"admin:usage");return}let o=U(r.data),a={period:o.period,topTenants:Ye(o.topTenants??o.data),totalUsage:o.totalUsage};e.format==="json"?Y(a,e.format,"admin:usage"):(s.info(`Usage report for period: ${R(a.period)}`),console.log(`Total usage: ${R(a.totalUsage)}`),a.topTenants.length>0&&(console.log(`
118
+ Top tenants:`),a.topTenants.forEach((i,l)=>{let u=U(i);console.log(` ${l+1}. ${R(u.tenantName||u.tenantId||u.name)} \u2014 ${R(u.usage)}`)})))}async function fs(e){s.info("Fetching dead letter queue...");let t=await Q("/api/v1/admin/dlq/list",{dryRun:e.dryRun});if(t.ok||(s.error(`Failed to fetch DLQ: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){Z(t.data,e.format,"admin:dlq:list");return}let n=U(t.data),r={messages:Ye(n.messages??n.data),count:Be(n,"count")||Be(n,"total")};e.format==="json"?Y(r,e.format,"admin:dlq:list"):(s.info(`Found ${r.count} message(s) in DLQ`),r.messages.length>0&&(console.log(`
119
+ Messages:`),r.messages.forEach(o=>{let a=U(o);console.log(` ${T.blue(R(a.id))}`),console.log(` Type: ${R(a.type)}`),console.log(` Error: ${R(a.error)}`),console.log(` Created: ${R(a.createdAt)}`)})))}async function gs(e,t){s.info(`Replaying DLQ message ${e}...`);let n=await Q(`/api/v1/admin/dlq/replay/${e}`,{method:"POST",dryRun:t.dryRun});if(n.ok||(s.error(`Failed to replay message: ${n.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){Z(n.data,t.format,"admin:dlq:replay");return}s.success(`Message ${T.blue(e)} replayed`),t.format==="json"&&Y({replayed:!0,messageId:e},t.format,"admin:dlq:replay")}async function ys(e){e.yes||(s.warn("This will permanently delete all messages in the DLQ"),s.info("Use --yes to confirm"),process.exit(c.CANCELLED)),s.info("Purging DLQ...");let t=await Q("/api/v1/admin/dlq/purge",{method:"POST",dryRun:e.dryRun});if(t.ok||(s.error(`Failed to purge DLQ: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){Z(t.data,e.format,"admin:dlq:purge");return}s.success("DLQ purged"),e.format==="json"&&Y({purged:!0,count:ze(t.data,"count")},e.format,"admin:dlq:purge")}async function hs(e){s.info("Fetching feature flags...");let t=await Q("/api/v1/admin/feature-flags",{dryRun:e.dryRun});if(t.ok||(s.error(`Failed to fetch flags: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){Z(t.data,e.format,"admin:flags:list");return}let n=U(t.data),r={flags:Ye(n.flags??n.data),total:Be(n,"total")};e.format==="json"?Y(r,e.format,"admin:flags:list"):(s.info(`Found ${r.total} flag(s)`),r.flags.length>0&&(console.log(`
120
+ Flags:`),r.flags.forEach(o=>{let a=U(o),i=a.override!==void 0?T.yellow(String(a.override)):T.gray(String(a.default??""));console.log(` ${T.blue(R(a.name))} = ${i}`)})))}async function bs(e,t,n){s.info(`Setting flag ${e}...`);let r=t;t==="true"?r=!0:t==="false"?r=!1:Number.isNaN(Number(t))||(r=Number(t));let o=await Q(`/api/v1/admin/feature-flags/${e}`,{method:"POST",body:{value:r},dryRun:n.dryRun});if(o.ok||(s.error(`Failed to set flag: ${o.error}`),process.exit(c.NETWORK_ERROR)),n.dryRun){Z(o.data,n.format,"admin:flags:set");return}s.success(`Flag ${T.blue(e)} set to ${r}`),n.format==="json"&&Y({flag:e,value:r},n.format,"admin:flags:set")}async function vs(e,t){s.info(`Unsetting flag ${e}...`);let n=await Q(`/api/v1/admin/feature-flags/${e}`,{method:"DELETE",dryRun:t.dryRun});if(n.ok||(s.error(`Failed to unset flag: ${n.error}`),process.exit(c.NETWORK_ERROR)),t.dryRun){Z(n.data,t.format,"admin:flags:unset");return}s.success(`Flag ${T.blue(e)} unset`),t.format==="json"&&Y({flag:e,unset:!0},t.format,"admin:flags:unset")}async function ws(e){s.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 n=`/api/v1/admin/audit${t.toString()?`?${t.toString()}`:""}`,r=await Q(n,{dryRun:e.dryRun});if(r.ok||(s.error(`Failed to fetch audit log: ${r.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){Z(r.data,e.format,"admin:audit");return}let o=U(r.data),a={entries:Ye(o.entries??o.data),total:Be(o,"total")};e.format==="json"?Y(a,e.format,"admin:audit"):(s.info(`Found ${a.total} audit log entries`),a.entries.length>0&&(console.log(`
121
+ Audit entries:`),a.entries.forEach(i=>{let l=U(i);console.log(` ${R(l.timestamp)} \u2014 ${T.blue(R(l.action))} by ${R(l.actor)}`),l.details&&console.log(` ${R(l.details)}`)})))}async function Rs(e){s.info("Running platform health check...");let t=await Q("/api/v1/system/status",{dryRun:e.dryRun});if(t.ok||(s.error(`Failed to fetch health status: ${t.error}`),process.exit(c.NETWORK_ERROR)),e.dryRun){Z(t.data,e.format,"admin:health");return}let n=U(t.data),r={status:R(n.status,"unknown"),services:U(n.services),timestamp:n.timestamp};if(e.format==="json")Y(r,e.format,"admin:health");else{let o=r.status==="healthy"?T.green:r.status==="degraded"?T.yellow:T.red;s.info(`Platform status: ${o(r.status)}`),Object.keys(r.services).length>0&&(console.log(`
122
+ Services:`),Object.entries(r.services).forEach(([a,i])=>{let l=U(i),u=l.status==="healthy"?T.green("\u2713"):T.red("\u2717");console.log(` ${u} ${a}: ${R(l.status)}`),l.latency&&console.log(` Latency: ${R(l.latency)}ms`),l.error&&console.log(` Error: ${R(l.error)}`)}))}}function Bn(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 a=o.optsWithGlobals?.()||o;await ls({limit:o.limit,offset:o.offset,status:o.status,format:o.format||a.format,dryRun:o.dryRun||a.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,a)=>{let i=a.optsWithGlobals?.()||a;await ds(o,{format:a.format||i.format,dryRun:a.dryRun||i.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,a)=>{let i=a.optsWithGlobals?.()||a;await us(o,{yes:a.yes||i.yes,format:a.format||i.format,dryRun:a.dryRun||i.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,a)=>{let i=a.optsWithGlobals?.()||a;await ms(o,{format:a.format||i.format,dryRun:a.dryRun||i.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 a=o.optsWithGlobals?.()||o;await ps({period:o.period,top:o.top,format:o.format||a.format,dryRun:o.dryRun||a.dryRun})});let n=t.command("dlq").description("Dead letter queue management");n.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 a=o.optsWithGlobals?.()||o;await fs({format:o.format||a.format,dryRun:o.dryRun||a.dryRun})}),n.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,a)=>{let i=a.optsWithGlobals?.()||a;await gs(o,{format:a.format||i.format,dryRun:a.dryRun||i.dryRun})}),n.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 a=o.optsWithGlobals?.()||o;await ys({yes:o.yes||a.yes,format:o.format||a.format,dryRun:o.dryRun||a.dryRun})});let r=t.command("flags").description("Feature flag management");r.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 a=o.optsWithGlobals?.()||o;await hs({format:o.format||a.format,dryRun:o.dryRun||a.dryRun})}),r.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,a,i)=>{let l=i.optsWithGlobals?.()||i;await bs(o,a,{format:i.format||l.format,dryRun:i.dryRun||l.dryRun})}),r.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,a)=>{let i=a.optsWithGlobals?.()||a;await vs(o,{format:a.format||i.format,dryRun:a.dryRun||i.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 a=o.optsWithGlobals?.()||o;await ws({actor:o.actor,action:o.action,since:o.since,limit:o.limit,format:o.format||a.format,dryRun:o.dryRun||a.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 a=o.optsWithGlobals?.()||o;await Rs({format:o.format||a.format,dryRun:o.dryRun||a.dryRun})})}import{existsSync as Cs,readFileSync as Es,writeFileSync as ks}from"fs";import{resolve as Gt}from"path";var b={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"]},Ss=[{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)"}],pe={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:Ss,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:"ui",description:"Search, inspect, validate, and plan migrations for @nebutra/ui components",usage:"nebutra ui [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 Gn="nebutra.config.json",xs=b.ai.filter(e=>e!=="none"),Mn={"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 ce(e,t,n){if(t==="json"){let r={command:n||"ai",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(r,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 Os(e){return e.split("-").map(t=>t.charAt(0).toUpperCase()+t.slice(1)).join(" ")}function As(e){return Mn[e]?Mn[e]:[`${e.replace(/-/g,"_").toUpperCase()}_API_KEY`]}function ft(){return Object.fromEntries(xs.map(e=>[e,{id:e,name:Os(e),envVars:As(e)}]))}function fe(){return Gt(process.cwd(),Gn)}function Ie(){let e=fe();if(!Cs(e))return{$schema:"https://nebutra.com/schema.json"};try{return JSON.parse(Es(e,"utf-8"))}catch(t){s.error(`Failed to parse ${Gn}: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}function gt(e){ks(fe(),`${JSON.stringify(e,null,2)}
123
+ `)}function Se(e){return e.ai={providers:{},routes:{},...e.ai},e.ai.providers={...e.ai.providers},e.ai.routes={...e.ai.routes},e.ai}function Kn(e){let t=ft(),n=[...new Set(e.map(o=>o.toLowerCase()))],r=n.filter(o=>!t[o]);return r.length>0&&(s.error(`Unknown AI provider(s): ${r.join(", ")}. Valid providers: ${Object.keys(t).join(", ")}`),process.exit(c.INVALID_ARGS)),n}function _s(e){let t=e?.split(",").map(r=>r.trim()).filter(Boolean)??[];t.length===0&&(s.error("Route fallback cannot be empty. Use --fallback provider:model,provider:model"),process.exit(c.INVALID_ARGS));let n=t.filter(r=>!/^[a-z0-9-]+:[^,\s]+$/i.test(r));return n.length>0&&(s.error(`Invalid fallback target(s): ${n.join(", ")}. Expected provider:model.`),process.exit(c.INVALID_ARGS)),t}function Vn(e){let t=Se(e),n=t.providers??{},r=t.routes??{},o=Object.entries(n).filter(([,a])=>a.enabled).map(([a])=>a);return{path:fe(),gateway:t.gateway??null,providers:n,enabledProviders:o,routes:r}}function ie(e){let t=typeof e.opts=="function"?e.opts():e,n=typeof e.optsWithGlobals=="function"?e.optsWithGlobals():t,r=t.format??n.format??Ps();return{...n,...t,...r?{format:r}:{}}}function Ps(){let e=process.argv.find(n=>n.startsWith("--format="));if(e)return e.slice(9);let t=process.argv.indexOf("--format");if(t>=0)return process.argv[t+1]}function He(e){return e?e.length<=8?"***":`${e.substring(0,8)}***`:"not set"}async function Is(e){e.format!=="json"&&s.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 r of Object.values(t))r.configured=r.keyVars.some(o=>process.env[o]);let n={providers:Object.entries(t).map(([r,o])=>({id:r,name:o.name,configured:o.configured,keys:o.keyVars.map(a=>({name:a,value:He(process.env[a])}))})),configuredCount:Object.values(t).filter(r=>r.configured).length,totalProviders:Object.keys(t).length};e.dryRun||(n.configuredCount===0?s.warn("No AI providers configured. Set API keys to enable AI features."):s.success(`${n.configuredCount} AI provider(s) configured`)),ce(n,e.format,"ai:models")}async function $s(e){e.format!=="json"&&s.info("Scanning for available agents...");try{let t=Gt(process.cwd(),"backends/gateway/src/routes/agents"),n=[];try{let o=await import("fs");o.existsSync(t)&&(n=o.readdirSync(t).filter(i=>i.endsWith(".ts")&&!i.endsWith(".d.ts")).map(i=>({name:i.replace(".ts",""),path:`backends/gateway/src/routes/agents/${i}`})))}catch{n=[]}let r={agents:n.length>0?n:[{name:"No agents found",path:"create agents in backends/gateway/src/routes/agents/"}],count:n.length};e.dryRun||(r.count===0?s.info("No agents configured. Create agents in backends/gateway/src/routes/agents/"):s.success(`Found ${r.count} agent(s)`)),ce(r,e.format,"ai:agents")}catch(t){s.error(`Failed to scan agents: ${t instanceof Error?t.message:String(t)}`),process.exit(c.ERROR)}}async function Ns(e,t){(!e||e.trim().length===0)&&(s.error("Prompt cannot be empty"),process.exit(c.INVALID_ARGS)),t.format!=="json"&&(s.info("Testing AI prompt against default model..."),s.info("Note: Ensure API gateway is running on http://localhost:3001"));let n={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||s.warn("AI test execution requires a running API gateway. Start it with: pnpm --filter @nebutra/gateway dev"),ce(n,t.format,"ai:test")}async function Ts(e){e.format!=="json"&&s.info("Checking AI configuration...");let t={providers:{openai:{key:He(process.env.OPENAI_API_KEY),configured:!!process.env.OPENAI_API_KEY},anthropic:{key:He(process.env.ANTHROPIC_API_KEY),configured:!!process.env.ANTHROPIC_API_KEY},openrouter:{key:He(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 r=Gt(process.cwd(),"nebutra.config.ts"),o=await import("fs");if(o.existsSync(r)){let i=o.readFileSync(r,"utf-8").match(/preset:\s*["']([^"']+)["']/);i&&(t.preset=i[1])}}catch{}let n=Object.entries(t.providers).filter(([,r])=>r.configured).map(([r])=>r);e.dryRun||(n.length===0?s.warn("No AI providers configured. Set environment variables to enable AI features."):s.success(`Configuration loaded: ${n.join(", ")}`)),ce(t,e.format,"ai:config")}async function Us(e){let t=Ie(),n=Se(t),r=ft(),o=Object.values(r).map(i=>{let l=n.providers?.[i.id];return{id:i.id,name:i.name,enabled:l?.enabled===!0,configured:i.envVars.some(u=>!!process.env[u]),envVars:i.envVars.map(u=>({name:u,value:He(process.env[u])}))}}),a={configPath:fe(),providers:o,enabledCount:o.filter(i=>i.enabled).length,totalProviders:o.length};if(e.format!=="json"){let i=o.filter(l=>l.enabled);i.length===0?s.warn("No runtime AI providers enabled in nebutra.config.json."):s.success(`Enabled AI providers: ${i.map(l=>l.id).join(", ")}`)}ce(a,e.format,"ai:provider:list")}async function js(e,t){let n=Kn(e),r=Ie(),o=Se(r),a=ft(),i=new Date().toISOString();for(let u of n)o.providers[u]={enabled:!0,envVars:a[u].envVars,enabledAt:o.providers?.[u]?.enabledAt??i};gt(r);let l={configPath:fe(),enabled:n,env:t.env===!0?n.flatMap(u=>a[u].envVars.map(m=>({provider:u,name:m,example:`${m}=`}))):void 0,ai:Vn(r)};if(t.format!=="json"&&(s.success(`Enabled AI provider(s): ${n.join(", ")}`),t.env)){s.info("Required environment variables:");for(let u of n)for(let m of a[u].envVars)console.log(`${m}=`)}ce(l,t.format,"ai:provider:enable")}async function Ls(e,t){let n=Kn(e),r=Ie(),o=Se(r),a=ft(),i=new Date().toISOString();for(let u of n)o.providers[u]={enabled:!1,envVars:o.providers?.[u]?.envVars??a[u].envVars,disabledAt:i};gt(r);let l={configPath:fe(),disabled:n,ai:Vn(r)};t.format!=="json"&&s.success(`Disabled AI provider(s): ${n.join(", ")}`),ce(l,t.format,"ai:provider:disable")}async function Ds(e){let t=Ie(),n=Se(t),r=new Date().toISOString();n.gateway={enabled:!0,mode:"local",initializedAt:n.gateway?.initializedAt??r,updatedAt:r},gt(t);let o={configPath:fe(),gateway:n.gateway};e.format!=="json"&&s.success("AI gateway governance initialized in nebutra.config.json"),ce(o,e.format,"ai:gateway:init")}async function Fs(e){let t=Ie(),n=Se(t),r={configPath:fe(),gateway:n.gateway??null,initialized:n.gateway?.enabled===!0};e.format!=="json"&&(r.initialized?s.success("AI gateway governance is initialized"):s.warn("AI gateway governance is not initialized. Run: nebutra ai gateway init")),ce(r,e.format,"ai:gateway:status")}async function Bs(e,t){(!e||e.trim().length===0)&&(s.error("Route name cannot be empty"),process.exit(c.INVALID_ARGS)),t.policy||(s.error("Route policy is required. Use --policy <policy>."),process.exit(c.INVALID_ARGS));let n=_s(t.fallback),r=Ie(),o=Se(r);o.routes[e]={policy:t.policy,fallback:n,updatedAt:new Date().toISOString()},gt(r);let a={configPath:fe(),route:{name:e,...o.routes[e]},routes:o.routes};t.format!=="json"&&s.success(`AI route '${e}' set with policy '${t.policy}'`),ce(a,t.format,"ai:route:set")}async function Ms(e){let t=Ie(),n=Se(t),r=Object.entries(n.routes??{}).map(([a,i])=>({name:a,...i})),o={configPath:fe(),routes:r,count:r.length};e.format!=="json"&&(r.length===0?s.warn("No AI routes configured. Run: nebutra ai route set chat --policy cost-latency-balanced --fallback openai:gpt-5.4"):s.success(`Configured AI routes: ${r.map(a=>a.name).join(", ")}`)),ce(o,e.format,"ai:route:list")}function qn(e){let t=e.command("ai").description("Manage AI models, agents, and configuration"),n=t.command("provider").description("Manage runtime AI provider governance");n.command("list").description("List supported and enabled AI providers").option("--format <type>","Output format: json or plain").action(async a=>{let i=ie(a);await Us({format:i.format,interactive:i.yes!==!0})}),n.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(a,i)=>{let l=ie(i);await js(a,{env:l.env===!0,format:l.format,interactive:l.yes!==!0})}),n.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(a,i)=>{let l=ie(i);await Ls(a,{format:l.format,interactive:l.yes!==!0})});let r=t.command("gateway").description("Manage local AI gateway governance");r.command("init").description("Initialize the local AI gateway governance block").option("--format <type>","Output format: json or plain").action(async a=>{let i=ie(a);await Ds({format:i.format,interactive:i.yes!==!0})}),r.command("status").description("Show local AI gateway governance status").option("--format <type>","Output format: json or plain").action(async a=>{let i=ie(a);await Fs({format:i.format,interactive:i.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(a,i)=>{let l=ie(i);await Bs(a,{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 a=>{let i=ie(a);await Ms({format:i.format,interactive:i.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 a=>{let i=ie(a);await Is({dryRun:i.dryRun===!0,format:i.format,interactive:i.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 a=>{let i=ie(a);await $s({dryRun:i.dryRun===!0,format:i.format,interactive:i.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(a,i)=>{let l=ie(i);await Ns(a,{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 a=>{let i=ie(a);await Ts({dryRun:i.dryRun===!0,format:i.format,interactive:i.yes!==!0})})}import{resolve as Gs}from"path";function Kt(e,t,n){if(t==="json"){let r={command:n||"auth",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(r,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 Ks(){try{let e=Gs(process.cwd(),"nebutra.config.ts"),t=Uo("fs");if(t.existsSync(e)){let n=t.readFileSync(e,"utf-8");if(n.includes("clerk"))return"clerk";if(n.includes("better-auth"))return"better-auth";if(n.includes("nextauth"))return"nextauth";if(n.includes("supabase"))return"supabase"}}catch{}return"clerk"}async function Vs(e){s.info("Checking authentication configuration...");let t=Ks(),n={provider:t,configured:!1,keys:{}};t==="clerk"?(n.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")},n.configured=!!process.env.CLERK_SECRET_KEY&&!!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY):t==="better-auth"?(n.keys={BETTER_AUTH_SECRET:v(process.env.BETTER_AUTH_SECRET,"secret"),BETTER_AUTH_URL:process.env.BETTER_AUTH_URL||"not set"},n.configured=!!process.env.BETTER_AUTH_SECRET):t==="nextauth"?(n.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")},n.configured=!!(process.env.AUTH_SECRET||process.env.NEXTAUTH_SECRET)):(n.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")},n.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||(n.configured?s.success(`Auth provider configured: ${t}`):s.warn(`Auth provider ${t} is not fully configured`)),Kt({...n},e.format,"auth:status")}async function qs(e,t){let n=["clerk","better-auth","nextauth","supabase"];n.includes(e.toLowerCase())||(s.error(`Invalid provider: ${e}. Choose from: ${n.join(", ")}`),process.exit(c.INVALID_ARGS));let r=e.toLowerCase();s.info(`Setting up ${r} authentication...`),r==="clerk"?(s.info("Clerk setup requires:"),s.info("1. A Clerk account (https://clerk.com)"),s.info("2. A Clerk application created"),s.info("3. API keys from the Clerk dashboard"),s.info(""),s.info("To complete setup:"),s.info("1. Go to https://dashboard.clerk.com"),s.info("2. Copy your Secret Key and Publishable Key"),s.info("3. Add them to .env.local:"),s.info(' CLERK_SECRET_KEY="sk_..."'),s.info(' NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_..."'),s.info(""),s.info("Webhook setup (optional):"),s.info("1. In Clerk dashboard, go to Webhooks"),s.info("2. Create endpoint: https://yourdomain.com/api/webhooks/clerk"),s.info("3. Copy the signing secret to .env.local:"),s.info(' CLERK_WEBHOOK_SECRET="whsec_..."')):r==="better-auth"?(s.info("Better Auth setup requires:"),s.info("1. Database URL configured (DATABASE_URL env var)"),s.info("2. A generated auth secret"),s.info(""),s.info("To complete setup:"),s.info("1. Ensure DATABASE_URL is set in .env.local"),s.info("2. Generate a new secret:"),s.info(" openssl rand -base64 32"),s.info("3. Add to .env.local:"),s.info(' BETTER_AUTH_SECRET="<generated_secret>"'),s.info(' BETTER_AUTH_URL="http://localhost:3000"'),s.info(""),s.info("4. Run database migration:"),s.info(" pnpm --filter @nebutra/web db:push")):r==="nextauth"?(s.info("NextAuth / Auth.js setup requires:"),s.info("1. A generated Auth.js secret"),s.info("2. NEXTAUTH_URL or AUTH_URL pointing at the web app origin"),s.info("3. OAuth provider credentials for each enabled provider"),s.info(""),s.info("To complete setup:"),s.info("1. Generate a new secret:"),s.info(" openssl rand -base64 32"),s.info("2. Add to the production environment:"),s.info(' AUTH_PROVIDER="nextauth"'),s.info(' NEXT_PUBLIC_AUTH_PROVIDER="nextauth"'),s.info(' AUTH_SECRET="<generated_secret>"'),s.info(' NEXTAUTH_URL="https://app.nebutra.com"'),s.info(' GOOGLE_CLIENT_ID="..."'),s.info(' GOOGLE_CLIENT_SECRET="..."')):(s.info("Supabase Auth setup requires:"),s.info("1. Supabase project URL"),s.info("2. Public anon key for browser auth"),s.info("3. Service role key for server-side user/session validation"),s.info(""),s.info("To complete setup:"),s.info(' AUTH_PROVIDER="supabase"'),s.info(' NEXT_PUBLIC_AUTH_PROVIDER="supabase"'),s.info(' NEXT_PUBLIC_SUPABASE_URL="https://xxx.supabase.co"'),s.info(' NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),s.info(' NEXT_PUBLIC_SUPABASE_ANON_KEY="..."'),s.info(' SUPABASE_URL="https://xxx.supabase.co"'),s.info(' SUPABASE_PUBLISHABLE_KEY="sb_publishable_..."'),s.info(' SUPABASE_ANON_KEY="..."'),s.info(' SUPABASE_SERVICE_ROLE_KEY="..."')),t.dryRun||s.success(`Setup instructions for ${r} displayed above`),Kt({provider:r,setupGuide:"Complete setup by following the instructions above",documentationUrl:r==="clerk"?"https://clerk.com/docs":r==="better-auth"?"https://www.better-auth.com":r==="nextauth"?"https://authjs.dev":"https://supabase.com/docs/guides/auth"},t.format,"auth:setup")}async function zs(e){s.info("Checking authentication keys and secrets...");let n={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 r=n.configured.clerk.secret&&n.configured.clerk.publishable,o=n.configured.betterAuth.secret&&n.configured.betterAuth.url,a=n.configured.nextAuth.secret&&n.configured.nextAuth.url,i=n.configured.supabase.url&&n.configured.supabase.publishableKey&&n.configured.supabase.serviceRole;!r&&!o&&!a&&!i?s.warn("No authentication keys configured"):(s.info("Auth keys status:"),r&&s.success("Clerk configured"),o&&s.success("Better Auth configured"),a&&s.success("NextAuth configured"),i&&s.success("Supabase configured"))}Kt(n,e.format,"auth:keys")}function zn(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 n=>{let r=n.optsWithGlobals?.()||n;await Vs({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.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(n,r)=>{let o=r.optsWithGlobals?.()||r;await qs(n,{dryRun:r.dryRun||!1,format:r.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 n=>{let r=n.optsWithGlobals?.()||n;await zs({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.yes!==!0})})}import Ce from"fs";import le from"path";import*as yt from"@clack/prompts";import Wn from"picocolors";function x(e,t){let n=typeof e.optsWithGlobals=="function"?e.optsWithGlobals():void 0;return{...t&&typeof t.optsWithGlobals=="function"?t.optsWithGlobals():void 0,...n,...e}}var Yn=["ts","py"],Ys=`{
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,a])=>{let s=a.status==="healt
135
135
  "hono": "^4.6.0"
136
136
  }
137
137
  }
138
- `,Li=`import { Hono } from "hono";
138
+ `,Hs=`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
- `,Di=`# @nebutra/gateway
145
+ `,Ws=`# @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 Fi(e){return`[project]
150
+ `;function Js(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 Vi(e){return`# backends/python/${e}
167
+ `}function Xs(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 Mi=`from fastapi import FastAPI
193
+ `}var Qs=`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 Bi(e,t){let r=oe.join(e,"backends/gateway");be.existsSync(r)&&(i.info(`backends/gateway already exists in this monorepo \u2014 nothing to do.
206
+ `;async function Zs(e,t){let n=le.join(e,"backends/gateway");Ce.existsSync(n)&&(s.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"),Ui),be.writeFileSync(oe.join(r,"src/index.ts"),Li),be.writeFileSync(oe.join(r,"README.md"),Di),i.success("Created backends/gateway scaffold"),process.exit(c.SUCCESS)}function Lr(e){return/^[a-z][a-z0-9_-]{0,40}$/.test(e)}async function Gi(e,t){let r=t.name,n=process.stdout.isTTY===!0&&!t.yes;if(!r&&n){let s=await st.text({message:"Service name (lowercase, hyphens or underscores):",placeholder:"translator",validate:l=>Lr(l)?void 0:"Invalid name"});st.isCancel(s)&&(i.warn("Cancelled."),process.exit(c.CANCELLED)),r=s}r||(i.error("Missing --name. Required in non-interactive mode."),process.exit(c.INVALID_ARGS)),Lr(r)||(i.error(`Invalid name: ${Dr.red(r)}. Use lowercase letters, digits, hyphen, underscore.`),process.exit(c.INVALID_ARGS));let o=oe.join(e,"backends/python",r);be.existsSync(o)&&(i.error(`backends/python/${r} already exists \u2014 refusing to overwrite.`),process.exit(c.CONFLICT));let a=[[oe.join(o,"pyproject.toml"),Fi(r)],[oe.join(o,"README.md"),Vi(r)],[oe.join(o,"src/main.py"),Mi],[oe.join(o,"src/__init__.py"),""]];t.dryRun&&(process.stdout.write(JSON.stringify({mode:"dry-run",command:`backend init py --name ${r}`,files:a.map(([s])=>s)},null,2)+`
209
- `),process.exit(c.DRY_RUN_OK));for(let[s,l]of a)be.mkdirSync(oe.dirname(s),{recursive:!0}),be.writeFileSync(s,l);i.success(`Created backends/python/${r} scaffold`),i.info("Update README.md to cite which ADR justification applies (batch | ML | specialized libs)."),process.exit(c.SUCCESS)}async function qi(e,t={}){Ur.includes(e)||(i.error(`Invalid runtime: ${Dr.red(e)}. Valid: ${Ur.join(", ")}`),process.exit(c.INVALID_ARGS));let r=h();e==="ts"?await Bi(r,t):await Gi(r,t)}function Fr(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 qi(r,{name:n.name,dryRun:n.dryRun||!1,yes:o.yes||!1,quiet:o.quiet||!1})})}function Lt(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 Ki(e,t){return e?e.length<=8?"***":`${e.substring(0,8)}*** (${t||e.length} chars)`:"not set"}var ct={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 Wi(e){i.info("Checking payment provider configuration...");let t=Object.entries(ct).map(([o,a])=>{let s=a.keyVars.every(l=>process.env[l]);return{id:o,name:a.name,configured:s,keys:a.keyVars.map(l=>({name:l,value:Ki(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?i.warn("No payment providers configured. Set API keys to enable billing."):i.success(`${n.configuredCount} payment provider(s) configured`)),Lt(n,e.format,"billing:status")}async function zi(e,t){let r=Object.keys(ct);r.includes(e.toLowerCase())||(i.error(`Invalid provider: ${e}. Choose from: ${r.join(", ")}`),process.exit(c.INVALID_ARGS));let n=e.toLowerCase(),o=ct[n];i.info(`Setting up ${o.name} payment provider...`),i.info(""),i.info("Setup steps:"),i.info(`1. Go to ${o.setupUrl}`),i.info("2. Create or log in to your account"),i.info("3. Generate API credentials"),i.info("4. Add the following to .env.local:"),i.info(""),o.keyVars.forEach(s=>{i.info(` ${s}="<your_${s.toLowerCase()}>"`.padStart(45))}),i.info(""),i.info("5. (Optional) Configure webhook in provider dashboard:"),i.info(` Webhook URL: https://yourdomain.com${o.webhookUrl}`),t.dryRun||i.success(`Setup instructions for ${o.name} displayed above`);let a={provider:n,name:o.name,requiredKeys:o.keyVars,webhookUrl:o.webhookUrl,setupGuide:"Follow the instructions above to complete setup",documentationUrl:o.setupUrl};Lt(a,t.format,"billing:setup")}async function Yi(e){i.info("Checking billing webhook configuration...");let t=process.env.NEXT_PUBLIC_APP_URL||"https://yourdomain.com",r=Object.entries(ct).map(([o,a])=>({provider:o,name:a.name,url:`${t}${a.webhookUrl}`,endpoint:a.webhookUrl,configured:a.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||(i.info("Webhook endpoints:"),r.forEach(o=>{o.configured?i.success(`${o.name}: configured`):i.warn(`${o.name}: not configured (missing API key)`)})),Lt(n,e.format,"billing:webhooks")}function Vr(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 Wi({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 zi(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 Yi({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}function Fe(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 Mr(e){return/^#[0-9A-Fa-f]{6}$/.test(e)}async function Hi(e){i.info("Initializing brand system...");let t=await K("brand:init",{dryRun:e.dryRun,interactive:e.interactive??!0});Fe(t,e.format,"brand:init"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||i.success("Brand system initialized successfully")}async function Ji(e){i.info("Applying brand configuration...");let t=await K("brand:apply",{dryRun:e.dryRun,interactive:e.interactive??!0});Fe(t,e.format,"brand:apply"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||i.success("Brand applied successfully")}async function Xi(e){let t=[];e.primary&&(Mr(e.primary)||(i.error(`Invalid primary color format: ${e.primary}. Expected hex format like #0033FE`),process.exit(c.INVALID_ARGS)),t.push(`--primary=${e.primary}`)),e.secondary&&(Mr(e.secondary)||(i.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&&(i.warn("No colors specified. Usage: nebutra brand palette --primary=#HEX --secondary=#HEX"),i.info("Example: nebutra brand palette --primary=#0033FE --secondary=#0BF1C3"),process.exit(c.INVALID_ARGS)),i.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"});Fe(r,e.format,"brand:palette"),r.exitCode!==0&&process.exit(r.exitCode),e.dryRun||i.success("Color palette generated successfully")}async function Qi(e){i.info("Syncing brand tokens across packages...");let t=await K("brand:sync",{dryRun:e.dryRun,interactive:e.interactive??!0});Fe(t,e.format,"brand:sync"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||i.success("Brand tokens synced successfully")}async function Zi(e){i.info("Verifying brand token consistency...");let t=await K("brand:verify-tokens",{dryRun:e.dryRun,interactive:e.interactive??!0});Fe(t,e.format,"brand:verify-tokens"),t.exitCode!==0&&(i.error("Brand token verification failed. There are inconsistencies in your design tokens."),process.exit(t.exitCode)),e.dryRun||i.success("All brand tokens are consistent")}function Br(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 Hi({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 Ji({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 Xi({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 Qi({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 Zi({dryRun:r.dryRun||!1,format:r.format||n.format,interactive:n.yes!==!0})})}import pe from"picocolors";var ea=process.env.NEBUTRA_API_URL||"http://localhost:3001/api";async function j(e,t={}){let r=`${ea}${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 ta(e){let t={dau_retention:.25,engagement_rate:.25,content_velocity:.2,response_time:.15,member_retention:.15},r={},n=0;for(let[o,a]of Object.entries(t)){let s=Math.min(100,(e[o]||0)*100);r[o]=s,n+=s*a}return{score:Math.round(n),breakdown:r}}async function ra(e){try{i.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 j(`/community/showcase?${t.toString()}`);if(!r.submissions||r.submissions.length===0)return i.warn("No showcase submissions found"),c.SUCCESS;i.info(`
210
- Showcase Submissions (${r.submissions.length})
211
- `);for(let n of r.submissions);return c.SUCCESS}catch(t){return i.error(`Failed to list showcase: ${t.message}`),c.ERROR}}async function na(e,t){try{if(!t.yes)return i.warn(`Approve showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;i.info(`Approving showcase submission ${e}...`);let r=await j(`/community/showcase/${e}/approve`,{method:"POST"});return i.success(`Approved: ${r.title}`),c.SUCCESS}catch(r){return i.error(`Failed to approve showcase: ${r.message}`),c.ERROR}}async function oa(e,t){try{if(!t.yes)return i.warn(`Reject showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;let r=t.reason||"Does not meet guidelines";i.info(`Rejecting showcase submission ${e}...`);let n=await j(`/community/showcase/${e}/reject`,{method:"POST",body:JSON.stringify({reason:r})});return i.success(`Rejected: ${n.title}`),c.SUCCESS}catch(r){return i.error(`Failed to reject showcase: ${r.message}`),c.ERROR}}async function ia(e,t){try{if(!t.yes)return i.warn(`Mark showcase as featured: ${e}? Use --yes to confirm`),c.SUCCESS;i.info(`Featuring showcase submission ${e}...`);let r=await j(`/community/showcase/${e}/feature`,{method:"POST"});return i.success(`Featured: ${r.title}`),c.SUCCESS}catch(r){return i.error(`Failed to feature showcase: ${r.message}`),c.ERROR}}async function aa(e){try{i.info("Fetching showcase statistics...");let t=await j("/community/showcase/stats");return i.info(`
208
+ `),process.exit(c.DRY_RUN_OK)),Ce.mkdirSync(le.join(n,"src"),{recursive:!0}),Ce.writeFileSync(le.join(n,"package.json"),Ys),Ce.writeFileSync(le.join(n,"src/index.ts"),Hs),Ce.writeFileSync(le.join(n,"README.md"),Ws),s.success("Created backends/gateway scaffold"),process.exit(c.SUCCESS)}function Hn(e){return/^[a-z][a-z0-9_-]{0,40}$/.test(e)}async function ea(e,t){let n=t.name,r=process.stdout.isTTY===!0&&!t.yes;if(!n&&r){let i=await yt.text({message:"Service name (lowercase, hyphens or underscores):",placeholder:"translator",validate:l=>Hn(l)?void 0:"Invalid name"});yt.isCancel(i)&&(s.warn("Cancelled."),process.exit(c.CANCELLED)),n=i}n||(s.error("Missing --name. Required in non-interactive mode."),process.exit(c.INVALID_ARGS)),Hn(n)||(s.error(`Invalid name: ${Wn.red(n)}. Use lowercase letters, digits, hyphen, underscore.`),process.exit(c.INVALID_ARGS));let o=le.join(e,"backends/python",n);Ce.existsSync(o)&&(s.error(`backends/python/${n} already exists \u2014 refusing to overwrite.`),process.exit(c.CONFLICT));let a=[[le.join(o,"pyproject.toml"),Js(n)],[le.join(o,"README.md"),Xs(n)],[le.join(o,"src/main.py"),Qs],[le.join(o,"src/__init__.py"),""]];t.dryRun&&(process.stdout.write(JSON.stringify({mode:"dry-run",command:`backend init py --name ${n}`,files:a.map(([i])=>i)},null,2)+`
209
+ `),process.exit(c.DRY_RUN_OK));for(let[i,l]of a)Ce.mkdirSync(le.dirname(i),{recursive:!0}),Ce.writeFileSync(i,l);s.success(`Created backends/python/${n} scaffold`),s.info("Update README.md to cite which ADR justification applies (batch | ML | specialized libs)."),process.exit(c.SUCCESS)}async function ta(e,t={}){Yn.includes(e)||(s.error(`Invalid runtime: ${Wn.red(e)}. Valid: ${Yn.join(", ")}`),process.exit(c.INVALID_ARGS));let n=h();e==="ts"?await Zs(n,t):await ea(n,t)}var Jn=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(n,r,o)=>{let a=x(r,o);await ta(n,{name:typeof r.name=="string"?r.name:void 0,dryRun:!!r.dryRun,yes:!!a.yes,quiet:!!a.quiet})})};function Vt(e,t,n){if(t==="json"){let r={command:n||"billing",...e&&typeof e=="object"&&"exitCode"in e?{exitCode:e.exitCode}:{},...e};console.log(JSON.stringify(r,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 na(e,t){return e?e.length<=8?"***":`${e.substring(0,8)}*** (${t||e.length} chars)`:"not set"}var ht={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 ra(e){s.info("Checking payment provider configuration...");let t=Object.entries(ht).map(([o,a])=>{let i=a.keyVars.every(l=>process.env[l]);return{id:o,name:a.name,configured:i,keys:a.keyVars.map(l=>({name:l,value:na(process.env[l],"key")}))}}),n=t.filter(o=>o.configured),r={providers:t,configuredCount:n.length,totalProviders:t.length,configuredList:n.map(o=>o.name)};e.dryRun||(r.configuredCount===0?s.warn("No payment providers configured. Set API keys to enable billing."):s.success(`${r.configuredCount} payment provider(s) configured`)),Vt(r,e.format,"billing:status")}async function oa(e,t){let n=Object.keys(ht);n.includes(e.toLowerCase())||(s.error(`Invalid provider: ${e}. Choose from: ${n.join(", ")}`),process.exit(c.INVALID_ARGS));let r=e.toLowerCase(),o=ht[r];s.info(`Setting up ${o.name} payment provider...`),s.info(""),s.info("Setup steps:"),s.info(`1. Go to ${o.setupUrl}`),s.info("2. Create or log in to your account"),s.info("3. Generate API credentials"),s.info("4. Add the following to .env.local:"),s.info(""),o.keyVars.forEach(i=>{s.info(` ${i}="<your_${i.toLowerCase()}>"`.padStart(45))}),s.info(""),s.info("5. (Optional) Configure webhook in provider dashboard:"),s.info(` Webhook URL: https://yourdomain.com${o.webhookUrl}`),t.dryRun||s.success(`Setup instructions for ${o.name} displayed above`);let a={provider:r,name:o.name,requiredKeys:o.keyVars,webhookUrl:o.webhookUrl,setupGuide:"Follow the instructions above to complete setup",documentationUrl:o.setupUrl};Vt(a,t.format,"billing:setup")}async function sa(e){s.info("Checking billing webhook configuration...");let t=process.env.NEXT_PUBLIC_APP_URL||"https://yourdomain.com",n=Object.entries(ht).map(([o,a])=>({provider:o,name:a.name,url:`${t}${a.webhookUrl}`,endpoint:a.webhookUrl,configured:a.keyVars.every(i=>process.env[i])})),r={baseUrl:t,webhooks:n,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||(s.info("Webhook endpoints:"),n.forEach(o=>{o.configured?s.success(`${o.name}: configured`):s.warn(`${o.name}: not configured (missing API key)`)})),Vt(r,e.format,"billing:webhooks")}function Xn(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 n=>{let r=n.optsWithGlobals?.()||n;await ra({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.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(n,r)=>{let o=r.optsWithGlobals?.()||r;await oa(n,{dryRun:r.dryRun||!1,format:r.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 n=>{let r=n.optsWithGlobals?.()||n;await sa({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.yes!==!0})})}function We(e,t,n){if(t==="json"){let r={command:n||"brand",exitCode:e.exitCode,success:e.exitCode===0,...e.stdout&&{stdout:e.stdout},...e.stderr&&{stderr:e.stderr}};console.log(JSON.stringify(r,null,2))}else e.stdout&&console.log(e.stdout),e.stderr&&e.exitCode!==0&&console.error(e.stderr)}function Qn(e){return/^#[0-9A-Fa-f]{6}$/.test(e)}async function aa(e){s.info("Initializing brand system...");let t=await z("brand:init",{dryRun:e.dryRun,interactive:e.interactive??!0});We(t,e.format,"brand:init"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||s.success("Brand system initialized successfully")}async function ia(e){s.info("Applying brand configuration...");let t=await z("brand:apply",{dryRun:e.dryRun,interactive:e.interactive??!0});We(t,e.format,"brand:apply"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||s.success("Brand applied successfully")}async function ca(e){let t=[];e.primary&&(Qn(e.primary)||(s.error(`Invalid primary color format: ${e.primary}. Expected hex format like #0033FE`),process.exit(c.INVALID_ARGS)),t.push(`--primary=${e.primary}`)),e.secondary&&(Qn(e.secondary)||(s.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&&(s.warn("No colors specified. Usage: nebutra brand palette --primary=#HEX --secondary=#HEX"),s.info("Example: nebutra brand palette --primary=#0033FE --secondary=#0BF1C3"),process.exit(c.INVALID_ARGS)),s.info(`Generating color palette: ${t.join(" ")}`);let n=await O({command:"node",args:["scripts/generate-palette.mjs",...t],dryRun:e.dryRun,interactive:e.interactive??!0,label:"Generate brand palette"});We(n,e.format,"brand:palette"),n.exitCode!==0&&process.exit(n.exitCode),e.dryRun||s.success("Color palette generated successfully")}async function la(e){s.info("Syncing brand tokens across packages...");let t=await z("brand:sync",{dryRun:e.dryRun,interactive:e.interactive??!0});We(t,e.format,"brand:sync"),t.exitCode!==0&&process.exit(t.exitCode),e.dryRun||s.success("Brand tokens synced successfully")}async function da(e){s.info("Verifying brand token consistency...");let t=await z("brand:verify-tokens",{dryRun:e.dryRun,interactive:e.interactive??!0});We(t,e.format,"brand:verify-tokens"),t.exitCode!==0&&(s.error("Brand token verification failed. There are inconsistencies in your design tokens."),process.exit(t.exitCode)),e.dryRun||s.success("All brand tokens are consistent")}function Zn(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 n=>{let r=n.optsWithGlobals?.()||n;await aa({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.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 n=>{let r=n.optsWithGlobals?.()||n;await ia({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.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 n=>{let r=n.optsWithGlobals?.()||n;await ca({primary:n.primary,secondary:n.secondary,dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.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 n=>{let r=n.optsWithGlobals?.()||n;await la({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.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 n=>{let r=n.optsWithGlobals?.()||n;await da({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.yes!==!0})})}import be from"picocolors";var ua=process.env.NEBUTRA_API_URL||"http://localhost:3001/api";function ee(e){return Array.isArray(e)?e.map(t=>t&&typeof t=="object"&&!Array.isArray(t)?t:{}):[]}function ma(e){if(!e||typeof e!="object"||Array.isArray(e))return{};let t={};for(let[n,r]of Object.entries(e))typeof r=="number"&&(t[n]=r);return t}async function j(e,t={}){let n=`${ua}${e}`,r=await fetch(n,{...t,headers:{"Content-Type":"application/json",Authorization:`Bearer ${process.env.NEBUTRA_ADMIN_TOKEN||""}`,...t.headers}});if(!r.ok){let a=await r.text().catch(()=>r.statusText);throw new Error(`API Error (${r.status}): ${a}`)}let o=await r.json();return o&&typeof o=="object"&&!Array.isArray(o)?o:{value:o}}function pa(e){let t={dau_retention:.25,engagement_rate:.25,content_velocity:.2,response_time:.15,member_retention:.15},n={},r=0;for(let[o,a]of Object.entries(t)){let i=Math.min(100,(e[o]||0)*100);n[o]=i,r+=i*a}return{score:Math.round(r),breakdown:n}}async function fa(e){try{s.info("Fetching showcase submissions...");let t=new URLSearchParams;e.status&&t.append("status",e.status),e.category&&t.append("category",e.category);let n=await j(`/community/showcase?${t.toString()}`);if(ee(n.submissions).length===0)return s.warn("No showcase submissions found"),c.SUCCESS;s.info(`
210
+ Showcase Submissions (${ee(n.submissions).length})
211
+ `);for(let r of ee(n.submissions));return c.SUCCESS}catch(t){return s.error(`Failed to list showcase: ${t.message}`),c.ERROR}}async function ga(e,t){try{if(!t.yes)return s.warn(`Approve showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;s.info(`Approving showcase submission ${e}...`);let n=await j(`/community/showcase/${e}/approve`,{method:"POST"});return s.success(`Approved: ${n.title}`),c.SUCCESS}catch(n){return s.error(`Failed to approve showcase: ${n.message}`),c.ERROR}}async function ya(e,t){try{if(!t.yes)return s.warn(`Reject showcase submission ${e}? Use --yes to confirm`),c.SUCCESS;let n=t.reason||"Does not meet guidelines";s.info(`Rejecting showcase submission ${e}...`);let r=await j(`/community/showcase/${e}/reject`,{method:"POST",body:JSON.stringify({reason:n})});return s.success(`Rejected: ${r.title}`),c.SUCCESS}catch(n){return s.error(`Failed to reject showcase: ${n.message}`),c.ERROR}}async function ha(e,t){try{if(!t.yes)return s.warn(`Mark showcase as featured: ${e}? Use --yes to confirm`),c.SUCCESS;s.info(`Featuring showcase submission ${e}...`);let n=await j(`/community/showcase/${e}/feature`,{method:"POST"});return s.success(`Featured: ${n.title}`),c.SUCCESS}catch(n){return s.error(`Failed to feature showcase: ${n.message}`),c.ERROR}}async function ba(e){try{s.info("Fetching showcase statistics...");let t=await j("/community/showcase/stats");return s.info(`
212
212
  Showcase Statistics
213
- `),c.SUCCESS}catch(t){return i.error(`Failed to fetch showcase stats: ${t.message}`),c.ERROR}}async function sa(e){try{i.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 j(`/community/content?${t.toString()}`);if(!r.items||r.items.length===0)return i.warn("No content found"),c.SUCCESS;i.info(`
214
- Community Content (${r.items.length})
215
- `);for(let n of r.items);return c.SUCCESS}catch(t){return i.error(`Failed to list content: ${t.message}`),c.ERROR}}async function ca(e,t){try{let r=["approve","flag","archive","delete"];if(!r.includes(t.action))return i.error(`Invalid action. Must be one of: ${r.join(", ")}`),c.ERROR;if(!t.yes)return i.warn(`${t.action} content ${e}? Use --yes to confirm`),c.SUCCESS;i.info(`Moderating content ${e} (${t.action})...`);let n=await j(`/community/content/${e}/moderate`,{method:"POST",body:JSON.stringify({action:t.action})});return i.success(`Content ${t.action}d: ${n.title}`),c.SUCCESS}catch(r){return i.error(`Failed to moderate content: ${r.message}`),c.ERROR}}async function la(e,t){try{if(!t.yes)return i.warn(`Publish content ${e}? Use --yes to confirm`),c.SUCCESS;i.info(`Publishing content ${e}...`);let r=await j(`/community/content/${e}/publish`,{method:"POST"});return i.success(`Published: ${r.title}`),c.SUCCESS}catch(r){return i.error(`Failed to publish content: ${r.message}`),c.ERROR}}async function da(e){try{i.info("Fetching content analytics...");let t=await j("/community/content/analytics");i.info(`
213
+ `),c.SUCCESS}catch(t){return s.error(`Failed to fetch showcase stats: ${t.message}`),c.ERROR}}async function va(e){try{s.info("Fetching community content...");let t=new URLSearchParams;e.status&&t.append("status",e.status),e.type&&t.append("type",e.type);let n=await j(`/community/content?${t.toString()}`);if(ee(n.items).length===0)return s.warn("No content found"),c.SUCCESS;s.info(`
214
+ Community Content (${ee(n.items).length})
215
+ `);for(let r of ee(n.items));return c.SUCCESS}catch(t){return s.error(`Failed to list content: ${t.message}`),c.ERROR}}async function wa(e,t){try{let n=["approve","flag","archive","delete"];if(!t.action||!n.includes(t.action))return s.error(`Invalid action. Must be one of: ${n.join(", ")}`),c.ERROR;if(!t.yes)return s.warn(`${t.action} content ${e}? Use --yes to confirm`),c.SUCCESS;s.info(`Moderating content ${e} (${t.action})...`);let r=await j(`/community/content/${e}/moderate`,{method:"POST",body:JSON.stringify({action:t.action})});return s.success(`Content ${t.action}d: ${r.title}`),c.SUCCESS}catch(n){return s.error(`Failed to moderate content: ${n.message}`),c.ERROR}}async function Ra(e,t){try{if(!t.yes)return s.warn(`Publish content ${e}? Use --yes to confirm`),c.SUCCESS;s.info(`Publishing content ${e}...`);let n=await j(`/community/content/${e}/publish`,{method:"POST"});return s.success(`Published: ${n.title}`),c.SUCCESS}catch(n){return s.error(`Failed to publish content: ${n.message}`),c.ERROR}}async function Sa(e){try{s.info("Fetching content analytics...");let t=await j("/community/content/analytics");s.info(`
216
216
  Content Performance Metrics
217
- `);for(let r of t.topContent.slice(0,5));return e.format,c.SUCCESS}catch(t){return i.error(`Failed to fetch analytics: ${t.message}`),c.ERROR}}async function ua(e){try{i.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 j(`/community/members?${t.toString()}`);if(!r.members||r.members.length===0)return i.warn("No members found"),c.SUCCESS;i.info(`
218
- Community Members (${r.members.length})
219
- `);for(let n of r.members){let a={owner:pe.red,admin:pe.yellow,moderator:pe.blue,member:pe.gray}[String(n.role)]??pe.gray}return c.SUCCESS}catch(t){return i.error(`Failed to list members: ${t.message}`),c.ERROR}}async function ma(e,t){try{i.info(`Fetching profile for ${e}...`);let r=await j(`/community/members/${e}`);return i.info(`
217
+ `);for(let n of ee(t.topContent).slice(0,5));return e.format,c.SUCCESS}catch(t){return s.error(`Failed to fetch analytics: ${t.message}`),c.ERROR}}async function Ca(e){try{s.info("Fetching community members...");let t=new URLSearchParams;e.role&&t.append("role",e.role),e.sort&&t.append("sort",e.sort);let n=await j(`/community/members?${t.toString()}`);if(ee(n.members).length===0)return s.warn("No members found"),c.SUCCESS;s.info(`
218
+ Community Members (${ee(n.members).length})
219
+ `);for(let r of ee(n.members)){let a={owner:be.red,admin:be.yellow,moderator:be.blue,member:be.gray}[String(r.role)]??be.gray}return c.SUCCESS}catch(t){return s.error(`Failed to list members: ${t.message}`),c.ERROR}}async function Ea(e,t){try{s.info(`Fetching profile for ${e}...`);let n=await j(`/community/members/${e}`);return s.info(`
220
220
  Member Profile
221
- `),c.SUCCESS}catch(r){return i.error(`Failed to fetch member profile: ${r.message}`),c.ERROR}}async function pa(e,t,r){try{let n=["member","moderator","admin","owner"];if(!n.includes(t))return i.error(`Invalid role. Must be one of: ${n.join(", ")}`),c.ERROR;if(!r.yes)return i.warn(`Change ${e} role to ${t}? Use --yes to confirm`),c.SUCCESS;i.info("Updating member role...");let o=await j(`/community/members/${e}/role`,{method:"POST",body:JSON.stringify({role:t})});return i.success(`Updated ${o.name} \u2192 ${pe.bold(t)}`),c.SUCCESS}catch(n){return i.error(`Failed to update member role: ${n.message}`),c.ERROR}}async function fa(e,t){try{i.info(`Sending invite to ${e}...`);let r=await j("/community/members/invite",{method:"POST",body:JSON.stringify({email:e})});return i.success(`Invite sent to ${e}`),c.SUCCESS}catch(r){return i.error(`Failed to send invite: ${r.message}`),c.ERROR}}async function ga(e,t){try{if(!t.yes)return i.warn(`Ban member ${e}? Use --yes to confirm`),c.SUCCESS;let r=t.reason||"Violation of community guidelines";i.info(`Banning member ${e}...`);let n=await j(`/community/members/${e}/ban`,{method:"POST",body:JSON.stringify({reason:r})});return i.success(`Banned: ${n.name}`),c.SUCCESS}catch(r){return i.error(`Failed to ban member: ${r.message}`),c.ERROR}}async function ya(e){try{i.info("Computing community health score...");let t=e.period||"30d",r=await j(`/community/health?period=${t}`),{score:n,breakdown:o}=ta(r.metrics);i.info(`
222
- Community Health Report (${t})
223
- `);for(let[a,s]of Object.entries(o)){let l=a.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 i.error(`Failed to compute health: ${t.message}`),c.ERROR}}async function ha(e){try{i.info("Fetching moderation queue...");let t=await j("/community/moderation/queue");if(!t.items||t.items.length===0)return i.success("No pending moderation items"),c.SUCCESS;i.info(`
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 i.error(`Failed to fetch queue: ${t.message}`),c.ERROR}}async function ba(e){try{i.info("Running AI-assisted moderation sweep..."),e.dryRun&&i.warn("DRY RUN MODE - no changes will be made");let t=await j("/community/moderation/auto",{method:"POST",body:JSON.stringify({dryRun:e.dryRun||!1})});return i.info(`
221
+ `),c.SUCCESS}catch(n){return s.error(`Failed to fetch member profile: ${n.message}`),c.ERROR}}async function ka(e,t,n){try{let r=["member","moderator","admin","owner"];if(!r.includes(t))return s.error(`Invalid role. Must be one of: ${r.join(", ")}`),c.ERROR;if(!n.yes)return s.warn(`Change ${e} role to ${t}? Use --yes to confirm`),c.SUCCESS;s.info("Updating member role...");let o=await j(`/community/members/${e}/role`,{method:"POST",body:JSON.stringify({role:t})});return s.success(`Updated ${o.name} \u2192 ${be.bold(t)}`),c.SUCCESS}catch(r){return s.error(`Failed to update member role: ${r.message}`),c.ERROR}}async function xa(e,t){try{s.info(`Sending invite to ${e}...`);let n=await j("/community/members/invite",{method:"POST",body:JSON.stringify({email:e})});return s.success(`Invite sent to ${e}`),c.SUCCESS}catch(n){return s.error(`Failed to send invite: ${n.message}`),c.ERROR}}async function Oa(e,t){try{if(!t.yes)return s.warn(`Ban member ${e}? Use --yes to confirm`),c.SUCCESS;let n=t.reason||"Violation of community guidelines";s.info(`Banning member ${e}...`);let r=await j(`/community/members/${e}/ban`,{method:"POST",body:JSON.stringify({reason:n})});return s.success(`Banned: ${r.name}`),c.SUCCESS}catch(n){return s.error(`Failed to ban member: ${n.message}`),c.ERROR}}async function Aa(e){try{s.info("Computing community health score...");let t=e.period||"30d",n=await j(`/community/health?period=${t}`),{score:r,breakdown:o}=pa(ma(n.metrics));s.info(`
222
+ Community Health Report (${t}) \u2014 score ${r}
223
+ `);for(let[a,i]of Object.entries(o)){let l=a.replace(/_/g," ").toLowerCase(),u="\u2588".repeat(Math.round(i/5))+"\u2591".repeat(20-Math.round(i/5));s.info(` ${l.padEnd(24)} ${String(i).padStart(3)} ${u}`)}return e.format,c.SUCCESS}catch(t){return s.error(`Failed to compute health: ${t.message}`),c.ERROR}}async function _a(e){try{s.info("Fetching moderation queue...");let t=await j("/community/moderation/queue");if(ee(t.items).length===0)return s.success("No pending moderation items"),c.SUCCESS;s.info(`
224
+ Moderation Queue (${ee(t.items).length} pending)
225
+ `);for(let n of ee(t.items)){let o={low:be.gray("\u25CF"),medium:be.yellow("\u25CF"),high:be.red("\u25CF")}[String(n.severity)]??"\u25CF"}return c.SUCCESS}catch(t){return s.error(`Failed to fetch queue: ${t.message}`),c.ERROR}}async function Pa(e){try{s.info("Running AI-assisted moderation sweep..."),e.dryRun&&s.warn("DRY RUN MODE - no changes will be made");let t=await j("/community/moderation/auto",{method:"POST",body:JSON.stringify({dryRun:e.dryRun||!1})});return s.info(`
226
226
  Moderation Results
227
- `),e.dryRun?i.info("DRY RUN COMPLETE - no changes committed"):i.success("Moderation sweep complete"),c.SUCCESS}catch(t){return i.error(`Failed to run moderation: ${t.message}`),c.ERROR}}function Gr(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=>ra(s).then(process.exit)),r.command("approve <id>").description("Approve a showcase submission").option("--yes","Skip confirmation").action((s,l)=>na(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)=>oa(s,l).then(process.exit)),r.command("feature <id>").description("Mark as featured").option("--yes","Skip confirmation").action((s,l)=>ia(s,l).then(process.exit)),r.command("stats").description("Showcase engagement metrics").action(s=>aa(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=>sa(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)=>ca(s,l).then(process.exit)),n.command("publish <id>").description("Publish approved content").option("--yes","Skip confirmation").action((s,l)=>la(s,l).then(process.exit)),n.command("analytics").description("Content performance metrics").option("--format <format>","Output format (json|text)").action(s=>da(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=>ua(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)=>pa(s,l,u).then(process.exit)),o.command("invite <email>").description("Invite to community").action((s,l)=>fa(s,l).then(process.exit)),o.command("ban <userId>").description("Ban member").option("--reason <text>","Ban reason").option("--yes","Skip confirmation").action((s,l)=>ga(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=>ya(s).then(process.exit));let a=t.command("moderate").description("AI-assisted moderation queue");a.command("queue").description("Show pending moderation items").action(s=>ha(s).then(process.exit)),a.command("auto").description("Run AI moderation sweep").option("--dry-run","Preview without committing").action(s=>ba(s).then(process.exit))}import{appendFileSync as va,existsSync as wa,readFileSync as Sa,writeFileSync as Ra}from"fs";import{homedir as Ve}from"os";import{join as Ie}from"path";import*as z from"@clack/prompts";import W from"picocolors";var lt=(ce.subcommands??[]).map(e=>e.name),qr={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"},ka=["--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"],Dt=["-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"],Ea={"-p":b.pm,"--pm":b.pm,"--region":b.region,"--orm":b.orm,"--db":b.db,"--auth":b.auth,"--payment":b.payment,"--deploy":b.deploy,"--docs":b.docs,"--email":b.email,"--storage":b.storage,"--monitoring":b.monitoring,"--analytics":b.analytics,"--sms":b.sms,"--queue":b.queue,"--search":b.search,"--cache":b.cache,"--notifications":b.notifications,"--webhooks":b.webhooks,"--cms":b.cms,"--feature-flags":b.featureFlags,"--captcha":b.captcha,"--mcp":b.mcp,"--metering":b.metering,"--billing-mode":b.billingMode,"--idp":b.idp},Ca=Object.entries(Ea).map(([e,t])=>` ${e})
227
+ `),e.dryRun?s.info("DRY RUN COMPLETE - no changes committed"):s.success("Moderation sweep complete"),c.SUCCESS}catch(t){return s.error(`Failed to run moderation: ${t.message}`),c.ERROR}}function er(e){let t=e.command("community").description("Manage Nebutra-Sailor community dimension"),n=t.command("showcase").description("Project showcase management");n.command("list").description("List submitted projects").option("--status <status>","Filter by status (pending|approved|rejected|featured)").option("--category <category>","Filter by category").action(i=>fa(i).then(process.exit)),n.command("approve <id>").description("Approve a showcase submission").option("--yes","Skip confirmation").action((i,l)=>ga(i,l).then(process.exit)),n.command("reject <id>").description("Reject a showcase submission").option("--reason <text>","Rejection reason").option("--yes","Skip confirmation").action((i,l)=>ya(i,l).then(process.exit)),n.command("feature <id>").description("Mark as featured").option("--yes","Skip confirmation").action((i,l)=>ha(i,l).then(process.exit)),n.command("stats").description("Showcase engagement metrics").action(i=>ba(i).then(process.exit));let r=t.command("content").description("Content moderation pipeline");r.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(i=>va(i).then(process.exit)),r.command("moderate <id>").description("Moderate content").option("--action <action>","Action (approve|flag|archive|delete)").option("--yes","Skip confirmation").action((i,l)=>wa(i,l).then(process.exit)),r.command("publish <id>").description("Publish approved content").option("--yes","Skip confirmation").action((i,l)=>Ra(i,l).then(process.exit)),r.command("analytics").description("Content performance metrics").option("--format <format>","Output format (json|text)").action(i=>Sa(i).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(i=>Ca(i).then(process.exit)),o.command("profile <userId>").description("View member profile + activity").action((i,l)=>Ea(i,l).then(process.exit)),o.command("role <userId> <role>").description("Update member role").option("--yes","Skip confirmation").action((i,l,u)=>ka(i,l,u).then(process.exit)),o.command("invite <email>").description("Invite to community").action((i,l)=>xa(i,l).then(process.exit)),o.command("ban <userId>").description("Ban member").option("--reason <text>","Ban reason").option("--yes","Skip confirmation").action((i,l)=>Oa(i,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(i=>Aa(i).then(process.exit));let a=t.command("moderate").description("AI-assisted moderation queue");a.command("queue").description("Show pending moderation items").action(i=>_a(i).then(process.exit)),a.command("auto").description("Run AI moderation sweep").option("--dry-run","Preview without committing").action(i=>Pa(i).then(process.exit))}import{appendFileSync as Ia,existsSync as $a,readFileSync as Na,writeFileSync as Ta}from"fs";import{homedir as Je}from"os";import{join as Me}from"path";import*as W from"@clack/prompts";import H from"picocolors";var bt=(pe.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"},Ua=["--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"],qt=["-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"],ja={"-p":b.pm,"--pm":b.pm,"--region":b.region,"--orm":b.orm,"--db":b.db,"--auth":b.auth,"--payment":b.payment,"--deploy":b.deploy,"--docs":b.docs,"--email":b.email,"--storage":b.storage,"--monitoring":b.monitoring,"--analytics":b.analytics,"--sms":b.sms,"--queue":b.queue,"--search":b.search,"--cache":b.cache,"--notifications":b.notifications,"--webhooks":b.webhooks,"--cms":b.cms,"--feature-flags":b.featureFlags,"--captcha":b.captcha,"--mcp":b.mcp,"--metering":b.metering,"--billing-mode":b.billingMode,"--idp":b.idp},La=Object.entries(ja).map(([e,t])=>` ${e})
228
228
  COMPREPLY=( $(compgen -W "${t.join(" ")}" -- \${cur}) )
229
229
  return 0
230
230
  ;;`).join(`
231
- `),Aa=Dt.map(e=>` "${e}"`).join(`
232
- `),xa=lt.map(e=>`complete -c nebutra -n "__fish_use_subcommand_only" -f -a "${e}" -d "${qr[e]}"`).join(`
233
- `),Oa=Dt.map(e=>`complete -c nebutra -n "__fish_seen_subcommand_from create" -f -a "${e}" -d "create-sailor option"`).join(`
234
- `);function Kr(){return`#!/usr/bin/env bash
231
+ `),Da=qt.map(e=>` "${e}"`).join(`
232
+ `),Fa=bt.map(e=>`complete -c nebutra -n "__fish_use_subcommand_only" -f -a "${e}" -d "${tr[e]}"`).join(`
233
+ `),Ba=qt.map(e=>`complete -c nebutra -n "__fish_seen_subcommand_from create" -f -a "${e}" -d "create-sailor option"`).join(`
234
+ `);function nr(){return`#!/usr/bin/env bash
235
235
 
236
236
  _nebutra_completions() {
237
237
  local cur prev opts cmd
@@ -240,13 +240,13 @@ _nebutra_completions() {
240
240
  prev="\${COMP_WORDS[COMP_CWORD-1]}"
241
241
 
242
242
  # Subcommands
243
- local subcommands="${lt.join(" ")}"
243
+ local subcommands="${bt.join(" ")}"
244
244
 
245
245
  # Flags
246
- local flags="${ka.join(" ")}"
246
+ local flags="${Ua.join(" ")}"
247
247
 
248
248
  case "\${prev}" in
249
- ${Ca}
249
+ ${La}
250
250
  esac
251
251
 
252
252
  if [[ \${cur} == -* ]]; then
@@ -260,7 +260,7 @@ ${Ca}
260
260
  COMPREPLY=( $(compgen -W "--21st --v0 --provider --dry-run --yes --if-not-exists" -- \${cur}) )
261
261
  elif [[ "\${prev}" == "create" ]]; then
262
262
  # create delegates to create-sailor
263
- COMPREPLY=( $(compgen -W "${Dt.join(" ")}" -- \${cur}) )
263
+ COMPREPLY=( $(compgen -W "${qt.join(" ")}" -- \${cur}) )
264
264
  elif [[ "\${prev}" == "completions" ]]; then
265
265
  # completions command takes shell type
266
266
  COMPREPLY=( $(compgen -W "bash zsh fish install" -- \${cur}) )
@@ -270,11 +270,11 @@ ${Ca}
270
270
  }
271
271
 
272
272
  complete -o bashdefault -o default -o nospace -F _nebutra_completions nebutra
273
- `}function Wr(){return`#compdef nebutra
273
+ `}function rr(){return`#compdef nebutra
274
274
 
275
275
  _nebutra() {
276
276
  local -a commands=(
277
- ${lt.map(e=>`"${e}:${qr[e]}"`).join(`
277
+ ${bt.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
- ${Aa}
294
+ ${Da}
295
295
  )
296
296
 
297
297
  local -a mcp_flags=(
@@ -332,12 +332,12 @@ ${Aa}
332
332
  }
333
333
 
334
334
  _nebutra
335
- `}function zr(){return`# Fish shell completions for nebutra
335
+ `}function or(){return`# Fish shell completions for nebutra
336
336
 
337
- complete -c nebutra -f -n "__fish_seen_subcommand_from; and not __fish_seen_subcommand_from ${lt.join(" ")}" -d "Nebutra governance CLI"
337
+ complete -c nebutra -f -n "__fish_seen_subcommand_from; and not __fish_seen_subcommand_from ${bt.join(" ")}" -d "Nebutra governance CLI"
338
338
 
339
339
  # Subcommands
340
- ${xa}
340
+ ${Fa}
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
- ${Oa}
352
+ ${Ba}
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 Yr(e){let r={bash:Kr,zsh:Wr,fish:zr}[e.toLowerCase()];r||(console.error(W.red(`Error: Unknown shell '${e}'. Supported: bash, zsh, fish`)),process.exit(c.INVALID_ARGS)),console.log(r())}async function _a(){let t=(process.env.SHELL||"/bin/bash").split("/").pop()||"bash";z.intro(W.bgCyan(W.black(" nebutra completions install ")));let r=z.spinner();r.start(W.cyan(`Detecting shell: ${t}...`));try{let n=null,o=null,a=null;if(t==="bash"?(n=Ie(Ve(),".bashrc"),o=Ie(Ve(),".bash_completion.d"),a="source ~/.bash_completion.d/nebutra"):t==="zsh"?(n=Ie(Ve(),".zshrc"),o=Ie(Ve(),".zsh/completions"),a="fpath=(~/.zsh/completions $fpath)"):t==="fish"?(o=Ie(Ve(),".config/fish/completions"),a="# Completions installed to ~/.config/fish/completions/nebutra.fish"):(r.stop(),z.log.warn(W.yellow(`Warning: Unsupported shell '${t}'. Please install completions manually.`)),Yr("bash"),z.outro(W.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"?Kr():t==="zsh"?Wr():zr();Ra(l,u),r.stop(W.green(`Completion script installed to ${l}`))}n&&a&&t!=="fish"&&(!wa(n)||!Sa(n,"utf8").includes("nebutra"))&&(va(n,(t==="bash"?`
367
+ `}function sr(e){let n={bash:nr,zsh:rr,fish:or}[e.toLowerCase()];n||(console.error(H.red(`Error: Unknown shell '${e}'. Supported: bash, zsh, fish`)),process.exit(c.INVALID_ARGS)),console.log(n())}async function Ma(){let t=(process.env.SHELL||"/bin/bash").split("/").pop()||"bash";W.intro(H.bgCyan(H.black(" nebutra completions install ")));let n=W.spinner();n.start(H.cyan(`Detecting shell: ${t}...`));try{let r=null,o=null,a=null;if(t==="bash"?(r=Me(Je(),".bashrc"),o=Me(Je(),".bash_completion.d"),a="source ~/.bash_completion.d/nebutra"):t==="zsh"?(r=Me(Je(),".zshrc"),o=Me(Je(),".zsh/completions"),a="fpath=(~/.zsh/completions $fpath)"):t==="fish"?(o=Me(Je(),".config/fish/completions"),a="# Completions installed to ~/.config/fish/completions/nebutra.fish"):(n.stop(),W.log.warn(H.yellow(`Warning: Unsupported shell '${t}'. Please install completions manually.`)),sr("bash"),W.outro(H.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=Me(o,t==="fish"?"nebutra.fish":"nebutra"),u=t==="bash"?nr():t==="zsh"?rr():or();Ta(l,u),n.stop(H.green(`Completion script installed to ${l}`))}r&&a&&t!=="fish"&&(!$a(r)||!Na(r,"utf8").includes("nebutra"))&&(Ia(r,(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
- `),z.log.info(W.green(`Added nebutra completions to ${n}`))),z.log.info(W.cyan("Completions installed! Restart your shell or run:")),z.log.info(W.dim(` source "${t==="bash"?"~/.bashrc":"~/.zshrc"}"`)),z.outro(W.green("Installation complete!"))}catch(n){r.stop(),z.log.error(W.red("Error installing completions. You can manually add them by running:")),z.log.info(W.cyan(` nebutra completions ${t} >> ~/.${t}rc`)),n instanceof Error&&console.error(W.dim(n.message)),process.exit(c.ERROR)}}function Hr(e){e.command("completions [shell]").description("Generate or install shell completions").action(async t=>{!t||t==="install"?await _a():Yr(t)})}import{spawn as Pa}from"child_process";import{dirname as Ta,resolve as $a}from"path";import{fileURLToPath as Ia}from"url";import*as ve from"@clack/prompts";import Me from"picocolors";var Na=Ta(Ia(import.meta.url));function ja(){let e=[()=>$a(Na,"../../../create-sailor/dist/index.js")];for(let t of e)try{return t()}catch(r){i.debug("create-sailor binary resolution strategy failed",{error:r})}return"create-sailor"}function Jr(e){e.command("create [dir]").description("Scaffold a new Nebutra-Sailor project").allowUnknownOption(!0).action(async(t,r,n)=>{ve.intro(Me.bgCyan(Me.black(" nebutra create ")));try{let o=ja(),a=t?[t]:[];if(n.args&&n.args.length>(t?1:0)){let u=n.args.slice(t?1:0);a.push(...u)}let s=ve.spinner();s.start(Me.cyan(`Launching create-sailor${t?` in ${t}`:""}...`));let l=Pa(process.execPath,[o,...a],{stdio:"inherit",env:{...process.env}});l.on("close",u=>{s.stop(),u===0&&ve.outro(Me.green("Project created successfully! Run 'npm install && npm run dev' to get started.")),process.exit(u??0)}),l.on("error",u=>{s.stop(),i.error(`
374
- Failed to launch create-sailor: ${u.message}`),u.code==="ENOENT"&&(i.warn(`
375
- Tip: Ensure create-sailor is installed or available in your PATH.`),i.info(" Install globally: npm install -g create-sailor"),process.exit(c.NOT_FOUND)),process.exit(c.ERROR)})}catch(o){ve.log.error(Me.red("Error: Unable to start create-sailor. Ensure it is properly installed.")),o instanceof Error&&i.error(o.message),process.exit(c.ERROR)}})}import*as dt from"@clack/prompts";async function Ua(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 Ft(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 La(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 Da(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 Fa(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 Va(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let n=await dt.confirm({message:"Reset database? This will delete all data.",initialValue:!1});(dt.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 Ma(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 Xr(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 a=o.optsWithGlobals?.(),s={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format};try{switch(r){case"generate":await Ua(s);break;case"migrate":n.length>0?n[0]==="create"&&n[1]?await Ft(n[1],s):await Ft(n[0],s):await Ft(void 0,s);break;case"push":await La(s);break;case"seed":await Da(s);break;case"studio":await Fa(s);break;case"reset":await Va(s);break;case"status":await Ma(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",`
373
+ `),W.log.info(H.green(`Added nebutra completions to ${r}`))),W.log.info(H.cyan("Completions installed! Restart your shell or run:")),W.log.info(H.dim(` source "${t==="bash"?"~/.bashrc":"~/.zshrc"}"`)),W.outro(H.green("Installation complete!"))}catch(r){n.stop(),W.log.error(H.red("Error installing completions. You can manually add them by running:")),W.log.info(H.cyan(` nebutra completions ${t} >> ~/.${t}rc`)),r instanceof Error&&console.error(H.dim(r.message)),process.exit(c.ERROR)}}function ar(e){e.command("completions [shell]").description("Generate or install shell completions").action(async t=>{!t||t==="install"?await Ma():sr(t)})}import{spawn as Ga}from"child_process";import{dirname as Ka,resolve as Va}from"path";import{fileURLToPath as qa}from"url";import*as Ee from"@clack/prompts";import Xe from"picocolors";var za=Ka(qa(import.meta.url));function Ya(){let e=[()=>Va(za,"../../../create-sailor/dist/index.js")];for(let t of e)try{return t()}catch(n){s.debug("create-sailor binary resolution strategy failed",{error:n})}return"create-sailor"}function ir(e){e.command("create [dir]").description("Scaffold a new Nebutra-Sailor project").allowUnknownOption(!0).action(async(t,n,r)=>{Ee.intro(Xe.bgCyan(Xe.black(" nebutra create ")));try{let o=Ya(),a=t?[t]:[];if(r.args&&r.args.length>(t?1:0)){let u=r.args.slice(t?1:0);a.push(...u)}let i=Ee.spinner();i.start(Xe.cyan(`Launching create-sailor${t?` in ${t}`:""}...`));let l=Ga(process.execPath,[o,...a],{stdio:"inherit",env:{...process.env}});l.on("close",u=>{i.stop(),u===0&&Ee.outro(Xe.green("Project created successfully! Run 'npm install && npm run dev' to get started.")),process.exit(u??0)}),l.on("error",u=>{i.stop(),s.error(`
374
+ Failed to launch create-sailor: ${u.message}`),u.code==="ENOENT"&&(s.warn(`
375
+ Tip: Ensure create-sailor is installed or available in your PATH.`),s.info(" Install globally: npm install -g create-sailor"),process.exit(c.NOT_FOUND)),process.exit(c.ERROR)})}catch(o){Ee.log.error(Xe.red("Error: Unable to start create-sailor. Ensure it is properly installed.")),o instanceof Error&&s.error(o.message),process.exit(c.ERROR)}})}import*as vt from"@clack/prompts";async function Ha(e){d("Generating Prisma client"+"...","info");let n=await he("generate",{dryRun:e.dryRun,interactive:!e.dryRun});n.exitCode===0?d("Prisma client generated successfully","success"):(d("Failed to generate Prisma client","error"),process.exit(n.exitCode||1))}async function zt(e,t){let n=t||{};if(e){d(`Creating migration: ${e}`,"info");let r=await he("migrate",{args:["dev","--name",e],dryRun:n.dryRun,interactive:!n.dryRun});r.exitCode===0?d(`Migration '${e}' created successfully`,"success"):(d(`Failed to create migration '${e}'`,"error"),process.exit(r.exitCode||1))}else{d("Running pending migrations...","info");let r=await he("migrate",{args:["deploy"],dryRun:n.dryRun,interactive:!n.dryRun});r.exitCode===0?d("All pending migrations completed","success"):(d("Migration deployment failed","error"),process.exit(r.exitCode||1))}}async function Wa(e){d("Pushing schema to database...","info");let t=await he("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 Ja(e){d("Seeding database...","info");let t=await he("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 Xa(e){d("Launching Prisma Studio...","info");let t=await he("studio",{dryRun:e.dryRun,interactive:!0});t.exitCode!==0&&(d("Failed to launch Prisma Studio","error"),process.exit(t.exitCode||1))}async function Qa(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let r=await vt.confirm({message:"Reset database? This will delete all data.",initialValue:!1});(vt.isCancel(r)||!r)&&(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 n=await he("migrate",{args:["reset",...e.yes?["--force"]:[]],dryRun:e.dryRun,interactive:!e.dryRun});n.exitCode===0?d("Database reset successfully","success"):(d("Failed to reset database","error"),process.exit(n.exitCode||1))}async function Za(e){d("Checking migration status...","info");let t=await he("migrate",{args:["status"],dryRun:e.dryRun,interactive:!e.dryRun});if(t.exitCode===0){if(e.format==="json")try{let n=JSON.parse(t.stdout);process.stdout.write(JSON.stringify(n,null,2)+`
376
+ `)}catch{process.stdout.write(t.stdout)}}else d("Failed to check migration status","error"),process.exit(t.exitCode||1)}function cr(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(n,r,o)=>{let a=o.optsWithGlobals?.(),i={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format};try{switch(n){case"generate":await Ha(i);break;case"migrate":r.length>0?r[0]==="create"&&r[1]?await zt(r[1],i):await zt(r[0],i):await zt(void 0,i);break;case"push":await Wa(i);break;case"seed":await Ja(i);break;case"studio":await Xa(i);break;case"reset":await Qa(i);break;case"status":await Za(i);break;default:d(`Unknown db subcommand: ${n}. 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"),k("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
@@ -388,53 +388,53 @@ Flags:
388
388
  --dry-run Show what would be run without executing
389
389
  --yes Skip confirmations
390
390
  --format <type> Output format: json, plain (default: plain)
391
- `)}import*as _ from"@clack/prompts";import E from"picocolors";var Ne=["landing-page","web","storybook","design-docs","sailor-docs","studio","docs","idp","mail-preview","gateway"];function ut(e){let t=`@nebutra/${e}`;if(!Ne.includes(e)){let r=E.yellow(`Valid apps: ${Ne.join(", ")}`);throw new Error(`Invalid app: ${E.red(e)}
392
- ${r}`)}return t}async function Ba(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){ut(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 Ga(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){ut(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 qa(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){ut(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 Ka(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){ut(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 Qr(e){e.command("dev").description("Start development servers (turbo dev)").option("--app <name>",`App to run: ${Ne.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await Ba({...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: ${Ne.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 Ga({...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: ${Ne.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 qa({...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: ${Ne.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async t=>{let r=t.optsWithGlobals?t.optsWithGlobals():t;await Ka({...t,quiet:r.quiet||!1,verbose:r.verbose||!1,format:r.format})})}import Zr from"fs";import en from"path";import Vt from"picocolors";var Mt=["smoke","golden","sleptons"],Wa={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 za(e,t={}){Mt.includes(e)||(i.error(`Invalid suite: ${Vt.red(e)}. Valid: ${Mt.join(", ")}`),process.exit(c.INVALID_ARGS));let r=h(),{config:n,suiteDir:o}=Wa[e],a=en.join(r,n),s=en.join(r,o);(!Zr.existsSync(s)||!Zr.existsSync(a))&&(i.error(`Suite ${Vt.red(e)} not found at ${o}.
393
- Expected config: ${n}
391
+ `)}import*as _ from"@clack/prompts";import C from"picocolors";function ke(e){if(e==="json"||e==="plain"||e==="table")return e}var Ge=["landing","web","storybook","design-docs","sailor-docs","studio","docs","idp","mail-preview","gateway"];function wt(e){let t=`@nebutra/${e}`;if(!Ge.includes(e)){let n=C.yellow(`Valid apps: ${Ge.join(", ")}`);throw new Error(`Invalid app: ${C.red(e)}
392
+ ${n}`)}return t}async function ei(e){e.dryRun&&(A({mode:"dry-run",timestamp:new Date().toISOString(),command:"dev",options:{app:e.app},task:e.app?"turbo dev":"turbo dev (all apps)"},{format:ke(e.format)}),process.exit(c.DRY_RUN_OK));try{if(e.app){wt(e.app);let n=`@nebutra/${e.app}`;e.quiet||_.log.info(C.cyan(`Starting dev server for ${C.bold(n)}...`));let r=await we("dev",{filter:n});process.exit(r.exitCode)}e.quiet||_.log.info(C.cyan("Starting dev servers for all apps..."));let t=await we("dev");process.exit(t.exitCode)}catch(t){t instanceof Error?_.log.error(C.red(t.message)):_.log.error(C.red("Unknown error occurred")),process.exit(c.ERROR)}}async function ti(e){e.dryRun&&(A({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:ke(e.format)}),process.exit(c.DRY_RUN_OK));try{if(e.app&&e.strict&&(_.log.error(C.red("Cannot use --strict with --app filter")),process.exit(c.INVALID_ARGS)),e.app){wt(e.app);let r=`@nebutra/${e.app}`;e.quiet||_.log.info(C.cyan(`Building ${C.bold(r)}...`));let o=await we("build",{filter:r});process.exit(o.exitCode)}let t=e.strict?"build:strict":"build";if(!e.quiet){let r=e.strict?"Running strict build (with UI governance verification)...":"Building all apps...";_.log.info(C.cyan(r))}let n=await z(t,{interactive:!0});process.exit(n.exitCode)}catch(t){t instanceof Error?_.log.error(C.red(t.message)):_.log.error(C.red("Unknown error occurred")),process.exit(c.ERROR)}}async function ni(e){e.dryRun&&(A({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:ke(e.format)}),process.exit(c.DRY_RUN_OK));try{if(e.app&&e.fix&&(_.log.error(C.red("Cannot use --fix with --app filter (lint:fix is global only)")),process.exit(c.INVALID_ARGS)),e.app){wt(e.app);let r=`@nebutra/${e.app}`;e.quiet||_.log.info(C.cyan(`Linting ${C.bold(r)}...`));let o=await O({command:"turbo",args:["run","lint","--filter",r],interactive:!0,label:`turbo lint --filter ${r}`,dryRun:e.dryRun});process.exit(o.exitCode)}let t=e.fix?"lint:fix":"lint";if(!e.quiet){let r=e.fix?"Fixing linting issues...":"Linting codebase...";_.log.info(C.cyan(r))}let n=await z(t,{interactive:!0});process.exit(n.exitCode)}catch(t){t instanceof Error?_.log.error(C.red(t.message)):_.log.error(C.red("Unknown error occurred")),process.exit(c.ERROR)}}async function ri(e){e.dryRun&&(A({mode:"dry-run",timestamp:new Date().toISOString(),command:"typecheck",options:{app:e.app},task:"turbo typecheck"},{format:ke(e.format)}),process.exit(c.DRY_RUN_OK));try{if(e.app){wt(e.app);let n=`@nebutra/${e.app}`;e.quiet||_.log.info(C.cyan(`Type-checking ${C.bold(n)}...`));let r=await we("typecheck",{filter:n});process.exit(r.exitCode)}e.quiet||_.log.info(C.cyan("Type-checking all packages..."));let t=await we("typecheck");process.exit(t.exitCode)}catch(t){t instanceof Error?_.log.error(C.red(t.message)):_.log.error(C.red("Unknown error occurred")),process.exit(c.ERROR)}}var lr=e=>{e.command("dev").description("Start development servers (turbo dev)").option("--app <name>",`App to run: ${Ge.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async(t,n)=>{let r=x(t,n);await ei({app:typeof t.app=="string"?t.app:void 0,dryRun:!!t.dryRun,quiet:!!r.quiet,verbose:!!r.verbose,format:ke(r.format)})}),e.command("build").description("Build all apps (pnpm build or turbo build)").option("--app <name>",`App to build: ${Ge.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,n)=>{let r=x(t,n);await ti({app:typeof t.app=="string"?t.app:void 0,dryRun:!!t.dryRun,strict:!!t.strict,quiet:!!r.quiet,verbose:!!r.verbose,format:ke(r.format)})}),e.command("lint").description("Lint with Biome (pnpm lint or pnpm lint:fix)").option("--app <name>",`App to lint: ${Ge.join(", ")}`).option("--fix","Fix linting issues automatically").option("--dry-run","Preview what would run (exit code 10)").action(async(t,n)=>{let r=x(t,n);await ni({app:typeof t.app=="string"?t.app:void 0,dryRun:!!t.dryRun,fix:!!t.fix,quiet:!!r.quiet,verbose:!!r.verbose,format:ke(r.format)})}),e.command("typecheck").description("Type-check with TypeScript (turbo typecheck)").option("--app <name>",`App to typecheck: ${Ge.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async(t,n)=>{let r=x(t,n);await ri({app:typeof t.app=="string"?t.app:void 0,dryRun:!!t.dryRun,quiet:!!r.quiet,verbose:!!r.verbose,format:ke(r.format)})})};import dr from"fs";import ur from"path";import Yt from"picocolors";var Ht=["smoke","golden","sleptons"],oi={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 si(e,t={}){Ht.includes(e)||(s.error(`Invalid suite: ${Yt.red(e)}. Valid: ${Ht.join(", ")}`),process.exit(c.INVALID_ARGS));let n=h(),{config:r,suiteDir:o}=oi[e],a=ur.join(n,r),i=ur.join(n,o);(!dr.existsSync(i)||!dr.existsSync(a))&&(s.error(`Suite ${Yt.red(e)} not found at ${o}.
393
+ Expected config: ${r}
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||i.info(`Running Playwright suite: ${Vt.bold(e)}`);let l=await x({command:"pnpm",args:["exec","playwright","test","--config",n],interactive:!0,label:`playwright ${e}`});process.exit(l.exitCode)}function tn(e){e.command("e2e <suite>").description(`Run a Playwright suite (${Mt.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 za(t,{dryRun:r.dryRun||!1,quiet:n.quiet||!1})})}import g from"picocolors";var Ya=process.env.NEBUTRA_ECOSYSTEM_URL||"https://api.nebutra.com/ecosystem",rn=process.env.NEBUTRA_ECOSYSTEM_TOKEN||"";async function P(e,t={}){let{method:r="GET",body:n,dryRun:o=!1,token:a=rn}=t,s=`${Ya}${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"};a&&(l.Authorization=`Bearer ${a}`);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 i.error(`Ecosystem API error: ${u}`),u}}function Ha(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 Ja(e){i.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 i.error(`Failed to fetch ecosystem status: ${t}`),c.ERROR}}async function Xa(e){i.info(g.cyan(`\u{1F517} Connect to Nebutra Ecosystem
397
- `));let t=e.token||rn;!t&&!e.yes&&(i.warn(`No NEBUTRA_ECOSYSTEM_TOKEN found. Starting OAuth flow...
398
- `),i.info("Visit: "+g.blue("https://nebutra.com/oauth/authorize?scope=ecosystem")),i.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):(i.success(`\u2713 Connected to Nebutra Ecosystem
399
- `),i.info(`Project ID: ${g.cyan(o.projectId)}`),i.info(`Organization: ${g.cyan(r)}`),i.info(`Ecosystem Config: ${g.cyan(".nebutra/ecosystem.json")}
400
- `),i.info(`Next steps: Run ${g.yellow("nebutra ecosystem publish")} to share your project`),c.SUCCESS)}catch(n){return i.error(`Connection failed: ${n}`),c.ERROR}}async function Qa(e){i.info(g.cyan(`\u{1F4E4} Publish to Ecosystem Marketplace
401
- `));let t=e.tag||"latest",r=e.visibility||"public",n=Ha();i.info(`${g.bold("Pre-Publish Checklist")}
402
- `);for(let o of n.checks){let a=o.pass?g.green("\u2713"):g.red("\u2717")}if(!n.valid)return i.error(`
403
- Fix the checks above before publishing`),c.ERROR;if(r==="public"&&!e.yes&&(i.info(`This project will be ${g.yellow("publicly listed")} in the ecosystem`),i.info(`Continue? Run with ${g.yellow("--yes")} to skip confirmation`),!e.yes))return c.CANCELLED;try{let a=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):(i.success(`\u2713 Published successfully!
404
- `),i.info(`Marketplace URL: ${g.blue(`https://nebutra.com/templates/${a.projectId}`)}`),i.info(`Visibility: ${r}`),i.info(`Tag: ${t}
405
- `),c.SUCCESS)}catch(o){return i.error(`Publish failed: ${o}`),c.ERROR}}async function Za(e){i.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"||i.info(`Run ${g.yellow("nebutra ecosystem templates info <id>")} for details`),c.SUCCESS}catch(t){return i.error(`Failed to list templates: ${t}`),c.ERROR}}async function es(e,t){i.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 i.error(`Search failed: ${r}`),c.ERROR}}async function ts(e){i.info(g.cyan(`\u{1F4D6} Template Details
408
- `));try{let r=await(await P(`/templates/${e}`)).json();return i.info(`Install: ${g.yellow("nebutra ecosystem templates install multi-tenant-saas")}`),c.SUCCESS}catch(t){return i.error(`Failed to fetch template info: ${t}`),c.ERROR}}async function rs(e,t){i.info(g.cyan(`\u2B07\uFE0F Installing template "${e}"
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):(i.success(`\u2713 Template installed!
410
- `),i.info("Project: ./my-saas"),i.info(`Next: ${g.yellow("cd my-saas && pnpm install && pnpm dev")}`),c.SUCCESS)}catch(r){return i.error(`Installation failed: ${r}`),c.ERROR}}async function ns(e){i.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"||(i.info(`Vote: ${g.yellow("nebutra ecosystem ideas vote <id>")}`),i.info(`Claim: ${g.yellow("nebutra ecosystem ideas claim <id>")}`)),c.SUCCESS}catch(t){return i.error(`Failed to list ideas: ${t}`),c.ERROR}}async function os(e){if(i.info(g.cyan(`\u2728 Submit New Idea
412
- `)),!e.title||!e.description)return i.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):(i.success(`\u2713 Idea submitted!
413
- `),i.info(`Idea URL: ${g.blue(`https://nebutra.com/ideas/${r.ideaId}`)}`),i.info(`Start voting and discussing! Community will help shape it.
414
- `),c.SUCCESS)}catch(t){return i.error(`Submission failed: ${t}`),c.ERROR}}async function is(e,t){i.info(g.cyan(`\u{1F44D} Voting on idea "${e}"
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):(i.success(`\u2713 Vote recorded! This idea now has more momentum.
416
- `),c.SUCCESS)}catch(r){return i.error(`Vote failed: ${r}`),c.ERROR}}async function as(e,t){i.info(g.cyan(`\u{1F3AF} Claiming idea "${e}"
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):(i.success(`\u2713 Idea claimed! You're now working on this.
418
- `),i.info("Post updates in the comments to keep the community informed."),c.SUCCESS)}catch(r){return i.error(`Claim failed: ${r}`),c.ERROR}}async function ss(e,t){if(i.info(g.cyan(`\u{1F4AC} Adding comment to idea "${e}"
419
- `)),!t.message)return i.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):(i.success(`\u2713 Comment posted!
420
- `),c.SUCCESS)}catch(r){return i.error(`Comment failed: ${r}`),c.ERROR}}async function cs(e){i.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"||(i.info(`View profile: ${g.yellow("nebutra ecosystem opc profile <handle>")}`),i.info(`Register: ${g.yellow("nebutra ecosystem opc register")}`)),c.SUCCESS}catch(t){return i.error(`Failed to list members: ${t}`),c.ERROR}}async function ls(){i.info(g.cyan(`\u{1F464} Legacy Member Profile
422
- `));try{let t=await(await P("/opc/me")).json();return i.info(`Edit profile: ${g.yellow("nebutra ecosystem opc register")}`),c.SUCCESS}catch(e){return i.error(`Failed to load profile: ${e}`),c.ERROR}}async function ds(e){i.info(g.cyan(`\u{1F4DD} Register Legacy Member Profile
423
- `));let t={name:"Your Name",handle:"your-handle",bio:"Building amazing products",skills:["nextjs","ai","devtools"],industry:"startup"};if(e.dryRun)return i.info(`[DRY RUN] Would register profile:
424
- `),c.SUCCESS;if(!e.yes)return i.info("This will create your public legacy member profile."),i.info(`Run with ${g.yellow("--yes")} to confirm`),c.CANCELLED;try{let r=await P("/opc/register",{method:"POST",body:t});return i.success(`\u2713 Legacy member profile created!
425
- `),i.info(`View at: ${g.blue("https://nebutra.com/members/your-handle")}`),i.info(`Compatibility command: ${g.yellow("nebutra ecosystem opc profile --share")}`),c.SUCCESS}catch(r){return i.error(`Registration failed: ${r}`),c.ERROR}}async function us(e){i.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"||(i.info(`Vote: ${g.yellow("nebutra ecosystem showcase vote <id>")}`),i.info(`Submit yours: ${g.yellow("nebutra ecosystem showcase submit")}`)),c.SUCCESS}catch(t){return i.error(`Failed to list showcase: ${t}`),c.ERROR}}async function ms(e){i.info(g.cyan(`\u{1F389} Submit Project to Showcase
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 i.info("This will add your project to the public showcase."),i.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):(i.success(`\u2713 Project added to showcase!
428
- `),i.info(`View at: ${g.blue("https://nebutra.com/showcase/my-project")}`),i.info("Community can now discover your work!"),c.SUCCESS)}catch(r){return i.error(`Submission failed: ${r}`),c.ERROR}}async function ps(e,t){i.info(g.cyan(`\u{1F44D} Voting on showcase project "${e}"
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):(i.success(`\u2713 Vote recorded! You're supporting this project.
430
- `),c.SUCCESS)}catch(r){return i.error(`Vote failed: ${r}`),c.ERROR}}async function fs(e){i.info(g.cyan(`\u{1F504} Sync with Ecosystem
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?(i.info(g.green(`\u2713 [DRY RUN] Would sync (${r})
432
- `)),c.SUCCESS):(i.success(`\u2713 Synced!
433
- `),t?i.info("Downloaded: ecosystem config, stats, badges"):i.info("Uploaded: project updates, metrics"),c.SUCCESS)}catch(n){return i.error(`Sync failed: ${n}`),c.ERROR}}function nn(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 Ja(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 Xa(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 Qa(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 Za(s)}),r.command("search <query>").description("Search templates").option("--format <format>","Output format","text").action(async(s,l)=>{await es(s,l)}),r.command("info <id>").description("Template details").action(async s=>{await ts(s)}),r.command("install <id>").description("Install/fork a template").option("--dry-run","Preview without making changes").action(async(s,l)=>{await rs(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 ns(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 os(s)}),n.command("vote <id>").description("Upvote an idea").option("--dry-run","Preview without making changes").action(async(s,l)=>{await is(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 as(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 ss(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 cs(s)}),o.command("profile").description("View/edit your legacy member profile").action(async()=>{await ls()}),o.command("register").description("Register a legacy member profile").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async s=>{await ds(s)});let a=t.command("showcase").description("Project showcase");a.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 us(s)}),a.command("submit").description("Submit your project to showcase").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async s=>{await ms(s)}),a.command("vote <id>").description("Upvote a project (Product Hunt style)").option("--dry-run","Preview without making changes").action(async(s,l)=>{await ps(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 fs(s)})}import{existsSync as mt,readFileSync as on,writeFileSync as gs}from"fs";import{resolve as pt}from"path";import*as Ae from"@clack/prompts";import ys from"picocolors";function ft(e){let t=pt(e,".env.example");if(!mt(t))throw new Error(`.env.example not found at ${t}`);let r=on(t,"utf-8"),n={};for(let o of r.split(`
434
- `)){if(o.trim().startsWith("#")||!o.trim())continue;let a=o.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(a){let[,s,l]=a;n[s]=l.replace(/^["'](.*)["']$/,"$1")}}return n}function Bt(e){let t=pt(e,".env.local"),r=pt(e,".env"),n=mt(t)?t:r;if(!mt(n))return{};let o=on(n,"utf-8"),a={};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;a[u]=m.replace(/^["'](.*)["']$/,"$1")}}return a}function hs(e,t){return["SECRET","KEY","TOKEN","PASSWORD"].some(o=>e.toUpperCase().includes(o))&&t.length>0}function bs(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 vs(e){d("Validating environment variables...","info");let t=h(),r=ft(t),n=Bt(t),o=process.env,a={},s=!0;for(let l of Object.keys(r)){let u=l in n||l in o;a[l]=u,u||(s=!1)}if(e.format==="json")k({valid:s,checked:Object.keys(r).length,missing:Object.entries(a).filter(([,l])=>!l).map(([l])=>l)},{format:"json"});else{ot("Environment Validation");let l=Object.entries(a).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 ws(e){let t=h(),r=ft(t),n=pt(t,".env.local");if(mt(n)&&!e.yes&&!e.dryRun){let u=await Ae.confirm({message:".env.local already exists. Overwrite?",initialValue:!1});(Ae.isCancel(u)||!u)&&(d("Template generation cancelled","warn"),process.exit(c.CANCELLED))}d("Generating .env.local from template...","info");let o={},a=0,s=Object.keys(r).length;for(let[u,m]of Object.entries(r))if(a++,e.yes)o[u]=m;else if(process.stdin.isTTY===!0){let p=`[${a}/${s}] ${u}`,y=await Ae.text({message:p,defaultValue:m});Ae.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"})):(gs(n,l+`
437
- `),d(`Environment template written to ${n}`,"success"))}async function Ss(e){d("Comparing environment variables...","info");let t=h(),r=ft(t),n=Bt(t),o=[],a=[],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||a.push(l);if(e.format==="json")k({matching:s.length,missing:o.length,extra:a.length,missing_vars:o,extra_vars:a},{format:"json"});else{if(ot("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(a.length>0){d(`Extra (${a.length}):`,"info");for(let l of a)d(` - ${l}`,"info")}}}async function Rs(e){d("Reading environment variables...","info");let t=h(),r=Bt(t),n=ft(t),o={};for(let a of Object.keys(n))if(a in r){let s=r[a];o[a]=hs(a,s)?bs(s):s||"(empty)"}else o[a]="(not set)";if(e.format==="json"){let a={};for(let[s,l]of Object.entries(o))a[s]=l;k(a,{format:"json"})}else{ot("Current Environment Variables");let a=Object.entries(o).map(([s,l])=>({Variable:ys.cyan(s),Value:l}));k(a,{format:"table"}),d("Note: Sensitive values (KEY, TOKEN, SECRET, PASSWORD) are masked","info")}}function an(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?.(),a={dryRun:n.dryRun||o?.dryRun,yes:n.yes||o?.yes,format:n.format||o?.format};try{switch(r){case"validate":await vs(a);break;case"template":await ws(a);break;case"diff":await Ss(a);break;case"show":await Rs(a);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",`
395
+ or restore the directory from git.`),process.exit(c.NOT_FOUND)),t.dryRun&&(A({mode:"dry-run",command:`e2e ${e}`,task:`pnpm exec playwright test --config ${r}`}),process.exit(c.DRY_RUN_OK)),t.quiet||s.info(`Running Playwright suite: ${Yt.bold(e)}`);let l=await O({command:"pnpm",args:["exec","playwright","test","--config",r],interactive:!0,label:`playwright ${e}`});process.exit(l.exitCode)}var mr=e=>{e.command("e2e <suite>").description(`Run a Playwright suite (${Ht.join(" | ")})`).option("--dry-run","Preview the command that would run (exit code 10)").action(async(t,n,r)=>{let o=x(n,r);await si(t,{dryRun:!!n.dryRun,quiet:!!o.quiet})})};import g from"picocolors";var ai=process.env.NEBUTRA_ECOSYSTEM_URL||"https://api.nebutra.com/ecosystem",pr=process.env.NEBUTRA_ECOSYSTEM_TOKEN||"";async function P(e,t={}){let{method:n="GET",body:r,dryRun:o=!1,token:a=pr}=t,i=`${ai}${e}`;if(o)return d(`[DRY RUN] ${n} ${i}`),r&&d(`Body: ${JSON.stringify(r)}`),A({mode:"dry-run",method:n,url:i,...r&&{body:r}}),{ok:!0,status:200,json:async()=>({dryRun:!0})};let l={"Content-Type":"application/json"};a&&(l.Authorization=`Bearer ${a}`);try{let u=await fetch(i,{method:n,headers:l,...r&&{body:JSON.stringify(r)}});if(!u.ok){let m=await u.text();throw new Error(`${u.status}: ${m}`)}return u}catch(u){throw s.error(`Ecosystem API error: ${u}`),u}}function ii(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(r=>r.pass),checks:t}}async function ci(e){s.info(g.cyan(`\u{1F4CA} Ecosystem Status Dashboard
396
+ `));try{let n=await(await P("/status")).json();return e.format,c.SUCCESS}catch(t){return s.error(`Failed to fetch ecosystem status: ${t}`),c.ERROR}}async function li(e){s.info(g.cyan(`\u{1F517} Connect to Nebutra Ecosystem
397
+ `));let t=e.token||pr;!t&&!e.yes&&(s.warn(`No NEBUTRA_ECOSYSTEM_TOKEN found. Starting OAuth flow...
398
+ `),s.info("Visit: "+g.blue("https://nebutra.com/oauth/authorize?scope=ecosystem")),s.info("Then paste your token below:"),t="token_example_"+Math.random().toString(36).slice(2));let n=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:n},dryRun:e.dryRun,token:t})).json();return e.dryRun?(d("[DRY RUN] Would connect project to ecosystem","success"),c.SUCCESS):(s.success(`\u2713 Connected to Nebutra Ecosystem
399
+ `),s.info(`Project ID: ${g.cyan(o.projectId)}`),s.info(`Organization: ${g.cyan(n)}`),s.info(`Ecosystem Config: ${g.cyan(".nebutra/ecosystem.json")}
400
+ `),s.info(`Next steps: Run ${g.yellow("nebutra ecosystem publish")} to share your project`),c.SUCCESS)}catch(r){return s.error(`Connection failed: ${r}`),c.ERROR}}async function di(e){s.info(g.cyan(`\u{1F4E4} Publish to Ecosystem Marketplace
401
+ `));let t=e.tag||"latest",n=e.visibility||"public",r=ii();s.info(`${g.bold("Pre-Publish Checklist")}
402
+ `);for(let o of r.checks){let a=o.pass?g.green("\u2713"):g.red("\u2717")}if(!r.valid)return s.error(`
403
+ Fix the checks above before publishing`),c.ERROR;if(n==="public"&&!e.yes&&(s.info(`This project will be ${g.yellow("publicly listed")} in the ecosystem`),s.info(`Continue? Run with ${g.yellow("--yes")} to skip confirmation`),!e.yes))return c.CANCELLED;try{let a=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:n},dryRun:e.dryRun})).json();return e.dryRun?(d("[DRY RUN] Would publish to ecosystem","success"),c.SUCCESS):(s.success(`\u2713 Published successfully!
404
+ `),s.info(`Marketplace URL: ${g.blue(`https://nebutra.com/templates/${a.projectId}`)}`),s.info(`Visibility: ${n}`),s.info(`Tag: ${t}
405
+ `),c.SUCCESS)}catch(o){return s.error(`Publish failed: ${o}`),c.ERROR}}async function ui(e){s.info(g.cyan(`\u{1F4DA} Template Marketplace
406
+ `));try{let n=await(await P(`/templates?category=${e.category||""}&sort=${e.sort||"downloads"}`)).json();return e.format==="json"||s.info(`Run ${g.yellow("nebutra ecosystem templates info <id>")} for details`),c.SUCCESS}catch(t){return s.error(`Failed to list templates: ${t}`),c.ERROR}}async function mi(e,t){s.info(g.cyan(`\u{1F50D} Searching templates for "${e}"
407
+ `));try{let r=await(await P(`/templates/search?q=${encodeURIComponent(e)}`)).json();return t.format,c.SUCCESS}catch(n){return s.error(`Search failed: ${n}`),c.ERROR}}async function pi(e){s.info(g.cyan(`\u{1F4D6} Template Details
408
+ `));try{let n=await(await P(`/templates/${e}`)).json();return s.info(`Install: ${g.yellow("nebutra ecosystem templates install multi-tenant-saas")}`),c.SUCCESS}catch(t){return s.error(`Failed to fetch template info: ${t}`),c.ERROR}}async function fi(e,t){s.info(g.cyan(`\u2B07\uFE0F Installing template "${e}"
409
+ `));try{let n=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):(s.success(`\u2713 Template installed!
410
+ `),s.info("Project: ./my-saas"),s.info(`Next: ${g.yellow("cd my-saas && pnpm install && pnpm dev")}`),c.SUCCESS)}catch(n){return s.error(`Installation failed: ${n}`),c.ERROR}}async function gi(e){s.info(g.cyan(`\u{1F4A1} Ideas Marketplace
411
+ `));try{let n=await(await P(`/ideas?status=${e.status||""}&sort=${e.sort||"recent"}`)).json();return e.format==="json"||(s.info(`Vote: ${g.yellow("nebutra ecosystem ideas vote <id>")}`),s.info(`Claim: ${g.yellow("nebutra ecosystem ideas claim <id>")}`)),c.SUCCESS}catch(t){return s.error(`Failed to list ideas: ${t}`),c.ERROR}}async function yi(e){if(s.info(g.cyan(`\u2728 Submit New Idea
412
+ `)),!e.title||!e.description)return s.error("Missing required fields: --title and --description"),c.INVALID_ARGS;try{let n=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):(s.success(`\u2713 Idea submitted!
413
+ `),s.info(`Idea URL: ${g.blue(`https://nebutra.com/ideas/${n.ideaId}`)}`),s.info(`Start voting and discussing! Community will help shape it.
414
+ `),c.SUCCESS)}catch(t){return s.error(`Submission failed: ${t}`),c.ERROR}}async function hi(e,t){s.info(g.cyan(`\u{1F44D} Voting on idea "${e}"
415
+ `));try{let n=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):(s.success(`\u2713 Vote recorded! This idea now has more momentum.
416
+ `),c.SUCCESS)}catch(n){return s.error(`Vote failed: ${n}`),c.ERROR}}async function bi(e,t){s.info(g.cyan(`\u{1F3AF} Claiming idea "${e}"
417
+ `));try{let n=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):(s.success(`\u2713 Idea claimed! You're now working on this.
418
+ `),s.info("Post updates in the comments to keep the community informed."),c.SUCCESS)}catch(n){return s.error(`Claim failed: ${n}`),c.ERROR}}async function vi(e,t){if(s.info(g.cyan(`\u{1F4AC} Adding comment to idea "${e}"
419
+ `)),!t.message)return s.error("Missing --message parameter"),c.INVALID_ARGS;try{let n=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):(s.success(`\u2713 Comment posted!
420
+ `),c.SUCCESS)}catch(n){return s.error(`Comment failed: ${n}`),c.ERROR}}async function wi(e){s.info(g.cyan(`\u{1F465} Legacy Member Directory
421
+ `));try{let n=await(await P(`/opc?skill=${e.skill||""}&industry=${e.industry||""}&sort=${e.sort||"active"}`)).json();return e.format==="json"||(s.info(`View profile: ${g.yellow("nebutra ecosystem opc profile <handle>")}`),s.info(`Register: ${g.yellow("nebutra ecosystem opc register")}`)),c.SUCCESS}catch(t){return s.error(`Failed to list members: ${t}`),c.ERROR}}async function Ri(){s.info(g.cyan(`\u{1F464} Legacy Member Profile
422
+ `));try{let t=await(await P("/opc/me")).json();return s.info(`Edit profile: ${g.yellow("nebutra ecosystem opc register")}`),c.SUCCESS}catch(e){return s.error(`Failed to load profile: ${e}`),c.ERROR}}async function Si(e){s.info(g.cyan(`\u{1F4DD} Register Legacy Member Profile
423
+ `));let t={name:"Your Name",handle:"your-handle",bio:"Building amazing products",skills:["nextjs","ai","devtools"],industry:"startup"};if(e.dryRun)return s.info(`[DRY RUN] Would register profile:
424
+ `),c.SUCCESS;if(!e.yes)return s.info("This will create your public legacy member profile."),s.info(`Run with ${g.yellow("--yes")} to confirm`),c.CANCELLED;try{let n=await P("/opc/register",{method:"POST",body:t});return s.success(`\u2713 Legacy member profile created!
425
+ `),s.info(`View at: ${g.blue("https://nebutra.com/members/your-handle")}`),s.info(`Compatibility command: ${g.yellow("nebutra ecosystem opc profile --share")}`),c.SUCCESS}catch(n){return s.error(`Registration failed: ${n}`),c.ERROR}}async function Ci(e){s.info(g.cyan(`\u2B50 Project Showcase
426
+ `));try{let n=await(await P(`/showcase?category=${e.category||""}&featured=${e.featured?"true":""}`)).json();return e.format==="json"||(s.info(`Vote: ${g.yellow("nebutra ecosystem showcase vote <id>")}`),s.info(`Submit yours: ${g.yellow("nebutra ecosystem showcase submit")}`)),c.SUCCESS}catch(t){return s.error(`Failed to list showcase: ${t}`),c.ERROR}}async function Ei(e){s.info(g.cyan(`\u{1F389} Submit Project to Showcase
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 s.info("This will add your project to the public showcase."),s.info(`Run with ${g.yellow("--yes")} to confirm`),c.CANCELLED;try{let n=await P("/showcase/submit",{method:"POST",body:t,dryRun:e.dryRun});return e.dryRun?(d("[DRY RUN] Would submit to showcase","success"),c.SUCCESS):(s.success(`\u2713 Project added to showcase!
428
+ `),s.info(`View at: ${g.blue("https://nebutra.com/showcase/my-project")}`),s.info("Community can now discover your work!"),c.SUCCESS)}catch(n){return s.error(`Submission failed: ${n}`),c.ERROR}}async function ki(e,t){s.info(g.cyan(`\u{1F44D} Voting on showcase project "${e}"
429
+ `));try{let n=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):(s.success(`\u2713 Vote recorded! You're supporting this project.
430
+ `),c.SUCCESS)}catch(n){return s.error(`Vote failed: ${n}`),c.ERROR}}async function xi(e){s.info(g.cyan(`\u{1F504} Sync with Ecosystem
431
+ `));let t=!e.push,n=e.push?"push":"pull";try{let r=await P("/sync",{method:"POST",body:{direction:n,timestamp:new Date().toISOString()},dryRun:e.dryRun});return e.dryRun?(s.info(g.green(`\u2713 [DRY RUN] Would sync (${n})
432
+ `)),c.SUCCESS):(s.success(`\u2713 Synced!
433
+ `),t?s.info("Downloaded: ecosystem config, stats, badges"):s.info("Uploaded: project updates, metrics"),c.SUCCESS)}catch(r){return s.error(`Sync failed: ${r}`),c.ERROR}}function fr(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 i=>{await ci(i)}),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 i=>{await li(i)}),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 i=>{await di(i)});let n=t.command("templates").description("Template marketplace");n.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 i=>{await ui(i)}),n.command("search <query>").description("Search templates").option("--format <format>","Output format","text").action(async(i,l)=>{await mi(i,l)}),n.command("info <id>").description("Template details").action(async i=>{await pi(i)}),n.command("install <id>").description("Install/fork a template").option("--dry-run","Preview without making changes").action(async(i,l)=>{await fi(i,l)});let r=t.command("ideas").description("Ideas marketplace");r.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 i=>{await gi(i)}),r.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 i=>{await yi(i)}),r.command("vote <id>").description("Upvote an idea").option("--dry-run","Preview without making changes").action(async(i,l)=>{await hi(i,l)}),r.command("claim <id>").description("Claim an idea to work on").option("--dry-run","Preview without making changes").action(async(i,l)=>{await bi(i,l)}),r.command("comment <id>").description("Comment on an idea").option("--message <message>","Comment text").option("--dry-run","Preview without making changes").action(async(i,l)=>{await vi(i,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 i=>{await wi(i)}),o.command("profile").description("View/edit your legacy member profile").action(async()=>{await Ri()}),o.command("register").description("Register a legacy member profile").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async i=>{await Si(i)});let a=t.command("showcase").description("Project showcase");a.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 i=>{await Ci(i)}),a.command("submit").description("Submit your project to showcase").option("--yes","Skip confirmations").option("--dry-run","Preview without making changes").action(async i=>{await Ei(i)}),a.command("vote <id>").description("Upvote a project (Product Hunt style)").option("--dry-run","Preview without making changes").action(async(i,l)=>{await ki(i,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 i=>{await xi(i)})}import{existsSync as Rt,readFileSync as gr,writeFileSync as Oi}from"fs";import{resolve as St}from"path";import*as $e from"@clack/prompts";import Ai from"picocolors";function Ct(e){let t=St(e,".env.example");if(!Rt(t))throw new Error(`.env.example not found at ${t}`);let n=gr(t,"utf-8"),r={};for(let o of n.split(`
434
+ `)){if(o.trim().startsWith("#")||!o.trim())continue;let a=o.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(a){let[,i,l]=a;r[i]=l.replace(/^["'](.*)["']$/,"$1")}}return r}function Wt(e){let t=St(e,".env.local"),n=St(e,".env"),r=Rt(t)?t:n;if(!Rt(r))return{};let o=gr(r,"utf-8"),a={};for(let i of o.split(`
435
+ `)){if(i.trim().startsWith("#")||!i.trim())continue;let l=i.match(/^([A-Z_][A-Z0-9_]*)\s*=\s*(.*)$/);if(l){let[,u,m]=l;a[u]=m.replace(/^["'](.*)["']$/,"$1")}}return a}function _i(e,t){return["SECRET","KEY","TOKEN","PASSWORD"].some(o=>e.toUpperCase().includes(o))&&t.length>0}function Pi(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 Ii(e){d("Validating environment variables...","info");let t=h(),n=Ct(t),r=Wt(t),o=process.env,a={},i=!0;for(let l of Object.keys(n)){let u=l in r||l in o;a[l]=u,u||(i=!1)}if(e.format==="json")S({valid:i,checked:Object.keys(n).length,missing:Object.entries(a).filter(([,l])=>!l).map(([l])=>l)},{format:"json"});else{pt("Environment Validation");let l=Object.entries(a).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")}}i||process.exit(c.CONFIG_ERROR)}async function $i(e){let t=h(),n=Ct(t),r=St(t,".env.local");if(Rt(r)&&!e.yes&&!e.dryRun){let u=await $e.confirm({message:".env.local already exists. Overwrite?",initialValue:!1});($e.isCancel(u)||!u)&&(d("Template generation cancelled","warn"),process.exit(c.CANCELLED))}d("Generating .env.local from template...","info");let o={},a=0,i=Object.keys(n).length;for(let[u,m]of Object.entries(n))if(a++,e.yes)o[u]=m;else if(process.stdin.isTTY===!0){let f=`[${a}/${i}] ${u}`,y=await $e.text({message:f,defaultValue:m});$e.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"),S(l,{format:"plain"})):(Oi(r,l+`
437
+ `),d(`Environment template written to ${r}`,"success"))}async function Ni(e){d("Comparing environment variables...","info");let t=h(),n=Ct(t),r=Wt(t),o=[],a=[],i=[];for(let l of Object.keys(n))l in r?i.push(l):o.push(l);for(let l of Object.keys(r))l in n||a.push(l);if(e.format==="json")S({matching:i.length,missing:o.length,extra:a.length,missing_vars:o,extra_vars:a},{format:"json"});else{if(pt("Environment Diff"),i.length>0&&d(`Matching (${i.length}): ${i.join(", ")}`,"success"),o.length>0){d(`Missing (${o.length}):`,"warn");for(let l of o)d(` - ${l}`,"warn")}if(a.length>0){d(`Extra (${a.length}):`,"info");for(let l of a)d(` - ${l}`,"info")}}}async function Ti(e){d("Reading environment variables...","info");let t=h(),n=Wt(t),r=Ct(t),o={};for(let a of Object.keys(r))if(a in n){let i=n[a];o[a]=_i(a,i)?Pi(i):i||"(empty)"}else o[a]="(not set)";if(e.format==="json"){let a={};for(let[i,l]of Object.entries(o))a[i]=l;S(a,{format:"json"})}else{pt("Current Environment Variables");let a=Object.entries(o).map(([i,l])=>({Variable:Ai.cyan(i),Value:l}));S(a,{format:"table"}),d("Note: Sensitive values (KEY, TOKEN, SECRET, PASSWORD) are masked","info")}}function yr(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(n,r)=>{let o=r.optsWithGlobals?.(),a={dryRun:r.dryRun||o?.dryRun,yes:r.yes||o?.yes,format:r.format||o?.format};try{switch(n){case"validate":await Ii(a);break;case"template":await $i(a);break;case"diff":await Ni(a);break;case"show":await Ti(a);break;default:d(`Unknown env subcommand: ${n}. Valid commands: validate, template, diff, show`,"error"),process.exit(c.INVALID_ARGS)}}catch(i){let l=i instanceof Error?i.message:String(i);d(`Environment command failed: ${l}`,"error"),k("Full error",{error:i}),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 sn}from"fs";import{join as xe}from"path";import*as Ge from"@clack/prompts";import U from"picocolors";var Be=["design","iam","commerce","integrations","platform","ops","ai"];function ks(e){return Be.includes(e)}function Gt(e,t){if(!t)throw new Error(`--category is required. Valid categories: ${Be.join(", ")}. Example: nebutra generate package ${e} --category iam`);if(!ks(t))throw new Error(`Unknown category "${t}". Valid categories: ${Be.join(", ")}.`);return`packages/${t}/${e}`}function cn(e){let t=e.split("-").map(r=>r.charAt(0).toUpperCase()+r.slice(1)).join("");return{"package.json":`{
454
+ `)}import{promises as hr}from"fs";import{join as Ne}from"path";import*as Ze from"@clack/prompts";import L from"picocolors";var Qe=["design","iam","commerce","integrations","platform","ops","ai"];function Ui(e){return Qe.includes(e)}function Jt(e,t){if(!t)throw new Error(`--category is required. Valid categories: ${Qe.join(", ")}. Example: nebutra generate package ${e} --category iam`);if(!Ui(t))throw new Error(`Unknown category "${t}". Valid categories: ${Qe.join(", ")}.`);return`packages/${t}/${e}`}function br(e){let t=e.split("-").map(n=>n.charAt(0).toUpperCase()+n.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 ln(e){return{"package.json":`{
539
+ }`}}function vr(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 dn(e){let t=e.replace(/\//g,"_").replace(/-/g,"_");return{[`src/routes/${e}.ts`]:`import { Hono } from "hono";
576
+ }`}}function wr(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 un(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 Rr(e){let t=e.replace(/([A-Z])/g,"-$1").toLowerCase().replace(/^-/,""),n=e.split("-").map(r=>r.charAt(0).toUpperCase()+r.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(
@@ -648,34 +648,34 @@ const ${t}Variants = cva(
648
648
  }
649
649
  );
650
650
 
651
- interface ${r}Props
651
+ interface ${n}Props
652
652
  extends VariantProps<typeof ${t}Variants> {
653
653
  children: React.ReactNode;
654
654
  className?: string;
655
655
  }
656
656
 
657
- export function ${r}({
657
+ export function ${n}({
658
658
  variant,
659
659
  size,
660
660
  children,
661
661
  className,
662
- }: ${r}Props) {
662
+ }: ${n}Props) {
663
663
  return (
664
664
  <div className={cn(${t}Variants({ variant, size }), className)}>
665
665
  {children}
666
666
  </div>
667
667
  );
668
668
  }`,[`src/components/${t}.stories.tsx`]:`import type { Meta, StoryObj } from "@storybook/react";
669
- import { ${r} } from "./${t}";
669
+ import { ${n} } from "./${t}";
670
670
 
671
- const meta: Meta<typeof ${r}> = {
672
- title: "Primitives/${r}",
673
- component: ${r},
671
+ const meta: Meta<typeof ${n}> = {
672
+ title: "Primitives/${n}",
673
+ component: ${n},
674
674
  tags: ["autodocs"],
675
675
  };
676
676
  export default meta;
677
677
 
678
- type Story = StoryObj<typeof ${r}>;
678
+ type Story = StoryObj<typeof ${n}>;
679
679
 
680
680
  export const Default: Story = {
681
681
  args: {
@@ -693,18 +693,18 @@ export const Primary: Story = {
693
693
  export const AllSizes: Story = {
694
694
  render: () => (
695
695
  <div className="space-y-4">
696
- <${r} size="sm">Small</\${pascalCase}>
697
- <${r} size="md">Medium</\${pascalCase}>
698
- <${r} size="lg">Large</\${pascalCase}>
696
+ <${n} size="sm">Small</\${pascalCase}>
697
+ <${n} size="md">Medium</\${pascalCase}>
698
+ <${n} size="lg">Large</\${pascalCase}>
699
699
  </div>
700
700
  ),
701
- };`}}async function gt(e,t,r){let n=h(),o=[],a={};switch(e){case"app":a=cn(t);break;case"package":a=ln(t);break;case"route":a=dn(t);break;case"component":a=un(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let s=e==="package"?Gt(t,r.category):void 0;for(let[l,u]of Object.entries(a)){let m=e==="app"?xe(n,"apps",t,l):e==="package"?xe(n,s??`packages/${t}`,l):xe(n,"backends/gateway",l);o.push({path:m,size:Buffer.byteLength(u)})}return o}async function yt(e,t,r={}){let n=h(),o=[],a={};switch(e){case"app":a=cn(t);break;case"package":a=ln(t);break;case"route":a=dn(t);break;case"component":a=un(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let s=e==="package"?Gt(t,r.category):void 0;for(let[l,u]of Object.entries(a)){let m;e==="app"?m=xe(n,"apps",t,l):e==="package"?m=xe(n,s??`packages/${t}`,l):e==="component"?m=xe(n,"packages/design/ui",l):m=xe(n,"backends/gateway",l);let p=m.substring(0,m.lastIndexOf("/"));await sn.mkdir(p,{recursive:!0}),await sn.writeFile(m,u,"utf-8"),o.push(m)}return o}async function Es(e,t){if(t.dryRun){let n=await gt("app",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"app",name:e,location:`apps/${e}`,files:n.map(a=>({path:a.path,sizeBytes:a.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)}Ge.intro(U.bgCyan(U.black(" nebutra generate app ")));let r=i.spinner();try{r.start(`Generating app ${U.cyan(e)}...`);let n=await yt("app",e);r.stop(`Created app ${U.cyan(e)}`,0),i.success(`App created with ${n.length} files`),i.info("Next steps:"),i.info(` cd apps/${e}`),i.info(" pnpm install"),i.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 Cs(e,t){let r;try{r=Gt(e,t.category)}catch(o){i.error(o instanceof Error?o.message:String(o)),process.exit(c.INVALID_ARGS)}if(t.dryRun){let o=await gt("package",e,t),a={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(a,null,2)+`
703
- `),process.exit(c.DRY_RUN_OK)}Ge.intro(U.bgCyan(U.black(" nebutra generate package ")));let n=i.spinner();try{n.start(`Generating package ${U.cyan(e)} in ${U.dim(r)}...`);let o=await yt("package",e,{category:t.category});n.stop(`Created package ${U.cyan(e)}`,0),i.success(`Package created with ${o.length} files`),i.info("Next steps:"),i.info(` Edit ${r}/src/index.ts`),i.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 As(e,t){if(t.dryRun){let n=await gt("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(a=>({path:a.path,sizeBytes:a.size}))};process.stdout.write(JSON.stringify(o,null,2)+`
704
- `),process.exit(c.DRY_RUN_OK)}Ge.intro(U.bgCyan(U.black(" nebutra generate route ")));let r=i.spinner();try{r.start(`Generating route ${U.cyan(e)}...`);let n=await yt("route",e);r.stop(`Created route ${U.cyan(e)}`,0),i.success(`Route created with ${n.length} files`),i.info(`File: backends/gateway/src/routes/${e}.ts`),i.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 xs(e,t){if(t.dryRun){let n=await gt("component",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"component",name:e,location:"packages/design/ui/src/components/",files:n.map(a=>({path:a.path,sizeBytes:a.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)}Ge.intro(U.bgCyan(U.black(" nebutra generate component ")));let r=i.spinner();try{r.start(`Generating component ${U.cyan(e)}...`);let n=await yt("component",e);r.stop(`Created component ${U.cyan(e)}`,0),i.success(`Component created with ${n.length} files`),i.info("Files created in packages/design/ui/src/components/"),i.info("Next steps:"),i.info(" 1. Add export to packages/design/ui/src/components/index.ts"),i.info(" 2. pnpm --filter @nebutra/ui typecheck"),i.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 mn(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 Es(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: ${Be.join(", ")}`).requiredOption("--category <category>",`Package category: ${Be.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 Cs(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 As(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 xs(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 h(),n=new URL(e,"http://localhost:3000/api/growth");t?.query&&Object.entries(t.query).forEach(([a,s])=>{n.searchParams.set(a,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 Os(e){try{let t=e.period||"7d",r=e.compare;i.info(`Fetching growth metrics for ${t}...`);let n=await Y("/summary",{query:{period:t,compare:r?"true":"false"}});return c.SUCCESS}catch(t){return i.error(`Dashboard error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function _s(e){try{let t=e.period||"7d",r=e.segment||"all";i.info(`Fetching funnel data for ${t} (${r})...`);let n=await Y("/funnel",{query:{period:t,segment:r}});return n.forEach((a,s)=>{let l="\u2588".repeat(Math.ceil(a.rate*20)),u="\u2591".repeat(20-Math.ceil(a.rate*20)),m=s<n.length-1?je.red(`\u2193 ${(a.dropoff_rate*100).toFixed(1)}% drop`):""}),n.reduce((a,s)=>s.dropoff_rate>a.dropoff_rate?s:a).dropoff_rate>.2,c.SUCCESS}catch(t){return i.error(`Funnel error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function Ps(e){try{let t=e.period||"weekly",r=parseInt(e.cohorts,10)||8;i.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(a=>{let l=String(a.cohort).padEnd(15);o.forEach(u=>{let m=a[u];if(typeof m=="number"){let p=m/100,y=String(Math.round(m)).padEnd(8);p>=.7?y=je.green(y):p>=.4?y=je.yellow(y):y=je.red(y),l+=y+" "}})}),c.SUCCESS}catch(t){return i.error(`Cohort error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function Ts(e,t){try{if(e==="stats"){i.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 i.info(`Fetching ${r} newsletter subscribers (offset ${n})...`),(await Y("/newsletter/subscribers",{query:{limit:String(r),offset:String(n)}})).forEach(a=>{}),c.SUCCESS}if(e==="send"){let r=t.template;return r?t.yes?(i.info(`Sending newsletter with template: ${r}`),await Y("/newsletter/send",{method:"POST",body:{template_id:r}}),c.SUCCESS):(i.warn("Use --yes to confirm newsletter send"),c.ERROR):(i.error("--template is required"),c.ERROR)}return i.error(`Unknown newsletter subcommand: ${e}`),c.ERROR}catch(r){return i.error(`Newsletter error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function $s(e,t){try{if(e==="status"){i.info("Fetching referral program status...");let r=await Y("/referral/status");return c.SUCCESS}if(e==="config"){i.info("Fetching referral config...");let r=await Y("/referral/config");return Object.entries(r).forEach(([n,o])=>{}),c.SUCCESS}return e==="leaderboard"?(i.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):(i.error(`Unknown referral subcommand: ${e}`),c.ERROR)}catch(r){return i.error(`Referral error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function Is(e,t){try{if(e==="list"){i.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 i.error("Required: --name <name> --variants <A,B> --metric <metric>"),c.ERROR;i.info(`Creating experiment: ${r}`);let a=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 i.error("--id is required"),c.ERROR;i.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?(i.error("Required: --id <id> --winner <variant>"),c.ERROR):t.yes?(i.info(`Concluding experiment ${r} with winner: ${n}`),await Y(`/experiment/${r}`,{method:"POST",body:{action:"conclude",winner:n}}),c.SUCCESS):(i.warn("Use --yes to confirm experiment conclusion"),c.ERROR)}return i.error(`Unknown experiment subcommand: ${e}`),c.ERROR}catch(r){return i.error(`Experiment error: ${r instanceof Error?r.message:String(r)}`),c.ERROR}}async function Ns(e){try{let t=e.focus||"activation",r=e.depth||"quick";i.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 i.error(`Pulse error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}function pn(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 a=>{process.exit(await Os(a))}),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 a=>{process.exit(await _s(a))}),t.command("cohort").description("Cohort retention analysis").option("--period <weekly|monthly>","Cohort period","weekly").option("--cohorts <n>","Number of cohorts","8").action(async a=>{process.exit(await Ps(a))}),t.command("newsletter <subcommand>").description("Newsletter management").action(async(a,s)=>{process.exit(await Ts(a,s))}),t.command("referral <subcommand>").description("Referral program management").action(async(a,s)=>{process.exit(await $s(a,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(a,s)=>{process.exit(await Is(a,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 a=>{process.exit(await Ns(a))}),t.option("--dry-run","Preview changes without applying them").option("--format <json|text>","Output format","text").option("--yes","Skip confirmation prompts")}import qt,{lstatSync as js,readdirSync as Kt,readFileSync as Us,writeFileSync as Ls}from"fs";import de from"path";import{fileURLToPath as Ds}from"url";import X from"picocolors";var Fs=de.dirname(Ds(import.meta.url));function Wt(){let e=new Map,t=de.join(Fs,"../../../apps");if(!qt.existsSync(t))return e;try{let r=Kt(t);for(let n of r){let o=de.join(t,n),a=de.join(o,"messages");qt.existsSync(a)&&js(a).isDirectory()&&e.set(n,a)}}catch(r){i.debug(`Error scanning apps directory: ${r instanceof Error?r.message:String(r)}`)}return e}function qe(e,t=""){let r=new Set;for(let[n,o]of Object.entries(e)){let a=t?`${t}.${n}`:n;if(typeof o=="object"&&o!==null&&!Array.isArray(o)){let s=qe(o,a);for(let l of s)r.add(l)}else r.add(a)}return r}function Ke(e){try{let t=Us(e,"utf-8");return JSON.parse(t)}catch(t){return i.debug(`Failed to parse ${e}: ${t instanceof Error?t.message:String(t)}`),null}}async function Vs(e){if(i.info("Syncing language files across the project..."),(await K("translate",{filter:"landing-page",dryRun:e.dryRun,interactive:e.interactive??!0})).exitCode!==0){i.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&&(i.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||i.success("Language files synced successfully")}else e.format==="json"?console.log(JSON.stringify({command:"i18n:sync",exitCode:0,success:!0},null,2)):e.dryRun||i.success("Language files synced successfully")}async function Ms(e){i.info("Validating translation files...");let t=Wt();t.size===0&&(i.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let r=new Map,n=!1;for(let[o,a]of t){let s=[];try{let l=Kt(a).filter(y=>y.endsWith(".json"));if(l.length===0)continue;let u=de.join(a,"en.json"),m=Ke(u);if(!m){i.warn(`Could not load reference locale en.json from ${o}`);continue}let p=qe(m);for(let y of l){if(y==="en.json")continue;let C=y.replace(".json",""),L=de.join(a,y),D=Ke(L);if(!D){i.debug(`Could not parse ${y}`);continue}let q=qe(D),ue=Array.from(p).filter(f=>!q.has(f)),ae=Array.from(q).filter(f=>!p.has(f)),ke=p.size>0?(p.size-ue.length)/p.size*100:100;(ue.length>0||ae.length>0)&&(n=!0),s.push({locale:C,totalKeys:p.size,missingKeys:ue,extraKeys:ae,coverage:Math.round(ke*100)/100})}s.length>0&&r.set(o,s)}catch(l){i.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((a,[s,l])=>(a[s]=l,a),{})};console.log(JSON.stringify(o,null,2))}else for(let[o,a]of r){i.info(`${X.bold(o)}:`);for(let s of a){let u=(s.coverage>=100?X.green:s.coverage>=80?X.yellow:X.red)(`${s.coverage}%`);i.info(` ${X.cyan(s.locale.padEnd(5))} ${u.padEnd(20)} [${s.totalKeys} keys]`),s.missingKeys.length>0&&i.warn(` Missing: ${s.missingKeys.slice(0,5).join(", ")}${s.missingKeys.length>5?` (+ ${s.missingKeys.length-5} more)`:""}`),s.extraKeys.length>0&&i.warn(` Extra: ${s.extraKeys.slice(0,5).join(", ")}${s.extraKeys.length>5?` (+ ${s.extraKeys.length-5} more)`:""}`)}}n&&process.exit(c.CONFLICT)}async function Bs(e,t){/^[a-z]{2}(-[A-Z]{2})?$/.test(e)||(i.error(`Invalid locale format: ${e}. Use 'en', 'es', 'zh-CN', etc.`),process.exit(c.INVALID_ARGS));let r=Wt();r.size===0&&(i.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(qt.existsSync(u)){i.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 a=C;let m=de.join(l,"en.json"),p=Ke(m);if(!p){i.warn(`Could not load reference en.json from ${s}, skipping...`);continue}let y=JSON.parse(JSON.stringify(p));C(y),t.dryRun?i.info(`Would create ${e} locale in ${s}`):(Ls(u,JSON.stringify(y,null,2)+`
706
- `),n.push({app:s,path:u}),i.success(`Created ${e} locale in ${s}`))}catch(m){i.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||i.success(`Locale '${e}' added to ${n.length} app(s)`),o&&process.exit(c.ERROR)}async function Gs(e){i.info("Checking translation coverage...");let t=Wt();t.size===0&&(i.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let r=new Map,n=0,o=0;for(let[a,s]of t){let l=[];try{let u=Kt(s).filter(C=>C.endsWith(".json"));if(u.length===0)continue;let m=de.join(s,"en.json"),p=Ke(m);if(!p){i.debug(`Could not load reference locale from ${a}`);continue}let y=qe(p);for(let C of u){let L=C.replace(".json",""),D=de.join(s,C),q=Ke(D);if(!q)continue;let ue=qe(q),ae=Array.from(ue).filter(F=>{let Pe=q[F.split(".")[0]];return Pe!==void 0&&Pe!==""}).length,ke=y.size-ae,f=y.size>0?ae/y.size*100:0;l.push({locale:L,coverage:Math.round(f*100)/100,totalKeys:y.size,translatedKeys:ae,missingKeys:ke})}l.length>0&&(r.set(a,l),o++,n+=l.reduce((C,L)=>C+L.coverage,0)/l.length)}catch(u){i.debug(`Error checking status for ${a}: ${u instanceof Error?u.message:String(u)}`)}}if(e.format==="json"){let a={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(a,null,2))}else{for(let[a,s]of r){i.info(`${X.bold(a)}:`);for(let l of s){let u="",p=Math.round(l.coverage/100*20);u="\u2588".repeat(p)+"\u2591".repeat(20-p);let C=(l.coverage>=100?X.green:l.coverage>=80?X.yellow:X.red)(`${l.coverage.toFixed(1)}%`);i.info(` ${X.cyan(l.locale.padEnd(5))} [${u}] ${C}`),i.info(` ${l.translatedKeys}/${l.totalKeys} keys (${l.missingKeys} missing)`)}}if(o>0){let a=n/o,s=a>=100?X.green:a>=80?X.yellow:X.red;i.info(`
707
- Average coverage: ${s(a.toFixed(1)+"%")}`)}}}function fn(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 Vs({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 Ms({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 Bs(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 Gs({format:r.format||n.format,interactive:n.yes!==!0})})}import*as ht from"@clack/prompts";async function qs(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 Te("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 Ks(e){d("Stopping infrastructure stack...","info");let t=await Te("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 Ws(e){d("Checking infrastructure status...","info");let t=await Te("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 zs(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 a=await Te(o.join(" "),{dryRun:r.dryRun});a.exitCode===0?k(a.stdout,{format:"plain"}):(d("Failed to fetch logs","error"),A("Docker compose output",{stderr:a.stderr}),process.exit(a.exitCode||1))}async function Ys(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let n=await ht.confirm({message:"Reset infrastructure? This will remove all containers and volumes.",initialValue:!1});(ht.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 Te("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 gn(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 a=o.optsWithGlobals?.(),s={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,lite:o.lite||!1,profile:o.profile};try{switch(r){case"up":await qs(s);break;case"down":await Ks(s);break;case"status":await Ws(s);break;case"logs":await zs(n,s);break;case"reset":await Ys(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 Et(e,t,n){let r=h(),o=[],a={};switch(e){case"app":a=br(t);break;case"package":a=vr(t);break;case"route":a=wr(t);break;case"component":a=Rr(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let i=e==="package"?Jt(t,n.category):void 0;for(let[l,u]of Object.entries(a)){let m=e==="app"?Ne(r,"apps",t,l):e==="package"?Ne(r,i??`packages/${t}`,l):Ne(r,"backends/gateway",l);o.push({path:m,size:Buffer.byteLength(u)})}return o}async function kt(e,t,n={}){let r=h(),o=[],a={};switch(e){case"app":a=br(t);break;case"package":a=vr(t);break;case"route":a=wr(t);break;case"component":a=Rr(t);break;default:throw new Error(`Unknown generate type: ${e}`)}let i=e==="package"?Jt(t,n.category):void 0;for(let[l,u]of Object.entries(a)){let m;e==="app"?m=Ne(r,"apps",t,l):e==="package"?m=Ne(r,i??`packages/${t}`,l):e==="component"?m=Ne(r,"packages/design/ui",l):m=Ne(r,"backends/gateway",l);let f=m.substring(0,m.lastIndexOf("/"));await hr.mkdir(f,{recursive:!0}),await hr.writeFile(m,u,"utf-8"),o.push(m)}return o}async function ji(e,t){if(t.dryRun){let r=await Et("app",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"app",name:e,location:`apps/${e}`,files:r.map(a=>({path:a.path,sizeBytes:a.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)}Ze.intro(L.bgCyan(L.black(" nebutra generate app ")));let n=s.spinner();try{n.start(`Generating app ${L.cyan(e)}...`);let r=await kt("app",e);n.stop(`Created app ${L.cyan(e)}`,0),s.success(`App created with ${r.length} files`),s.info("Next steps:"),s.info(` cd apps/${e}`),s.info(" pnpm install"),s.info(" pnpm run dev"),process.exit(c.SUCCESS)}catch(r){n.stop(`Failed to generate app: ${r instanceof Error?r.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function Li(e,t){let n;try{n=Jt(e,t.category)}catch(o){s.error(o instanceof Error?o.message:String(o)),process.exit(c.INVALID_ARGS)}if(t.dryRun){let o=await Et("package",e,t),a={mode:"dry-run",timestamp:new Date().toISOString(),type:"package",name:e,category:t.category,location:n,files:o.map(i=>({path:i.path,sizeBytes:i.size}))};process.stdout.write(JSON.stringify(a,null,2)+`
703
+ `),process.exit(c.DRY_RUN_OK)}Ze.intro(L.bgCyan(L.black(" nebutra generate package ")));let r=s.spinner();try{r.start(`Generating package ${L.cyan(e)} in ${L.dim(n)}...`);let o=await kt("package",e,{category:t.category});r.stop(`Created package ${L.cyan(e)}`,0),s.success(`Package created with ${o.length} files`),s.info("Next steps:"),s.info(` Edit ${n}/src/index.ts`),s.info(` Run: pnpm --filter @nebutra/${e} build`),process.exit(c.SUCCESS)}catch(o){r.stop(`Failed to generate package: ${o instanceof Error?o.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function Di(e,t){if(t.dryRun){let r=await Et("route",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"route",path:e,location:`backends/gateway/src/routes/${e}.ts`,files:r.map(a=>({path:a.path,sizeBytes:a.size}))};process.stdout.write(JSON.stringify(o,null,2)+`
704
+ `),process.exit(c.DRY_RUN_OK)}Ze.intro(L.bgCyan(L.black(" nebutra generate route ")));let n=s.spinner();try{n.start(`Generating route ${L.cyan(e)}...`);let r=await kt("route",e);n.stop(`Created route ${L.cyan(e)}`,0),s.success(`Route created with ${r.length} files`),s.info(`File: backends/gateway/src/routes/${e}.ts`),s.info(`Add to your main app.ts: app.route("/${e}", routes)`),process.exit(c.SUCCESS)}catch(r){n.stop(`Failed to generate route: ${r instanceof Error?r.message:"Unknown error"}`,1),process.exit(c.ERROR)}}async function Fi(e,t){if(t.dryRun){let r=await Et("component",e,t),o={mode:"dry-run",timestamp:new Date().toISOString(),type:"component",name:e,location:"packages/design/ui/src/components/",files:r.map(a=>({path:a.path,sizeBytes:a.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)}Ze.intro(L.bgCyan(L.black(" nebutra generate component ")));let n=s.spinner();try{n.start(`Generating component ${L.cyan(e)}...`);let r=await kt("component",e);n.stop(`Created component ${L.cyan(e)}`,0),s.success(`Component created with ${r.length} files`),s.info("Files created in packages/design/ui/src/components/"),s.info("Next steps:"),s.info(" 1. Add export to packages/design/ui/src/components/index.ts"),s.info(" 2. pnpm --filter @nebutra/ui typecheck"),s.info(" 3. pnpm --filter @nebutra/storybook dev"),process.exit(c.SUCCESS)}catch(r){n.stop(`Failed to generate component: ${r instanceof Error?r.message:"Unknown error"}`,1),process.exit(c.ERROR)}}var Sr=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(n,r,o)=>{let a=x(r,o);await ji(n,{dryRun:!!r.dryRun,yes:!!a.yes,interactive:!!process.stdin.isTTY,template:(r.template==="nextjs","nextjs"),port:typeof r.port=="string"?Number(r.port):void 0})}),t.command("package <name>").description(`Scaffold a new categorized package (@nebutra/<name>). Categories: ${Qe.join(", ")}`).requiredOption("--category <category>",`Package category: ${Qe.join(" | ")}`).option("--dry-run","Preview changes without writing files").option("--yes","Skip all prompts").action(async(n,r,o)=>{let a=x(r,o);await Li(n,{category:String(r.category??""),dryRun:!!r.dryRun,yes:!!a.yes})}),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(n,r,o)=>{let a=x(r,o);await Di(n,{dryRun:!!r.dryRun,yes:!!a.yes})}),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(n,r,o)=>{let a=x(r,o);await Fi(n,{dryRun:!!r.dryRun,yes:!!a.yes,variants:typeof r.variants=="string"?r.variants:void 0,sizes:typeof r.sizes=="string"?r.sizes:void 0})})};import Ke from"picocolors";async function J(e,t){let n=await h(),r=new URL(e,"http://localhost:3000/api/growth");t?.query&&Object.entries(t.query).forEach(([a,i])=>{r.searchParams.set(a,i)});let o=await fetch(r,{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 Bi(e){try{let t=e.period||"7d",n=e.compare;s.info(`Fetching growth metrics for ${t}...`);let r=await J("/summary",{query:{period:t,compare:n?"true":"false"}});return c.SUCCESS}catch(t){return s.error(`Dashboard error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function Mi(e){try{let t=e.period||"7d",n=e.segment||"all";s.info(`Fetching funnel data for ${t} (${n})...`);let r=await J("/funnel",{query:{period:t,segment:n}});return r.forEach((a,i)=>{let l="\u2588".repeat(Math.ceil(a.rate*20)),u="\u2591".repeat(20-Math.ceil(a.rate*20)),m=i<r.length-1?Ke.red(`\u2193 ${(a.dropoff_rate*100).toFixed(1)}% drop`):""}),r.reduce((a,i)=>i.dropoff_rate>a.dropoff_rate?i:a).dropoff_rate>.2,c.SUCCESS}catch(t){return s.error(`Funnel error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function Gi(e){try{let t=e.period||"weekly",n=parseInt(e.cohorts,10)||8;s.info(`Fetching ${t} cohort data (${n} cohorts)...`);let r=await J("/cohort",{query:{period:t,cohorts:String(n)}});if(r.length===0)return c.SUCCESS;let o=Object.keys(r[0]).slice(1);return r.forEach(a=>{let l=String(a.cohort).padEnd(15);o.forEach(u=>{let m=a[u];if(typeof m=="number"){let f=m/100,y=String(Math.round(m)).padEnd(8);f>=.7?y=Ke.green(y):f>=.4?y=Ke.yellow(y):y=Ke.red(y),l+=y+" "}})}),c.SUCCESS}catch(t){return s.error(`Cohort error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}async function Ki(e,t){try{if(e==="stats"){s.info("Fetching newsletter stats...");let n=await J("/newsletter/stats");return c.SUCCESS}if(e==="subscribers"){let n=parseInt(t.limit,10)||10,r=parseInt(t.offset,10)||0;return s.info(`Fetching ${n} newsletter subscribers (offset ${r})...`),(await J("/newsletter/subscribers",{query:{limit:String(n),offset:String(r)}})).forEach(a=>{}),c.SUCCESS}if(e==="send"){let n=t.template;return n?t.yes?(s.info(`Sending newsletter with template: ${n}`),await J("/newsletter/send",{method:"POST",body:{template_id:n}}),c.SUCCESS):(s.warn("Use --yes to confirm newsletter send"),c.ERROR):(s.error("--template is required"),c.ERROR)}return s.error(`Unknown newsletter subcommand: ${e}`),c.ERROR}catch(n){return s.error(`Newsletter error: ${n instanceof Error?n.message:String(n)}`),c.ERROR}}async function Vi(e,t){try{if(e==="status"){s.info("Fetching referral program status...");let n=await J("/referral/status");return c.SUCCESS}if(e==="config"){s.info("Fetching referral config...");let n=await J("/referral/config");return Object.entries(n).forEach(([r,o])=>{}),c.SUCCESS}return e==="leaderboard"?(s.info("Fetching referral leaderboard..."),(await J("/referral/leaderboard")).forEach(r=>{let o=r.rank===1?"\u{1F947}":r.rank===2?"\u{1F948}":"\u{1F949}"}),c.SUCCESS):(s.error(`Unknown referral subcommand: ${e}`),c.ERROR)}catch(n){return s.error(`Referral error: ${n instanceof Error?n.message:String(n)}`),c.ERROR}}async function qi(e,t){try{if(e==="list"){s.info("Fetching active experiments...");let n=await J("/experiment");return n.length===0?c.SUCCESS:(n.forEach(r=>{let o=r.status==="running"?Ke.yellow("\u25CF"):Ke.green("\u2713")}),c.SUCCESS)}if(e==="create"){let n=t.name,r=t.variants?.split(","),o=t.metric;if(!n||!r||!o)return s.error("Required: --name <name> --variants <A,B> --metric <metric>"),c.ERROR;s.info(`Creating experiment: ${n}`);let a=await J("/experiment",{method:"POST",body:{name:n,variants:r,metric:o}});return c.SUCCESS}if(e==="results"){let n=t.id;if(!n)return s.error("--id is required"),c.ERROR;s.info(`Fetching results for experiment ${n}...`);let r=await J(`/experiment/${n}`);return r.winner,r.significance,c.SUCCESS}if(e==="conclude"){let n=t.id,r=t.winner;return!n||!r?(s.error("Required: --id <id> --winner <variant>"),c.ERROR):t.yes?(s.info(`Concluding experiment ${n} with winner: ${r}`),await J(`/experiment/${n}`,{method:"POST",body:{action:"conclude",winner:r}}),c.SUCCESS):(s.warn("Use --yes to confirm experiment conclusion"),c.ERROR)}return s.error(`Unknown experiment subcommand: ${e}`),c.ERROR}catch(n){return s.error(`Experiment error: ${n instanceof Error?n.message:String(n)}`),c.ERROR}}async function zi(e){try{let t=e.focus||"activation",n=e.depth||"quick";s.info(`Generating growth insights (focus: ${t}, depth: ${n})...`);let r=await J("/pulse",{query:{focus:t,depth:n}});return r.insights.forEach(o=>{}),r.recommendations.forEach(o=>{}),c.SUCCESS}catch(t){return s.error(`Pulse error: ${t instanceof Error?t.message:String(t)}`),c.ERROR}}function Cr(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 a=>{process.exit(await Bi(a))}),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 a=>{process.exit(await Mi(a))}),t.command("cohort").description("Cohort retention analysis").option("--period <weekly|monthly>","Cohort period","weekly").option("--cohorts <n>","Number of cohorts","8").action(async a=>{process.exit(await Gi(a))}),t.command("newsletter <subcommand>").description("Newsletter management").action(async(a,i)=>{process.exit(await Ki(a,i))}),t.command("referral <subcommand>").description("Referral program management").action(async(a,i)=>{process.exit(await Vi(a,i))}),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(a,i)=>{process.exit(await qi(a,i))}),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 a=>{process.exit(await zi(a))}),t.option("--dry-run","Preview changes without applying them").option("--format <json|text>","Output format","text").option("--yes","Skip confirmation prompts")}import Xt,{lstatSync as Yi,readdirSync as Qt,readFileSync as Hi,writeFileSync as Wi}from"fs";import ge from"path";import{fileURLToPath as Ji}from"url";import te from"picocolors";var Xi=ge.dirname(Ji(import.meta.url));function Zt(){let e=new Map,t=ge.join(Xi,"../../../apps");if(!Xt.existsSync(t))return e;try{let n=Qt(t);for(let r of n){let o=ge.join(t,r),a=ge.join(o,"messages");Xt.existsSync(a)&&Yi(a).isDirectory()&&e.set(r,a)}}catch(n){s.debug(`Error scanning apps directory: ${n instanceof Error?n.message:String(n)}`)}return e}function et(e,t=""){let n=new Set;for(let[r,o]of Object.entries(e)){let a=t?`${t}.${r}`:r;if(typeof o=="object"&&o!==null&&!Array.isArray(o)){let i=et(o,a);for(let l of i)n.add(l)}else n.add(a)}return n}function tt(e){try{let t=Hi(e,"utf-8");return JSON.parse(t)}catch(t){return s.debug(`Failed to parse ${e}: ${t instanceof Error?t.message:String(t)}`),null}}async function Qi(e){if(s.info("Syncing language files across the project..."),(await z("translate",{filter:"landing",dryRun:e.dryRun,interactive:e.interactive??!0})).exitCode!==0){s.warn("Landing page translate script not found or failed. Trying sync-lang.mjs...");let n=await O({command:"node",args:["scripts/sync-lang.mjs"],dryRun:e.dryRun,interactive:e.interactive??!0,label:"Sync language files"});n.exitCode!==0&&(s.error("Failed to sync language files"),process.exit(n.exitCode)),e.format==="json"?console.log(JSON.stringify({command:"i18n:sync",exitCode:0,success:!0},null,2)):e.dryRun||s.success("Language files synced successfully")}else e.format==="json"?console.log(JSON.stringify({command:"i18n:sync",exitCode:0,success:!0},null,2)):e.dryRun||s.success("Language files synced successfully")}async function Zi(e){s.info("Validating translation files...");let t=Zt();t.size===0&&(s.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let n=new Map,r=!1;for(let[o,a]of t){let i=[];try{let l=Qt(a).filter(y=>y.endsWith(".json"));if(l.length===0)continue;let u=ge.join(a,"en.json"),m=tt(u);if(!m){s.warn(`Could not load reference locale en.json from ${o}`);continue}let f=et(m);for(let y of l){if(y==="en.json")continue;let E=y.replace(".json",""),D=ge.join(a,y),F=tt(D);if(!F){s.debug(`Could not parse ${y}`);continue}let q=et(F),ye=Array.from(f).filter(p=>!q.has(p)),ue=Array.from(q).filter(p=>!f.has(p)),_e=f.size>0?(f.size-ye.length)/f.size*100:100;(ye.length>0||ue.length>0)&&(r=!0),i.push({locale:E,totalKeys:f.size,missingKeys:ye,extraKeys:ue,coverage:Math.round(_e*100)/100})}i.length>0&&n.set(o,i)}catch(l){s.debug(`Error validating ${o}: ${l instanceof Error?l.message:String(l)}`)}}if(e.format==="json"){let o={command:"i18n:validate",success:!r,results:Array.from(n.entries()).reduce((a,[i,l])=>(a[i]=l,a),{})};console.log(JSON.stringify(o,null,2))}else for(let[o,a]of n){s.info(`${te.bold(o)}:`);for(let i of a){let u=(i.coverage>=100?te.green:i.coverage>=80?te.yellow:te.red)(`${i.coverage}%`);s.info(` ${te.cyan(i.locale.padEnd(5))} ${u.padEnd(20)} [${i.totalKeys} keys]`),i.missingKeys.length>0&&s.warn(` Missing: ${i.missingKeys.slice(0,5).join(", ")}${i.missingKeys.length>5?` (+ ${i.missingKeys.length-5} more)`:""}`),i.extraKeys.length>0&&s.warn(` Extra: ${i.extraKeys.slice(0,5).join(", ")}${i.extraKeys.length>5?` (+ ${i.extraKeys.length-5} more)`:""}`)}}r&&process.exit(c.CONFLICT)}async function ec(e,t){/^[a-z]{2}(-[A-Z]{2})?$/.test(e)||(s.error(`Invalid locale format: ${e}. Use 'en', 'es', 'zh-CN', etc.`),process.exit(c.INVALID_ARGS));let n=Zt();n.size===0&&(s.error("No message directories found in the project"),process.exit(c.NOT_FOUND));let r=[],o=!1;for(let[i,l]of n){let u=ge.join(l,`${e}.json`);if(Xt.existsSync(u)){s.warn(`Locale ${e} already exists in ${i}`);continue}try{let E=function(D){for(let F in D)typeof D[F]=="string"?D[F]="":typeof D[F]=="object"&&D[F]!==null&&E(D[F])};var a=E;let m=ge.join(l,"en.json"),f=tt(m);if(!f){s.warn(`Could not load reference en.json from ${i}, skipping...`);continue}let y=JSON.parse(JSON.stringify(f));E(y),t.dryRun?s.info(`Would create ${e} locale in ${i}`):(Wi(u,JSON.stringify(y,null,2)+`
706
+ `),r.push({app:i,path:u}),s.success(`Created ${e} locale in ${i}`))}catch(m){s.error(`Failed to create locale in ${i}: ${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:r,success:!o},null,2)):t.dryRun||s.success(`Locale '${e}' added to ${r.length} app(s)`),o&&process.exit(c.ERROR)}async function tc(e){s.info("Checking translation coverage...");let t=Zt();t.size===0&&(s.warn("No message directories found in the project"),process.exit(c.NOT_FOUND));let n=new Map,r=0,o=0;for(let[a,i]of t){let l=[];try{let u=Qt(i).filter(E=>E.endsWith(".json"));if(u.length===0)continue;let m=ge.join(i,"en.json"),f=tt(m);if(!f){s.debug(`Could not load reference locale from ${a}`);continue}let y=et(f);for(let E of u){let D=E.replace(".json",""),F=ge.join(i,E),q=tt(F);if(!q)continue;let ye=et(q),ue=Array.from(ye).filter(B=>{let Le=q[B.split(".")[0]];return Le!==void 0&&Le!==""}).length,_e=y.size-ue,p=y.size>0?ue/y.size*100:0;l.push({locale:D,coverage:Math.round(p*100)/100,totalKeys:y.size,translatedKeys:ue,missingKeys:_e})}l.length>0&&(n.set(a,l),o++,r+=l.reduce((E,D)=>E+D.coverage,0)/l.length)}catch(u){s.debug(`Error checking status for ${a}: ${u instanceof Error?u.message:String(u)}`)}}if(e.format==="json"){let a={command:"i18n:status",averageCoverage:o>0?Math.round(r/o*100)/100:0,results:Array.from(n.entries()).reduce((i,[l,u])=>(i[l]=u,i),{})};console.log(JSON.stringify(a,null,2))}else{for(let[a,i]of n){s.info(`${te.bold(a)}:`);for(let l of i){let u="",f=Math.round(l.coverage/100*20);u="\u2588".repeat(f)+"\u2591".repeat(20-f);let E=(l.coverage>=100?te.green:l.coverage>=80?te.yellow:te.red)(`${l.coverage.toFixed(1)}%`);s.info(` ${te.cyan(l.locale.padEnd(5))} [${u}] ${E}`),s.info(` ${l.translatedKeys}/${l.totalKeys} keys (${l.missingKeys} missing)`)}}if(o>0){let a=r/o,i=a>=100?te.green:a>=80?te.yellow:te.red;s.info(`
707
+ Average coverage: ${i(a.toFixed(1)+"%")}`)}}}function Er(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 n=>{let r=n.optsWithGlobals?.()||n;await Qi({dryRun:n.dryRun||!1,format:n.format||r.format,interactive:r.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 n=>{let r=n.optsWithGlobals?.()||n;await Zi({format:n.format||r.format,interactive:r.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(n,r)=>{let o=r.optsWithGlobals?.()||r;await ec(n,{dryRun:r.dryRun||!1,format:r.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 n=>{let r=n.optsWithGlobals?.()||n;await tc({format:n.format||r.format,interactive:r.yes!==!0})})}import*as xt from"@clack/prompts";async function nc(e){let t=e.lite?"docker-compose.lite.yml":void 0,n=e.lite?"Starting lite stack (PostgreSQL + Redis)":"Starting full stack";d(n+"...","info");let r=await De("up -d",{file:t,profile:e.profile,dryRun:e.dryRun});r.exitCode===0?d("Infrastructure stack started successfully","success"):(d("Failed to start infrastructure stack","error"),k("Docker compose output",{stderr:r.stderr}),process.exit(r.exitCode||1))}async function rc(e){d("Stopping infrastructure stack...","info");let t=await De("down",{dryRun:e.dryRun});t.exitCode===0?d("Infrastructure stack stopped","success"):(d("Failed to stop infrastructure stack","error"),k("Docker compose output",{stderr:t.stderr}),process.exit(t.exitCode||1))}async function oc(e){d("Checking infrastructure status...","info");let t=await De("ps --format json",{dryRun:e.dryRun});if(t.exitCode===0)try{let n=JSON.parse(t.stdout);if(e.format==="json")S(n,{format:"json"});else{let r=n.map(o=>({name:o.Name,status:o.Status,ports:o.Ports||"-"}));S(r,{format:"table"})}}catch{S(t.stdout,{format:"plain"})}else d("Failed to check infrastructure status","error"),k("Docker compose output",{stderr:t.stderr}),process.exit(t.exitCode||1)}async function sc(e,t){let n=t||{},r=e?`Fetching logs for ${e}...`:"Fetching infrastructure logs...";d(r,"info");let o=["logs","--tail","50"];e&&o.push(e);let a=await De(o.join(" "),{dryRun:n.dryRun});a.exitCode===0?S(a.stdout,{format:"plain"}):(d("Failed to fetch logs","error"),k("Docker compose output",{stderr:a.stderr}),process.exit(a.exitCode||1))}async function ac(e){let t=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!e.yes&&!e.dryRun)if(t){let r=await xt.confirm({message:"Reset infrastructure? This will remove all containers and volumes.",initialValue:!1});(xt.isCancel(r)||!r)&&(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 n=await De("down -v",{dryRun:e.dryRun});n.exitCode===0?d("Infrastructure reset successfully","success"):(d("Failed to reset infrastructure","error"),k("Docker compose output",{stderr:n.stderr}),process.exit(n.exitCode||1))}function kr(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(n,r,o)=>{let a=o.optsWithGlobals?.(),i={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,lite:o.lite||!1,profile:o.profile};try{switch(n){case"up":await nc(i);break;case"down":await rc(i);break;case"status":await oc(i);break;case"logs":await sc(r,i);break;case"reset":await ac(i);break;default:d(`Unknown infra subcommand: ${n}. 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"),k("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,14 @@ 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 zt from"fs";import Hs from"path";import*as Z from"@clack/prompts";import bt from"picocolors";var Js={$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 Xs(){return process.stdout.isTTY===!0}function Qs(e){return e.yes===!0||e.dryRun===!0||!Xs()}function Zs(e,t,r){return{operation:r?"update":"create",path:e,...r&&{before:r},after:t}}async function yn(e={}){let t=process.cwd(),r=Hs.join(t,"nebutra.config.json"),n=zt.existsSync(r);e.ifNotExists&&n&&(i.info("nebutra.config.json already exists, skipping initialization."),process.exit(c.SUCCESS));let o=Qs(e);o||Z.intro(bt.bgCyan(bt.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 a={...Js};if(e.dryRun){let s=n?JSON.parse(zt.readFileSync(r,"utf-8")):void 0,l=Zs(r,a,s);O(l),d("Dry-run completed. No changes made."),process.exit(c.DRY_RUN_OK)}o?i.info("Initializing Nebutra CLI configuration..."):Z.spinner().start("Initializing Nebutra CLI configuration..."),zt.writeFileSync(r,JSON.stringify(a,null,2)+`
725
- `),o?(i.success("Configuration saved to nebutra.config.json"),i.info('Initialization complete! You can now use "nebutra add" to start injecting components.')):(await new Promise(s=>setTimeout(s,800)),Z.spinner().stop(bt.green("Configuration saved to nebutra.config.json")),Z.outro(bt.cyan('Initialization complete! You can now use "nebutra add" to start injecting components.'))),process.exit(c.SUCCESS)}import St from"fs/promises";import cc from"os";import We from"path";import*as T from"@clack/prompts";import R from"picocolors";var ec="https://analytics.nebutra.com";function tc(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function rc(){return process.env.npm_package_version??"0.0.0-dev"}function vt(e,t={}){tc(t)||(async()=>{try{let r=await import("./dist-XXK46RYX.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??ec},onError:()=>{}});if(typeof n?.track!="function")return;let o=n.track("license.cli",{action:e.action,cli_version:rc(),...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 nc}from"crypto";var oc=[{id:"v1",key:"nebutra-sailor:scaffold-marker:v1"}],ic="v1";function ac(e){if(e)return oc.find(t=>t.id===e)}function sc(e,t){let r=`${e.cliVersion}|${e.scaffoldedAt}|${e.projectName}|${e.nonce}`;return nc("sha256",t).update(r).digest("hex")}function hn(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??ic,r=ac(t);return r?sc({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 wt={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 bn=process.env.NEBUTRA_LICENSE_API_URL??"https://nebutra.com";async function vn(){let e=cc.homedir(),t=We.join(e,".config","nebutra");try{await St.mkdir(t,{recursive:!0})}catch{}return t}async function lc(e){let t=`${bn}/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 (${bn}). 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 dc(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 uc(e,t){let r=t.quiet===!0;r||T.intro(R.bgCyan(R.black(" Nebutra License Activation "))),vt({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 lc(e),a=await vn(),s=We.join(a,"license.json");await St.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!"))),vt({action:"activated",tier:n,type:o})}catch(n){vt({action:"failed",error_code:dc(n)}),r||(T.log.error(R.red("Activation failed")),i.error(n instanceof Error?n.message:String(n)),T.outro("Please check your key and try again.")),process.exit(c.ERROR)}}async function mc(e){let t=e.quiet===!0;t||T.intro(R.bgCyan(R.black(" Nebutra License Status ")));try{let r=await vn(),n=We.join(r,"license.json"),o=await St.readFile(n,"utf-8"),a=JSON.parse(o);if(a.licenseKey)t||(T.log.success(R.green("License is active!")),T.log.info(`Key: ${a.licenseKey.substring(0,8)}...`),a.tier&&T.log.info(`Tier: ${R.bold(a.tier)}`),a.type&&T.log.info(`Type: ${a.type}`),T.log.info(`Activated: ${new Date(a.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 pc(e,t){let r=t.format==="json",n=t.quiet===!0,o=e?We.resolve(process.cwd(),e):process.cwd(),a=We.join(o,".nebutra","scaffold-meta.json"),s;try{s=await St.readFile(a,"utf-8")}catch{let y={valid:!1,tier:null,cliVersion:null,scaffoldedAt:null,projectName:null,reason:"missing_meta",reasonText:wt.missing_meta,path:a};r?process.stdout.write(`${JSON.stringify(y,null,2)}
726
- `):n||process.stderr.write(`${R.red("\u2718")} No scaffold marker found at ${R.dim(a)}.
727
- This project does not appear to be scaffolded by ${R.bold("create-sailor")}.
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=hn(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:wt[u.reason],path:a};if(r&&(process.stdout.write(`${JSON.stringify(m,null,2)}
730
- `),process.exit(u.valid?c.SUCCESS:c.INCOMPATIBLE)),!n)if(u.valid&&l){let p=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 ${p}`,` 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
- `)}
732
- `)}else{let p=wt[u.reason];process.stderr.write(`${R.red("\u2718")} Invalid scaffold marker.
733
- Reason: ${R.yellow(p)}
734
- File: ${R.dim(a)}
735
- `)}process.exit(u.valid?c.SUCCESS:c.INCOMPATIBLE)}function wn(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 uc(r,n)}),t.command("status").description("Check the locally configured license status").option("--quiet","Suppress output").action(async r=>{await mc(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 a=o&&typeof o.optsWithGlobals=="function"?o.optsWithGlobals()??{}:{...n},s=typeof n?.format=="string"?n.format:typeof a.format=="string"?a.format:void 0,l=!!n?.quiet||!!a.quiet;await pc(r,{format:s,quiet:l})})}import{existsSync as Sn,readFileSync as fc,writeFileSync as gc}from"fs";import{dirname as yc,join as Rn,parse as hc}from"path";import*as Rt from"@clack/prompts";function bc(e){let t=e,{root:r}=hc(t);for(;;){if(Sn(Rn(t,"package.json")))return t;if(t===r)return null;let n=yc(t);if(n===t)return null;t=n}}function vc(e){if(!Sn(e))return{};try{return JSON.parse(fc(e,"utf-8"))}catch{return{}}}function wc(e,t){gc(e,JSON.stringify(t,null,2)+`
736
- `)}async function Sc(e,t){let r=t.format==="json",n=bc(process.cwd());n||(r?console.log(JSON.stringify({command:"link",success:!1,error:"No package.json found upstream"},null,2)):i.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)):i.error("project-id is required when running with --yes / non-interactive."),process.exit(c.INVALID_ARGS));let u=await Rt.text({message:"Project ID to link to:",placeholder:"proj_abc123",validate:m=>m&&m.trim().length>0?void 0:"Project ID cannot be empty"});Rt.isCancel(u)&&(i.warn("Cancelled"),process.exit(c.CANCELLED)),o=String(u).trim()}let a=Rn(n,"nebutra.config.json"),l={...vc(a),projectId:o};wc(a,l),r?console.log(JSON.stringify({command:"link",success:!0,projectId:o,configPath:a},null,2)):i.success(`Linked to project: ${o}`)}function kn(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 Sc(t,{yes:o.yes||!1,format:r.format||o.format})})}import{existsSync as En,rmSync as Rc,unlinkSync as kc}from"fs";import{homedir as Cn,platform as Ec}from"os";import{join as ze}from"path";function Cc(){if(Ec()==="win32"){let t=process.env.LOCALAPPDATA||ze(Cn(),"AppData","Local");return ze(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?ze(e,"nebutra"):ze(Cn(),".config","nebutra")}var Ac=["auth.json","session.json","token","credentials.json"];async function xc(e){let t=Cc(),r=e.format==="json",n=0,o=[];if(e.all){if(En(t))try{Rc(t,{recursive:!0,force:!0}),n=1,o.push(t)}catch(a){let s=a instanceof Error?a.message:String(a);r?console.log(JSON.stringify({command:"logout",success:!1,error:s},null,2)):i.error(`Failed to clear config directory: ${s}`),process.exit(c.PERMISSION_DENIED)}}else for(let a of Ac){let s=ze(t,a);if(En(s))try{kc(s),n++,o.push(s)}catch{}}n===0&&(r?console.log(JSON.stringify({command:"logout",success:!0,alreadyLoggedOut:!0,removed:[]},null,2)):i.info("Already logged out"),process.exit(c.SUCCESS)),r?console.log(JSON.stringify({command:"logout",success:!0,removed:o,clearedAll:!!e.all},null,2)):i.success(e.all?"Cleared all nebutra config":"Logged out of nebutra.com")}function An(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 xc({all:t.all||!1,format:t.format||n.format})})}import{spawn as Oc}from"child_process";import{dirname as _c,resolve as Pc}from"path";import{fileURLToPath as Tc}from"url";import*as ie from"@clack/prompts";import fe from"picocolors";var $c=_c(Tc(import.meta.url));function Ic(){let e=[()=>Pc($c,"../../../mcp/dist/server/contextServer.js")];for(let t of e)try{return t()}catch(r){i.debug("MCP server binary resolution strategy failed",{error:r})}return"nebutra-mcp"}function xn(e){e.command("mcp").description("Start the Nebutra MCP server for Cursor/Windsurf").option("--stdio","Use stdio transport (default)",!0).action(async t=>{ie.intro(fe.bgCyan(fe.black(" nebutra mcp ")));try{let r=Ic();ie.log.info(fe.cyan("Starting Nebutra MCP server for Cursor/Windsurf integration...")),ie.log.info(fe.dim(`Press Ctrl+C to stop the server.
737
- `));let n=Oc(process.execPath,[r],{stdio:"inherit",env:{...process.env}});n.on("close",o=>{o===0?ie.outro(fe.green("MCP server stopped gracefully.")):o===null&&ie.outro(fe.yellow("MCP server terminated.")),process.exit(o??0)}),n.on("error",o=>{i.error(`
738
- Failed to start MCP server: ${o.message}`),o.code==="ENOENT"&&(i.warn(`
739
- Tip: Ensure @nebutra/mcp is installed or available in your PATH.`),i.info(" Install globally: npm install -g @nebutra/mcp"),process.exit(c.NOT_FOUND)),process.exit(c.ERROR)}),process.on("SIGINT",()=>{ie.log.info(fe.yellow(`
740
- Shutting down MCP server...`)),n.kill("SIGINT")}),process.on("SIGTERM",()=>{ie.log.info(fe.yellow("Terminating MCP server...")),n.kill("SIGTERM")})}catch(r){ie.log.error(fe.red("Error: Unable to start MCP server. Ensure @nebutra/mcp is properly installed.")),r instanceof Error&&i.error(r.message),process.exit(c.ERROR)}})}import*as V from"@clack/prompts";import ee from"picocolors";var _n=Object.fromEntries(Object.entries(mr).map(([e,t])=>[e,t]));function Pn(e){return typeof e=="boolean"?"boolean":"string"}function Nc(){let e=hr().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 jc(e){let t=e.arguments.map(a=>a.name==="components"?{...a,description:"Local feature names to install from the Nebutra registry"}:a),n=e.options.some(a=>a.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(a=>a.command.includes("--21st")||a.command.includes("--v0"))];return{...e,arguments:t,options:n,examples:o,extensions:Nc()}}function Uc(e){return{...e,extensions:{valueDomains:b,aliases:{storage:{supabase:"supabase-storage"},payment:{lemonsqueezy:"lemon"}}}}}function Tn(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:Pn(r.default)})),examples:e.examples||[]};return e.name==="add"?jc(t):e.name==="create"?Uc(t):t}function Lc(e){let r=(ce.subcommands||[]).find(n=>n.name===e);return r?Tn(r):null}function Dc(){return(ce.options??[]).map(e=>({flags:e.flags,description:e.description,required:!1,type:Pn(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:Dc(),commands:t.map(Tn),exitCodes:_n,timestamp:new Date().toISOString()}}function On(){return(ce.subcommands||[]).map(t=>t.name)}function kt(e){process.stdout.write(`${JSON.stringify(e,null,2)}
741
- `)}function Vc(e){return e instanceof Error&&e.message.startsWith("EXIT:")}async function Mc(e,t){let r=t.quiet===!0,n="0.1.0";try{if(t.all===!0&&(kt(Fc(n)),process.exit(0)),t.list===!0&&(kt(On()),process.exit(0)),(t.exitCodes===!0||t["exit-codes"]===!0)&&(kt(_n),process.exit(0)),e){let o=Lc(e);o||(r||(i.error(`Unknown command '${e}'`),i.info(`Available commands: ${On().join(", ")}`)),process.exit(c.NOT_FOUND)),kt(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(Vc(o))throw o;r||i.error(o instanceof Error?o.message:String(o)),process.exit(c.ERROR)}}function $n(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 Mc(t,r)})}import*as Et from"@clack/prompts";import te from"picocolors";function Ye(){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 Bc(e){d("Detecting search provider...","info");let t=Ye();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 Gc(e){d("Fetching search indexes...","info"),Ye().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 In(e,t){let r=t||{},n=Ye();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 Et.confirm({message:"Reindex ALL indexes? This will recreate all indexes from scratch.",initialValue:!1});(Et.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 a=e||"all";if(d(`Reindexing ${te.cyan(a)}...`,"info"),r.dryRun){d(`Would reindex ${a} with provider ${n.type}`,"info");return}d(`Reindexing ${a} on ${n.type}...`,"info"),d(`Index ${te.cyan(a)} reindexed successfully`,"success")}async function qc(e,t,r){d(`Querying ${te.cyan(e)} for "${te.yellow(t)}"...`,"info");let n=Ye();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..."}}],a={index:e,query:t,provider:n.type,hits:o.length,limit:r.limit||10,results:o};if(r.format==="json")k(a,{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 Kc(e){d("Fetching search statistics...","info");let t=Ye();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 Nn(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 a=o.optsWithGlobals?.(),s={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,force:o.force||!1,limit:o.limit??10,filters:o.filters,tenant:o.tenant};try{switch(r){case"status":await Bc(s);break;case"indexes":await Gc(s);break;case"reindex":n.length>0?await In(n[0],s):await In(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 qc(n[0],n.slice(1).join(" "),s);break;case"stats":await Kc(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",`
724
+ `)}import en from"fs";import ic from"path";import*as re from"@clack/prompts";import Ot from"picocolors";var cc={$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 lc(){return process.stdout.isTTY===!0}function dc(e){return e.yes===!0||e.dryRun===!0||!lc()}function uc(e,t,n){return{operation:n?"update":"create",path:e,...n&&{before:n},after:t}}async function xr(e={}){let t=process.cwd(),n=ic.join(t,"nebutra.config.json"),r=en.existsSync(n);e.ifNotExists&&r&&(s.info("nebutra.config.json already exists, skipping initialization."),process.exit(c.SUCCESS));let o=dc(e);o||re.intro(Ot.bgCyan(Ot.black(" nebutra init "))),r&&!o&&(re.log.warn("nebutra.config.json already exists in this directory."),await re.confirm({message:"Do you want to overwrite it?",initialValue:!1})||(re.outro("Operation aborted."),process.exit(c.CANCELLED)));let a={...cc};if(e.dryRun){let i=r?JSON.parse(en.readFileSync(n,"utf-8")):void 0,l=uc(n,a,i);A(l),d("Dry-run completed. No changes made."),process.exit(c.DRY_RUN_OK)}o?s.info("Initializing Nebutra CLI configuration..."):re.spinner().start("Initializing Nebutra CLI configuration..."),en.writeFileSync(n,JSON.stringify(a,null,2)+`
725
+ `),o?(s.success("Configuration saved to nebutra.config.json"),s.info('Initialization complete! You can now use "nebutra add" to start injecting components.')):(await new Promise(i=>setTimeout(i,800)),re.spinner().stop(Ot.green("Configuration saved to nebutra.config.json")),re.outro(Ot.cyan('Initialization complete! You can now use "nebutra add" to start injecting components.'))),process.exit(c.SUCCESS)}import tn from"fs/promises";import gc from"os";import nn from"path";import*as I from"@clack/prompts";import oe from"picocolors";var mc="https://analytics.nebutra.com";function pc(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function fc(){return process.env.npm_package_version??"0.0.0-dev"}function At(e,t={}){pc(t)||(async()=>{try{let n=await import("./dist-CRJLUGP2.js");if(typeof n.createProductAnalyticsClient!="function")return;let r=n.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??mc},onError:()=>{}});if(typeof r?.track!="function")return;let o=r.track("license.cli",{action:e.action,cli_version:fc(),...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{}})()}var Or=process.env.NEBUTRA_LICENSE_API_URL??"https://nebutra.com";async function Ar(){let e=gc.homedir(),t=nn.join(e,".config","nebutra");try{await tn.mkdir(t,{recursive:!0})}catch{}return t}async function yc(e){let t=`${Or}/api/license/validate?key=${encodeURIComponent(e)}`,n;try{n=await fetch(t,{signal:AbortSignal.timeout(1e4)})}catch{throw new Error(`Could not reach the Nebutra license server (${Or}). Check your internet connection or set NEBUTRA_LICENSE_API_URL.`)}if(n.status===404)throw new Error("License key not found. Please check the key and try again.");if(n.status===410)throw new Error("License key has expired. Please renew your license at nebutra.com.");if(!n.ok)throw new Error(`License validation failed (HTTP ${n.status}). Please try again later.`);let r=await n.json();if(!r.valid)throw new Error("License key is not valid. Please check the key and try again.");return{tier:r.tier??"UNKNOWN",type:r.type??"UNKNOWN"}}function hc(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 bc(e,t){let n=t.quiet===!0;n||I.intro(oe.bgCyan(oe.black(" Nebutra License Activation "))),At({action:"activate_attempted"});try{if(e.length<10)throw new Error("Invalid license key format.");n||I.log.step("Validating license key with Nebutra...");let{tier:r,type:o}=await yc(e),a=await Ar(),i=nn.join(a,"license.json");await tn.writeFile(i,JSON.stringify({licenseKey:e,tier:r,type:o,activatedAt:new Date().toISOString()},null,2),"utf-8"),n||(I.log.success(oe.green(`${r} license activated and saved to ${i}`)),I.outro(oe.cyan("Premium CLI capabilities are now unlocked!"))),At({action:"activated",tier:r,type:o})}catch(r){At({action:"failed",error_code:hc(r)}),n||(I.log.error(oe.red("Activation failed")),s.error(r instanceof Error?r.message:String(r)),I.outro("Please check your key and try again.")),process.exit(c.ERROR)}}async function vc(e){let t=e.quiet===!0;t||I.intro(oe.bgCyan(oe.black(" Nebutra License Status ")));try{let n=await Ar(),r=nn.join(n,"license.json"),o=await tn.readFile(r,"utf-8"),a=JSON.parse(o);if(a.licenseKey)t||(I.log.success(oe.green("License is active!")),I.log.info(`Key: ${a.licenseKey.substring(0,8)}...`),a.tier&&I.log.info(`Tier: ${oe.bold(a.tier)}`),a.type&&I.log.info(`Type: ${a.type}`),I.log.info(`Activated: ${new Date(a.activatedAt).toLocaleString()}`),I.outro(oe.cyan("You are ready to use premium features.")));else throw new Error("License key not found in config.")}catch{t||(I.log.warn(oe.yellow("No active license found locally.")),I.log.message(oe.dim("Run `nebutra license activate <key>` to unlock premium features.")),I.outro("")),process.exit(c.NOT_FOUND)}}function _r(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(n,r)=>{await bc(n,r)}),t.command("status").description("Check the locally configured license status").option("--quiet","Suppress output").action(async n=>{await vc(n)})}import{existsSync as Pr,readFileSync as wc,writeFileSync as Rc}from"fs";import{dirname as Sc,join as Ir,parse as Cc}from"path";import*as _t from"@clack/prompts";function Ec(e){let t=e,{root:n}=Cc(t);for(;;){if(Pr(Ir(t,"package.json")))return t;if(t===n)return null;let r=Sc(t);if(r===t)return null;t=r}}function kc(e){if(!Pr(e))return{};try{let t=JSON.parse(wc(e,"utf-8"));return t&&typeof t=="object"&&!Array.isArray(t)?t:{}}catch{return{}}}function xc(e,t){Rc(e,JSON.stringify(t,null,2)+`
726
+ `)}async function Oc(e,t){let n=t.format==="json",r=Ec(process.cwd());r||(n?console.log(JSON.stringify({command:"link",success:!1,error:"No package.json found upstream"},null,2)):s.error("No package.json found in current or parent directories."),process.exit(c.NOT_FOUND));let o=e;if(!o){t.yes&&(n?console.log(JSON.stringify({command:"link",success:!1,error:"project-id required in --yes mode"},null,2)):s.error("project-id is required when running with --yes / non-interactive."),process.exit(c.INVALID_ARGS));let u=await _t.text({message:"Project ID to link to:",placeholder:"proj_abc123",validate:m=>m&&m.trim().length>0?void 0:"Project ID cannot be empty"});_t.isCancel(u)&&(s.warn("Cancelled"),process.exit(c.CANCELLED)),o=String(u).trim()}let a=Ir(r,"nebutra.config.json"),l={...kc(a),projectId:o};xc(a,l),n?console.log(JSON.stringify({command:"link",success:!0,projectId:o,configPath:a},null,2)):s.success(`Linked to project: ${o}`)}function $r(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,n,r)=>{let o=r?.optsWithGlobals?.()||n;await Oc(t,{yes:o.yes||!1,format:n.format||o.format})})}import{existsSync as Nr,rmSync as Ac,unlinkSync as _c}from"fs";import{homedir as Tr,platform as Pc}from"os";import{join as nt}from"path";function Ic(){if(Pc()==="win32"){let t=process.env.LOCALAPPDATA||nt(Tr(),"AppData","Local");return nt(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?nt(e,"nebutra"):nt(Tr(),".config","nebutra")}var $c=["auth.json","session.json","token","credentials.json"];async function Nc(e){let t=Ic(),n=e.format==="json",r=0,o=[];if(e.all){if(Nr(t))try{Ac(t,{recursive:!0,force:!0}),r=1,o.push(t)}catch(a){let i=a instanceof Error?a.message:String(a);n?console.log(JSON.stringify({command:"logout",success:!1,error:i},null,2)):s.error(`Failed to clear config directory: ${i}`),process.exit(c.PERMISSION_DENIED)}}else for(let a of $c){let i=nt(t,a);if(Nr(i))try{_c(i),r++,o.push(i)}catch{}}r===0&&(n?console.log(JSON.stringify({command:"logout",success:!0,alreadyLoggedOut:!0,removed:[]},null,2)):s.info("Already logged out"),process.exit(c.SUCCESS)),n?console.log(JSON.stringify({command:"logout",success:!0,removed:o,clearedAll:!!e.all},null,2)):s.success(e.all?"Cleared all nebutra config":"Logged out of nebutra.com")}function Ur(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,n)=>{let r=n?.optsWithGlobals?.()||t;await Nc({all:t.all||!1,format:t.format||r.format})})}import{spawn as Tc}from"child_process";import{dirname as Uc,resolve as jc}from"path";import{fileURLToPath as Lc}from"url";import*as de from"@clack/prompts";import ve from"picocolors";var Dc=Uc(Lc(import.meta.url));function Fc(){let e=[()=>jc(Dc,"../../../mcp/dist/server/contextServer.js")];for(let t of e)try{return t()}catch(n){s.debug("MCP server binary resolution strategy failed",{error:n})}return"nebutra-mcp"}function jr(e){e.command("mcp").description("Start the Nebutra MCP server for Cursor/Windsurf").option("--stdio","Use stdio transport (default)",!0).action(async t=>{de.intro(ve.bgCyan(ve.black(" nebutra mcp ")));try{let n=Fc();de.log.info(ve.cyan("Starting Nebutra MCP server for Cursor/Windsurf integration...")),de.log.info(ve.dim(`Press Ctrl+C to stop the server.
727
+ `));let r=Tc(process.execPath,[n],{stdio:"inherit",env:{...process.env}});r.on("close",o=>{o===0?de.outro(ve.green("MCP server stopped gracefully.")):o===null&&de.outro(ve.yellow("MCP server terminated.")),process.exit(o??0)}),r.on("error",o=>{s.error(`
728
+ Failed to start MCP server: ${o.message}`),o.code==="ENOENT"&&(s.warn(`
729
+ Tip: Ensure @nebutra/mcp is installed or available in your PATH.`),s.info(" Install globally: npm install -g @nebutra/mcp"),process.exit(c.NOT_FOUND)),process.exit(c.ERROR)}),process.on("SIGINT",()=>{de.log.info(ve.yellow(`
730
+ Shutting down MCP server...`)),r.kill("SIGINT")}),process.on("SIGTERM",()=>{de.log.info(ve.yellow("Terminating MCP server...")),r.kill("SIGTERM")})}catch(n){de.log.error(ve.red("Error: Unable to start MCP server. Ensure @nebutra/mcp is properly installed.")),n instanceof Error&&s.error(n.message),process.exit(c.ERROR)}})}import*as M from"@clack/prompts";import se from"picocolors";var Dr=Object.fromEntries(Object.entries(Cn).map(([e,t])=>[e,t]));function Fr(e){return typeof e=="boolean"?"boolean":"string"}function Bc(){let e=An().map(n=>({name:n.name,description:n.description,envFile:n.envFile??".env.local",providers:(n.providers??[]).map(r=>({id:r.id,description:r.description,dependencies:r.dependencies??[],devDependencies:r.devDependencies??[],env:r.env??[]})),files:(n.files??[]).map(r=>r.path)})),t=Array.from(new Set(e.flatMap(n=>n.providers.map(r=>r.id))));return{localFeatures:e,valueDomains:{components:e.map(n=>n.name),provider:t}}}function Mc(e){let t=e.arguments.map(a=>a.name==="components"?{...a,description:"Local feature names to install from the Nebutra registry"}:a),r=e.options.some(a=>a.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(a=>a.command.includes("--21st")||a.command.includes("--v0"))];return{...e,arguments:t,options:r,examples:o,extensions:Bc()}}function Gc(e){return{...e,extensions:{valueDomains:b,aliases:{storage:{supabase:"supabase-storage"},payment:{lemonsqueezy:"lemon"}}}}}function Br(e){let t={name:e.name,description:e.description,usage:e.usage,arguments:e.arguments||[],options:(e.options||[]).map(n=>({flags:n.flags,description:n.description,default:n.default,required:!1,type:Fr(n.default)})),examples:e.examples||[]};return e.name==="add"?Mc(t):e.name==="create"?Gc(t):t}function Kc(e){let n=(pe.subcommands||[]).find(r=>r.name===e);return n?Br(n):null}function Vc(){return(pe.options??[]).map(e=>({flags:e.flags,description:e.description,required:!1,type:Fr(e.default)}))}function qc(e){let t=pe.subcommands||[];return{name:pe.name,version:e,description:pe.description,usage:pe.usage||"nebutra [command] [options]",globalOptions:Vc(),commands:t.map(Br),exitCodes:Dr,timestamp:new Date().toISOString()}}function Lr(){return(pe.subcommands||[]).map(t=>t.name)}function Pt(e){process.stdout.write(`${JSON.stringify(e,null,2)}
731
+ `)}function zc(e){return e instanceof Error&&e.message.startsWith("EXIT:")}async function Yc(e,t){let n=t.quiet===!0,r="0.1.0";try{if(t.all===!0&&(Pt(qc(r)),process.exit(0)),t.list===!0&&(Pt(Lr()),process.exit(0)),(t.exitCodes===!0||t["exit-codes"]===!0)&&(Pt(Dr),process.exit(0)),e){let o=Kc(e);o||(n||(s.error(`Unknown command '${e}'`),s.info(`Available commands: ${Lr().join(", ")}`)),process.exit(c.NOT_FOUND)),Pt(o),process.exit(0)}n||(M.intro(se.bgCyan(se.black(" nebutra schema "))),M.log.info(se.cyan("Agent-friendly introspection of CLI commands, arguments, and value domains.")),M.log.message(""),M.log.info(se.bold("Usage:")),M.log.message(se.dim(" nebutra schema --all Show full command tree as JSON")),M.log.message(se.dim(" nebutra schema <command> Show schema for a specific command")),M.log.message(se.dim(" nebutra schema --list List available command names")),M.log.message(se.dim(" nebutra schema --exit-codes Show exit codes reference")),M.log.message(""),M.log.info(se.bold("Example:")),M.log.message(se.dim(" nebutra schema add")),M.log.message(se.dim(" nebutra schema --all | jq '.commands[0]'")),M.outro(se.cyan("All output is JSON for easy parsing by agents and automation tools."))),process.exit(0)}catch(o){if(zc(o))throw o;n||s.error(o instanceof Error?o.message:String(o)),process.exit(c.ERROR)}}function Mr(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,n)=>{await Yc(t,n)})}import*as It from"@clack/prompts";import ae from"picocolors";function rt(){let e=process.env.MEILISEARCH_URL,t=process.env.TYPESENSE_URL,n=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"}:n?{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=rt();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 n={provider:t.type,configured:!0,url:t.url||"managed",health:t.health,message:t.message};e.format==="json"?S(n,{format:"json"}):(d(`Search Provider: ${ae.cyan(t.type.toUpperCase())}`,"success"),d(`Status: ${t.health?ae.green("Healthy"):ae.red("Unhealthy")}`,t.health?"success":"error"),t.url&&d(`URL: ${t.url}`,"info"))}async function Wc(e){d("Fetching search indexes...","info"),rt().type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let n=[{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")S(n,{format:"json"});else{d("Search Indexes","info");for(let r of n)d(`${ae.cyan(r.name)}: ${r.documentCount} documents (${r.size})`,"info")}}async function Gr(e,t){let n=t||{},r=rt();r.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&&!n.force&&!n.dryRun&&o){let i=await It.confirm({message:"Reindex ALL indexes? This will recreate all indexes from scratch.",initialValue:!1});(It.isCancel(i)||!i)&&(d("Reindex cancelled","warn"),process.exit(c.CANCELLED))}!n.yes&&!n.dryRun&&!e&&(d("Full reindex requires --yes confirmation","error"),process.exit(c.INVALID_ARGS));let a=e||"all";if(d(`Reindexing ${ae.cyan(a)}...`,"info"),n.dryRun){d(`Would reindex ${a} with provider ${r.type}`,"info");return}d(`Reindexing ${a} on ${r.type}...`,"info"),d(`Index ${ae.cyan(a)} reindexed successfully`,"success")}async function Jc(e,t,n){d(`Querying ${ae.cyan(e)} for "${ae.yellow(t)}"...`,"info");let r=rt();r.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..."}}],a={index:e,query:t,provider:r.type,hits:o.length,limit:n.limit||10,results:o};if(n.format==="json")S(a,{format:"json"});else{d(`Found ${ae.cyan(String(o.length))} results for "${t}"`,"success");for(let i of o)d(`${ae.dim(String(i.score))}: ${i.title}`,"info")}}async function Xc(e){d("Fetching search statistics...","info");let t=rt();t.type==="none"&&(d("No search provider configured","error"),process.exit(c.CONFIG_ERROR));let n={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")S(n,{format:"json"});else{d("Search Statistics","info"),d(`Provider: ${ae.cyan(n.provider)}`,"info"),d(`Total Indexes: ${n.indexes.length}`,"info"),d(`Total Documents: ${n.totalDocuments.toLocaleString()}`,"info"),d(`Total Size: ${(n.totalSize/1024/1024).toFixed(2)} MB`,"info"),d("Index Breakdown:","info");for(let r of n.indexes)d(` ${ae.cyan(r.name)}: ${r.documents.toLocaleString()} docs (${(r.size/1024/1024).toFixed(2)} MB)`,"info")}}function Kr(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(n,r,o)=>{let a=o.optsWithGlobals?.(),i={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,force:o.force||!1,limit:o.limit??10,filters:o.filters,tenant:o.tenant};try{switch(n){case"status":await Hc(i);break;case"indexes":await Wc(i);break;case"reindex":r.length>0?await Gr(r[0],i):await Gr(void 0,i);break;case"query":r.length<2&&(d("query requires an index and search term: nebutra search query <index> <query>","error"),process.exit(c.INVALID_ARGS)),await Jc(r[0],r.slice(1).join(" "),i);break;case"stats":await Xc(i);break;default:d(`Unknown search subcommand: ${n}. 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"),k("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
742
732
  Examples:
743
733
  nebutra search status Show search provider status
744
734
  nebutra search indexes List all indexes
@@ -761,7 +751,7 @@ Flags:
761
751
  --limit <n> Result limit for queries (default: 10)
762
752
  --filters <json> Filters for search query
763
753
  --tenant <id> Tenant ID for multi-tenant searches
764
- `)}import{stdin as He}from"process";import*as Ct from"@clack/prompts";import $ from"picocolors";async function Wc(){return new Promise((e,t)=>{let r="";He.setEncoding("utf8"),He.on("readable",()=>{let n;for(;(n=He.read())!==null;)r+=n}),He.on("end",()=>{e(r.trim())}),He.on("error",t)})}async function zc(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(`${$.cyan(r.key)}${$.gray(n)}`,"info"),d(` Updated: ${r.updatedAt}`,"info")}}}async function Yc(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 Wc()}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 ${$.cyan(e)}...`,"info"),t.dryRun){d(`Would encrypt and store secret ${e} for tenant ${t.tenant||"org_123"}`,"info");return}d(`Secret ${$.cyan(e)} encrypted and stored successfully`,"success"),t.description&&d(`Description: ${t.description}`,"info")}async function Hc(e,t){e||(d("Secret key is required: nebutra secrets get <key>","error"),process.exit(c.INVALID_ARGS)),d(`Retrieving secret ${$.cyan(e)}...`,"info");let n=t.unmask?"sk_live_abc123xyz789...":"***masked***";t.unmask||d(`Secret value is ${$.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(`${$.cyan(e)}: ${n}`,"info")}async function Jc(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 Ct.confirm({message:`Rotate encryption key for ${$.cyan(e)}? This will re-encrypt with new key material.`,initialValue:!1});(Ct.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 ${$.cyan(e)}...`,"info"),t.dryRun){d(`Would rotate encryption key for ${e}`,"info");return}d(`Encryption key for ${$.cyan(e)} rotated successfully`,"success"),d(`New key version: ${$.dim("v2")}`,"info")}async function Xc(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?$.green("\u2713"):$.red("\u2716");d(`${o} ${n.timestamp} ${$.cyan(n.action)} ${n.key}`,n.success?"success":"error"),d(` Actor: ${n.actor}${n.message?` \u2014 ${n.message}`:""}`,"info")}}}async function Qc(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?$.green("\u2713"):$.red("\u2716");d(`${o} ${n.name}: ${n.message}`,n.healthy?"success":"error")}let r=t.every(n=>n.healthy);d(`Overall: ${r?$.green("HEALTHY"):$.red("UNHEALTHY")}`,r?"success":"error")}}function jn(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 a=o.optsWithGlobals?.(),s={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,tenant:o.tenant||a?.tenant,unmask:o.unmask||!1,description:o.description,value:o.value,since:o.since,limit:o.limit??50};try{switch(r){case"list":await zc(s);break;case"set":n.length===0&&(d("set requires a secret key: nebutra secrets set <key>","error"),process.exit(c.INVALID_ARGS)),await Yc(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 Hc(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 Jc(n[0],s);break;case"audit":await Xc(s);break;case"verify":await Qc(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",`
754
+ `)}import{stdin as ot}from"process";import*as $t from"@clack/prompts";import $ from"picocolors";async function Qc(){return new Promise((e,t)=>{let n="";ot.setEncoding("utf8"),ot.on("readable",()=>{let r;for(;(r=ot.read())!==null;)n+=r}),ot.on("end",()=>{e(n.trim())}),ot.on("error",t)})}async function Zc(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")S(t,{format:"json"});else{d("Secrets for tenant: "+(e.tenant||"org_123"),"info");for(let n of t){let r=n.description?` \u2014 ${n.description}`:"";d(`${$.cyan(n.key)}${$.gray(r)}`,"info"),d(` Updated: ${n.updatedAt}`,"info")}}}async function el(e,t){e||(d("Secret key is required: nebutra secrets set <key>","error"),process.exit(c.INVALID_ARGS));let n;if(t.value)d("WARNING: Using --value flag exposes secret in shell history. Prefer stdin.","warn"),n=t.value;else{d("Enter secret value (will not echo). Press Ctrl+D when done:","info");try{n=await Qc()}catch{d("Failed to read secret from stdin","error"),process.exit(c.ERROR)}}if(n||(d("Secret value cannot be empty","error"),process.exit(c.INVALID_ARGS)),d(`Setting secret ${$.cyan(e)}...`,"info"),t.dryRun){d(`Would encrypt and store secret ${e} for tenant ${t.tenant||"org_123"}`,"info");return}d(`Secret ${$.cyan(e)} encrypted and stored successfully`,"success"),t.description&&d(`Description: ${t.description}`,"info")}async function tl(e,t){e||(d("Secret key is required: nebutra secrets get <key>","error"),process.exit(c.INVALID_ARGS)),d(`Retrieving secret ${$.cyan(e)}...`,"info");let r=t.unmask?"sk_live_abc123xyz789...":"***masked***";t.unmask||d(`Secret value is ${$.yellow("masked")}. Use --unmask to display.`,"warn");let o={key:e,tenant:t.tenant||"org_123",value:r,encrypted:!0};t.format==="json"?S(o,{format:"json"}):d(`${$.cyan(e)}: ${r}`,"info")}async function nl(e,t){e||(d("Secret key is required: nebutra secrets rotate <key>","error"),process.exit(c.INVALID_ARGS));let n=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!t.yes&&!t.dryRun&&n){let r=await $t.confirm({message:`Rotate encryption key for ${$.cyan(e)}? This will re-encrypt with new key material.`,initialValue:!1});($t.isCancel(r)||!r)&&(d("Rotation cancelled","warn"),process.exit(c.CANCELLED))}if(!t.yes&&!t.dryRun&&!n&&(d("Key rotation requires --yes confirmation","error"),process.exit(c.INVALID_ARGS)),d(`Rotating encryption key for ${$.cyan(e)}...`,"info"),t.dryRun){d(`Would rotate encryption key for ${e}`,"info");return}d(`Encryption key for ${$.cyan(e)} rotated successfully`,"success"),d(`New key version: ${$.dim("v2")}`,"info")}async function rl(e){d("Fetching audit log...","info");let n=[{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&&(n=n.slice(0,e.limit)),e.format==="json")S(n,{format:"json"});else{d("Secret Access Audit Log","info");for(let r of n){let o=r.success?$.green("\u2713"):$.red("\u2716");d(`${o} ${r.timestamp} ${$.cyan(r.action)} ${r.key}`,r.success?"success":"error"),d(` Actor: ${r.actor}${r.message?` \u2014 ${r.message}`:""}`,"info")}}}async function ol(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")S(t,{format:"json"});else{d("Vault Configuration Check","info");for(let r of t){let o=r.healthy?$.green("\u2713"):$.red("\u2716");d(`${o} ${r.name}: ${r.message}`,r.healthy?"success":"error")}let n=t.every(r=>r.healthy);d(`Overall: ${n?$.green("HEALTHY"):$.red("UNHEALTHY")}`,n?"success":"error")}}function Vr(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(n,r,o)=>{let a=o.optsWithGlobals?.(),i={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,tenant:o.tenant||a?.tenant,unmask:o.unmask||!1,description:o.description,value:o.value,since:o.since,limit:o.limit??50};try{switch(n){case"list":await Zc(i);break;case"set":r.length===0&&(d("set requires a secret key: nebutra secrets set <key>","error"),process.exit(c.INVALID_ARGS)),await el(r[0],i);break;case"get":r.length===0&&(d("get requires a secret key: nebutra secrets get <key>","error"),process.exit(c.INVALID_ARGS)),await tl(r[0],i);break;case"rotate":r.length===0&&(d("rotate requires a secret key: nebutra secrets rotate <key>","error"),process.exit(c.INVALID_ARGS)),await nl(r[0],i);break;case"audit":await rl(i);break;case"verify":await ol(i);break;default:d(`Unknown secrets subcommand: ${n}. 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"),k("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
765
755
  Examples:
766
756
  nebutra secrets list List all secrets (metadata only)
767
757
  nebutra secrets list --tenant org_456 List secrets for specific tenant
@@ -796,7 +786,7 @@ Security Notes:
796
786
  - Never use --value in production (visible in shell history)
797
787
  - Always use --unmask when viewing secrets in scripts
798
788
  - Audit log tracks all access and modifications
799
- `)}import*as At from"@clack/prompts";import M from"picocolors";function Un(e){switch(e.toLowerCase()){case"running":return"running";case"exited":return"exited";case"restarting":return"restarting";case"paused":return"paused";default:return"exited"}}function Zc(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 el(e){d("Checking service status...","info");let t=await x({command:"docker",args:["compose","ps","--format","json"],cwd:h(),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:Un(o.State),exitCode:o.ExitCode}));k(n,{format:"json"})}else{d("Service Status","info");let n=r.map(o=>({Service:Zc(Un(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 tl(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:h(),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 rl(e,t){let r=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!t.yes&&!t.dryRun&&r){let a=await At.confirm({message:`Restart service ${M.cyan(e)}?`,initialValue:!1});(At.isCancel(a)||!a)&&(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:h(),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 nl(e){d("Running deep health check...","info");let t=[],r=await x({command:"docker",args:["compose","exec","-T","postgres","pg_isready"],cwd:h(),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:h(),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:h(),interactive:!1,label:"ClickHouse Health",dryRun:e.dryRun});t.push({service:"ClickHouse",healthy:o.exitCode===0,message:o.exitCode===0?"Ready":"Not responding"});let a=await x({command:"docker",args:["compose","exec","-T","meilisearch","curl","-s","http://localhost:7700/health"],cwd:h(),interactive:!1,label:"Meilisearch Health",dryRun:e.dryRun});if(t.push({service:"Meilisearch",healthy:a.exitCode===0,message:a.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 ol(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:h(),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 Ln(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 a=o.optsWithGlobals?.(),s={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,tail:o.tail??100,since:o.since,timeout:o.timeout};try{switch(r){case"status":await el(s);break;case"logs":n.length===0&&(d("logs requires a service name: nebutra services logs <service>","error"),process.exit(c.INVALID_ARGS)),await tl(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 rl(n[0],s);break;case"health":await nl(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 ol(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",`
789
+ `)}import*as Nt from"@clack/prompts";import G from"picocolors";function qr(e){switch(e.toLowerCase()){case"running":return"running";case"exited":return"exited";case"restarting":return"restarting";case"paused":return"paused";default:return"exited"}}function sl(e){switch(e){case"running":return G.green("\u25CF");case"exited":return G.red("\u25CF");case"restarting":return G.yellow("\u25CF");case"paused":return G.gray("\u25CF");default:return G.gray("\u25CF")}}async function al(e){d("Checking service status...","info");let t=await O({command:"docker",args:["compose","ps","--format","json"],cwd:h(),interactive:!1,label:"Docker Compose PS",dryRun:e.dryRun});t.exitCode!==0&&(d("Failed to fetch service status","error"),k("Docker error",{stderr:t.stderr}),process.exit(c.ERROR));try{let n=JSON.parse(t.stdout);if(e.format==="json"){let r=n.map(o=>({name:o.Name,status:qr(o.State),exitCode:o.ExitCode}));S(r,{format:"json"})}else{d("Service Status","info");let r=n.map(o=>({Service:sl(qr(o.State))+" "+o.Name,Status:o.State,"Exit Code":o.ExitCode||"\u2014"}));for(let o of r)d(`${o.Service} (${o.Status})`,"info")}}catch(n){d("Failed to parse service status","error"),k("Parse error",{error:String(n)}),process.exit(c.ERROR)}}async function il(e,t){d(`Streaming logs for ${G.cyan(e)}...`,"info");let n=["compose","logs"];t.tail?n.push("--tail",String(t.tail)):n.push("--tail","100"),t.since&&n.push("--since",t.since),n.push("-f",e),(await O({command:"docker",args:n,cwd:h(),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 cl(e,t){let n=process.stdin.isTTY===!0&&process.stdout.isTTY===!0;if(!t.yes&&!t.dryRun&&n){let a=await Nt.confirm({message:`Restart service ${G.cyan(e)}?`,initialValue:!1});(Nt.isCancel(a)||!a)&&(d("Restart cancelled","warn"),process.exit(c.CANCELLED))}d(`Restarting service ${G.cyan(e)}...`,"info");let r=["compose","restart"];t.timeout&&r.push("--timeout",String(t.timeout)),r.push(e);let o=await O({command:"docker",args:r,cwd:h(),interactive:!1,label:`Docker Compose Restart (${e})`,dryRun:t.dryRun});o.exitCode===0?d(`Service ${G.cyan(e)} restarted successfully`,"success"):(d(`Failed to restart service ${e}`,"error"),k("Docker error",{stderr:o.stderr}),process.exit(c.ERROR))}async function ll(e){d("Running deep health check...","info");let t=[],n=await O({command:"docker",args:["compose","exec","-T","postgres","pg_isready"],cwd:h(),interactive:!1,label:"PostgreSQL Health",dryRun:e.dryRun});t.push({service:"PostgreSQL",healthy:n.exitCode===0,message:n.exitCode===0?"Ready":"Not responding"});let r=await O({command:"docker",args:["compose","exec","-T","redis","redis-cli","ping"],cwd:h(),interactive:!1,label:"Redis Health",dryRun:e.dryRun});t.push({service:"Redis",healthy:r.exitCode===0,message:r.exitCode===0?"Ready":"Not responding"});let o=await O({command:"docker",args:["compose","exec","-T","clickhouse","curl","-s","http://localhost:8123/ping"],cwd:h(),interactive:!1,label:"ClickHouse Health",dryRun:e.dryRun});t.push({service:"ClickHouse",healthy:o.exitCode===0,message:o.exitCode===0?"Ready":"Not responding"});let a=await O({command:"docker",args:["compose","exec","-T","meilisearch","curl","-s","http://localhost:7700/health"],cwd:h(),interactive:!1,label:"Meilisearch Health",dryRun:e.dryRun});if(t.push({service:"Meilisearch",healthy:a.exitCode===0,message:a.exitCode===0?"Healthy":"Not responding"}),e.format==="json")S(t,{format:"json"});else{for(let l of t){let u=l.healthy?G.green("\u2713"):G.red("\u2716");d(`${u} ${l.service}: ${l.message}`,l.healthy?"success":"error")}let i=t.every(l=>l.healthy);d(`Overall health: ${i?G.green("HEALTHY"):G.red("UNHEALTHY")}`,i?"success":"error")}}async function dl(e,t,n){let r=parseInt(t,10);(Number.isNaN(r)||r<0)&&(d("Invalid replica count (must be a non-negative number)","error"),process.exit(c.INVALID_ARGS)),d(`Scaling ${G.cyan(e)} to ${G.cyan(String(r))} replicas...`,"info");let o=await O({command:"docker",args:["compose","up","-d","--scale",`${e}=${r}`],cwd:h(),interactive:!1,label:`Docker Compose Scale (${e})`,dryRun:n.dryRun});o.exitCode===0?d(`Service ${G.cyan(e)} scaled to ${r} replicas`,"success"):(d(`Failed to scale service ${e}`,"error"),k("Docker error",{stderr:o.stderr}),process.exit(c.ERROR))}function zr(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(n,r,o)=>{let a=o.optsWithGlobals?.(),i={dryRun:o.dryRun||a?.dryRun,yes:o.yes||a?.yes,format:o.format||a?.format,tail:o.tail??100,since:o.since,timeout:o.timeout};try{switch(n){case"status":await al(i);break;case"logs":r.length===0&&(d("logs requires a service name: nebutra services logs <service>","error"),process.exit(c.INVALID_ARGS)),await il(r[0],i);break;case"restart":r.length===0&&(d("restart requires a service name: nebutra services restart <service>","error"),process.exit(c.INVALID_ARGS)),await cl(r[0],i);break;case"health":await ll(i);break;case"scale":r.length<2&&(d("scale requires a service name and replica count: nebutra services scale <service> <count>","error"),process.exit(c.INVALID_ARGS)),await dl(r[0],r[1],i);break;default:d(`Unknown services subcommand: ${n}. 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"),k("Full error",{error:l}),process.exit(c.ERROR)}}).addHelpText("after",`
800
790
  Examples:
801
791
  nebutra services status Show all service status
802
792
  nebutra services logs postgres Stream postgres logs
@@ -817,22 +807,22 @@ Flags:
817
807
  --tail <n> Log lines to show (default: 100)
818
808
  --since <duration> Show logs since (e.g., 10m, 1h)
819
809
  --timeout <seconds> Timeout for restart
820
- `)}import{existsSync as Q,readdirSync as Je,readFileSync as Dn}from"fs";import{resolve as B}from"path";import Ue from"picocolors";function Oe(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 Fn(e){try{let t=Dn(B(e,"package.json"),"utf-8");return JSON.parse(t)}catch{return{}}}function Vn(e){try{return Je(e,{recursive:!0}).length}catch{return 0}}async function il(e){i.info("Gathering monorepo statistics...");let t=h(),r=B(t,"packages"),n=B(t,"apps"),o=[],a=[],s=0,l="unknown";try{Q(r)&&(o=Je(r).filter(p=>!p.startsWith(".")&&Q(B(r,p,"package.json")))),Q(n)&&(a=Je(n).filter(p=>!p.startsWith(".")&&Q(B(n,p,"package.json"))));let m=B(t,"nebutra.config.ts");if(Q(m)){let y=Dn(m,"utf-8").match(/preset:\s*["']([^"']+)["']/);y&&(l=y[1])}}catch(m){i.warn(`Failed to read monorepo structure: ${m instanceof Error?m.message:String(m)}`)}let u={monorepo:{root:t,packages:o.length,apps:a.length,preset:l},statistics:{totalWorkspaces:o.length+a.length,packageCount:o.length,appCount:a.length}};e.dryRun||(i.success(`Found ${u.statistics.totalWorkspaces} workspaces`),i.info(`Packages: ${u.statistics.packageCount}, Apps: ${u.statistics.appCount}`),i.info(`Preset: ${l}`)),Oe(u,e.format,"stats")}async function al(e){i.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&&i.warn("Size analysis failed. Ensure your project is built."),Oe(r,e.format,"stats:size")}async function sl(e){i.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?i.success("No unused dependencies detected"):i.info("Run 'npx knip' to see detailed dependency analysis")),Oe(r,e.format,"stats:deps")}async function cl(e){i.info("Listing packages...");let t=h(),r=B(t,"packages"),n=[];try{Q(r)&&(n=Je(r).filter(s=>!s.startsWith(".")&&Q(B(r,s,"package.json"))).map(s=>{let l=B(r,s),u=Fn(l);return{name:u.name||s,version:u.version,description:u.description,files:Vn(l)}}))}catch(a){i.error(`Failed to list packages: ${a instanceof Error?a.message:String(a)}`),process.exit(c.ERROR)}let o={packages:n,total:n.length};e.dryRun||e.format==="json"?Oe(o,e.format,"stats:packages"):(console.log(`
821
- ${Ue.cyan("Packages")} (${n.length} total)
822
- `),n.forEach(a=>{console.log(` ${Ue.blue(a.name)}`),a.version&&console.log(` version: ${a.version}`),a.description&&console.log(` ${a.description}`),console.log(` files: ${a.files}`)}),console.log(""))}async function ll(e){i.info("Listing apps...");let t=h(),r=B(t,"apps"),n=[];try{Q(r)&&(n=Je(r).filter(s=>!s.startsWith(".")&&Q(B(r,s,"package.json"))).map(s=>{let l=B(r,s),u=Fn(l),m=Q(B(l,"next.config.ts"))||Q(B(l,"next.config.js")),p=Q(B(l,"server.ts"))||Q(B(l,"server.js"));return{name:u.name||s,version:u.version,description:u.description,files:Vn(l),status:m||p?"ready":"unknown"}}))}catch(a){i.error(`Failed to list apps: ${a instanceof Error?a.message:String(a)}`),process.exit(c.ERROR)}let o={apps:n,total:n.length,ready:n.filter(a=>a.status==="ready").length};e.dryRun||e.format==="json"?Oe(o,e.format,"stats:apps"):(console.log(`
823
- ${Ue.cyan("Apps")} (${n.length} total, ${o.ready} ready)
824
- `),n.forEach(a=>{let s=a.status==="ready"?Ue.green("\u2713"):Ue.gray("\u25CB");console.log(` ${s} ${Ue.blue(a.name)}`),a.version&&console.log(` version: ${a.version}`),a.description&&console.log(` ${a.description}`),console.log(` files: ${a.files}`)}),console.log(""))}function Mn(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 il({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 al({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 sl({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 cl({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 ll({format:r.format||n.format})})}import*as G from"@clack/prompts";import I from"picocolors";var Yt=["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 dl(e){let t=`@nebutra/${e}`;if(!Yt.includes(e)){let r=I.yellow(`Valid apps: ${Yt.join(", ")}`);throw new Error(`Invalid app: ${I.red(e)}
825
- ${r}`)}return t}async function ul(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(I.red("Cannot use --watch or --coverage with --app filter (app-level tests use turbo)")),process.exit(c.INVALID_ARGS)),e.app){dl(e.app);let n=`@nebutra/${e.app}`;e.quiet||G.log.info(I.cyan(`Running tests for ${I.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(I.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error(I.red(t.message)):G.log.error(I.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Bn(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(I.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(I.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error(I.red(t.message)):G.log.error(I.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Gn(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(I.cyan(n))}let r=await K(t,{interactive:!0});process.exit(r.exitCode)}catch(t){t instanceof Error?G.log.error(I.red(t.message)):G.log.error(I.red("Unknown error occurred")),process.exit(c.ERROR)}}async function qn(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(I.cyan("Running architecture tests..."));let t=await K("test:arch",{interactive:!0});process.exit(t.exitCode)}catch(t){t instanceof Error?G.log.error(I.red(t.message)):G.log.error(I.red("Unknown error occurred")),process.exit(c.ERROR)}}function Kn(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: ${Yt.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 Bn({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 Gn({why:n.why||!1,dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):r==="arch"?await qn({dryRun:n.dryRun||!1,quiet:o.quiet||!1,verbose:o.verbose||!1,format:o.format}):await ul({...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 Bn({...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 Gn({...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 qn({dryRun:r.dryRun||!1,quiet:n.quiet||!1,verbose:n.verbose||!1,format:n.format})})}var Wn={$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=Wn,Xp=we.themes.map(e=>e.id);var Qp=we.defaultTheme;function zn(e){return we.themes.find(t=>t.id===e)}function Yn(e){let t=e.opts?e.opts():e,r=e.optsWithGlobals?e.optsWithGlobals():e;return t.format??r.format??pl()}function pl(){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 fl(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 gl(e="table"){let t=we.themes.map(fl);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 yl(e,t="table"){let r=zn(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 Hn(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(gl(Yn(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=yl(r,Yn(n));o||(i.error(`Theme '${r}' was not found in the Nebutra theme registry.`),process.exit(c.NOT_FOUND)),console.log(o)})}import{existsSync as Qn,readFileSync as Zn}from"fs";import{resolve as Jn,join as Ht}from"path";function eo(e={}){let t=e.manifestPath?Jn(e.manifestPath):Ht(Jn(e.root??process.cwd()),"apps","design-docs","public","agent-manifest.json");return{manifestPath:t,componentDir:Ht(t,"..","agent","components")}}function hl(e){return e.trim().toLowerCase()}function bl(e){let t=hl(e);if(!/^[a-z0-9-]+$/.test(t))throw new Error(`Invalid UI component name "${e}". Use a registry kebab-case id such as "button".`);return t}function to(e={}){let{manifestPath:t}=eo(e);if(!Qn(t))throw new Error(`Missing Nebutra UI agent manifest at ${t}. Run pnpm --filter @nebutra/design-docs build:registry.`);return JSON.parse(Zn(t,"utf8"))}function Jt(e,t={}){let r=bl(e),{componentDir:n}=eo(t),o=Ht(n,`${r}.json`);if(!Qn(o))throw new Error(`UI component contract not found: ${r}`);return JSON.parse(Zn(o,"utf8"))}function ro(e,t="",r={}){let n=t.trim().toLowerCase(),o=Xn(r.limit??20,1,100),a=Xn(r.offset??0,0,Number.MAX_SAFE_INTEGER),s=r.tag?.trim().toLowerCase(),l=e.components.filter(p=>r.status&&p.status!==r.status||r.maturity&&p.maturity!==r.maturity||s&&!p.tags.includes(s)?!1:n?vl(p).includes(n):!0).map(p=>({component:p,score:wl(p,n)})).sort((p,y)=>y.score-p.score||p.component.name.localeCompare(y.component.name)).map(({component:p})=>p),u=l.slice(a,a+o),m=a+u.length;return{query:t,total:l.length,count:u.length,offset:a,limit:o,hasMore:m<l.length,...m<l.length&&{nextOffset:m},items:u}}function Xt(e){let t=[],r=[];return e.evidence.source||t.push("Missing source evidence."),e.evidence.docs||t.push("Missing docs evidence."),e.evidence.registry||t.push("Missing registry evidence."),(e.status==="stable"||e.maturity==="canonical")&&!e.evidence.storybook&&t.push("Stable/canonical components must have Storybook evidence."),!e.evidence.tokens&&e.package==="@nebutra/ui"&&r.push("No token evidence was detected; confirm this primitive intentionally has no CSS variables."),e.migration.requiredForBreakingChanges&&e.migration.hints.length===0&&r.push("Breaking-change migration policy is enabled but no migration hints are present."),{name:e.name,valid:t.length===0,errors:t,warnings:r,evidence:e.evidence,migration:e.migration}}function vl(e){return[e.name,e.title,e.description,e.status,e.maturity,e.layer,e.source,...e.tags].join(" ").toLowerCase()}function wl(e,t){return t?e.name===t?100:e.name.startsWith(t)?80:e.title.toLowerCase().startsWith(t)?70:e.tags.includes(t)?60:e.name.includes(t)?50:e.title.toLowerCase().includes(t)?40:e.description.toLowerCase().includes(t)?20:1:e.maturity==="canonical"?20:10}function Xn(e,t,r){return Number.isFinite(e)?Math.min(Math.max(Math.trunc(e),t),r):t}import{stderr as Sl}from"process";import Se from"picocolors";function Rl(){return process.stderr.isTTY===!0&&!process.env.CI&&!process.env.NEBUTRA_NON_TTY}function kl(e){let t=[];return t.push(Se.red(`\u2716 ${e.error}`)),t.push(Se.white(e.message)),e.suggestion&&(t.push(""),t.push(Se.cyan("\u{1F4A1} Suggestion:")),t.push(Se.gray(` ${e.suggestion}`))),process.env.NEBUTRA_DEBUG&&e.context&&Object.keys(e.context).length>0&&(t.push(""),t.push(Se.dim("Debug context:")),t.push(Se.dim(JSON.stringify(e.context,null,2)))),process.env.NEBUTRA_DEBUG&&e.stack&&(t.push(""),t.push(Se.dim("Stack trace:")),t.push(Se.dim(e.stack))),t.join(`
828
- `)}function El(e){let t={error:e.error,message:e.message,...e.suggestion&&{suggestion:e.suggestion},retryable:e.retryable,exitCode:e.exitCode,...e.context&&Object.keys(e.context).length>0&&{context:e.context},...process.env.NEBUTRA_DEBUG&&e.stack&&{stack:e.stack}};return JSON.stringify(t)}function Xe(e){return{error:e.error,message:e.message,suggestion:e.suggestion,retryable:e.retryable??!1,exitCode:e.exitCode??c.ERROR,context:e.context,stack:e.cause?.stack}}function Qt(e){let t=Rl()?kl(e):El(e);Sl.write(t+`
829
- `)}function Cl(e){Qt(e),process.exit(e.exitCode)}function Zt(e,t){Cl(Xe({error:"not_found",message:e,suggestion:t??"Check the resource path and try again",exitCode:c.NOT_FOUND}))}function xt(e){let t=e.opts?e.opts():e,r=e.optsWithGlobals?e.optsWithGlobals():e;return t.format??r.format??Al()}function Al(){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 tr(e){let t=e.opts?e.opts():e;return{root:h(),manifestPath:t.manifest}}function no(e,t){if(!e)return t;let r=Number(e);return Number.isFinite(r)?r:t}function xl(e,t="json"){if(t==="plain"||t==="table"){let r=[`Nebutra UI components (${e.total})`,""];for(let n of e.items)r.push(`${n.name.padEnd(22)} ${n.status.padEnd(12)} ${n.maturity.padEnd(10)} ${n.title}`);return e.hasMore&&r.push("",`Next offset: ${e.nextOffset}`),r.join(`
830
- `)}return JSON.stringify(e,null,2)}function Ol(e,t="json"){return t==="plain"||t==="table"?[`${e.title} (${e.name})`,`Status: ${e.status}`,`Maturity: ${e.maturity}`,`Source: ${e.source}`,`Package import: ${e.imports.package}`,`Registry: ${e.imports.registry}`,`Docs: ${e.docs.routes.join(", ")||"missing"}`,`Storybook: ${e.docs.storybook??"missing"}`,`Tokens: ${e.tokens.join(", ")||"none detected"}`].join(`
831
- `):JSON.stringify(e,null,2)}function _l(e,t="json"){if(t==="plain"||t==="table"){if("results"in e){let r=[`Nebutra UI validation: ${e.valid?"valid":"invalid"}`,`Total: ${e.total}`,`Invalid: ${e.invalid}`];for(let n of e.results.filter(o=>!o.valid))r.push(`- ${n.name}: ${n.errors.join("; ")}`);return r.join(`
832
- `)}return[`${e.name}: ${e.valid?"valid":"invalid"}`,...e.errors.map(r=>`error: ${r}`),...e.warnings.map(r=>`warning: ${r}`)].join(`
833
- `)}return JSON.stringify(e,null,2)}function Pl(e,t="json"){let r={component:e.name,dryRun:!0,codemods:e.migration.codemods,hints:e.migration.hints,requiredForBreakingChanges:e.migration.requiredForBreakingChanges};return t==="plain"||t==="table"?[`Migration hints for ${e.name}`,`Codemods: ${r.codemods.length===0?"none registered":r.codemods.join(", ")}`,...r.hints.map(n=>`- ${n}`)].join(`
834
- `):JSON.stringify(r,null,2)}function er(e,t){try{return Jt(e,tr(t))}catch{Zt(`UI component contract not found: ${e}`,"Run `nebutra ui search <query> --format json` to discover available component ids.")}}function oo(e){try{return to(tr(e))}catch(t){Zt(t instanceof Error?t.message:"UI agent manifest not found","Run `pnpm --filter @nebutra/design-docs build:registry` from the Nebutra monorepo.")}}function Tl(e,t){let r=e.components.map(o=>Xt(Jt(o.name,tr(t)))),n=r.filter(o=>!o.valid).length;return{valid:n===0,total:r.length,invalid:n,results:r}}function io(e){let t=e.command("ui").description("Inspect Nebutra UI agent contracts, production evidence, and migration hints");t.command("search [query]").description("Search the agent-readable @nebutra/ui component contract").option("--limit <number>","Maximum number of results","20").option("--offset <number>","Pagination offset","0").option("--tag <tag>","Filter by generated tag").option("--status <status>","Filter by status").option("--maturity <maturity>","Filter by maturity").option("--manifest <path>","Read a specific agent-manifest.json").option("--format <type>","Output format: json, table, plain").action((r,n)=>{let o=oo(n),a=ro(o,r??"",{limit:no(n.limit,20),offset:no(n.offset,0),tag:n.tag,status:n.status,maturity:n.maturity});console.log(xl(a,xt(n)))}),t.command("component <name>").description("Print one component contract with imports, evidence, and migration policy").option("--manifest <path>","Read a specific agent-manifest.json").option("--format <type>","Output format: json, table, plain").action((r,n)=>{let o=er(r,n);console.log(Ol(o,xt(n)))}),t.command("validate [name]").description("Validate production evidence for one component or the full UI contract").option("--manifest <path>","Read a specific agent-manifest.json").option("--warn-only","Report validation failures without a non-zero exit").option("--format <type>","Output format: json, table, plain").action((r,n)=>{let o=r?Xt(er(r,n)):Tl(oo(n),n);console.log(_l(o,xt(n))),!o.valid&&!n.warnOnly&&process.exit(c.INCOMPATIBLE)}),t.command("migrate <name>").description("Print dry-run codemod and migration hints for a component").option("--manifest <path>","Read a specific agent-manifest.json").option("--apply","Reserved for future codemod execution").option("--format <type>","Output format: json, table, plain").action((r,n)=>{n.apply&&(console.error("Codemod execution is not implemented yet. Use `nebutra ui migrate <name>` for the dry-run plan."),process.exit(c.INCOMPATIBLE));let o=er(r,n);console.log(Pl(o,xt(n)))})}import{existsSync as ao,readFileSync as $l,unlinkSync as Il,writeFileSync as Nl}from"fs";import{dirname as jl,join as so,parse as Ul}from"path";function Ll(e){let t=e,{root:r}=Ul(t);for(;;){if(ao(so(t,"package.json")))return t;if(t===r)return null;let n=jl(t);if(n===t)return null;t=n}}async function Dl(e){let t=e.format==="json",r=Ll(process.cwd())??process.cwd(),n=so(r,"nebutra.config.json");if(ao(n)||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):i.info("Already unlinked"),process.exit(c.SUCCESS)),e.force){try{Il(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)):i.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)):i.success("Removed nebutra.config.json");return}let o={};try{o=JSON.parse($l(n,"utf-8"))}catch{o={}}"projectId"in o||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):i.info("Already unlinked"),process.exit(c.SUCCESS));let{projectId:a,...s}=o;Nl(n,JSON.stringify(s,null,2)+`
835
- `),t?console.log(JSON.stringify({command:"unlink",success:!0,configPath:n},null,2)):i.success("Unlinked from project")}function co(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 Dl({force:t.force||!1,format:t.format||n.format})})}import{spawnSync as Jl}from"child_process";import{promises as Ot}from"fs";import{homedir as Fl}from"os";import{join as uo}from"path";import Vl from"p-timeout";import Re from"picocolors";var Ml=1440*60*1e3,mo=uo(Fl(),".nebutra"),rr=uo(mo,"update-check.json"),Bl="https://registry.npmjs.org/nebutra",Gl=5e3;async function ql(){try{await Ot.mkdir(mo,{recursive:!0})}catch{}}async function Kl(){try{let e=await Ot.readFile(rr,"utf-8"),t=JSON.parse(e);return Date.now()-t.timestamp<Ml?t:(await Ot.unlink(rr).catch(n=>{i.debug("Failed to remove expired update cache file",{error:n})}),null)}catch{return null}}async function Wl(e){try{await ql();let t={timestamp:Date.now(),latestVersion:e};await Ot.writeFile(rr,JSON.stringify(t,null,2),"utf-8")}catch{}}async function zl(){try{let e=new AbortController,t=await Vl(fetch(Bl,{signal:e.signal,headers:{Accept:"application/json"}}),{milliseconds:Gl,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 lo(e){return e.split(".").map(t=>parseInt(t.replace(/[^0-9]/g,""),10)||0).slice(0,3)}function Yl(e,t){let r=lo(e),n=lo(t);for(let o=0;o<3;o++){let a=r[o]??0,s=n[o]??0;if(s>a)return!0;if(s<a)return!1}return!1}async function nr(e){let t=await Kl(),r=null;return t?r=t.latestVersion:(r=await zl(),r&&await Wl(r)),!r||!Yl(e,r)?null:{currentVersion:e,latestVersion:r,isUpdate:!0}}function Hl(e){let r=`Update available: ${e.currentVersion} \u2192 ${e.latestVersion}`,n="Run `npm i -g nebutra` to update",o=" ".repeat((43-r.length)/2),a=" ".repeat((43-n.length)/2),s=[Re.cyan("\u256D"+"\u2500".repeat(41)+"\u256E"),Re.cyan("\u2502")+Re.yellow(o+r+o)+Re.cyan("\u2502"),Re.cyan("\u2502")+Re.gray(a+n+a)+Re.cyan("\u2502"),Re.cyan("\u2570"+"\u2500".repeat(41)+"\u256F")]}async function po(e){let t=null;return nr(e).then(r=>{t=r}),async()=>{!process.stdout.isTTY||process.env.CI||(t||await new Promise(r=>setTimeout(r,100)),t&&Hl(t))}}function Xl(){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 Ql(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 _e="0.1.0";async function Zl(e){let t=Xl(),r=Ql(t),n=e.format==="json",o=await nr(_e),a=o?.latestVersion??null,s=!!o?.isUpdate;e.dryRun&&(n?console.log(JSON.stringify({command:"upgrade",dryRun:!0,installer:t,command_to_run:r,currentVersion:_e,latestVersion:a,hasUpdate:s},null,2)):(i.info(`Detected installer: ${t}`),i.info(`Current: ${_e}${a?` \u2192 Latest: ${a}`:""}`),i.info(`Upgrade command: ${r}`)),process.exit(c.DRY_RUN_OK)),!s&&a&&(n?console.log(JSON.stringify({command:"upgrade",success:!0,alreadyLatest:!0,version:_e},null,2)):i.success(`Already on the latest version (${_e})`),process.exit(c.SUCCESS)),e.yes||(n?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,command_to_run:r,currentVersion:_e,latestVersion:a,requiresConfirmation:!0},null,2)):(i.info(`Current: ${_e}${a?` \u2192 Latest: ${a}`:""}`),i.info("To upgrade, run:"),i.info(` ${r}`),i.info("Or re-run this command with --yes to execute it now.")),process.exit(c.SUCCESS));let[l,...u]=r.split(" ");n||i.info(`Running: ${r}`);let m=Jl(l,u,{stdio:n?"pipe":"inherit"});m.status===0&&(n?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,ran:r},null,2)):i.success("Upgrade complete"),process.exit(c.SUCCESS));let p=m.stderr?.toString()||`Upgrade failed (exit ${m.status})`;n?console.log(JSON.stringify({command:"upgrade",success:!1,installer:t,ran:r,error:p},null,2)):i.error(p),process.exit(c.ERROR)}function fo(e){let t=(r,n)=>{let o=n?.optsWithGlobals?.()||r;return Zl({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 or from"fs";import ir from"path";import ed from"picocolors";var ar=["inngest","n8n","pusher"],td=`import { Inngest } from "inngest";
810
+ `)}import{existsSync as ne,readdirSync as st,readFileSync as Yr}from"fs";import{resolve as K}from"path";import Ve from"picocolors";function Te(e,t,n){if(t==="json"){let r={command:n||"stats",...e};console.log(JSON.stringify(r,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 Hr(e){try{let t=Yr(K(e,"package.json"),"utf-8");return JSON.parse(t)}catch{return{}}}function Wr(e){try{return st(e,{recursive:!0}).length}catch{return 0}}async function ul(e){s.info("Gathering monorepo statistics...");let t=h(),n=K(t,"packages"),r=K(t,"apps"),o=[],a=[],i=0,l="unknown";try{ne(n)&&(o=st(n).filter(f=>!f.startsWith(".")&&ne(K(n,f,"package.json")))),ne(r)&&(a=st(r).filter(f=>!f.startsWith(".")&&ne(K(r,f,"package.json"))));let m=K(t,"nebutra.config.ts");if(ne(m)){let y=Yr(m,"utf-8").match(/preset:\s*["']([^"']+)["']/);y&&(l=y[1])}}catch(m){s.warn(`Failed to read monorepo structure: ${m instanceof Error?m.message:String(m)}`)}let u={monorepo:{root:t,packages:o.length,apps:a.length,preset:l},statistics:{totalWorkspaces:o.length+a.length,packageCount:o.length,appCount:a.length}};e.dryRun||(s.success(`Found ${u.statistics.totalWorkspaces} workspaces`),s.info(`Packages: ${u.statistics.packageCount}, Apps: ${u.statistics.appCount}`),s.info(`Preset: ${l}`)),Te(u,e.format,"stats")}async function ml(e){s.info("Analyzing bundle and dependency sizes...");let t=await O({command:"pnpm",args:["size"],interactive:!1,label:"Analyze package sizes",dryRun:e.dryRun}),n={analysis:"pnpm size",exitCode:t.exitCode,...t.stdout&&{stdout:t.stdout},...t.stderr&&{stderr:t.stderr}};t.exitCode!==0&&s.warn("Size analysis failed. Ensure your project is built."),Te(n,e.format,"stats:size")}async function pl(e){s.info("Analyzing dependencies...");let t=await O({command:"npx",args:["knip","--no-progress"],interactive:!1,label:"Analyze dependencies",dryRun:e.dryRun}),n={analysis:"knip (unused dependencies)",exitCode:t.exitCode,command:"npx knip",...t.stdout&&{stdout:t.stdout.substring(0,500)}};e.dryRun||(t.exitCode===0?s.success("No unused dependencies detected"):s.info("Run 'npx knip' to see detailed dependency analysis")),Te(n,e.format,"stats:deps")}async function fl(e){s.info("Listing packages...");let t=h(),n=K(t,"packages"),r=[];try{ne(n)&&(r=st(n).filter(i=>!i.startsWith(".")&&ne(K(n,i,"package.json"))).map(i=>{let l=K(n,i),u=Hr(l);return{name:u.name||i,version:u.version,description:u.description,files:Wr(l)}}))}catch(a){s.error(`Failed to list packages: ${a instanceof Error?a.message:String(a)}`),process.exit(c.ERROR)}let o={packages:r,total:r.length};e.dryRun||e.format==="json"?Te(o,e.format,"stats:packages"):(console.log(`
811
+ ${Ve.cyan("Packages")} (${r.length} total)
812
+ `),r.forEach(a=>{console.log(` ${Ve.blue(a.name)}`),a.version&&console.log(` version: ${a.version}`),a.description&&console.log(` ${a.description}`),console.log(` files: ${a.files}`)}),console.log(""))}async function gl(e){s.info("Listing apps...");let t=h(),n=K(t,"apps"),r=[];try{ne(n)&&(r=st(n).filter(i=>!i.startsWith(".")&&ne(K(n,i,"package.json"))).map(i=>{let l=K(n,i),u=Hr(l),m=ne(K(l,"next.config.ts"))||ne(K(l,"next.config.js")),f=ne(K(l,"server.ts"))||ne(K(l,"server.js"));return{name:u.name||i,version:u.version,description:u.description,files:Wr(l),status:m||f?"ready":"unknown"}}))}catch(a){s.error(`Failed to list apps: ${a instanceof Error?a.message:String(a)}`),process.exit(c.ERROR)}let o={apps:r,total:r.length,ready:r.filter(a=>a.status==="ready").length};e.dryRun||e.format==="json"?Te(o,e.format,"stats:apps"):(console.log(`
813
+ ${Ve.cyan("Apps")} (${r.length} total, ${o.ready} ready)
814
+ `),r.forEach(a=>{let i=a.status==="ready"?Ve.green("\u2713"):Ve.gray("\u25CB");console.log(` ${i} ${Ve.blue(a.name)}`),a.version&&console.log(` version: ${a.version}`),a.description&&console.log(` ${a.description}`),console.log(` files: ${a.files}`)}),console.log(""))}function Jr(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 n=>{let r=typeof n.optsWithGlobals=="function"?n.optsWithGlobals():n;await ul({format:typeof n.format=="string"?n.format:typeof r.format=="string"?r.format:void 0})}),t.command("size").description("Analyze bundle and package sizes").option("--format <type>","Output format: json or plain").action(async n=>{let r=n.optsWithGlobals?.()||n;await ml({format:n.format||r.format})}),t.command("deps").description("Analyze dependencies (unused, missing, duplicate)").option("--format <type>","Output format: json or plain").action(async n=>{let r=n.optsWithGlobals?.()||n;await pl({format:n.format||r.format})}),t.command("packages").description("List all packages with metadata").option("--format <type>","Output format: json or plain").action(async n=>{let r=n.optsWithGlobals?.()||n;await fl({format:n.format||r.format})}),t.command("apps").description("List all apps with status").option("--format <type>","Output format: json or plain").action(async n=>{let r=n.optsWithGlobals?.()||n;await gl({format:n.format||r.format})})}import*as V from"@clack/prompts";import N from"picocolors";function xe(e){if(e==="json"||e==="plain"||e==="table")return e}var rn=["landing","web","storybook","backends/gateway","design-docs","studio","docs","ui","tokens","brand","theme","icons","preset","queue","search","notifications","permissions","webhooks","metering","uploads","vault","tenant"];function yl(e){let t=`@nebutra/${e}`;if(!rn.includes(e)){let n=N.yellow(`Valid apps: ${rn.join(", ")}`);throw new Error(`Invalid app: ${N.red(e)}
815
+ ${n}`)}return t}async function hl(e){e.dryRun&&(A({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:xe(e.format)}),process.exit(c.DRY_RUN_OK));try{if(e.app&&(e.watch||e.coverage)&&(V.log.error(N.red("Cannot use --watch or --coverage with --app filter (app-level tests use turbo)")),process.exit(c.INVALID_ARGS)),e.app){yl(e.app);let r=`@nebutra/${e.app}`;e.quiet||V.log.info(N.cyan(`Running tests for ${N.bold(r)}...`));let o=await we("test",{filter:r});process.exit(o.exitCode)}let t="test";if(e.coverage?t="test:coverage":e.watch&&(t="test:watch"),!e.quiet){let r=t==="test:coverage"?"Running tests with coverage...":t==="test:watch"?"Running tests in watch mode...":"Running tests...";V.log.info(N.cyan(r))}let n=await z(t,{interactive:!0});process.exit(n.exitCode)}catch(t){t instanceof Error?V.log.error(N.red(t.message)):V.log.error(N.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Xr(e){e.dryRun&&(A({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:xe(e.format)}),process.exit(c.DRY_RUN_OK));try{e.ui&&e.ci&&(V.log.error(N.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 r=t==="e2e:ci"?"Running E2E tests (CI mode)...":t==="e2e:ui"?"Opening E2E tests in UI mode...":"Running E2E tests...";V.log.info(N.cyan(r))}let n=await z(t,{interactive:!0});process.exit(n.exitCode)}catch(t){t instanceof Error?V.log.error(N.red(t.message)):V.log.error(N.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Qr(e){e.dryRun&&(A({mode:"dry-run",timestamp:new Date().toISOString(),command:"test size",options:{why:e.why},task:e.why?"pnpm size:why":"pnpm size"},{format:xe(e.format)}),process.exit(c.DRY_RUN_OK));try{let t=e.why?"size:why":"size";if(!e.quiet){let r=e.why?"Analyzing bundle size (showing largest assets)...":"Checking bundle size...";V.log.info(N.cyan(r))}let n=await z(t,{interactive:!0});process.exit(n.exitCode)}catch(t){t instanceof Error?V.log.error(N.red(t.message)):V.log.error(N.red("Unknown error occurred")),process.exit(c.ERROR)}}async function Zr(e){e.dryRun&&(A({mode:"dry-run",timestamp:new Date().toISOString(),command:"test arch",task:"pnpm test:arch"},{format:xe(e.format)}),process.exit(c.DRY_RUN_OK));try{e.quiet||V.log.info(N.cyan("Running architecture tests..."));let t=await z("test:arch",{interactive:!0});process.exit(t.exitCode)}catch(t){t instanceof Error?V.log.error(N.red(t.message)):V.log.error(N.red("Unknown error occurred")),process.exit(c.ERROR)}}var eo=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: ${rn.join(", ")}`).option("--dry-run","Preview what would run (exit code 10)").action(async(n,r,o)=>{let a=x(r,o),i={dryRun:!!r.dryRun,quiet:!!a.quiet,verbose:!!a.verbose,format:xe(a.format)};n==="e2e"?await Xr({...i,ui:!!r.ui,ci:!!r.ci}):n==="size"?await Qr({...i,why:!!r.why}):n==="arch"?await Zr(i):await hl({...i,watch:!!r.watch,coverage:!!r.coverage,app:typeof r.app=="string"?r.app:void 0})});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(n,r)=>{let o=x(n,r);await Xr({ui:!!n.ui,ci:!!n.ci,dryRun:!!n.dryRun,quiet:!!o.quiet,verbose:!!o.verbose,format:xe(o.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(n,r)=>{let o=x(n,r);await Qr({why:!!n.why,dryRun:!!n.dryRun,quiet:!!o.quiet,verbose:!!o.verbose,format:xe(o.format)})}),t.command("arch").description("Run architecture tests (verify design layer isolation)").option("--dry-run","Preview what would run (exit code 10)").action(async(n,r)=>{let o=x(n,r);await Zr({dryRun:!!n.dryRun,quiet:!!o.quiet,verbose:!!o.verbose,format:xe(o.format)})})};var to={$schema:"https://nebutra.com/schemas/design-language-registry.json",version:"2026.07",defaultLanguage:"factory",description:"Design-language catalog for global product chrome swap (Create Center / SaaS theme). Not color moods \u2014 full Brand Packages (roles + recipe + elev + zones).",languages:[{id:"factory",name:"Nebutra Factory",kind:"design-language",description:"Default product chrome from @nebutra/tokens (no skin). Clear data-brand to restore.",proves:["factory HSL SSOT","recipe defaults","action\u2261brand-mark until skin"],darkDefault:!0,brandPath:null,skinPath:null,install:{command:"nebutra theme use factory",cssImport:null},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}},{id:"gsap",name:"GSAP",kind:"design-language",description:"Dark cream-on-void; shockingly-green is accent \u2014 CTA is gradient-stroke/outline, not solid green fill.",proves:["outline / gradient-stroke recipe","category extensions","marketing display zone"],darkDefault:!0,brandPath:"brands/gsap/brand.json",skinPath:"skins/gsap.css",install:{command:"nebutra theme use gsap",cssImport:"@nebutra/tokens/skins/gsap.css"},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}},{id:"linear",name:"Linear",kind:"design-language",description:"Dual-mode: dark void default + light paper; solid acid-lime CTA, compact density.",proves:["chromatic solid action","dark product chrome","dual-mode light/dark palettes"],darkDefault:!0,brandPath:"brands/linear/brand.json",skinPath:"skins/linear.css",install:{command:"nebutra theme use linear",cssImport:"@nebutra/tokens/skins/linear.css"},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}},{id:"notion",name:"Notion",kind:"design-language",description:"Warm paper notebook; Notion Blue sole filled CTA \u2260 Ink brand-mark; 8px buttons / 12px cards; elev=none + hairline; accent hues decorative only.",proves:["action \u2260 brand-mark (blue vs ink)","canvas\u2260card (paper-warmth vs pure-white)","elevation=none content cards + raised nav shadow slot","table radius priority (8/12 over tertiary 4px)","decorative accents never product CTA"],darkDefault:!1,brandPath:"brands/notion/brand.json",skinPath:"skins/notion.css",install:{command:"nebutra theme use notion",cssImport:"@nebutra/tokens/skins/notion.css"},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}},{id:"raycast",name:"Raycast",kind:"design-language",description:"Neutral Mist/Iron filled CTA; Coral is brand-mark only. Key elevation stack.",proves:["action \u2260 brand-mark","elevation=key free CSS"],darkDefault:!0,brandPath:"brands/raycast/brand.json",skinPath:"skins/raycast.css",install:{command:"nebutra theme use raycast",cssImport:"@nebutra/tokens/skins/raycast.css"},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}},{id:"stripe",name:"Stripe",kind:"design-language",description:"Indigo-ink ledger on frost glass; Indigo action \u2260 Midnight brand-mark; 4px controls; elevation=none (tint + frost rules).",proves:["action \u2260 brand-mark (chromatic indigo vs midnight)","elevation=none tint-ladder depth","4px squared controls (not pill)","whisper heading weight 300"],darkDefault:!1,brandPath:"brands/stripe/brand.json",skinPath:"skins/stripe.css",install:{command:"nebutra theme use stripe",cssImport:"@nebutra/tokens/skins/stripe.css"},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}},{id:"vanta",name:"Vanta",kind:"design-language",description:"Editorial violet on parchment; Vivid Violet action \u2260 Indigo Ink brand-mark; full pills; elevation=none (carbon hairlines).",proves:["action \u2260 brand-mark (chromatic)","elevation=none border-only","999px pill controls","serif display + sans UI zones"],darkDefault:!1,brandPath:"brands/vanta/brand.json",skinPath:"skins/vanta.css",install:{command:"nebutra theme use vanta",cssImport:"@nebutra/tokens/skins/vanta.css"},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}},{id:"vercel",name:"Vercel",kind:"design-language",description:"Monochrome dual-mode: light paper + Obsidian CTA; dark carbon + white CTA; hairline elevation (no chromatic CTA).",proves:["light monochrome action","elevation=hairline","dual-mode light/dark palettes"],darkDefault:!1,brandPath:"brands/vercel/brand.json",skinPath:"skins/vercel.css",install:{command:"nebutra theme use vercel",cssImport:"@nebutra/tokens/skins/vercel.css"},compatibility:{tailwind:"4",cssVariables:!0,brandPackage:!0,dataBrand:!0}}]};var Ue=to,sf=Ue.languages.map(e=>e.id),no=Ue.defaultLanguage;function ro(e){return Ue.languages.find(t=>t.id===e)}function oo(e){let t=e.opts?e.opts():e,n=e.optsWithGlobals?e.optsWithGlobals():e;return t.format??n.format??vl()}function vl(){let e=process.argv.find(n=>n.startsWith("--format="));if(e)return e.slice(9);let t=process.argv.indexOf("--format");if(t>=0)return process.argv[t+1]}function wl(e="table"){let t=Ue.languages;return e==="json"?JSON.stringify({version:Ue.version,defaultLanguage:Ue.defaultLanguage,count:t.length,languages:t},null,2):[`Nebutra design languages (${t.length}) \u2014 global product chrome swap`,`Default: ${no} (factory tokens; no skin)`,"Contract: roles.action \u2192 CTA; roles.brand \u2192 brand-mark; free elev/radii/zones","",...t.map(r=>`${r.id.padEnd(10)} ${r.darkDefault?"dark ":"light"} ${(r.proves[0]??"").slice(0,48)} ${r.description.slice(0,56)}`)].join(`
816
+ `)}function Rl(e,t="table"){let n=ro(e);if(n)return t==="json"?JSON.stringify(n,null,2):[`${n.name} (${n.id}) \u2014 design language`,`Description: ${n.description}`,`Dark default: ${n.darkDefault}`,`Brand JSON: ${n.brandPath??"(factory \u2014 none)"}`,`Skin CSS: ${n.skinPath??"(factory \u2014 none)"}`,`Install: ${n.install.command}`,`CSS import: ${n.install.cssImport??"(clear data-brand)"}`,`Proves: ${n.proves.join("; ")}`].join(`
817
+ `)}function so(e){let t=e.command("theme").description("Design languages (Brand Package global product chrome swap)");t.command("list").description("List design languages").option("--format <type>","Output format: json or table").action(n=>{console.log(wl(oo(n)))}),t.command("inspect <id>").description("Show a design language by id").option("--format <type>","Output format: json or table").action((n,r)=>{let o=Rl(n,oo(r));o||(s.error(`Design language '${n}' not found. Run: nebutra theme list`),process.exit(c.NOT_FOUND)),console.log(o)})}import{existsSync as co,readFileSync as lo}from"fs";import{resolve as ao,join as on}from"path";function uo(e={}){let t=e.manifestPath?ao(e.manifestPath):on(ao(e.root??process.cwd()),"apps","design-docs","public","agent-manifest.json");return{manifestPath:t,componentDir:on(t,"..","agent","components")}}function Sl(e){return e.trim().toLowerCase()}function Cl(e){let t=Sl(e);if(!/^[a-z0-9-]+$/.test(t))throw new Error(`Invalid UI component name "${e}". Use a registry kebab-case id such as "button".`);return t}function mo(e={}){let{manifestPath:t}=uo(e);if(!co(t))throw new Error(`Missing Nebutra UI agent manifest at ${t}. Run pnpm --filter @nebutra/design-docs build:registry.`);return JSON.parse(lo(t,"utf8"))}function sn(e,t={}){let n=Cl(e),{componentDir:r}=uo(t),o=on(r,`${n}.json`);if(!co(o))throw new Error(`UI component contract not found: ${n}`);return JSON.parse(lo(o,"utf8"))}function po(e,t="",n={}){let r=t.trim().toLowerCase(),o=io(n.limit??20,1,100),a=io(n.offset??0,0,Number.MAX_SAFE_INTEGER),i=n.tag?.trim().toLowerCase(),l=e.components.filter(f=>n.status&&f.status!==n.status||n.maturity&&f.maturity!==n.maturity||i&&!f.tags.includes(i)?!1:r?El(f).includes(r):!0).map(f=>({component:f,score:kl(f,r)})).sort((f,y)=>y.score-f.score||f.component.name.localeCompare(y.component.name)).map(({component:f})=>f),u=l.slice(a,a+o),m=a+u.length;return{query:t,total:l.length,count:u.length,offset:a,limit:o,hasMore:m<l.length,...m<l.length&&{nextOffset:m},items:u}}function an(e){let t=[],n=[];return e.evidence.source||t.push("Missing source evidence."),e.evidence.docs||t.push("Missing docs evidence."),e.evidence.registry||t.push("Missing registry evidence."),(e.status==="stable"||e.maturity==="canonical")&&!e.evidence.storybook&&t.push("Stable/canonical components must have Storybook evidence."),!e.evidence.tokens&&e.package==="@nebutra/ui"&&n.push("No token evidence was detected; confirm this primitive intentionally has no CSS variables."),e.migration.requiredForBreakingChanges&&e.migration.hints.length===0&&n.push("Breaking-change migration policy is enabled but no migration hints are present."),{name:e.name,valid:t.length===0,errors:t,warnings:n,evidence:e.evidence,migration:e.migration}}function El(e){return[e.name,e.title,e.description,e.status,e.maturity,e.layer,e.source,...e.tags].join(" ").toLowerCase()}function kl(e,t){return t?e.name===t?100:e.name.startsWith(t)?80:e.title.toLowerCase().startsWith(t)?70:e.tags.includes(t)?60:e.name.includes(t)?50:e.title.toLowerCase().includes(t)?40:e.description.toLowerCase().includes(t)?20:1:e.maturity==="canonical"?20:10}function io(e,t,n){return Number.isFinite(e)?Math.min(Math.max(Math.trunc(e),t),n):t}import{stderr as xl}from"process";import Oe from"picocolors";function Ol(){return process.stderr.isTTY===!0&&!process.env.CI&&!process.env.NEBUTRA_NON_TTY}function Al(e){let t=[];return t.push(Oe.red(`\u2716 ${e.error}`)),t.push(Oe.white(e.message)),e.suggestion&&(t.push(""),t.push(Oe.cyan("\u{1F4A1} Suggestion:")),t.push(Oe.gray(` ${e.suggestion}`))),process.env.NEBUTRA_DEBUG&&e.context&&Object.keys(e.context).length>0&&(t.push(""),t.push(Oe.dim("Debug context:")),t.push(Oe.dim(JSON.stringify(e.context,null,2)))),process.env.NEBUTRA_DEBUG&&e.stack&&(t.push(""),t.push(Oe.dim("Stack trace:")),t.push(Oe.dim(e.stack))),t.join(`
818
+ `)}function _l(e){let t={error:e.error,message:e.message,...e.suggestion&&{suggestion:e.suggestion},retryable:e.retryable,exitCode:e.exitCode,...e.context&&Object.keys(e.context).length>0&&{context:e.context},...process.env.NEBUTRA_DEBUG&&e.stack&&{stack:e.stack}};return JSON.stringify(t)}function at(e){return{error:e.error,message:e.message,suggestion:e.suggestion,retryable:e.retryable??!1,exitCode:e.exitCode??c.ERROR,context:e.context,stack:e.cause?.stack}}function cn(e){let t=Ol()?Al(e):_l(e);xl.write(t+`
819
+ `)}function Pl(e){cn(e),process.exit(e.exitCode)}function ln(e,t){Pl(at({error:"not_found",message:e,suggestion:t??"Check the resource path and try again",exitCode:c.NOT_FOUND}))}function Tt(e){let t=e.opts?e.opts():e,n=e.optsWithGlobals?e.optsWithGlobals():e;return t.format??n.format??Il()}function Il(){let e=process.argv.find(n=>n.startsWith("--format="));if(e)return e.slice(9);let t=process.argv.indexOf("--format");if(t>=0)return process.argv[t+1]}function un(e){let t=e.opts?e.opts():e;return{root:h(),manifestPath:t.manifest}}function fo(e,t){if(!e)return t;let n=Number(e);return Number.isFinite(n)?n:t}function $l(e,t="json"){if(t==="plain"||t==="table"){let n=[`Nebutra UI components (${e.total})`,""];for(let r of e.items)n.push(`${r.name.padEnd(22)} ${r.status.padEnd(12)} ${r.maturity.padEnd(10)} ${r.title}`);return e.hasMore&&n.push("",`Next offset: ${e.nextOffset}`),n.join(`
820
+ `)}return JSON.stringify(e,null,2)}function Nl(e,t="json"){return t==="plain"||t==="table"?[`${e.title} (${e.name})`,`Status: ${e.status}`,`Maturity: ${e.maturity}`,`Source: ${e.source}`,`Package import: ${e.imports.package}`,`Registry: ${e.imports.registry}`,`Docs: ${e.docs.routes.join(", ")||"missing"}`,`Storybook: ${e.docs.storybook??"missing"}`,`Tokens: ${e.tokens.join(", ")||"none detected"}`].join(`
821
+ `):JSON.stringify(e,null,2)}function Tl(e,t="json"){if(t==="plain"||t==="table"){if("results"in e){let n=[`Nebutra UI validation: ${e.valid?"valid":"invalid"}`,`Total: ${e.total}`,`Invalid: ${e.invalid}`];for(let r of e.results.filter(o=>!o.valid))n.push(`- ${r.name}: ${r.errors.join("; ")}`);return n.join(`
822
+ `)}return[`${e.name}: ${e.valid?"valid":"invalid"}`,...e.errors.map(n=>`error: ${n}`),...e.warnings.map(n=>`warning: ${n}`)].join(`
823
+ `)}return JSON.stringify(e,null,2)}function Ul(e,t="json"){let n={component:e.name,dryRun:!0,codemods:e.migration.codemods,hints:e.migration.hints,requiredForBreakingChanges:e.migration.requiredForBreakingChanges};return t==="plain"||t==="table"?[`Migration hints for ${e.name}`,`Codemods: ${n.codemods.length===0?"none registered":n.codemods.join(", ")}`,...n.hints.map(r=>`- ${r}`)].join(`
824
+ `):JSON.stringify(n,null,2)}function dn(e,t){try{return sn(e,un(t))}catch{ln(`UI component contract not found: ${e}`,"Run `nebutra ui search <query> --format json` to discover available component ids.")}}function go(e){try{return mo(un(e))}catch(t){ln(t instanceof Error?t.message:"UI agent manifest not found","Run `pnpm --filter @nebutra/design-docs build:registry` from the Nebutra monorepo.")}}function jl(e,t){let n=e.components.map(o=>an(sn(o.name,un(t)))),r=n.filter(o=>!o.valid).length;return{valid:r===0,total:n.length,invalid:r,results:n}}function yo(e){let t=e.command("ui").description("Inspect Nebutra UI agent contracts, production evidence, and migration hints");t.command("search [query]").description("Search the agent-readable @nebutra/ui component contract").option("--limit <number>","Maximum number of results","20").option("--offset <number>","Pagination offset","0").option("--tag <tag>","Filter by generated tag").option("--status <status>","Filter by status").option("--maturity <maturity>","Filter by maturity").option("--manifest <path>","Read a specific agent-manifest.json").option("--format <type>","Output format: json, table, plain").action((n,r)=>{let o=go(r),a=po(o,n??"",{limit:fo(r.limit,20),offset:fo(r.offset,0),tag:r.tag,status:r.status,maturity:r.maturity});console.log($l(a,Tt(r)))}),t.command("component <name>").description("Print one component contract with imports, evidence, and migration policy").option("--manifest <path>","Read a specific agent-manifest.json").option("--format <type>","Output format: json, table, plain").action((n,r)=>{let o=dn(n,r);console.log(Nl(o,Tt(r)))}),t.command("validate [name]").description("Validate production evidence for one component or the full UI contract").option("--manifest <path>","Read a specific agent-manifest.json").option("--warn-only","Report validation failures without a non-zero exit").option("--format <type>","Output format: json, table, plain").action((n,r)=>{let o=n?an(dn(n,r)):jl(go(r),r);console.log(Tl(o,Tt(r))),!o.valid&&!r.warnOnly&&process.exit(c.INCOMPATIBLE)}),t.command("migrate <name>").description("Print dry-run codemod and migration hints for a component").option("--manifest <path>","Read a specific agent-manifest.json").option("--apply","Reserved for future codemod execution").option("--format <type>","Output format: json, table, plain").action((n,r)=>{r.apply&&(console.error("Codemod execution is not implemented yet. Use `nebutra ui migrate <name>` for the dry-run plan."),process.exit(c.INCOMPATIBLE));let o=dn(n,r);console.log(Ul(o,Tt(r)))})}import{existsSync as ho,readFileSync as Ll,unlinkSync as Dl,writeFileSync as Fl}from"fs";import{dirname as Bl,join as bo,parse as Ml}from"path";function Gl(e){let t=e,{root:n}=Ml(t);for(;;){if(ho(bo(t,"package.json")))return t;if(t===n)return null;let r=Bl(t);if(r===t)return null;t=r}}async function Kl(e){let t=e.format==="json",n=Gl(process.cwd())??process.cwd(),r=bo(n,"nebutra.config.json");if(ho(r)||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):s.info("Already unlinked"),process.exit(c.SUCCESS)),e.force){try{Dl(r)}catch(l){let u=l instanceof Error?l.message:String(l);t?console.log(JSON.stringify({command:"unlink",success:!1,error:u},null,2)):s.error(`Failed to delete config: ${u}`),process.exit(c.PERMISSION_DENIED)}t?console.log(JSON.stringify({command:"unlink",success:!0,deletedConfig:!0,configPath:r},null,2)):s.success("Removed nebutra.config.json");return}let o={};try{o=JSON.parse(Ll(r,"utf-8"))}catch{o={}}"projectId"in o||(t?console.log(JSON.stringify({command:"unlink",success:!0,alreadyUnlinked:!0},null,2)):s.info("Already unlinked"),process.exit(c.SUCCESS));let{projectId:a,...i}=o;Fl(r,JSON.stringify(i,null,2)+`
825
+ `),t?console.log(JSON.stringify({command:"unlink",success:!0,configPath:r},null,2)):s.success("Unlinked from project")}function vo(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,n)=>{let r=n?.optsWithGlobals?.()||t;await Kl({force:t.force||!1,format:t.format||r.format})})}import{spawnSync as td}from"child_process";import{promises as Ut}from"fs";import{homedir as Vl}from"os";import{join as Ro}from"path";import ql from"p-timeout";import Ae from"picocolors";var zl=1440*60*1e3,So=Ro(Vl(),".nebutra"),mn=Ro(So,"update-check.json"),Yl="https://registry.npmjs.org/nebutra",Hl=5e3;async function Wl(){try{await Ut.mkdir(So,{recursive:!0})}catch{}}async function Jl(){try{let e=await Ut.readFile(mn,"utf-8"),t=JSON.parse(e);return Date.now()-t.timestamp<zl?t:(await Ut.unlink(mn).catch(r=>{s.debug("Failed to remove expired update cache file",{error:r})}),null)}catch{return null}}async function Xl(e){try{await Wl();let t={timestamp:Date.now(),latestVersion:e};await Ut.writeFile(mn,JSON.stringify(t,null,2),"utf-8")}catch{}}async function Ql(){try{let e=new AbortController,t=await ql(fetch(Yl,{signal:e.signal,headers:{Accept:"application/json"}}),{milliseconds:Hl,fallback:()=>(e.abort(),null)});if(!t?.ok)return null;let r=(await t.json())["dist-tags"];return!r||typeof r.latest!="string"?null:r.latest}catch{return null}}function wo(e){return e.split(".").map(t=>parseInt(t.replace(/[^0-9]/g,""),10)||0).slice(0,3)}function Zl(e,t){let n=wo(e),r=wo(t);for(let o=0;o<3;o++){let a=n[o]??0,i=r[o]??0;if(i>a)return!0;if(i<a)return!1}return!1}async function pn(e){let t=await Jl(),n=null;return t?n=t.latestVersion:(n=await Ql(),n&&await Xl(n)),!n||!Zl(e,n)?null:{currentVersion:e,latestVersion:n,isUpdate:!0}}function ed(e){let n=`Update available: ${e.currentVersion} \u2192 ${e.latestVersion}`,r="Run `npm i -g nebutra` to update",o=" ".repeat((43-n.length)/2),a=" ".repeat((43-r.length)/2),i=[Ae.cyan("\u256D"+"\u2500".repeat(41)+"\u256E"),Ae.cyan("\u2502")+Ae.yellow(o+n+o)+Ae.cyan("\u2502"),Ae.cyan("\u2502")+Ae.gray(a+r+a)+Ae.cyan("\u2502"),Ae.cyan("\u2570"+"\u2500".repeat(41)+"\u256F")]}async function Co(e){let t=null;return pn(e).then(n=>{t=n}),async()=>{!process.stdout.isTTY||process.env.CI||(t||await new Promise(n=>setTimeout(n,100)),t&&ed(t))}}function nd(){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 n=process.env.npm_config_user_agent||"";return n.startsWith("pnpm")?"pnpm":n.startsWith("yarn")?"yarn":n.startsWith("bun")?"bun":n.startsWith("npm")?"npm":"unknown"}function rd(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 je="0.1.0";async function od(e){let t=nd(),n=rd(t),r=e.format==="json",o=await pn(je),a=o?.latestVersion??null,i=!!o?.isUpdate;e.dryRun&&(r?console.log(JSON.stringify({command:"upgrade",dryRun:!0,installer:t,command_to_run:n,currentVersion:je,latestVersion:a,hasUpdate:i},null,2)):(s.info(`Detected installer: ${t}`),s.info(`Current: ${je}${a?` \u2192 Latest: ${a}`:""}`),s.info(`Upgrade command: ${n}`)),process.exit(c.DRY_RUN_OK)),!i&&a&&(r?console.log(JSON.stringify({command:"upgrade",success:!0,alreadyLatest:!0,version:je},null,2)):s.success(`Already on the latest version (${je})`),process.exit(c.SUCCESS)),e.yes||(r?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,command_to_run:n,currentVersion:je,latestVersion:a,requiresConfirmation:!0},null,2)):(s.info(`Current: ${je}${a?` \u2192 Latest: ${a}`:""}`),s.info("To upgrade, run:"),s.info(` ${n}`),s.info("Or re-run this command with --yes to execute it now.")),process.exit(c.SUCCESS));let[l,...u]=n.split(" ");r||s.info(`Running: ${n}`);let m=td(l,u,{stdio:r?"pipe":"inherit"});m.status===0&&(r?console.log(JSON.stringify({command:"upgrade",success:!0,installer:t,ran:n},null,2)):s.success("Upgrade complete"),process.exit(c.SUCCESS));let f=m.stderr?.toString()||`Upgrade failed (exit ${m.status})`;r?console.log(JSON.stringify({command:"upgrade",success:!1,installer:t,ran:n,error:f},null,2)):s.error(f),process.exit(c.ERROR)}function Eo(e){let t=(n,r)=>{let o=r?.optsWithGlobals?.()||n;return od({yes:n.yes||o.yes||!1,dryRun:n.dryRun||!1,format:n.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 fn from"fs";import gn from"path";import sd from"picocolors";var yn=["inngest","n8n","pusher"],ad=`import { Inngest } from "inngest";
836
826
 
837
827
  export const inngest = new Inngest({ id: "nebutra-sailor" });
838
828
 
@@ -846,7 +836,7 @@ export const exampleFn = inngest.createFunction(
846
836
  return { status: "completed" };
847
837
  },
848
838
  );
849
- `,rd=`# n8n Workflows (Self-hosted Convention)
839
+ `,id=`# n8n Workflows (Self-hosted Convention)
850
840
 
851
841
  Nebutra Sailor uses n8n in self-hosted mode for visual workflow orchestration.
852
842
 
@@ -870,7 +860,7 @@ docker run -it --rm \\
870
860
  ## Webhook endpoints
871
861
 
872
862
  Production webhooks route through \`backends/gateway\` (see \`packages/integrations/webhooks\`).
873
- `,nd=`{
863
+ `,cd=`{
874
864
  "name": "example-workflow",
875
865
  "nodes": [
876
866
  {
@@ -886,7 +876,7 @@ Production webhooks route through \`backends/gateway\` (see \`packages/integrati
886
876
  "settings": {},
887
877
  "tags": []
888
878
  }
889
- `,od=`import Pusher from "pusher";
879
+ `,ld=`import Pusher from "pusher";
890
880
 
891
881
  export const pusher = new Pusher({
892
882
  appId: process.env.PUSHER_APP_ID ?? "",
@@ -902,8 +892,8 @@ export async function publishExample(channel: string, event: string, data: unkno
902
892
  }
903
893
  return pusher.trigger(channel, event, data);
904
894
  }
905
- `;function id(e){switch(e){case"inngest":return[{relPath:"workflows/inngest/example.ts",content:td}];case"n8n":return[{relPath:"workflows/n8n/README.md",content:rd},{relPath:"workflows/n8n/example.json",content:nd}];case"pusher":return[{relPath:"workflows/pusher/example.ts",content:od}]}}async function ad(e,t={}){ar.includes(e)||(i.error(`Invalid provider: ${ed.red(e)}. Valid: ${ar.join(", ")}`),process.exit(c.INVALID_ARGS));let r=h(),n=id(e);t.dryRun&&(O({mode:"dry-run",command:`workflow init ${e}`,files:n.map(s=>({path:ir.join(r,s.relPath)}))}),process.exit(c.DRY_RUN_OK));let o=0,a=0;for(let s of n){let l=ir.join(r,s.relPath);if(or.existsSync(l)){i.warn(`Skipping ${s.relPath} \u2014 already exists.`),a++;continue}or.mkdirSync(ir.dirname(l),{recursive:!0}),or.writeFileSync(l,s.content),t.quiet||i.success(`Created ${s.relPath}`),o++}o===0&&a>0&&(i.info(`No files created \u2014 ${e} scaffold already present.`),process.exit(c.CONFLICT)),process.exit(c.SUCCESS)}function go(e){e.command("workflow").description("Manage workflow provider scaffolding (inngest | n8n | pusher)").command("init <provider>").description(`Scaffold a starter workflow file for a provider (${ar.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 ad(r,{dryRun:n.dryRun||!1,quiet:o.quiet||!1})})}var Qe=class extends Error{code;exitCode;suggestion;retryable;context;cause;constructor(t){super(t.message),this.name="CommandError",this.code=t.code,this.exitCode=t.exitCode??c.ERROR,this.suggestion=t.suggestion,this.retryable=t.retryable??!1,this.context=t.context,this.cause=t.cause}};function sd(e){return e instanceof Qe}function cd(e){return sd(e)?Xe({error:e.code,message:e.message,suggestion:e.suggestion,retryable:e.retryable,exitCode:e.exitCode,context:e.context,cause:e.cause instanceof Error?e.cause:e}):e instanceof Error?Xe({error:"unexpected_error",message:e.message,suggestion:"Re-run with NEBUTRA_DEBUG=1 for a stack trace.",exitCode:c.ERROR,cause:e}):Xe({error:"unexpected_error",message:String(e),suggestion:"Re-run with NEBUTRA_DEBUG=1 for a stack trace.",exitCode:c.ERROR})}function sr(e){let t=cd(e);return Qt(t),t.exitCode}async function cr(e){try{await e()}catch(t){process.exitCode=sr(t)}}import{existsSync as ld,mkdirSync as yo,writeFileSync as ho}from"fs";import{homedir as bo,platform as dd}from"os";import{join as Ze}from"path";function ud(){if(dd()==="win32"){let t=process.env.LOCALAPPDATA||Ze(bo(),"AppData","Local");return Ze(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?Ze(e,"nebutra"):Ze(bo(),".config","nebutra")}function md(){let e=process.env.NEBUTRA_TELEMETRY;return e==="0"||e==="false"||e==="no"}function vo(){if(!process.stderr.isTTY||!process.stdin.isTTY||process.env.CI)return;let e=ud(),t=Ze(e,"first-run-acked");try{if(ld(t))return}catch{return}if(md()){try{yo(e,{recursive:!0}),ho(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(`
906
- `))}catch{}try{yo(e,{recursive:!0}),ho(t,"")}catch{}}var hd=gd(fd(lr(import.meta.url)),"..","package.json"),Ro=JSON.parse(pd(hd,"utf8")).version;function bd(e){let t=new yd,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(n=>cr(async()=>{let o=n.optsWithGlobals?n.optsWithGlobals():n;await yn({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 a=o.optsWithGlobals?o.optsWithGlobals():o;await Cr(n,{...o,yes:a.yes||!r})}),Jr(t),xn(t),$n(t),Br(t),fn(t),gn(t),an(t),wn(t),Nr(t),jr(t),Vr(t),Mn(t),Xr(t),mn(t),Qr(t),Kn(t),go(t),Fr(t),tn(t),Hn(t),io(t),_r(t),Gr(t),pn(t),nn(t),Ln(t),Nn(t),jn(t),Hr(t),An(t),fo(t),kn(t),co(t),t.command("doctor").description("Check your Nebutra project setup for common issues").action(()=>cr(async()=>{let{logger:n}=await import("./logger-WOLJCPZK.js"),{findMonorepoRoot:o}=await import("./delegate-7HQKV277.js"),a=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})`),a.existsSync(s.join(u,"nebutra.config.json"))?n.success("nebutra.config.json found"):n.warn("nebutra.config.json missing. Try running 'nebutra init'"),a.existsSync(s.join(u,"package.json"))?n.success("package.json found"):(n.error("No package.json found in root directory"),l=!0),a.existsSync(s.join(u,".env"))||a.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");a.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");a.existsSync(L)?n.success("backends/gateway/ present"):a.existsSync(s.join(u,"backends"));let D=s.join(u,"packages");if(a.existsSync(D)){let ae=new Set(["design","iam","commerce","integrations","platform","ops","ai"]);try{let ke=a.readdirSync(D,{withFileTypes:!0}),f=[];for(let F of ke){if(!F.isDirectory()||ae.has(F.name))continue;let Pe=s.join(D,F.name,"package.json");a.existsSync(Pe)&&f.push(F.name)}f.length>0?n.warn(`Found ${f.length} uncategorized package(s) under packages/: ${f.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");if(a.existsSync(ue)?n.success(".nebutra/scaffold-meta.json present (CLI-scaffolded project)"):a.existsSync(q)&&n.warn(".nebutra/ directory exists but scaffold-meta.json is missing. Run `nebutra license verify` for details."),l)throw new Qe({code:"doctor_failed",message:"Doctor found critical issues that require your attention.",suggestion:"Fix the errors above, then re-run `nebutra doctor`.",exitCode: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",`
895
+ `;function dd(e){switch(e){case"inngest":return[{relPath:"workflows/inngest/example.ts",content:ad}];case"n8n":return[{relPath:"workflows/n8n/README.md",content:id},{relPath:"workflows/n8n/example.json",content:cd}];case"pusher":return[{relPath:"workflows/pusher/example.ts",content:ld}]}}async function ud(e,t={}){yn.includes(e)||(s.error(`Invalid provider: ${sd.red(e)}. Valid: ${yn.join(", ")}`),process.exit(c.INVALID_ARGS));let n=h(),r=dd(e);t.dryRun&&(A({mode:"dry-run",command:`workflow init ${e}`,files:r.map(i=>({path:gn.join(n,i.relPath)}))}),process.exit(c.DRY_RUN_OK));let o=0,a=0;for(let i of r){let l=gn.join(n,i.relPath);if(fn.existsSync(l)){s.warn(`Skipping ${i.relPath} \u2014 already exists.`),a++;continue}fn.mkdirSync(gn.dirname(l),{recursive:!0}),fn.writeFileSync(l,i.content),t.quiet||s.success(`Created ${i.relPath}`),o++}o===0&&a>0&&(s.info(`No files created \u2014 ${e} scaffold already present.`),process.exit(c.CONFLICT)),process.exit(c.SUCCESS)}var ko=e=>{e.command("workflow").description("Manage workflow provider scaffolding (inngest | n8n | pusher)").command("init <provider>").description(`Scaffold a starter workflow file for a provider (${yn.join(" | ")})`).option("--dry-run","Preview files that would be created (exit code 10)").action(async(n,r,o)=>{let a=x(r,o);await ud(n,{dryRun:!!r.dryRun,quiet:!!a.quiet})})};var it=class extends Error{code;exitCode;suggestion;retryable;context;cause;constructor(t){super(t.message),this.name="CommandError",this.code=t.code,this.exitCode=t.exitCode??c.ERROR,this.suggestion=t.suggestion,this.retryable=t.retryable??!1,this.context=t.context,this.cause=t.cause}};function md(e){return e instanceof it}function pd(e){return md(e)?at({error:e.code,message:e.message,suggestion:e.suggestion,retryable:e.retryable,exitCode:e.exitCode,context:e.context,cause:e.cause instanceof Error?e.cause:e}):e instanceof Error?at({error:"unexpected_error",message:e.message,suggestion:"Re-run with NEBUTRA_DEBUG=1 for a stack trace.",exitCode:c.ERROR,cause:e}):at({error:"unexpected_error",message:String(e),suggestion:"Re-run with NEBUTRA_DEBUG=1 for a stack trace.",exitCode:c.ERROR})}function hn(e){let t=pd(e);return cn(t),t.exitCode}async function bn(e){try{await e()}catch(t){process.exitCode=hn(t)}}import{existsSync as fd,mkdirSync as Oo,writeFileSync as Ao}from"fs";import{homedir as _o,platform as gd}from"os";import{join as ct}from"path";var xo={name:"Nebutra",nameCn:"\u4E91\u6BD3\u667A\u80FD",nameFull:"\u65E0\u9521\u4E91\u6BD3\u667A\u80FD\u79D1\u6280\u6709\u9650\u516C\u53F8",nameFullEn:"Wuxi Nebutra Intelligence Technology Co., Ltd.",tagline:"Ship AI products, not boilerplate.",taglineCn:"AI\u539F\u751F\xB7\u5FEB\u901F\u51FA\u6D77\xB7\u5373\u523B\u4EA4\u4ED8",description:"Production-ready Next.js monorepo template for AI SaaS products. Auth, billing, multi-tenancy, AI services, design system, and enterprise infrastructure \u2014 pre-configured.",descriptionCn:"\u9762\u5411AI\u521B\u4E1A\u8005\u7684\u4E00\u4F53\u5316SaaS\u57FA\u7840\u8BBE\u65BD\u6A21\u677F\uFF0C\u8986\u76D6\u8BA4\u8BC1\u3001\u8BA1\u8D39\u3001\u591A\u79DF\u6237\u3001AI\u670D\u52A1\u4E0E\u8BBE\u8BA1\u7CFB\u7EDF\uFF0C\u5F00\u7BB1\u5373\u4EA7\u54C1",story:{concept:"Logo\u4EE5\u9996\u5B57\u6BCDN\u7684\u57FA\u7840\u9020\u578B\u6982\u5FF5\u4E3A\u4E3B\u8981\u8BBE\u8BA1\u6846\u67B6\uFF0C\u901A\u8FC7\u51E0\u4F55\u6B63\u8D1F\u7A7A\u95F4\u6784\u5EFA\u9690\u5F62'N'\uFF0C\u5F62\u6210\u8FD1\u4F3C\u516D\u8FB9\u5F62\u7684\u7A33\u5B9A\u7ED3\u6784",colorMeaning:"\u84DD\u7EFF\u6E10\u53D8\u4F53\u73B0\u672A\u6765\u611F\u4E0E\u79D1\u6280\u950B\u8292\uFF0C'\u4E91'\u4EE3\u8868\u4E91\u7AEF\u5E73\u53F0\uFF0C'\u6BD3'\u5BD3\u610F\u5B55\u80B2\u4E0E\u8F6C\u5316",values:["AI Native","Ship Fast","Open by Default","Global-Ready","Enterprise-Grade"],missionStatement:"Help AI founders and SaaS teams go from idea to production 10x faster by providing the infrastructure layer they shouldn't have to build."},domains:{landing:"nebutra.com",app:"app.nebutra.com",api:"api.nebutra.com",auth:"auth.nebutra.com",sso:"sso.nebutra.com",docs:"docs.nebutra.com",studio:"studio.nebutra.com",cdn:"cdn.nebutra.com",router:"router.nebutra.com",forge:"forge.nebutra.com",design:"design.nebutra.com",status:"status.nebutra.com",analytics:"analytics.nebutra.com"},social:{twitter:"https://twitter.com/nebutra",github:"https://github.com/nebutra",discord:"https://discord.gg/nebutra",linkedin:"https://linkedin.com/company/nebutra"}};function yd(){if(gd()==="win32"){let t=process.env.LOCALAPPDATA||ct(_o(),"AppData","Local");return ct(t,"nebutra")}let e=process.env.XDG_CONFIG_HOME;return e?ct(e,"nebutra"):ct(_o(),".config","nebutra")}function hd(){let e=process.env.NEBUTRA_TELEMETRY;return e==="0"||e==="false"||e==="no"}function Po(){if(!process.stderr.isTTY||!process.stdin.isTTY||process.env.CI)return;let e=yd(),t=ct(e,"first-run-acked");try{if(fd(t))return}catch{return}if(hd()){try{Oo(e,{recursive:!0}),Ao(t,"")}catch{}return}let n=[`\x1B[36m\u2139\x1B[0m ${xo.name} collects anonymous usage analytics to improve the CLI.`," Opt out at any time: export NEBUTRA_TELEMETRY=0",` Privacy policy: ${Sn("landing")}/legal/cli-analytics`,""];try{process.stderr.write(n.join(`
896
+ `))}catch{}try{Oo(e,{recursive:!0}),Ao(t,"")}catch{}}var Sd=wd(vd(vn(import.meta.url)),"..","package.json"),No=JSON.parse(bd(Sd,"utf8")).version;function Cd(e){let t=new Rd,n=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(r=>bn(async()=>{let o=r.optsWithGlobals?r.optsWithGlobals():r;await xr({dryRun:r.dryRun||!1,yes:o.yes||!1,ifNotExists:r.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(r,o)=>{let a=o.optsWithGlobals?o.optsWithGlobals():o;await jn(r,{...o,yes:a.yes||!n})}),ir(t),jr(t),Mr(t),Zn(t),Er(t),kr(t),yr(t),_r(t),qn(t),zn(t),Xn(t),Jr(t),cr(t),Sr(t),lr(t),eo(t),ko(t),Jn(t),mr(t),so(t),yo(t),Bn(t),er(t),Cr(t),fr(t),zr(t),Kr(t),Vr(t),ar(t),Ur(t),Eo(t),$r(t),vo(t),t.command("doctor").description("Check your Nebutra project setup for common issues").action(()=>bn(async()=>{let{logger:r}=await import("./logger-WOLJCPZK.js"),{findMonorepoRoot:o}=await import("./delegate-7HQKV277.js"),a=await import("fs"),i=await import("path");r.info("Running project health check...");let l=!1,u=o(),m=process.version;parseInt(m.replace("v","").split(".")[0]??"0",10)<22?(r.error(`Node.js >= 22 required, found ${m}`),l=!0):r.success(`Node.js version OK (${m})`),a.existsSync(i.join(u,"nebutra.config.json"))?r.success("nebutra.config.json found"):r.warn("nebutra.config.json missing. Try running 'nebutra init'"),a.existsSync(i.join(u,"package.json"))?r.success("package.json found"):(r.error("No package.json found in root directory"),l=!0),a.existsSync(i.join(u,".env"))||a.existsSync(i.join(u,".env.local"))?r.success("Environment variables configured"):r.warn("No .env or .env.local found. Some features may not work properly.");let E=i.join(u,"apps/api-gateway");a.existsSync(E)&&r.warn("Legacy `apps/api-gateway/` present. Expected `backends/gateway/` \u2014 see CLAUDE.md for the W2.x restructure.");let D=i.join(u,"backends/gateway");a.existsSync(D)?r.success("backends/gateway/ present"):a.existsSync(i.join(u,"backends"));let F=i.join(u,"packages");if(a.existsSync(F)){let ue=new Set(["design","iam","commerce","integrations","platform","ops","ai"]);try{let _e=a.readdirSync(F,{withFileTypes:!0}),p=[];for(let B of _e){if(!B.isDirectory()||ue.has(B.name))continue;let Le=i.join(F,B.name,"package.json");a.existsSync(Le)&&p.push(B.name)}p.length>0?r.warn(`Found ${p.length} uncategorized package(s) under packages/: ${p.join(", ")}. Expected packages/<category>/<name>/ \u2014 see CLAUDE.md.`):r.success("Packages follow categorized layout")}catch{}}let q=i.join(u,".nebutra"),ye=i.join(q,"scaffold-meta.json");if(a.existsSync(ye)?r.success(".nebutra/scaffold-meta.json present (CLI-scaffolded project)"):a.existsSync(q)&&r.warn(".nebutra/ directory exists but scaffold-meta.json is missing. Harmless \u2014 the marker is provenance only and grants nothing."),l)throw new it({code:"doctor_failed",message:"Doctor found critical issues that require your attention.",suggestion:"Fix the errors above, then re-run `nebutra doctor`.",exitCode:c.CONFIG_ERROR});r.success("Doctor is happy. Your project looks healthy!")})),t.hook("preAction",r=>{let o=r.optsWithGlobals();(!n||o.noInteractive)&&(o.yes=!0)}),t.addHelpText("after",`
907
897
  Examples:
908
898
  $ nebutra init Initialize a new project
909
899
  $ nebutra add cache --provider upstash-redis --yes Install a registry feature
@@ -918,8 +908,6 @@ Examples:
918
908
  $ nebutra test e2e Run Playwright E2E tests
919
909
  $ nebutra stats Monorepo overview
920
910
  $ nebutra schema --all Full CLI schema (for Agents)
921
- $ nebutra license verify Verify the scaffold-meta HMAC signature
922
- $ nebutra license verify --format json Same, in JSON for Agents
923
911
 
924
912
  Platform & Ecosystem:
925
913
  $ nebutra admin tenants List all tenants
@@ -950,4 +938,4 @@ Environment:
950
938
  NEBUTRA_OUTPUT_FORMAT Output format (json|table|plain)
951
939
  NO_COLOR Disable colored output
952
940
  CI Auto-enable non-interactive mode
953
- `),t}async function vd(){vo();let e=await po(Ro),t=bd({version:Ro,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 wd(){if(!process.argv[1])return!1;try{return wo(lr(import.meta.url))===wo(So(process.argv[1]))}catch{return lr(import.meta.url)===So(process.argv[1])}}var Sd=wd();Sd&&vd().catch(e=>{process.exitCode=sr(e)});export{bd as buildProgram};
941
+ `),t}async function Ed(){Po();let e=await Co(No),t=Cd({version:No,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 kd(){if(!process.argv[1])return!1;try{return Io(vn(import.meta.url))===Io($o(process.argv[1]))}catch{return vn(import.meta.url)===$o(process.argv[1])}}var xd=kd();xd&&Ed().catch(e=>{process.exitCode=hn(e)});export{Cd as buildProgram};