create-sailor 1.3.6 → 1.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.
Files changed (44) hide show
  1. package/README.md +19 -0
  2. package/dist/index.js +182 -175
  3. package/package.json +13 -14
  4. package/dist/aws-kms-ZX6CTY62.js +0 -1
  5. package/dist/chunk-4NVBWJ2Q.js +0 -1
  6. package/dist/chunk-7DCGNQSQ.js +0 -5
  7. package/dist/chunk-7HOF72FC.js +0 -1
  8. package/dist/chunk-7VJYOZUP.js +0 -2
  9. package/dist/chunk-A2KGYHAM.js +0 -1
  10. package/dist/chunk-A75AMTOI.js +0 -1
  11. package/dist/chunk-B5RLHF2U.js +0 -40
  12. package/dist/chunk-DIXI4M5O.js +0 -1
  13. package/dist/chunk-EXLRPVEX.js +0 -1
  14. package/dist/chunk-FGJ5K4WM.js +0 -1
  15. package/dist/chunk-FSRPMVAS.js +0 -1
  16. package/dist/chunk-J7NVVT5I.js +0 -20
  17. package/dist/chunk-LDOHSEAR.js +0 -9
  18. package/dist/chunk-NK255JZN.js +0 -1
  19. package/dist/chunk-OJM5Y4UT.js +0 -1
  20. package/dist/chunk-PXU2OOBT.js +0 -1
  21. package/dist/chunk-QEIMNOY2.js +0 -1
  22. package/dist/chunk-QMKVUKS6.js +0 -1
  23. package/dist/chunk-RR5R4AKJ.js +0 -1
  24. package/dist/chunk-SDX64WW4.js +0 -23
  25. package/dist/chunk-XSSPJU77.js +0 -1
  26. package/dist/chunk-YR32FZAX.js +0 -1
  27. package/dist/credits-6AUSU6X6.js +0 -1787
  28. package/dist/dist-B4YTE2SQ.js +0 -5
  29. package/dist/dist-es-4EORLV5B.js +0 -1
  30. package/dist/dist-es-7IMKW7US.js +0 -1
  31. package/dist/dist-es-FJUQ4DBK.js +0 -2
  32. package/dist/dist-es-GP7DK3S3.js +0 -5
  33. package/dist/dist-es-JXNWCJHW.js +0 -1
  34. package/dist/dist-es-YKXA2GQ2.js +0 -1
  35. package/dist/dist-es-ZA2NRM7G.js +0 -2
  36. package/dist/event-streams-T5RU6C4N.js +0 -1
  37. package/dist/loadSso-YQ73JVR6.js +0 -1
  38. package/dist/local-WW37QOXE.js +0 -1
  39. package/dist/query_compiler_fast_bg.postgresql-PN2AWLCP.js +0 -2
  40. package/dist/query_compiler_fast_bg.postgresql.wasm-base64-CASS54LO.js +0 -1
  41. package/dist/signin-LD4OP44K.js +0 -1
  42. package/dist/src-MVDQLN5F.js +0 -1
  43. package/dist/sso-oidc-4BAF7BYK.js +0 -1
  44. package/dist/sts-3V5Q4UTA.js +0 -6
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import"./chunk-FSRPMVAS.js";import{execSync as kt}from"child_process";import de from"fs";import ut from"path";import*as C from"@clack/prompts";import{Command as Bs}from"commander";import w from"picocolors";import Ys from"update-notifier";import Xo from"cfonts";import zo from"picocolors";import nn from"fs";import Lt from"path";import{fileURLToPath as Ho}from"url";function Wo(){try{let t=Lt.dirname(Ho(import.meta.url));for(let o=0;o<4;o++){let n=Lt.join(t,"package.json");if(nn.existsSync(n)){let r=nn.readFileSync(n,"utf-8"),i=JSON.parse(r);if(i.name==="create-sailor"&&typeof i.version=="string")return i.version}t=Lt.dirname(t)}return"0.0.0-dev"}catch{return"0.0.0-dev"}}var ee=Wo();function on(){if(process.env.NO_COLOR||!process.stdout.isTTY){process.stdout.write([`Sailor v${ee}`,"AI-Native SaaS Unicorn Template","by Nebutra \xB7 https://nebutra.com","",""].join(`
3
- `));return}Xo.say("Sailor",{font:"block",align:"left",colors:["#0033FE","#0BF1C3"],gradient:["#0033FE","#0BF1C3"],transitionGradient:!0,space:!1}),process.stdout.write(zo.dim(` AI-Native SaaS Template \xB7 v${ee} \xB7 nebutra.com
2
+ import{execSync as Ut}from"child_process";import ye from"fs";import ft from"path";import*as R from"@clack/prompts";import{Command as Qi}from"commander";import N from"picocolors";import Zi from"update-notifier";import or from"cfonts";import rr from"picocolors";import cn from"fs";import Ft from"path";import{fileURLToPath as tr}from"url";function nr(){try{let t=Ft.dirname(tr(import.meta.url));for(let o=0;o<4;o++){let n=Ft.join(t,"package.json");if(cn.existsSync(n)){let r=cn.readFileSync(n,"utf-8"),s=JSON.parse(r);if(s.name==="create-sailor"&&typeof s.version=="string")return s.version}t=Ft.dirname(t)}return"0.0.0-dev"}catch{return"0.0.0-dev"}}var re=nr();function pn(){if(process.env.NO_COLOR||!process.stdout.isTTY){process.stdout.write([`Sailor v${re}`,"AI-Native SaaS Unicorn Template","by Nebutra \xB7 https://nebutra.com","",""].join(`
3
+ `));return}or.say("Sailor",{font:"block",align:"left",colors:["#0033FE","#0BF1C3"],gradient:["#0033FE","#0BF1C3"],transitionGradient:!0,space:!1}),process.stdout.write(rr.dim(` AI-Native SaaS Template \xB7 v${re} \xB7 nebutra.com
4
4
 
5
- `))}import _ from"picocolors";var Qo={qstash:"foundation",bullmq:"foundation",upstash:"foundation",sqs:"foundation",meilisearch:"foundation",typesense:"foundation",algolia:"foundation",pgvector:"foundation",novu:"foundation",knock:"foundation",svix:"foundation","vercel-flags":"wip",growthbook:"wip",configcat:"wip",turnstile:"wip",hcaptcha:"wip","aliyun-slide":"wip"};function Jo(e){return e?Qo[e]??"stable":"stable"}function qe(e){switch(e){case"stable":return"";case"foundation":return"[Foundation]";case"wip":return"[WIP]";case"deprecated":return"[Deprecated]"}}function te(e){switch(e){case"stable":return"Production-ready.";case"foundation":return"Foundation status \u2014 types + factory are complete, but provider adapters are stub-level and require external credentials.";case"wip":return"WIP \u2014 actively being built, should not be used in production.";case"deprecated":return"Deprecated \u2014 scheduled for removal, do not use."}}function rn(e){let t=[];for(let{flag:o,provider:n}of e){if(!n||n==="none")continue;let r=Jo(n);r!=="stable"&&t.push({flag:o,provider:n,status:r})}return t}function Zo(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function sn(e){let t=Zo(),o=t?"\u2693":"-",n=t?"\u25B8":"->",r=t?"\u2605":"*",i=t?"\u{1F4E7}":"*",c=["",` ${t?_.bold(`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`):`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`}`,"",` ${t?_.bold("Next:"):"Next:"}`,` ${n} cd ${e.targetDir}`];e.skippedInstall&&c.push(` ${n} pnpm install (if --no-install was set)`),c.push(` ${n} fill in .env.local ${t?_.dim("\u2192 add provider keys before booting apps"):"-> add provider keys before booting apps"}`,` ${n} pnpm db:migrate ${t?_.dim("\u2192 sync Prisma schema"):"-> sync Prisma schema"}`,` ${n} pnpm db:seed ${t?_.dim("\u2192 load example tenants and records"):"-> load example tenants and records"}`,` ${n} pnpm dev ${t?_.dim("\u2192 http://localhost:3000"):"-> http://localhost:3000"}`,"",` ${t?_.bold("Customize:"):"Customize:"}`,` ${n} pnpm brand:init ${t?_.dim("\u2192 create brand.config.ts"):"-> create brand.config.ts"}`,` ${n} pnpm brand:apply ${t?_.dim("\u2192 propagate brand changes"):"-> propagate brand changes"}`,` ${n} pnpm preset:env ${t?_.dim("\u2192 review preset env requirements"):"-> review preset env requirements"}`,"",` ${t?_.bold("Useful scripts:"):"Useful scripts:"}`,` ${n} pnpm infra:up ${t?_.dim("\u2192 start local PostgreSQL/Redis/ClickHouse"):"-> start local PostgreSQL/Redis/ClickHouse"}`,` ${n} pnpm generate:api-types ${t?_.dim("\u2192 refresh shared API client types"):"-> refresh shared API client types"}`,` ${n} pnpm lint ${t?_.dim("\u2192 quick repo sanity check"):"-> quick repo sanity check"}`);let a=e.previewSelections??[];if(a.length>0){let d=t?_.bold(_.yellow("\u26A0 Preview features selected:")):"!! Preview features selected:";c.push("",` ${d}`);for(let u of a){let h=qe(u.status),O=` ${n} ${u.flag} (${u.provider}) ${h}`;c.push(t?_.yellow(O):O)}c.push("",` ${t?_.dim(te("foundation")):te("foundation")}`,` ${t?_.dim("You may need to contribute the provider integration yourself."):"You may need to contribute the provider integration yourself."}`,` ${t?_.dim("See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"):"See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"}`)}c.push("",` ${t?_.bold("Ship faster:"):"Ship faster:"}`,` ${r} Star us https://github.com/nebutra/nebutra-sailor`,` ${i} Free license https://nebutra.com/get-license`,""),process.stdout.write(c.join(`
5
+ `))}import P from"picocolors";var sr={qstash:"foundation",bullmq:"foundation",upstash:"foundation",sqs:"foundation",meilisearch:"foundation",typesense:"foundation",algolia:"foundation",pgvector:"foundation",novu:"foundation",knock:"foundation",svix:"foundation","vercel-flags":"wip",growthbook:"wip",configcat:"wip",turnstile:"wip",hcaptcha:"wip","aliyun-slide":"wip"};function ir(e){return e?sr[e]??"stable":"stable"}function ze(e){switch(e){case"stable":return"";case"foundation":return"[Foundation]";case"wip":return"[WIP]";case"deprecated":return"[Deprecated]"}}function se(e){switch(e){case"stable":return"Production-ready.";case"foundation":return"Foundation status \u2014 types + factory are complete, but provider adapters are stub-level and require external credentials.";case"wip":return"WIP \u2014 actively being built, should not be used in production.";case"deprecated":return"Deprecated \u2014 scheduled for removal, do not use."}}function ln(e){let t=[];for(let{flag:o,provider:n}of e){if(!n||n==="none")continue;let r=ir(n);r!=="stable"&&t.push({flag:o,provider:n,status:r})}return t}function ar(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function dn(e){let t=ar(),o=t?"\u2693":"-",n=t?"\u25B8":"->",r=t?"\u2605":"*",s=t?"\u{1F4E7}":"*",c=["",` ${t?P.bold(`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`):`${o} Done in ${e.elapsedSec}s \xB7 ${e.targetDir}/`}`,"",` ${t?P.bold("Next:"):"Next:"}`,` ${n} cd ${e.targetDir}`];e.skippedInstall&&c.push(` ${n} pnpm install (if --no-install was set)`),c.push(` ${n} fill in .env.local ${t?P.dim("\u2192 add provider keys before booting apps"):"-> add provider keys before booting apps"}`,` ${n} pnpm db:migrate ${t?P.dim("\u2192 sync Prisma schema"):"-> sync Prisma schema"}`,` ${n} pnpm db:seed ${t?P.dim("\u2192 load example tenants and records"):"-> load example tenants and records"}`,` ${n} pnpm dev ${t?P.dim("\u2192 http://localhost:3000"):"-> http://localhost:3000"}`,"",` ${t?P.bold("Customize:"):"Customize:"}`,` ${n} pnpm brand:init ${t?P.dim("\u2192 create brand.config.ts"):"-> create brand.config.ts"}`,` ${n} pnpm brand:apply ${t?P.dim("\u2192 propagate brand changes"):"-> propagate brand changes"}`,` ${n} pnpm preset:env ${t?P.dim("\u2192 review preset env requirements"):"-> review preset env requirements"}`,"",` ${t?P.bold("Useful scripts:"):"Useful scripts:"}`,` ${n} pnpm infra:up ${t?P.dim("\u2192 start local PostgreSQL/Redis/ClickHouse"):"-> start local PostgreSQL/Redis/ClickHouse"}`,` ${n} pnpm generate:api-types ${t?P.dim("\u2192 refresh shared API client types"):"-> refresh shared API client types"}`,` ${n} pnpm lint ${t?P.dim("\u2192 quick repo sanity check"):"-> quick repo sanity check"}`,` ${n} pnpm audit ${t?P.dim("\u2192 scan deps for known CVEs"):"-> scan deps for known CVEs"}`);let a=e.previewSelections??[];if(a.length>0){let k=t?P.bold(P.yellow("\u26A0 Preview features selected:")):"!! Preview features selected:";c.push("",` ${k}`);for(let x of a){let L=ze(x.status),oe=` ${n} ${x.flag} (${x.provider}) ${L}`;c.push(t?P.yellow(oe):oe)}c.push("",` ${t?P.dim(se("foundation")):se("foundation")}`,` ${t?P.dim("You may need to contribute the provider integration yourself."):"You may need to contribute the provider integration yourself."}`,` ${t?P.dim("See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"):"See: https://github.com/Nebutra/Nebutra-Sailor/blob/main/docs/package-status.md"}`)}let l=e.waveFeatures??{},m=k=>k!==!1,y=[];m(l.apiKeys)&&y.push("Manage API keys at /settings/api-keys"),m(l.auditLog)&&y.push("View audit log at /settings/audit-log"),y.push("Configure webhooks at /settings/webhooks"),m(l.commandPalette)&&y.push("Press Cmd/Ctrl+K to open the command palette"),y.push("Edit notification preferences at /settings/notifications"),y.push("Export your data at /settings/account/export"),l.chinaCompliance&&y.push("China deployments \u2014 see packages/china-compliance/README.md"),c.push("",` ${t?P.bold("What you can do next:"):"What you can do next:"}`);for(let k of y)c.push(` ${n} ${k}`);c.push("",` ${t?P.bold("Ship faster:"):"Ship faster:"}`,` ${r} Star us https://github.com/nebutra/nebutra-sailor`,` ${s} Free license https://nebutra.com/get-license`,""),process.stdout.write(c.join(`
6
6
  `)+`
7
- `)}var er=`Usage: create-sailor [name] [options]
7
+ `)}var cr=`Usage: create-sailor [name] [options]
8
8
 
9
9
  Arguments:
10
10
  name project directory (default: ./my-saas-app)
@@ -73,9 +73,9 @@ Examples:
73
73
  $ npx create-sailor@latest my-app --region=cn --auth=clerk
74
74
  $ npx create-sailor@latest my-app --region=hybrid --ai=openai,deepseek
75
75
  $ npm create sailor@latest --dry-run --region=cn
76
- `;function an(){process.stdout.write(er)}import Et from"picocolors";function cn(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function tr(e){let t=cn()?"\u25B8":"->",o=`[${e.index}/${e.total}]`,n=e.label.padEnd(18," ");return cn()?`${Et.dim(o)} ${Et.bold(n)} ${Et.dim(t)} ${Et.cyan(e.value)}`:`${o} ${n} ${t} ${e.value}`}function pn(e){process.stdout.write(tr(e)+`
77
- `)}var Mt=[{id:"anthropic",name:"Anthropic",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.anthropic.com",envVarPrefix:"ANTHROPIC",requiredEnvVars:["ANTHROPIC_API_KEY"]},{id:"openai",name:"OpenAI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.openai.com/docs",envVarPrefix:"OPENAI",requiredEnvVars:["OPENAI_API_KEY"]},{id:"deepseek",name:"DeepSeek",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.deepseek.com/api-docs",envVarPrefix:"DEEPSEEK",requiredEnvVars:["DEEPSEEK_API_KEY"]},{id:"xai",name:"xAI (Grok)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.x.ai/api",envVarPrefix:"XAI",requiredEnvVars:["XAI_API_KEY"]},{id:"moonshot",name:"Moonshot (Kimi)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.moonshot.cn/docs",envVarPrefix:"MOONSHOT",requiredEnvVars:["MOONSHOT_API_KEY","MOONSHOT_BASE_URL"]},{id:"google",name:"Google Gemini",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://ai.google.dev/gemini-api/docs",envVarPrefix:"GOOGLE_GENERATIVE_AI",requiredEnvVars:["GOOGLE_GENERATIVE_AI_API_KEY"]},{id:"mistral",name:"Mistral AI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.mistral.ai",envVarPrefix:"MISTRAL",requiredEnvVars:["MISTRAL_API_KEY"]},{id:"cohere",name:"Cohere",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.cohere.com",envVarPrefix:"COHERE",requiredEnvVars:["COHERE_API_KEY"]},{id:"perplexity",name:"Perplexity",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.perplexity.ai",baseURL:"https://api.perplexity.ai",envVarPrefix:"PERPLEXITY",requiredEnvVars:["PERPLEXITY_API_KEY"]},{id:"ai21",name:"AI21 Labs",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.ai21.com",baseURL:"https://api.ai21.com/studio/v1",envVarPrefix:"AI21",requiredEnvVars:["AI21_API_KEY"]},{id:"upstage",name:"Upstage (Solar)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://developers.upstage.ai/docs",baseURL:"https://api.upstage.ai/v1/solar",envVarPrefix:"UPSTAGE",requiredEnvVars:["UPSTAGE_API_KEY"]},{id:"siliconflow",name:"\u7845\u57FA\u6D41\u52A8 SiliconFlow",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://docs.siliconflow.cn",baseURL:"https://api.siliconflow.cn/v1",envVarPrefix:"SILICONFLOW",requiredEnvVars:["SILICONFLOW_API_KEY"]},{id:"volcengine-ark",name:"\u706B\u5C71\u5F15\u64CE ARK (\u8C46\u5305)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://www.volcengine.com/docs/82379",baseURL:"https://ark.cn-beijing.volces.com/api/v3",envVarPrefix:"ARK",requiredEnvVars:["ARK_API_KEY"]},{id:"bailian",name:"\u767E\u70BC Bailian (\u901A\u4E49)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://help.aliyun.com/zh/model-studio",baseURL:"https://dashscope.aliyuncs.com/compatible-mode/v1",envVarPrefix:"DASHSCOPE",requiredEnvVars:["DASHSCOPE_API_KEY"]},{id:"zhipu",name:"\u667A\u8C31 AI Zhipu",category:"\u56FD\u5185\u5E73\u53F0",status:"ai-sdk",docs:"https://docs.bigmodel.cn",baseURL:"https://open.bigmodel.cn/api/paas/v4",envVarPrefix:"ZHIPU",requiredEnvVars:["ZHIPU_API_KEY"]},{id:"baichuan",name:"\u767E\u5DDD\u667A\u80FD Baichuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.baichuan-ai.com/docs",baseURL:"https://api.baichuan-ai.com/v1",envVarPrefix:"BAICHUAN",requiredEnvVars:["BAICHUAN_API_KEY"]},{id:"minimax",name:"MiniMax (ABAB)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.minimaxi.com/document/guides",baseURL:"https://api.minimax.chat/v1",envVarPrefix:"MINIMAX",requiredEnvVars:["MINIMAX_API_KEY","MINIMAX_GROUP_ID"]},{id:"stepfun",name:"\u9636\u8DC3\u661F\u8FB0 StepFun",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.stepfun.com/docs",baseURL:"https://api.stepfun.com/v1",envVarPrefix:"STEPFUN",requiredEnvVars:["STEPFUN_API_KEY"]},{id:"sensetime",name:"\u5546\u6C64 SenseNova",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.sensetime.com",baseURL:"https://api.sensenova.cn/v1",envVarPrefix:"SENSENOVA",requiredEnvVars:["SENSENOVA_API_KEY"]},{id:"tencent",name:"\u817E\u8BAF\u6DF7\u5143 Hunyuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://cloud.tencent.com/document/product/1729",baseURL:"https://api.hunyuan.cloud.tencent.com/v1",envVarPrefix:"HUNYUAN",requiredEnvVars:["HUNYUAN_API_KEY"]},{id:"lingyi",name:"\u96F6\u4E00\u4E07\u7269 Yi",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.lingyiwanwu.com/docs",baseURL:"https://api.lingyiwanwu.com/v1",envVarPrefix:"YI",requiredEnvVars:["YI_API_KEY"]},{id:"openrouter",name:"OpenRouter",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://openrouter.ai/docs",envVarPrefix:"OPENROUTER",requiredEnvVars:["OPENROUTER_API_KEY"]},{id:"vercel-gateway",name:"Vercel AI Gateway",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://vercel.com/docs/ai-gateway",envVarPrefix:"AI_GATEWAY",requiredEnvVars:["AI_GATEWAY_API_KEY"]},{id:"litellm",name:"LiteLLM Proxy",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://docs.litellm.ai",baseURL:"http://localhost:4000/v1",envVarPrefix:"LITELLM",requiredEnvVars:["LITELLM_API_KEY"]},{id:"portkey",name:"Portkey",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://portkey.ai/docs",baseURL:"https://api.portkey.ai/v1",envVarPrefix:"PORTKEY",requiredEnvVars:["PORTKEY_API_KEY"]},{id:"aws-bedrock",name:"AWS Bedrock",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://aws.amazon.com/bedrock/",envVarPrefix:"AWS_BEDROCK",requiredEnvVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"]},{id:"azure-openai",name:"Azure OpenAI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://azure.microsoft.com/en-us/products/cognitive-services/openai-service/",envVarPrefix:"AZURE_OPENAI",requiredEnvVars:["AZURE_OPENAI_API_KEY","AZURE_OPENAI_ENDPOINT"]},{id:"gcp-vertex",name:"GCP Vertex AI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://cloud.google.com/vertex-ai",envVarPrefix:"GOOGLE_VERTEX",requiredEnvVars:["GOOGLE_APPLICATION_CREDENTIALS"]},{id:"groq",name:"Groq",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://console.groq.com/docs",envVarPrefix:"GROQ",requiredEnvVars:["GROQ_API_KEY"]},{id:"fireworks",name:"Fireworks AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.fireworks.ai",envVarPrefix:"FIREWORKS",requiredEnvVars:["FIREWORKS_API_KEY"]},{id:"together",name:"Together AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.together.ai",envVarPrefix:"TOGETHER",requiredEnvVars:["TOGETHER_API_KEY"]},{id:"huggingface",name:"Hugging Face",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://huggingface.co/docs/inference-providers",envVarPrefix:"HF",requiredEnvVars:["HF_API_KEY"]},{id:"replicate",name:"Replicate",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://replicate.com/docs",envVarPrefix:"REPLICATE",requiredEnvVars:["REPLICATE_API_TOKEN"]},{id:"lepton",name:"Lepton AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://www.lepton.ai/docs",baseURL:"https://api.lepton.ai/v1",envVarPrefix:"LEPTON",requiredEnvVars:["LEPTON_API_KEY"]},{id:"anyscale",name:"Anyscale Endpoints",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://docs.endpoints.anyscale.com/",baseURL:"https://api.endpoints.anyscale.com/v1",envVarPrefix:"ANYSCALE",requiredEnvVars:["ANYSCALE_API_KEY"]},{id:"octoai",name:"OctoAI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://octoai.cloud/docs",baseURL:"https://text.octoai.run/v1",envVarPrefix:"OCTOAI",requiredEnvVars:["OCTOAI_TOKEN"]},{id:"deepinfra",name:"DeepInfra",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://deepinfra.com/docs",baseURL:"https://api.deepinfra.com/v1/openai",envVarPrefix:"DEEPINFRA",requiredEnvVars:["DEEPINFRA_API_KEY"]},{id:"novita",name:"Novita AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://novita.ai/docs",baseURL:"https://api.novita.ai/v3/openai",envVarPrefix:"NOVITA",requiredEnvVars:["NOVITA_API_KEY"]},{id:"black-forest-labs",name:"Black Forest Labs (FLUX)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://docs.bfl.ml",envVarPrefix:"BFL",requiredEnvVars:["BFL_API_KEY"]},{id:"elevenlabs",name:"ElevenLabs (TTS)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://elevenlabs.io/docs",envVarPrefix:"ELEVENLABS",requiredEnvVars:["ELEVENLABS_API_KEY"]},{id:"runway",name:"Runway (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://runwayml.com",envVarPrefix:"RUNWAY",requiredEnvVars:["RUNWAY_API_KEY"]},{id:"luma",name:"Luma (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://lumalabs.ai",envVarPrefix:"LUMA",requiredEnvVars:["LUMA_API_KEY"]},{id:"midjourney",name:"Midjourney",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://docs.midjourney.com",envVarPrefix:"MIDJOURNEY",requiredEnvVars:[]},{id:"ollama",name:"Ollama (\u672C\u5730)",category:"\u672C\u5730\u90E8\u7F72",status:"opencode",docs:"https://github.com/ollama/ollama",baseURL:"http://localhost:11434/v1",envVarPrefix:"OLLAMA",requiredEnvVars:["OLLAMA_BASE_URL"]},{id:"lmstudio",name:"LM Studio",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://lmstudio.ai/docs",baseURL:"http://localhost:1234/v1",envVarPrefix:"LMSTUDIO",requiredEnvVars:[]},{id:"vllm",name:"vLLM",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://docs.vllm.ai",baseURL:"http://localhost:8000/v1",envVarPrefix:"VLLM",requiredEnvVars:[]},{id:"tgi",name:"HF TGI",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://huggingface.co/docs/text-generation-inference",baseURL:"http://localhost:8080/v1",envVarPrefix:"TGI",requiredEnvVars:[]}],pa=Mt.reduce((e,t)=>(e[t.category]||(e[t.category]=[]),e[t.category].push(t),e),{});var nr=["openai","anthropic","google"],or=["openai"];function Dt(e){let t=e.providerIds??[];switch(e.mode){case"gateway":{let o=t.length>0?t:[...nr];return{mode:"gateway",providerIds:o,customEndpoint:e.customEndpoint,routing:{profile:"multi-provider-gateway",providerSeed:o,runtimeGovernance:!0}}}case"direct":{let o=t.length>0?t:[...or];return{mode:"direct",providerIds:o,customEndpoint:e.customEndpoint,routing:{profile:"direct-adapters",providerSeed:o,runtimeGovernance:!1}}}case"custom":return{mode:"custom",providerIds:t,customEndpoint:e.customEndpoint,routing:{profile:"openai-compatible",providerSeed:t,runtimeGovernance:!0}};case"none":return{mode:"none",providerIds:[],routing:{profile:"disabled",providerSeed:[],runtimeGovernance:!1}}}}import Ge from"fs";import k from"path";var ln=[{id:"posthog",name:"PostHog",region:"both",envVars:["POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_HOST"],docs:"https://posthog.com/docs",pkgs:["posthog-js","posthog-node"],providerFile:"apps/web/src/lib/analytics/posthog.client.ts"},{id:"plausible",name:"Plausible",region:"global",envVars:["NEXT_PUBLIC_PLAUSIBLE_DOMAIN","NEXT_PUBLIC_PLAUSIBLE_SRC"],docs:"https://plausible.io/docs",providerFile:"apps/web/src/components/analytics/PlausibleScript.tsx"},{id:"umami",name:"Umami",region:"both",envVars:["NEXT_PUBLIC_UMAMI_WEBSITE_ID","NEXT_PUBLIC_UMAMI_SRC"],docs:"https://umami.is/docs",providerFile:"apps/web/src/components/analytics/UmamiScript.tsx"},{id:"mixpanel",name:"Mixpanel",region:"global",envVars:["MIXPANEL_TOKEN","NEXT_PUBLIC_MIXPANEL_TOKEN"],docs:"https://docs.mixpanel.com",pkgs:["mixpanel-browser","mixpanel"],providerFile:"apps/web/src/lib/analytics/mixpanel.client.ts"},{id:"baidu",name:"\u767E\u5EA6\u7EDF\u8BA1 Baidu Tongji",region:"cn",envVars:["NEXT_PUBLIC_BAIDU_STATS_ID"],docs:"https://tongji.baidu.com",providerFile:"apps/web/src/components/analytics/BaiduStatsScript.tsx"},{id:"sensors",name:"\u795E\u7B56 Sensors Analytics",region:"cn",envVars:["NEXT_PUBLIC_SENSORS_SERVER_URL","NEXT_PUBLIC_SENSORS_APP_JS_URL"],docs:"https://manual.sensorsdata.cn",pkgs:["sa-sdk-javascript"],providerFile:"apps/web/src/lib/analytics/sensors.client.ts"},{id:"growingio",name:"GrowingIO",region:"cn",envVars:["NEXT_PUBLIC_GROWINGIO_ACCOUNT_ID"],docs:"https://growingio.com/docs",providerFile:"apps/web/src/components/analytics/GrowingIoScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],ua=ln.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function dn(e){return ln.find(t=>t.id===e)}function rr(e){Ge.mkdirSync(e,{recursive:!0})}function $(e,t){rr(k.dirname(e)),Ge.writeFileSync(e,t)}function ge(e,t){let o=k.join(e,".env.example");Ge.existsSync(o)?Ge.appendFileSync(o,`
78
- `+t):Ge.writeFileSync(o,t)}function ir(e){let t=`"use client";
76
+ `;function un(){process.stdout.write(cr)}import _t from"picocolors";function mn(){return!process.env.NO_COLOR&&!!process.stdout.isTTY}function pr(e){let t=mn()?"\u25B8":"->",o=`[${e.index}/${e.total}]`,n=e.label.padEnd(18," ");return mn()?`${_t.dim(o)} ${_t.bold(n)} ${_t.dim(t)} ${_t.cyan(e.value)}`:`${o} ${n} ${t} ${e.value}`}function gn(e){process.stdout.write(pr(e)+`
77
+ `)}var Dt=[{id:"anthropic",name:"Anthropic",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.anthropic.com",envVarPrefix:"ANTHROPIC",requiredEnvVars:["ANTHROPIC_API_KEY"]},{id:"openai",name:"OpenAI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.openai.com/docs",envVarPrefix:"OPENAI",requiredEnvVars:["OPENAI_API_KEY"]},{id:"deepseek",name:"DeepSeek",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.deepseek.com/api-docs",envVarPrefix:"DEEPSEEK",requiredEnvVars:["DEEPSEEK_API_KEY"]},{id:"xai",name:"xAI (Grok)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://docs.x.ai/api",envVarPrefix:"XAI",requiredEnvVars:["XAI_API_KEY"]},{id:"moonshot",name:"Moonshot (Kimi)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"opencode",docs:"https://platform.moonshot.cn/docs",envVarPrefix:"MOONSHOT",requiredEnvVars:["MOONSHOT_API_KEY","MOONSHOT_BASE_URL"]},{id:"google",name:"Google Gemini",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://ai.google.dev/gemini-api/docs",envVarPrefix:"GOOGLE_GENERATIVE_AI",requiredEnvVars:["GOOGLE_GENERATIVE_AI_API_KEY"]},{id:"mistral",name:"Mistral AI",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.mistral.ai",envVarPrefix:"MISTRAL",requiredEnvVars:["MISTRAL_API_KEY"]},{id:"cohere",name:"Cohere",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"ai-sdk",docs:"https://docs.cohere.com",envVarPrefix:"COHERE",requiredEnvVars:["COHERE_API_KEY"]},{id:"perplexity",name:"Perplexity",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.perplexity.ai",baseURL:"https://api.perplexity.ai",envVarPrefix:"PERPLEXITY",requiredEnvVars:["PERPLEXITY_API_KEY"]},{id:"ai21",name:"AI21 Labs",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://docs.ai21.com",baseURL:"https://api.ai21.com/studio/v1",envVarPrefix:"AI21",requiredEnvVars:["AI21_API_KEY"]},{id:"upstage",name:"Upstage (Solar)",category:"\u76F4\u63A5\u5B9E\u9A8C\u5BA4",status:"cn-compatible",docs:"https://developers.upstage.ai/docs",baseURL:"https://api.upstage.ai/v1/solar",envVarPrefix:"UPSTAGE",requiredEnvVars:["UPSTAGE_API_KEY"]},{id:"siliconflow",name:"\u7845\u57FA\u6D41\u52A8 SiliconFlow",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://docs.siliconflow.cn",baseURL:"https://api.siliconflow.cn/v1",envVarPrefix:"SILICONFLOW",requiredEnvVars:["SILICONFLOW_API_KEY"]},{id:"volcengine-ark",name:"\u706B\u5C71\u5F15\u64CE ARK (\u8C46\u5305)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://www.volcengine.com/docs/82379",baseURL:"https://ark.cn-beijing.volces.com/api/v3",envVarPrefix:"ARK",requiredEnvVars:["ARK_API_KEY"]},{id:"bailian",name:"\u767E\u70BC Bailian (\u901A\u4E49)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://help.aliyun.com/zh/model-studio",baseURL:"https://dashscope.aliyuncs.com/compatible-mode/v1",envVarPrefix:"DASHSCOPE",requiredEnvVars:["DASHSCOPE_API_KEY"]},{id:"zhipu",name:"\u667A\u8C31 AI Zhipu",category:"\u56FD\u5185\u5E73\u53F0",status:"ai-sdk",docs:"https://docs.bigmodel.cn",baseURL:"https://open.bigmodel.cn/api/paas/v4",envVarPrefix:"ZHIPU",requiredEnvVars:["ZHIPU_API_KEY"]},{id:"baichuan",name:"\u767E\u5DDD\u667A\u80FD Baichuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.baichuan-ai.com/docs",baseURL:"https://api.baichuan-ai.com/v1",envVarPrefix:"BAICHUAN",requiredEnvVars:["BAICHUAN_API_KEY"]},{id:"minimax",name:"MiniMax (ABAB)",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.minimaxi.com/document/guides",baseURL:"https://api.minimax.chat/v1",envVarPrefix:"MINIMAX",requiredEnvVars:["MINIMAX_API_KEY","MINIMAX_GROUP_ID"]},{id:"stepfun",name:"\u9636\u8DC3\u661F\u8FB0 StepFun",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.stepfun.com/docs",baseURL:"https://api.stepfun.com/v1",envVarPrefix:"STEPFUN",requiredEnvVars:["STEPFUN_API_KEY"]},{id:"sensetime",name:"\u5546\u6C64 SenseNova",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.sensetime.com",baseURL:"https://api.sensenova.cn/v1",envVarPrefix:"SENSENOVA",requiredEnvVars:["SENSENOVA_API_KEY"]},{id:"tencent",name:"\u817E\u8BAF\u6DF7\u5143 Hunyuan",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://cloud.tencent.com/document/product/1729",baseURL:"https://api.hunyuan.cloud.tencent.com/v1",envVarPrefix:"HUNYUAN",requiredEnvVars:["HUNYUAN_API_KEY"]},{id:"lingyi",name:"\u96F6\u4E00\u4E07\u7269 Yi",category:"\u56FD\u5185\u5E73\u53F0",status:"cn-compatible",docs:"https://platform.lingyiwanwu.com/docs",baseURL:"https://api.lingyiwanwu.com/v1",envVarPrefix:"YI",requiredEnvVars:["YI_API_KEY"]},{id:"openrouter",name:"OpenRouter",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://openrouter.ai/docs",envVarPrefix:"OPENROUTER",requiredEnvVars:["OPENROUTER_API_KEY"]},{id:"vercel-gateway",name:"Vercel AI Gateway",category:"\u7EDF\u4E00\u7F51\u5173",status:"opencode",docs:"https://vercel.com/docs/ai-gateway",envVarPrefix:"AI_GATEWAY",requiredEnvVars:["AI_GATEWAY_API_KEY"]},{id:"litellm",name:"LiteLLM Proxy",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://docs.litellm.ai",baseURL:"http://localhost:4000/v1",envVarPrefix:"LITELLM",requiredEnvVars:["LITELLM_API_KEY"]},{id:"portkey",name:"Portkey",category:"\u7EDF\u4E00\u7F51\u5173",status:"cn-compatible",docs:"https://portkey.ai/docs",baseURL:"https://api.portkey.ai/v1",envVarPrefix:"PORTKEY",requiredEnvVars:["PORTKEY_API_KEY"]},{id:"aws-bedrock",name:"AWS Bedrock",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://aws.amazon.com/bedrock/",envVarPrefix:"AWS_BEDROCK",requiredEnvVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"]},{id:"azure-openai",name:"Azure OpenAI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://azure.microsoft.com/en-us/products/cognitive-services/openai-service/",envVarPrefix:"AZURE_OPENAI",requiredEnvVars:["AZURE_OPENAI_API_KEY","AZURE_OPENAI_ENDPOINT"]},{id:"gcp-vertex",name:"GCP Vertex AI",category:"\u4E91\u5E73\u53F0",status:"ai-sdk",docs:"https://cloud.google.com/vertex-ai",envVarPrefix:"GOOGLE_VERTEX",requiredEnvVars:["GOOGLE_APPLICATION_CREDENTIALS"]},{id:"groq",name:"Groq",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://console.groq.com/docs",envVarPrefix:"GROQ",requiredEnvVars:["GROQ_API_KEY"]},{id:"fireworks",name:"Fireworks AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.fireworks.ai",envVarPrefix:"FIREWORKS",requiredEnvVars:["FIREWORKS_API_KEY"]},{id:"together",name:"Together AI",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://docs.together.ai",envVarPrefix:"TOGETHER",requiredEnvVars:["TOGETHER_API_KEY"]},{id:"huggingface",name:"Hugging Face",category:"\u63A8\u7406\u52A0\u901F",status:"opencode",docs:"https://huggingface.co/docs/inference-providers",envVarPrefix:"HF",requiredEnvVars:["HF_API_KEY"]},{id:"replicate",name:"Replicate",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://replicate.com/docs",envVarPrefix:"REPLICATE",requiredEnvVars:["REPLICATE_API_TOKEN"]},{id:"lepton",name:"Lepton AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://www.lepton.ai/docs",baseURL:"https://api.lepton.ai/v1",envVarPrefix:"LEPTON",requiredEnvVars:["LEPTON_API_KEY"]},{id:"anyscale",name:"Anyscale Endpoints",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://docs.endpoints.anyscale.com/",baseURL:"https://api.endpoints.anyscale.com/v1",envVarPrefix:"ANYSCALE",requiredEnvVars:["ANYSCALE_API_KEY"]},{id:"octoai",name:"OctoAI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://octoai.cloud/docs",baseURL:"https://text.octoai.run/v1",envVarPrefix:"OCTOAI",requiredEnvVars:["OCTOAI_TOKEN"]},{id:"deepinfra",name:"DeepInfra",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://deepinfra.com/docs",baseURL:"https://api.deepinfra.com/v1/openai",envVarPrefix:"DEEPINFRA",requiredEnvVars:["DEEPINFRA_API_KEY"]},{id:"novita",name:"Novita AI",category:"\u63A8\u7406\u52A0\u901F",status:"cn-compatible",docs:"https://novita.ai/docs",baseURL:"https://api.novita.ai/v3/openai",envVarPrefix:"NOVITA",requiredEnvVars:["NOVITA_API_KEY"]},{id:"black-forest-labs",name:"Black Forest Labs (FLUX)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://docs.bfl.ml",envVarPrefix:"BFL",requiredEnvVars:["BFL_API_KEY"]},{id:"elevenlabs",name:"ElevenLabs (TTS)",category:"\u591A\u6A21\u6001",status:"ai-sdk",docs:"https://elevenlabs.io/docs",envVarPrefix:"ELEVENLABS",requiredEnvVars:["ELEVENLABS_API_KEY"]},{id:"runway",name:"Runway (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://runwayml.com",envVarPrefix:"RUNWAY",requiredEnvVars:["RUNWAY_API_KEY"]},{id:"luma",name:"Luma (Video)",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://lumalabs.ai",envVarPrefix:"LUMA",requiredEnvVars:["LUMA_API_KEY"]},{id:"midjourney",name:"Midjourney",category:"\u591A\u6A21\u6001",status:"pending",docs:"https://docs.midjourney.com",envVarPrefix:"MIDJOURNEY",requiredEnvVars:[]},{id:"ollama",name:"Ollama (\u672C\u5730)",category:"\u672C\u5730\u90E8\u7F72",status:"opencode",docs:"https://github.com/ollama/ollama",baseURL:"http://localhost:11434/v1",envVarPrefix:"OLLAMA",requiredEnvVars:["OLLAMA_BASE_URL"]},{id:"lmstudio",name:"LM Studio",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://lmstudio.ai/docs",baseURL:"http://localhost:1234/v1",envVarPrefix:"LMSTUDIO",requiredEnvVars:[]},{id:"vllm",name:"vLLM",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://docs.vllm.ai",baseURL:"http://localhost:8000/v1",envVarPrefix:"VLLM",requiredEnvVars:[]},{id:"tgi",name:"HF TGI",category:"\u672C\u5730\u90E8\u7F72",status:"cn-compatible",docs:"https://huggingface.co/docs/text-generation-inference",baseURL:"http://localhost:8080/v1",envVarPrefix:"TGI",requiredEnvVars:[]}],Ea=Dt.reduce((e,t)=>(e[t.category]||(e[t.category]=[]),e[t.category].push(t),e),{});var lr=["openai","anthropic","google"],dr=["openai"];function Kt(e){let t=e.providerIds??[];switch(e.mode){case"gateway":{let o=t.length>0?t:[...lr];return{mode:"gateway",providerIds:o,customEndpoint:e.customEndpoint,routing:{profile:"multi-provider-gateway",providerSeed:o,runtimeGovernance:!0}}}case"direct":{let o=t.length>0?t:[...dr];return{mode:"direct",providerIds:o,customEndpoint:e.customEndpoint,routing:{profile:"direct-adapters",providerSeed:o,runtimeGovernance:!1}}}case"custom":return{mode:"custom",providerIds:t,customEndpoint:e.customEndpoint,routing:{profile:"openai-compatible",providerSeed:t,runtimeGovernance:!0}};case"none":return{mode:"none",providerIds:[],routing:{profile:"disabled",providerSeed:[],runtimeGovernance:!1}}}}import Je from"fs";import j from"path";var fn=[{id:"posthog",name:"PostHog",region:"both",envVars:["POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_KEY","NEXT_PUBLIC_POSTHOG_HOST"],docs:"https://posthog.com/docs",pkgs:["posthog-js","posthog-node"],providerFile:"apps/web/src/lib/analytics/posthog.client.ts"},{id:"plausible",name:"Plausible",region:"global",envVars:["NEXT_PUBLIC_PLAUSIBLE_DOMAIN","NEXT_PUBLIC_PLAUSIBLE_SRC"],docs:"https://plausible.io/docs",providerFile:"apps/web/src/components/analytics/PlausibleScript.tsx"},{id:"umami",name:"Umami",region:"both",envVars:["NEXT_PUBLIC_UMAMI_WEBSITE_ID","NEXT_PUBLIC_UMAMI_SRC"],docs:"https://umami.is/docs",providerFile:"apps/web/src/components/analytics/UmamiScript.tsx"},{id:"mixpanel",name:"Mixpanel",region:"global",envVars:["MIXPANEL_TOKEN","NEXT_PUBLIC_MIXPANEL_TOKEN"],docs:"https://docs.mixpanel.com",pkgs:["mixpanel-browser","mixpanel"],providerFile:"apps/web/src/lib/analytics/mixpanel.client.ts"},{id:"baidu",name:"\u767E\u5EA6\u7EDF\u8BA1 Baidu Tongji",region:"cn",envVars:["NEXT_PUBLIC_BAIDU_STATS_ID"],docs:"https://tongji.baidu.com",providerFile:"apps/web/src/components/analytics/BaiduStatsScript.tsx"},{id:"sensors",name:"\u795E\u7B56 Sensors Analytics",region:"cn",envVars:["NEXT_PUBLIC_SENSORS_SERVER_URL","NEXT_PUBLIC_SENSORS_APP_JS_URL"],docs:"https://manual.sensorsdata.cn",pkgs:["sa-sdk-javascript"],providerFile:"apps/web/src/lib/analytics/sensors.client.ts"},{id:"growingio",name:"GrowingIO",region:"cn",envVars:["NEXT_PUBLIC_GROWINGIO_ACCOUNT_ID"],docs:"https://growingio.com/docs",providerFile:"apps/web/src/components/analytics/GrowingIoScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],ba=fn.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function yn(e){return fn.find(t=>t.id===e)}function ur(e){Je.mkdirSync(e,{recursive:!0})}function G(e,t){ur(j.dirname(e)),Je.writeFileSync(e,t)}function Ee(e,t){let o=j.join(e,".env.example");Je.existsSync(o)?Je.appendFileSync(o,`
78
+ `+t):Je.writeFileSync(o,t)}function mr(e){let t=`"use client";
79
79
  /**
80
80
  * PostHog browser SDK \u2014 lazy-initialized on first access.
81
81
  */
@@ -158,11 +158,11 @@ export function AnalyticsProvider({ children }: { children: React.ReactNode }) {
158
158
 
159
159
  return <>{children}</>;
160
160
  }
161
- `;$(k.join(e,"src","lib","analytics","posthog.client.ts"),t),$(k.join(e,"src","lib","analytics","posthog.server.ts"),o),$(k.join(e,"src","components","analytics","AnalyticsProvider.tsx"),n)}function sr(){return`# PostHog \u2014 product analytics
161
+ `;G(j.join(e,"src","lib","analytics","posthog.client.ts"),t),G(j.join(e,"src","lib","analytics","posthog.server.ts"),o),G(j.join(e,"src","components","analytics","AnalyticsProvider.tsx"),n)}function gr(){return`# PostHog \u2014 product analytics
162
162
  POSTHOG_KEY=
163
163
  NEXT_PUBLIC_POSTHOG_KEY=
164
164
  NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
165
- `}function ar(e){$(k.join(e,"src","components","analytics","PlausibleScript.tsx"),`"use client";
165
+ `}function fr(e){G(j.join(e,"src","components","analytics","PlausibleScript.tsx"),`"use client";
166
166
  /**
167
167
  * Plausible script tag \u2014 lightweight, privacy-friendly analytics.
168
168
  */
@@ -182,10 +182,10 @@ export function PlausibleScript() {
182
182
  />
183
183
  );
184
184
  }
185
- `)}function cr(){return`# Plausible \u2014 privacy-friendly analytics
185
+ `)}function yr(){return`# Plausible \u2014 privacy-friendly analytics
186
186
  NEXT_PUBLIC_PLAUSIBLE_DOMAIN=
187
187
  NEXT_PUBLIC_PLAUSIBLE_SRC=https://plausible.io/js/script.js
188
- `}function pr(e){$(k.join(e,"src","components","analytics","UmamiScript.tsx"),`"use client";
188
+ `}function Sr(e){G(j.join(e,"src","components","analytics","UmamiScript.tsx"),`"use client";
189
189
  /**
190
190
  * Umami analytics \u2014 self-hosted OR umami.is cloud.
191
191
  */
@@ -205,10 +205,10 @@ export function UmamiScript() {
205
205
  />
206
206
  );
207
207
  }
208
- `)}function lr(){return`# Umami \u2014 self-hostable analytics
208
+ `)}function hr(){return`# Umami \u2014 self-hostable analytics
209
209
  NEXT_PUBLIC_UMAMI_WEBSITE_ID=
210
210
  NEXT_PUBLIC_UMAMI_SRC=https://cloud.umami.is/script.js
211
- `}function dr(e){let t=`"use client";
211
+ `}function Er(e){let t=`"use client";
212
212
  import mixpanel from "mixpanel-browser";
213
213
 
214
214
  let initialized = false;
@@ -247,10 +247,10 @@ export function trackServer(
247
247
  if (!c) return;
248
248
  c.track(event, { distinct_id: distinctId, ...properties });
249
249
  }
250
- `;$(k.join(e,"src","lib","analytics","mixpanel.client.ts"),t),$(k.join(e,"src","lib","analytics","mixpanel.server.ts"),o)}function ur(){return`# Mixpanel \u2014 product analytics
250
+ `;G(j.join(e,"src","lib","analytics","mixpanel.client.ts"),t),G(j.join(e,"src","lib","analytics","mixpanel.server.ts"),o)}function vr(){return`# Mixpanel \u2014 product analytics
251
251
  MIXPANEL_TOKEN=
252
252
  NEXT_PUBLIC_MIXPANEL_TOKEN=
253
- `}function mr(e){$(k.join(e,"src","components","analytics","BaiduStatsScript.tsx"),`"use client";
253
+ `}function _r(e){G(j.join(e,"src","components","analytics","BaiduStatsScript.tsx"),`"use client";
254
254
  /**
255
255
  * \u767E\u5EA6\u7EDF\u8BA1 Baidu Tongji \u2014 hm.js \u57CB\u70B9\u811A\u672C.
256
256
  */
@@ -276,9 +276,9 @@ var _hmt = _hmt || [];
276
276
  />
277
277
  );
278
278
  }
279
- `)}function gr(){return`# \u767E\u5EA6\u7EDF\u8BA1 \u2014 \u4E2D\u56FD\u533A\u7F51\u7AD9\u5206\u6790
279
+ `)}function br(){return`# \u767E\u5EA6\u7EDF\u8BA1 \u2014 \u4E2D\u56FD\u533A\u7F51\u7AD9\u5206\u6790
280
280
  NEXT_PUBLIC_BAIDU_STATS_ID=
281
- `}function fr(e){$(k.join(e,"src","lib","analytics","sensors.client.ts"),`"use client";
281
+ `}function Pr(e){G(j.join(e,"src","lib","analytics","sensors.client.ts"),`"use client";
282
282
  /**
283
283
  * \u795E\u7B56\u5206\u6790 (Sensors Analytics) \u2014 sa-sdk-javascript \u5C01\u88C5.
284
284
  */
@@ -306,10 +306,10 @@ export function initSensors(): void {
306
306
  }
307
307
 
308
308
  export { sensors };
309
- `)}function yr(){return`# \u795E\u7B56\u5206\u6790 Sensors Analytics
309
+ `)}function Cr(){return`# \u795E\u7B56\u5206\u6790 Sensors Analytics
310
310
  NEXT_PUBLIC_SENSORS_SERVER_URL=
311
311
  NEXT_PUBLIC_SENSORS_APP_JS_URL=
312
- `}function Sr(e){$(k.join(e,"src","components","analytics","GrowingIoScript.tsx"),`"use client";
312
+ `}function Ir(e){G(j.join(e,"src","components","analytics","GrowingIoScript.tsx"),`"use client";
313
313
  /**
314
314
  * GrowingIO CDP \u2014 inline snippet installer.
315
315
  */
@@ -334,21 +334,21 @@ gdp("send");
334
334
  />
335
335
  );
336
336
  }
337
- `)}function Er(){return`# GrowingIO \u2014 \u5168\u57CB\u70B9 CDP (\u4E2D\u56FD\u533A)
337
+ `)}function Ar(){return`# GrowingIO \u2014 \u5168\u57CB\u70B9 CDP (\u4E2D\u56FD\u533A)
338
338
  NEXT_PUBLIC_GROWINGIO_ACCOUNT_ID=
339
- `}async function un(e,t,o="global"){let n=dn(t);if(!n||n.id==="none")return;let r=k.join(e,"apps","web");if(!Ge.existsSync(r))return;let i=n.id;try{switch(i){case"posthog":ir(r),ge(e,sr());return;case"plausible":ar(r),ge(e,cr());return;case"umami":pr(r),ge(e,lr());return;case"mixpanel":dr(r),ge(e,ur());return;case"baidu":mr(r),ge(e,gr());return;case"sensors":fr(r),ge(e,yr());return;case"growingio":Sr(r),ge(e,Er());return;default:return}}catch(s){throw console.error(`Failed to apply analytics selection "${t}":`,s),new Error(`Analytics scaffold for "${t}" failed \u2014 see stderr for details.`)}}var hr="https://analytics.nebutra.com";function vr(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function mn(e,t={}){vr(t)||(async()=>{try{let o=await import("./dist-B4YTE2SQ.js");if(typeof o.createAnalyticsClient!="function")return;let n=o.createAnalyticsClient({posthog:{apiKey:process.env.NEBUTRA_POSTHOG_KEY??"",host:process.env.NEBUTRA_POSTHOG_HOST??hr},onError:()=>{}});if(typeof n?.track!="function")return;let r=n.track("scaffold.completed",e);r&&typeof r.then=="function"&&await r.catch(()=>{})}catch{}})()}import U from"fs";import fe from"path";function Ft(e){U.existsSync(e)&&U.rmSync(e,{recursive:!0,force:!0})}function gn(e,t){let o=fe.join(e,".env.example");U.existsSync(o)?U.appendFileSync(o,`
340
- `+t):U.writeFileSync(o,t)}function fn(e,t){if(!U.existsSync(e))return;let o=U.readFileSync(e,"utf8"),n=o.replace(/export type AuthProviderId\s*=\s*"[^"]+"\s*\|\s*"[^"]+";/,`export type AuthProviderId = "${t}";`);n!==o&&U.writeFileSync(e,n)}function _r(e,t){let o=fe.join(e,"README.md");if(!U.existsSync(o)){U.writeFileSync(o,t);return}U.appendFileSync(o,`
341
- `+t)}async function yn(e,t){let o=fe.join(e,"packages","auth");if(!U.existsSync(o))return;if(t==="none"){Ft(o),_r(e,`
339
+ `}async function Sn(e,t,o="global"){let n=yn(t);if(!n||n.id==="none")return;let r=j.join(e,"apps","web");if(!Je.existsSync(r))return;let s=n.id;try{switch(s){case"posthog":mr(r),Ee(e,gr());return;case"plausible":fr(r),Ee(e,yr());return;case"umami":Sr(r),Ee(e,hr());return;case"mixpanel":Er(r),Ee(e,vr());return;case"baidu":_r(r),Ee(e,br());return;case"sensors":Pr(r),Ee(e,Cr());return;case"growingio":Ir(r),Ee(e,Ar());return;default:return}}catch(i){throw console.error(`Failed to apply analytics selection "${t}":`,i),new Error(`Analytics scaffold for "${t}" failed \u2014 see stderr for details.`)}}var wr="https://analytics.nebutra.com";function Rr(e={}){if(e.noTelemetry===!0)return!0;let t=process.env.NEBUTRA_TELEMETRY;return t==="0"||t==="false"}function hn(e,t={}){Rr(t)||(async()=>{try{let o=await import("@nebutra/analytics");if(typeof o.createAnalyticsClient!="function")return;let n=o.createAnalyticsClient({posthog:{apiKey:process.env.NEBUTRA_POSTHOG_KEY??"",host:process.env.NEBUTRA_POSTHOG_HOST??wr},onError:()=>{}});if(typeof n?.track!="function")return;let r=n.track("scaffold.completed",e);r&&typeof r.then=="function"&&await r.catch(()=>{})}catch{}})()}import F from"fs";import ve from"path";function Vt(e){F.existsSync(e)&&F.rmSync(e,{recursive:!0,force:!0})}function En(e,t){let o=ve.join(e,".env.example");F.existsSync(o)?F.appendFileSync(o,`
340
+ `+t):F.writeFileSync(o,t)}function vn(e,t){if(!F.existsSync(e))return;let o=F.readFileSync(e,"utf8"),n=o.replace(/export type AuthProviderId\s*=\s*"[^"]+"\s*\|\s*"[^"]+";/,`export type AuthProviderId = "${t}";`);n!==o&&F.writeFileSync(e,n)}function kr(e,t){let o=ve.join(e,"README.md");if(!F.existsSync(o)){F.writeFileSync(o,t);return}F.appendFileSync(o,`
341
+ `+t)}async function _n(e,t){let o=ve.join(e,"packages","auth");if(!F.existsSync(o))return;if(t==="none"){Vt(o),kr(e,`
342
342
  ## Auth
343
343
 
344
- Auth was skipped at scaffold time (\`--auth=none\`). Add your preferred auth provider manually (e.g. Clerk, Better Auth, NextAuth).
345
- `);return}let n=fe.join(o,"src","providers"),r=fe.join(o,"src","types.ts");if(t==="clerk"){Ft(fe.join(n,"better-auth.ts")),fn(r,"clerk"),gn(e,`# Clerk auth
344
+ Auth was skipped at scaffold time (\`--auth=none\`). Add your preferred auth provider manually (e.g. Clerk, Better Auth).
345
+ `);return}let n=ve.join(o,"src","providers"),r=ve.join(o,"src","types.ts");if(t==="clerk"){Vt(ve.join(n,"better-auth.ts")),vn(r,"clerk"),En(e,`# Clerk auth
346
346
  CLERK_PUBLISHABLE_KEY=
347
347
  CLERK_SECRET_KEY=
348
- `);return}if(t==="betterauth"){Ft(fe.join(n,"clerk.ts")),fn(r,"better-auth"),gn(e,`# Better Auth
348
+ `);return}if(t==="betterauth"){Vt(ve.join(n,"clerk.ts")),vn(r,"better-auth"),En(e,`# Better Auth
349
349
  BETTER_AUTH_SECRET=
350
350
  BETTER_AUTH_URL=http://localhost:3000
351
- `);return}}var nt=[{id:"wechat",name:"\u5FAE\u4FE1\u5F00\u653E\u5E73\u53F0",region:"cn",envVars:["WECHAT_APP_ID","WECHAT_APP_SECRET"],docs:"https://open.weixin.qq.com/cgi-bin/showdocument",callbackUrl:"/api/auth/callback/wechat",tokenEndpoint:"https://api.weixin.qq.com/sns/oauth2/access_token"},{id:"qq",name:"QQ \u767B\u5F55",region:"cn",envVars:["QQ_APP_ID","QQ_APP_KEY"],docs:"https://wiki.connect.qq.com",callbackUrl:"/api/auth/callback/qq",tokenEndpoint:"https://graph.qq.com/oauth2.0/token"},{id:"dingtalk",name:"\u9489\u9489",region:"cn",envVars:["DINGTALK_APP_ID","DINGTALK_APP_SECRET"],docs:"https://open.dingtalk.com/document/",callbackUrl:"/api/auth/callback/dingtalk",tokenEndpoint:"https://api.dingtalk.com/v1.0/oauth2/userAccessToken"},{id:"workweixin",name:"\u4F01\u4E1A\u5FAE\u4FE1",region:"cn",envVars:["WORKWEIXIN_CORP_ID","WORKWEIXIN_AGENT_ID","WORKWEIXIN_SECRET"],docs:"https://developer.work.weixin.qq.com",callbackUrl:"/api/auth/callback/workweixin",tokenEndpoint:"https://qyapi.weixin.qq.com/cgi-bin/gettoken"},{id:"feishu",name:"\u98DE\u4E66 / Lark",region:"cn",envVars:["FEISHU_APP_ID","FEISHU_APP_SECRET"],docs:"https://open.feishu.cn/document/",callbackUrl:"/api/auth/callback/feishu",tokenEndpoint:"https://open.feishu.cn/open-apis/authen/v1/access_token"},{id:"weibo",name:"\u5FAE\u535A",region:"cn",envVars:["WEIBO_APP_KEY","WEIBO_APP_SECRET"],docs:"https://open.weibo.com/wiki/",callbackUrl:"/api/auth/callback/weibo",tokenEndpoint:"https://api.weibo.com/oauth2/access_token"}],Pr=new Set(nt.map(e=>e.id));function Sn(e){return nt.find(t=>t.id===e)}function En(e){if(!e)return[];let t=e.split(",").map(r=>r.trim().toLowerCase()).filter(Boolean);if(t.includes("none"))return[];let o=[],n=new Set;for(let r of t)Pr.has(r)&&!n.has(r)&&(o.push(r),n.add(r));return o}import Se from"fs";import ye from"path";function br(e,t){let o=`// apps/web/src/app/api/auth/callback/${e.id}/route.ts
351
+ `);return}}var st=[{id:"wechat",name:"\u5FAE\u4FE1\u5F00\u653E\u5E73\u53F0",region:"cn",envVars:["WECHAT_APP_ID","WECHAT_APP_SECRET"],docs:"https://open.weixin.qq.com/cgi-bin/showdocument",callbackUrl:"/api/auth/callback/wechat",tokenEndpoint:"https://api.weixin.qq.com/sns/oauth2/access_token"},{id:"qq",name:"QQ \u767B\u5F55",region:"cn",envVars:["QQ_APP_ID","QQ_APP_KEY"],docs:"https://wiki.connect.qq.com",callbackUrl:"/api/auth/callback/qq",tokenEndpoint:"https://graph.qq.com/oauth2.0/token"},{id:"dingtalk",name:"\u9489\u9489",region:"cn",envVars:["DINGTALK_APP_ID","DINGTALK_APP_SECRET"],docs:"https://open.dingtalk.com/document/",callbackUrl:"/api/auth/callback/dingtalk",tokenEndpoint:"https://api.dingtalk.com/v1.0/oauth2/userAccessToken"},{id:"workweixin",name:"\u4F01\u4E1A\u5FAE\u4FE1",region:"cn",envVars:["WORKWEIXIN_CORP_ID","WORKWEIXIN_AGENT_ID","WORKWEIXIN_SECRET"],docs:"https://developer.work.weixin.qq.com",callbackUrl:"/api/auth/callback/workweixin",tokenEndpoint:"https://qyapi.weixin.qq.com/cgi-bin/gettoken"},{id:"feishu",name:"\u98DE\u4E66 / Lark",region:"cn",envVars:["FEISHU_APP_ID","FEISHU_APP_SECRET"],docs:"https://open.feishu.cn/document/",callbackUrl:"/api/auth/callback/feishu",tokenEndpoint:"https://open.feishu.cn/open-apis/authen/v1/access_token"},{id:"weibo",name:"\u5FAE\u535A",region:"cn",envVars:["WEIBO_APP_KEY","WEIBO_APP_SECRET"],docs:"https://open.weibo.com/wiki/",callbackUrl:"/api/auth/callback/weibo",tokenEndpoint:"https://api.weibo.com/oauth2/access_token"}],xr=new Set(st.map(e=>e.id));function bn(e){return st.find(t=>t.id===e)}function Pn(e){if(!e)return[];let t=e.split(",").map(r=>r.trim().toLowerCase()).filter(Boolean);if(t.includes("none"))return[];let o=[],n=new Set;for(let r of t)xr.has(r)&&!n.has(r)&&(o.push(r),n.add(r));return o}import be from"fs";import _e from"path";function Nr(e,t){let o=`// apps/web/src/app/api/auth/callback/${e.id}/route.ts
352
352
  // Generated by create-sailor \u2014 OAuth callback for ${e.name}
353
353
  // Primary auth provider: ${t}
354
354
  // Docs: ${e.docs}`,n={wechat:` const tokenRes = await fetch(
@@ -473,7 +473,7 @@ ${n[e.id]}
473
473
  void state;
474
474
  return NextResponse.redirect(new URL("/dashboard", req.url));
475
475
  }
476
- `}function Ir(e){return`"use client";
476
+ `}function Tr(e){return`"use client";
477
477
 
478
478
  /**
479
479
  * SocialLoginButtons \u2014 generated by create-sailor.
@@ -516,23 +516,23 @@ export function SocialLoginButtons() {
516
516
  </div>
517
517
  );
518
518
  }
519
- `}function hn(e){Se.mkdirSync(e,{recursive:!0})}function Ar(e,t){let o=ye.join(e,".env.example");Se.existsSync(o)?Se.appendFileSync(o,`
520
- `+t):Se.writeFileSync(o,t)}function Cr(e){let t=`# ${e.name} (${e.id}) \u2014 ${e.docs}`,o=e.envVars.map(n=>`${n}=`).join(`
519
+ `}function Cn(e){be.mkdirSync(e,{recursive:!0})}function Or(e,t){let o=_e.join(e,".env.example");be.existsSync(o)?be.appendFileSync(o,`
520
+ `+t):be.writeFileSync(o,t)}function Ur(e){let t=`# ${e.name} (${e.id}) \u2014 ${e.docs}`,o=e.envVars.map(n=>`${n}=`).join(`
521
521
  `);return`${t}
522
522
  ${o}
523
- `}async function vn(e,t,o){if(!t||t.length===0)return;let n=ye.join(e,"apps","web");if(!Se.existsSync(n))return;let r=new Set,i=[];for(let d of t){if(r.has(d))continue;r.add(d);let u=Sn(d);u&&i.push(u)}if(i.length===0)return;for(let d of i)Ar(e,Cr(d));let s=ye.join(n,"src","app","api","auth","callback");for(let d of i){let u=ye.join(s,d.id);hn(u);let h=ye.join(u,"route.ts");Se.writeFileSync(h,br(d,o))}let c=ye.join(n,"src","components","auth");hn(c);let a=ye.join(c,"SocialLoginButtons.tsx");Se.writeFileSync(a,Ir(i))}import ne from"fs";import jt from"path";var ht=[{id:"upstash-redis",name:"Upstash Redis",region:"both",envVars:["UPSTASH_REDIS_REST_URL","UPSTASH_REDIS_REST_TOKEN"],docs:"https://upstash.com/docs/redis",description:"Serverless Redis"},{id:"vercel-kv",name:"Vercel KV",region:"global",envVars:["KV_URL","KV_REST_API_URL","KV_REST_API_TOKEN","KV_REST_API_READ_ONLY_TOKEN"],docs:"https://vercel.com/docs/storage/vercel-kv",description:"Vercel native KV"},{id:"redis",name:"Redis (self-hosted)",region:"both",envVars:["REDIS_URL"],docs:"https://redis.io/docs/",description:"Self-hosted Redis"},{id:"dragonfly",name:"Dragonfly",region:"global",envVars:["DRAGONFLY_URL"],docs:"https://www.dragonflydb.io/docs",description:"Drop-in Redis replacement, faster"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip cache package"}];function _n(e){return ht.find(t=>t.id===e)}var wa=ht.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function Pn(e){return ne.existsSync(e)?ne.readFileSync(e,"utf-8"):null}function wr(e,t){let o=jt.join(e,".env.example"),n=Pn(o);if(n===null)return;let r=`# Cache: ${t.name}`;if(n.includes(r))return;let i=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(s=>`${s}=""`),""].join(`
524
- `);ne.appendFileSync(o,i)}function Rr(e,t,o){let n=jt.join(e,".env.example"),r=Pn(n);if(r===null)return;let i=new RegExp(`^${t}=.*$`,"m");i.test(r)?ne.writeFileSync(n,r.replace(i,`${t}="${o}"`)):ne.appendFileSync(n,`${t}="${o}"
525
- `)}async function bn(e,t,o){let n=jt.join(e,"packages","cache");if(t==="none"){ne.existsSync(n)&&ne.rmSync(n,{recursive:!0,force:!0});return}let r=_n(t);if(!r)throw new Error(`Unknown cache provider "${t}". Valid ids: ${ht.map(i=>i.id).join(", ")}`);ne.existsSync(n)&&(wr(e,r),Rr(e,"CACHE_PROVIDER",t))}var vt=[{id:"turnstile",name:"Cloudflare Turnstile",region:"global",envVars:["NEXT_PUBLIC_TURNSTILE_SITE_KEY","TURNSTILE_SECRET_KEY"],docs:"https://developers.cloudflare.com/turnstile/",description:"Free, privacy-focused captcha alternative"},{id:"hcaptcha",name:"hCaptcha",region:"global",envVars:["NEXT_PUBLIC_HCAPTCHA_SITE_KEY","HCAPTCHA_SECRET_KEY"],docs:"https://docs.hcaptcha.com/",description:"Privacy-respecting captcha"},{id:"aliyun-slide",name:"\u963F\u91CC\u4E91\u9A8C\u8BC1\u7801 2.0",region:"cn",envVars:["ALIYUN_CAPTCHA_ACCESS_KEY_ID","ALIYUN_CAPTCHA_ACCESS_KEY_SECRET","ALIYUN_CAPTCHA_APP_KEY","NEXT_PUBLIC_ALIYUN_CAPTCHA_APP_KEY"],docs:"https://help.aliyun.com/product/28308.html",description:"\u963F\u91CC\u4E91\u667A\u80FD\u9A8C\u8BC1 (\u6ED1\u5757/\u65E0\u75D5)"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function In(e){return vt.find(t=>t.id===e)}var Oa=vt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});import J from"fs";import Vt from"path";function q(e,t){let o=Vt.join(e,".env.example");if(!J.existsSync(o)||t.envVars.length===0)return;let r=`# ${t.category??t.name}: ${t.name}`;if(J.readFileSync(o,"utf-8").includes(r))return;let c=["","# =============================================",r,t.docs?`# Docs: ${t.docs}`:null,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].filter(a=>a!==null).join(`
526
- `);J.appendFileSync(o,c)}function G(e,t,o){let n=Vt.join(e,".env.example");if(!J.existsSync(n))return;let r=J.readFileSync(n,"utf-8"),i=`${t}="${o}"`,s=new RegExp(`^${t}=.*$`,"m");if(s.test(r)){J.writeFileSync(n,r.replace(s,i));return}let c=r.endsWith(`
523
+ `}async function In(e,t,o){if(!t||t.length===0)return;let n=_e.join(e,"apps","web");if(!be.existsSync(n))return;let r=new Set,s=[];for(let l of t){if(r.has(l))continue;r.add(l);let m=bn(l);m&&s.push(m)}if(s.length===0)return;for(let l of s)Or(e,Ur(l));let i=_e.join(n,"src","app","api","auth","callback");for(let l of s){let m=_e.join(i,l.id);Cn(m);let y=_e.join(m,"route.ts");be.writeFileSync(y,Nr(l,o))}let c=_e.join(n,"src","components","auth");Cn(c);let a=_e.join(c,"SocialLoginButtons.tsx");be.writeFileSync(a,Tr(s))}import ie from"fs";import Bt from"path";var bt=[{id:"upstash-redis",name:"Upstash Redis",region:"both",envVars:["UPSTASH_REDIS_REST_URL","UPSTASH_REDIS_REST_TOKEN"],docs:"https://upstash.com/docs/redis",description:"Serverless Redis"},{id:"vercel-kv",name:"Vercel KV",region:"global",envVars:["KV_URL","KV_REST_API_URL","KV_REST_API_TOKEN","KV_REST_API_READ_ONLY_TOKEN"],docs:"https://vercel.com/docs/storage/vercel-kv",description:"Vercel native KV"},{id:"redis",name:"Redis (self-hosted)",region:"both",envVars:["REDIS_URL"],docs:"https://redis.io/docs/",description:"Self-hosted Redis"},{id:"dragonfly",name:"Dragonfly",region:"global",envVars:["DRAGONFLY_URL"],docs:"https://www.dragonflydb.io/docs",description:"Drop-in Redis replacement, faster"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip cache package"}];function An(e){return bt.find(t=>t.id===e)}var ja=bt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function wn(e){return ie.existsSync(e)?ie.readFileSync(e,"utf-8"):null}function Lr(e,t){let o=Bt.join(e,".env.example"),n=wn(o);if(n===null)return;let r=`# Cache: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(i=>`${i}=""`),""].join(`
524
+ `);ie.appendFileSync(o,s)}function Mr(e,t,o){let n=Bt.join(e,".env.example"),r=wn(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?ie.writeFileSync(n,r.replace(s,`${t}="${o}"`)):ie.appendFileSync(n,`${t}="${o}"
525
+ `)}async function Rn(e,t,o){let n=Bt.join(e,"packages","cache");if(t==="none"){ie.existsSync(n)&&ie.rmSync(n,{recursive:!0,force:!0});return}let r=An(t);if(!r)throw new Error(`Unknown cache provider "${t}". Valid ids: ${bt.map(s=>s.id).join(", ")}`);ie.existsSync(n)&&(Lr(e,r),Mr(e,"CACHE_PROVIDER",t))}var Pt=[{id:"turnstile",name:"Cloudflare Turnstile",region:"global",envVars:["NEXT_PUBLIC_TURNSTILE_SITE_KEY","TURNSTILE_SECRET_KEY"],docs:"https://developers.cloudflare.com/turnstile/",description:"Free, privacy-focused captcha alternative"},{id:"hcaptcha",name:"hCaptcha",region:"global",envVars:["NEXT_PUBLIC_HCAPTCHA_SITE_KEY","HCAPTCHA_SECRET_KEY"],docs:"https://docs.hcaptcha.com/",description:"Privacy-respecting captcha"},{id:"aliyun-slide",name:"\u963F\u91CC\u4E91\u9A8C\u8BC1\u7801 2.0",region:"cn",envVars:["ALIYUN_CAPTCHA_ACCESS_KEY_ID","ALIYUN_CAPTCHA_ACCESS_KEY_SECRET","ALIYUN_CAPTCHA_APP_KEY","NEXT_PUBLIC_ALIYUN_CAPTCHA_APP_KEY"],docs:"https://help.aliyun.com/product/28308.html",description:"\u963F\u91CC\u4E91\u667A\u80FD\u9A8C\u8BC1 (\u6ED1\u5757/\u65E0\u75D5)"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function kn(e){return Pt.find(t=>t.id===e)}var Ya=Pt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});import ee from"fs";import Yt from"path";function W(e,t){let o=Yt.join(e,".env.example");if(!ee.existsSync(o)||t.envVars.length===0)return;let r=`# ${t.category??t.name}: ${t.name}`;if(ee.readFileSync(o,"utf-8").includes(r))return;let c=["","# =============================================",r,t.docs?`# Docs: ${t.docs}`:null,"# =============================================",...t.envVars.map(a=>`${a}=""`),""].filter(a=>a!==null).join(`
526
+ `);ee.appendFileSync(o,c)}function H(e,t,o){let n=Yt.join(e,".env.example");if(!ee.existsSync(n))return;let r=ee.readFileSync(n,"utf-8"),s=`${t}="${o}"`,i=new RegExp(`^${t}=.*$`,"m");if(i.test(r)){ee.writeFileSync(n,r.replace(i,s));return}let c=r.endsWith(`
527
527
  `)?"":`
528
- `;J.appendFileSync(n,`${c}${i}
529
- `)}function K(e,t){let o=Vt.join(e,"packages",t);J.existsSync(o)&&J.rmSync(o,{recursive:!0,force:!0})}async function An(e,t,o="global"){let n=In(t);if(!n)throw new Error(`Unknown captcha provider "${t}". Valid ids: ${vt.map(r=>r.id).join(", ")}`);if(n.id==="none"){K(e,"captcha");return}n.envVars.length>0&&q(e,{category:"Captcha",name:n.name,envVars:n.envVars,docs:n.docs}),G(e,"CAPTCHA_PROVIDER",n.id)}import Pt from"fs";import xr from"path";var _t=[{id:"sanity",name:"Sanity",region:"global",envVars:["SANITY_PROJECT_ID","SANITY_DATASET","SANITY_API_TOKEN","SANITY_API_VERSION"],docs:"https://www.sanity.io/docs",description:"Structured content platform with Studio"},{id:"contentful",name:"Contentful",region:"global",envVars:["CONTENTFUL_SPACE_ID","CONTENTFUL_ACCESS_TOKEN","CONTENTFUL_PREVIEW_ACCESS_TOKEN"],docs:"https://www.contentful.com/developers/docs/",description:"Headless CMS"},{id:"strapi",name:"Strapi",region:"both",envVars:["STRAPI_URL","STRAPI_API_TOKEN"],docs:"https://docs.strapi.io",description:"Open-source self-hosted CMS"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function Cn(e){return _t.find(t=>t.id===e)}var Ka=_t.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function wn(e,t,o="global"){let n=Cn(t);if(!n)throw new Error(`Unknown CMS provider "${t}". Valid ids: ${_t.map(i=>i.id).join(", ")}`);let r=xr.join(e,"apps","studio");if(n.id==="none"){K(e,"sanity"),Pt.existsSync(r)&&Pt.rmSync(r,{recursive:!0,force:!0});return}n.id!=="sanity"&&(K(e,"sanity"),Pt.existsSync(r)&&Pt.rmSync(r,{recursive:!0,force:!0})),n.envVars.length>0&&q(e,{category:"CMS",name:n.name,envVars:n.envVars,docs:n.docs}),G(e,"CMS_PROVIDER",n.id)}import A from"fs";import I from"path";var Nr=I.join("apps","web"),Kt=I.join("src","components","compliance"),ot=I.join("src","app","[locale]");function H(e){return I.join(e,Nr)}function kr(e){A.mkdirSync(e,{recursive:!0})}function B(e,t){kr(I.dirname(e)),A.writeFileSync(e,t,"utf8")}function Bt(e,t){let o=I.join(e,".env.example");if(A.existsSync(o)){if(A.readFileSync(o,"utf8").includes(t.split(`
530
- `)[0]??""))return;A.appendFileSync(o,`
528
+ `;ee.appendFileSync(n,`${c}${s}
529
+ `)}function Y(e,t){let o=Yt.join(e,"packages",t);ee.existsSync(o)&&ee.rmSync(o,{recursive:!0,force:!0})}async function xn(e,t,o="global"){let n=kn(t);if(!n)throw new Error(`Unknown captcha provider "${t}". Valid ids: ${Pt.map(r=>r.id).join(", ")}`);if(n.id==="none"){Y(e,"captcha");return}n.envVars.length>0&&W(e,{category:"Captcha",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"CAPTCHA_PROVIDER",n.id)}import It from"fs";import jr from"path";var Ct=[{id:"sanity",name:"Sanity",region:"global",envVars:["SANITY_PROJECT_ID","SANITY_DATASET","SANITY_API_TOKEN","SANITY_API_VERSION"],docs:"https://www.sanity.io/docs",description:"Structured content platform with Studio"},{id:"contentful",name:"Contentful",region:"global",envVars:["CONTENTFUL_SPACE_ID","CONTENTFUL_ACCESS_TOKEN","CONTENTFUL_PREVIEW_ACCESS_TOKEN"],docs:"https://www.contentful.com/developers/docs/",description:"Headless CMS"},{id:"strapi",name:"Strapi",region:"both",envVars:["STRAPI_URL","STRAPI_API_TOKEN"],docs:"https://docs.strapi.io",description:"Open-source self-hosted CMS"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function Nn(e){return Ct.find(t=>t.id===e)}var Ja=Ct.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Tn(e,t,o="global"){let n=Nn(t);if(!n)throw new Error(`Unknown CMS provider "${t}". Valid ids: ${Ct.map(s=>s.id).join(", ")}`);let r=jr.join(e,"apps","studio");if(n.id==="none"){Y(e,"sanity"),It.existsSync(r)&&It.rmSync(r,{recursive:!0,force:!0});return}n.id!=="sanity"&&(Y(e,"sanity"),It.existsSync(r)&&It.rmSync(r,{recursive:!0,force:!0})),n.envVars.length>0&&W(e,{category:"CMS",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"CMS_PROVIDER",n.id)}import w from"fs";import A from"path";var Fr=A.join("apps","web"),$t=A.join("src","components","compliance"),it=A.join("src","app","[locale]");function X(e){return A.join(e,Fr)}function Dr(e){w.mkdirSync(e,{recursive:!0})}function $(e,t){Dr(A.dirname(e)),w.writeFileSync(e,t,"utf8")}function qt(e,t){let o=A.join(e,".env.example");if(w.existsSync(o)){if(w.readFileSync(o,"utf8").includes(t.split(`
530
+ `)[0]??""))return;w.appendFileSync(o,`
531
531
  `+t+`
532
- `)}else A.writeFileSync(o,t+`
533
- `)}var rt=`> **TEMPLATE \u2014 NOT LEGAL ADVICE.** This document is a boilerplate scaffold only.
532
+ `)}else w.writeFileSync(o,t+`
533
+ `)}var at=`> **TEMPLATE \u2014 NOT LEGAL ADVICE.** This document is a boilerplate scaffold only.
534
534
  > Consult a qualified lawyer in every jurisdiction you operate in before publishing.
535
- > \u672C\u6587\u6863\u4E3A\u6A21\u677F\u811A\u624B\u67B6\uFF0C\u4E0D\u6784\u6210\u6CD5\u5F8B\u610F\u89C1\u3002\u53D1\u5E03\u524D\u8BF7\u54A8\u8BE2\u76F8\u5173\u53F8\u6CD5\u8F96\u533A\u7684\u5408\u683C\u5F8B\u5E08\u3002`,Tr=`import Link from "next/link";
535
+ > \u672C\u6587\u6863\u4E3A\u6A21\u677F\u811A\u624B\u67B6\uFF0C\u4E0D\u6784\u6210\u6CD5\u5F8B\u610F\u89C1\u3002\u53D1\u5E03\u524D\u8BF7\u54A8\u8BE2\u76F8\u5173\u53F8\u6CD5\u8F96\u533A\u7684\u5408\u683C\u5F8B\u5E08\u3002`,Kr=`import Link from "next/link";
536
536
  import { IcpFooter } from "@/components/compliance/IcpFooter";
537
537
  import { PublicSecurityFooter } from "@/components/compliance/PublicSecurityFooter";
538
538
 
@@ -583,7 +583,7 @@ export function Footer({ region = "global" }: FooterProps) {
583
583
  </footer>
584
584
  );
585
585
  }
586
- `,Or=`export function IcpFooter() {
586
+ `,Vr=`export function IcpFooter() {
587
587
  const icp = process.env.NEXT_PUBLIC_ICP_BEIAN;
588
588
  if (!icp) return null;
589
589
  return (
@@ -597,7 +597,7 @@ export function Footer({ region = "global" }: FooterProps) {
597
597
  </a>
598
598
  );
599
599
  }
600
- `,Ur=`export function PublicSecurityFooter() {
600
+ `,Br=`export function PublicSecurityFooter() {
601
601
  const psb = process.env.NEXT_PUBLIC_PSB_BEIAN;
602
602
  const psbCode = process.env.NEXT_PUBLIC_PSB_CODE;
603
603
  if (!psb) return null;
@@ -614,7 +614,7 @@ export function Footer({ region = "global" }: FooterProps) {
614
614
  </a>
615
615
  );
616
616
  }
617
- `,Lr=`"use client";
617
+ `,Yr=`"use client";
618
618
 
619
619
  import { useCallback, useEffect, useState } from "react";
620
620
 
@@ -841,7 +841,7 @@ function CategoryRow({ id, title, description, checked, disabled, onChange }: Ca
841
841
  </label>
842
842
  );
843
843
  }
844
- `,Mr=`interface AigcDisclaimerProps {
844
+ `,$r=`interface AigcDisclaimerProps {
845
845
  className?: string;
846
846
  }
847
847
 
@@ -861,13 +861,13 @@ export function AigcDisclaimer({ className }: AigcDisclaimerProps) {
861
861
  </div>
862
862
  );
863
863
  }
864
- `,Dr=`---
864
+ `,qr=`---
865
865
  title: Privacy Policy / \u9690\u79C1\u653F\u7B56
866
866
  description: How {{COMPANY_NAME}} collects, uses, shares, and protects personal information.
867
867
  lastUpdated: 2026-01-01
868
868
  ---
869
869
 
870
- ${rt}
870
+ ${at}
871
871
 
872
872
  # Privacy Policy / \u9690\u79C1\u653F\u7B56
873
873
 
@@ -1006,13 +1006,13 @@ or in-app notification before the change takes effect.
1006
1006
  **Data Controller / \u6570\u636E\u63A7\u5236\u8005:** {{COMPANY_NAME}}
1007
1007
  **Address / \u5730\u5740:** {{COMPANY_ADDRESS}}
1008
1008
  **Email / \u90AE\u7BB1:** {{COMPANY_CONTACT_EMAIL}}
1009
- `,Fr=`---
1009
+ `,Gr=`---
1010
1010
  title: Terms of Service / \u670D\u52A1\u6761\u6B3E
1011
1011
  description: Terms governing your use of {{COMPANY_NAME}}.
1012
1012
  lastUpdated: 2026-01-01
1013
1013
  ---
1014
1014
 
1015
- ${rt}
1015
+ ${at}
1016
1016
 
1017
1017
  # Terms of Service / \u670D\u52A1\u6761\u6B3E
1018
1018
 
@@ -1125,13 +1125,13 @@ conflict-of-laws principles. Disputes shall be resolved in the competent courts
1125
1125
  ## 11. Contact / \u8054\u7CFB\u65B9\u5F0F
1126
1126
 
1127
1127
  {{COMPANY_NAME}} \xB7 {{COMPANY_ADDRESS}} \xB7 {{COMPANY_CONTACT_EMAIL}}
1128
- `,jr=`---
1128
+ `,Wr=`---
1129
1129
  title: AIGC Disclosure / \u751F\u6210\u5F0F AI \u670D\u52A1\u8BF4\u660E
1130
1130
  description: Disclosure required by \u7F51\u4FE1\u529E\u300A\u751F\u6210\u5F0F\u4EBA\u5DE5\u667A\u80FD\u670D\u52A1\u7BA1\u7406\u6682\u884C\u529E\u6CD5\u300B
1131
1131
  lastUpdated: 2026-01-01
1132
1132
  ---
1133
1133
 
1134
- ${rt}
1134
+ ${at}
1135
1135
 
1136
1136
  # AIGC Disclosure / \u751F\u6210\u5F0F AI \u670D\u52A1\u8BF4\u660E
1137
1137
 
@@ -1207,13 +1207,13 @@ human professional.
1207
1207
 
1208
1208
  AI \u8F93\u51FA\u53EF\u80FD\u4E0D\u51C6\u786E\u3001\u5B58\u5728\u504F\u89C1\u6216\u8FC7\u65F6\u3002**\u8BF7\u52FF**\u5728\u672A\u7ECF\u5408\u683C\u4E13\u4E1A\u4EBA\u58EB\u72EC\u7ACB\u6838\u5B9E\u7684\u60C5\u51B5\u4E0B\uFF0C\u5C06 AI \u8F93\u51FA
1209
1209
  \u7528\u4E8E\u533B\u7597\u3001\u6CD5\u5F8B\u3001\u91D1\u878D\u6216\u5B89\u5168\u6538\u5173\u7684\u51B3\u7B56\u3002
1210
- `,Vr=`---
1210
+ `,Hr=`---
1211
1211
  title: Cross-Border Data Notice / \u6570\u636E\u51FA\u5883\u544A\u77E5
1212
1212
  description: Notice of cross-border transfer of personal information, per PIPL.
1213
1213
  lastUpdated: 2026-01-01
1214
1214
  ---
1215
1215
 
1216
- ${rt}
1216
+ ${at}
1217
1217
 
1218
1218
  # Cross-Border Data Notice / \u6570\u636E\u51FA\u5883\u544A\u77E5
1219
1219
 
@@ -1272,13 +1272,13 @@ Refusal may limit your ability to use features that rely on overseas services.
1272
1272
  - \u4F20\u8F93\u4E2D\u52A0\u5BC6 (TLS 1.2+) \u53CA\u9759\u6001\u52A0\u5BC6 (AES-256)\u3002
1273
1273
  - \u5408\u540C\u6761\u6B3E\u8981\u6C42\u5883\u5916\u63A5\u6536\u65B9\u63D0\u4F9B\u7B49\u540C\u4E8E PIPL \u7684\u4FDD\u62A4\u3002
1274
1274
  - \u8BBF\u95EE\u63A7\u5236\u3001\u5BA1\u8BA1\u65E5\u5FD7\u548C\u8FDD\u89C4\u901A\u77E5\u7A0B\u5E8F\u3002
1275
- `,Kr=`---
1275
+ `,Xr=`---
1276
1276
  title: Personal Information Collection List / \u4E2A\u4EBA\u4FE1\u606F\u6536\u96C6\u6E05\u5355
1277
1277
  description: Itemized list of personal information collected, per PIPL Article 17.
1278
1278
  lastUpdated: 2026-01-01
1279
1279
  ---
1280
1280
 
1281
- ${rt}
1281
+ ${at}
1282
1282
 
1283
1283
  # Personal Information Collection List / \u4E2A\u4EBA\u4FE1\u606F\u6536\u96C6\u6E05\u5355
1284
1284
 
@@ -1314,19 +1314,19 @@ To exercise your rights (access, rectify, delete, export, withdraw consent), con
1314
1314
  **{{COMPANY_CONTACT_EMAIL}}**.
1315
1315
 
1316
1316
  \u5982\u9700\u884C\u4F7F\u60A8\u7684\u6743\u5229\uFF08\u8BBF\u95EE\u3001\u66F4\u6B63\u3001\u5220\u9664\u3001\u5BFC\u51FA\u3001\u64A4\u56DE\u540C\u610F\uFF09\uFF0C\u8BF7\u8054\u7CFB **{{COMPANY_CONTACT_EMAIL}}**\u3002
1317
- `;async function Br(e,t){let o=H(e);if(!A.existsSync(o))return;let n=I.join(o,"src","components","compliance","Footer.tsx");B(n,Tr);let r=I.join(o,"src","components","compliance","README.md");B(r,["# Compliance Components","",`Auto-generated by \`create-sailor\` for region: \`${t}\`.`,"","## Mounting the Footer","","```tsx",'import { Footer } from "@/components/compliance/Footer";','import { CookieBanner } from "@/components/compliance/CookieBanner";',"","export default function RootLayout({ children }) {"," return ("," <html>"," <body>"," {children}",` <Footer region="${t}" />`," <CookieBanner />"," </body>"," </html>"," );","}","```","","## Placeholders","","Policy MDX files contain `{{COMPANY_NAME}}`, `{{COMPANY_ADDRESS}}`,","`{{COMPANY_CONTACT_EMAIL}}`, `{{GOVERNING_JURISDICTION}}`, and","`{{AIGC_ALGORITHM_FILING_NUMBER}}`. These are filled by the `brand-apply` step.",""].join(`
1318
- `))}async function Yr(e,t){let o=H(e);if(!A.existsSync(o))return;let n=I.join(o,"src","components","compliance","CookieBanner.tsx");B(n,Lr)}async function $r(e,t){let o=H(e);if(!A.existsSync(o))return;let n=I.join(o,ot,"privacy","page.mdx");B(n,Dr)}async function qr(e,t){let o=H(e);if(!A.existsSync(o))return;let n=I.join(o,ot,"terms","page.mdx");B(n,Fr)}async function Gr(e){let t=H(e);if(!A.existsSync(t))return;let o=I.join(t,Kt,"IcpFooter.tsx");B(o,Or),Bt(e,["# Chinese ICP filing (\u5DE5\u4FE1\u90E8 ICP \u5907\u6848) \u2014 required to legally host a","# public-facing site from mainland China. Apply at https://beian.miit.gov.cn/",'NEXT_PUBLIC_ICP_BEIAN="" # \u5982 \u82CFICP\u59072024XXXXXX\u53F7'].join(`
1319
- `))}async function Hr(e){let t=H(e);if(!A.existsSync(t))return;let o=I.join(t,Kt,"PublicSecurityFooter.tsx");B(o,Ur),Bt(e,["# Chinese Public Security Bureau filing (\u516C\u5B89\u8054\u7F51\u5907\u6848)","# Required in addition to ICP. Apply at http://www.beian.gov.cn/",'NEXT_PUBLIC_PSB_BEIAN="" # \u5982 \u82CF\u516C\u7F51\u5B89\u5907 32011402XXXXXX\u53F7','NEXT_PUBLIC_PSB_CODE="" # 14-digit record code'].join(`
1320
- `))}async function Wr(e){let t=H(e);if(!A.existsSync(t))return;let o=I.join(t,Kt,"AigcDisclaimer.tsx");B(o,Mr),Bt(e,["# Generative AI algorithm filing (\u7B97\u6CD5\u5907\u6848\u53F7) \u2014 required by","# \u7F51\u4FE1\u529E\u300A\u751F\u6210\u5F0F\u4EBA\u5DE5\u667A\u80FD\u670D\u52A1\u7BA1\u7406\u6682\u884C\u529E\u6CD5\u300Bfor services offered in China.",'NEXT_PUBLIC_AIGC_FILING_NUMBER="" # e.g. \u7F51\u4FE1\u7B97\u5907XXXXXXXX\u53F7'].join(`
1321
- `))}async function Xr(e){let t=H(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"aigc-disclosure","page.mdx");B(o,jr)}async function zr(e){let t=H(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"cross-border-data","page.mdx");B(o,Vr)}async function Qr(e){let t=H(e);if(!A.existsSync(t))return;let o=I.join(t,ot,"pii-collection","page.mdx");B(o,Kr)}async function Rn(e,t){try{await Br(e,t),await Yr(e,t),await $r(e,t),await qr(e,t),(t==="cn"||t==="hybrid")&&(await Gr(e),await Hr(e),await Wr(e),await Xr(e),await zr(e),await Qr(e))}catch(o){throw console.error("applyComplianceTemplates failed:",o),new Error(`Failed to apply compliance templates for region "${t}". Check that ${e} is writable.`)}}import Jr from"fs";import Zr from"path";async function xn(e,t){let o=Zr.join(e,"nebutra.config.json");Jr.writeFileSync(o,JSON.stringify(t,null,2)+`
1322
- `)}import oe from"fs";import Yt from"path";function ei(e){oe.existsSync(e)&&oe.rmSync(e,{recursive:!0,force:!0})}function Nn(e,t){return e.replace(/provider\s*=\s*"postgresql"/,`provider = "${t}"`)}function ti(e){return e.replace(/^\s*directUrl\s*=\s*env\([^)]*\)\s*\n/gm,"")}function kn(e){let t=e.replace(/^\s*extensions\s*=\s*\[[^\]]*\]\s*\n/gm,"");return t=t.replace(/previewFeatures\s*=\s*\[\s*"postgresqlExtensions"\s*\]\s*\n/g,""),t}function ni(e,t){let o=Yt.join(e,".env.example");oe.existsSync(o)?oe.appendFileSync(o,`
1323
- `+t):oe.writeFileSync(o,t)}async function Tn(e,t,o){let n=Yt.join(e,"packages","db");if(t==="none"){ei(n);return}let r=Yt.join(n,"prisma","schema.prisma"),i;if(t==="postgresql"?i=`postgresql://postgres:postgres@localhost:5432/${o}`:t==="mysql"?i=`mysql://root:root@localhost:3306/${o}`:i="file:./dev.db",ni(e,`# Database (${t})
1324
- DATABASE_URL="${i}"
1325
- `),!oe.existsSync(r))return;let s=oe.readFileSync(r,"utf8"),c=s;t==="mysql"?(c=Nn(c,"mysql"),c=kn(c)):t==="sqlite"&&(c=Nn(c,"sqlite"),c=ti(c),c=kn(c)),c!==s&&oe.writeFileSync(r,c)}import it from"fs";import L from"path";import{fileURLToPath as oi}from"url";var ri=oi(import.meta.url),ii=L.dirname(ri);async function On(e,t){if(t==="none")return;let o=L.join(ii,"../../templates/deploy");t==="vercel"?await it.promises.copyFile(L.join(o,"vercel.json"),L.join(e,"vercel.json")):t==="railway"?await it.promises.copyFile(L.join(o,"railway.toml"),L.join(e,"railway.toml")):t==="cloudflare"?await it.promises.copyFile(L.join(o,"wrangler.toml"),L.join(e,"wrangler.toml")):t==="selfhost"&&(await it.promises.copyFile(L.join(o,"docker-compose.yml"),L.join(e,"docker-compose.yml")),await it.promises.copyFile(L.join(o,"Dockerfile.web"),L.join(e,"Dockerfile.web")))}import re from"fs";import Ee from"path";import{fileURLToPath as si}from"url";var ai=si(import.meta.url),Un=Ee.dirname(ai),ci=/\.(md|mdx|json|ts|tsx|js|mjs|cjs|yaml|yml)$/;function pi(e){let t=[Ee.join(Un,"..","templates","docs",e),Ee.join(Un,"..","..","templates","docs",e)];for(let o of t)if(re.existsSync(o))return o;return t[0]}async function Ln(e,t){if(t.framework==="none")return;let o=(t.framework==="fumadocs","fumadocs"),n=pi(o),r=Ee.join(e,"apps","docs");if(!re.existsSync(n))throw new Error(`Docs template not found: ${n}`);Mn(n,r),Dn(r,{"{PRODUCT_NAME}":t.projectName})}function Mn(e,t){re.mkdirSync(t,{recursive:!0});for(let o of re.readdirSync(e,{withFileTypes:!0})){let n=Ee.join(e,o.name),r=Ee.join(t,o.name);o.isDirectory()?Mn(n,r):re.copyFileSync(n,r)}}function Dn(e,t){for(let o of re.readdirSync(e,{withFileTypes:!0})){let n=Ee.join(e,o.name);if(o.isDirectory())Dn(n,t);else if(ci.test(o.name)){let r=re.readFileSync(n,"utf-8");for(let[i,s]of Object.entries(t))r=r.split(i).join(s);re.writeFileSync(n,r)}}}import ve from"fs";import he from"path";var bt=[{id:"resend",name:"Resend",region:"global",envVars:["RESEND_API_KEY","RESEND_FROM"],docs:"https://resend.com/docs",pkg:"resend",pkgVersion:"^4.0.1"},{id:"postmark",name:"Postmark",region:"global",envVars:["POSTMARK_API_KEY","POSTMARK_FROM"],docs:"https://postmarkapp.com/developer",pkg:"postmark",pkgVersion:"^4.0.5"},{id:"ses",name:"AWS SES",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SES_REGION","SES_FROM"],docs:"https://docs.aws.amazon.com/ses",pkg:"@aws-sdk/client-sesv2",pkgVersion:"^3.658.0"},{id:"aliyun-dm",name:"\u963F\u91CC\u4E91\u90AE\u4EF6\u63A8\u9001",region:"cn",envVars:["ALIYUN_DM_ACCESS_KEY","ALIYUN_DM_ACCESS_SECRET","ALIYUN_DM_ACCOUNT_NAME","ALIYUN_DM_FROM_ALIAS"],docs:"https://help.aliyun.com/product/29412.html",pkg:"@alicloud/dm20151123",pkgVersion:"^3.0.0"},{id:"tencent-ses",name:"\u817E\u8BAF\u4E91 SES",region:"cn",envVars:["TENCENT_SECRET_ID","TENCENT_SECRET_KEY","TENCENT_SES_FROM_EMAIL"],docs:"https://cloud.tencent.com/document/product/1288",pkg:"tencentcloud-sdk-nodejs-ses",pkgVersion:"^4.0.900"},{id:"netease",name:"\u7F51\u6613\u4F01\u4E1A\u90AE\u7BB1",region:"cn",envVars:["NETEASE_USER","NETEASE_PASS","NETEASE_FROM"],docs:"https://qiye.163.com/help",pkg:"nodemailer",pkgVersion:"^6.9.15"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function Fn(e){return bt.find(t=>t.id===e)}var dc=bt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var _e="@nebutra/email";function $t(e,t){ve.mkdirSync(he.dirname(e),{recursive:!0}),ve.writeFileSync(e,t)}function li(e,t){let o=he.join(e,".env.example");ve.existsSync(o)?ve.appendFileSync(o,`
1326
- `+t):ve.writeFileSync(o,t)}function di(e){if(e.envVars.length===0)return"";let t=`# Email provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
1317
+ `;async function zr(e,t){let o=X(e);if(!w.existsSync(o))return;let n=A.join(o,"src","components","compliance","Footer.tsx");$(n,Kr);let r=A.join(o,"src","components","compliance","README.md");$(r,["# Compliance Components","",`Auto-generated by \`create-sailor\` for region: \`${t}\`.`,"","## Mounting the Footer","","```tsx",'import { Footer } from "@/components/compliance/Footer";','import { CookieBanner } from "@/components/compliance/CookieBanner";',"","export default function RootLayout({ children }) {"," return ("," <html>"," <body>"," {children}",` <Footer region="${t}" />`," <CookieBanner />"," </body>"," </html>"," );","}","```","","## Placeholders","","Policy MDX files contain `{{COMPANY_NAME}}`, `{{COMPANY_ADDRESS}}`,","`{{COMPANY_CONTACT_EMAIL}}`, `{{GOVERNING_JURISDICTION}}`, and","`{{AIGC_ALGORITHM_FILING_NUMBER}}`. These are filled by the `brand-apply` step.",""].join(`
1318
+ `))}async function Jr(e,t){let o=X(e);if(!w.existsSync(o))return;let n=A.join(o,"src","components","compliance","CookieBanner.tsx");$(n,Yr)}async function Qr(e,t){let o=X(e);if(!w.existsSync(o))return;let n=A.join(o,it,"privacy","page.mdx");$(n,qr)}async function Zr(e,t){let o=X(e);if(!w.existsSync(o))return;let n=A.join(o,it,"terms","page.mdx");$(n,Gr)}async function es(e){let t=X(e);if(!w.existsSync(t))return;let o=A.join(t,$t,"IcpFooter.tsx");$(o,Vr),qt(e,["# Chinese ICP filing (\u5DE5\u4FE1\u90E8 ICP \u5907\u6848) \u2014 required to legally host a","# public-facing site from mainland China. Apply at https://beian.miit.gov.cn/",'NEXT_PUBLIC_ICP_BEIAN="" # \u5982 \u82CFICP\u59072024XXXXXX\u53F7'].join(`
1319
+ `))}async function ts(e){let t=X(e);if(!w.existsSync(t))return;let o=A.join(t,$t,"PublicSecurityFooter.tsx");$(o,Br),qt(e,["# Chinese Public Security Bureau filing (\u516C\u5B89\u8054\u7F51\u5907\u6848)","# Required in addition to ICP. Apply at http://www.beian.gov.cn/",'NEXT_PUBLIC_PSB_BEIAN="" # \u5982 \u82CF\u516C\u7F51\u5B89\u5907 32011402XXXXXX\u53F7','NEXT_PUBLIC_PSB_CODE="" # 14-digit record code'].join(`
1320
+ `))}async function ns(e){let t=X(e);if(!w.existsSync(t))return;let o=A.join(t,$t,"AigcDisclaimer.tsx");$(o,$r),qt(e,["# Generative AI algorithm filing (\u7B97\u6CD5\u5907\u6848\u53F7) \u2014 required by","# \u7F51\u4FE1\u529E\u300A\u751F\u6210\u5F0F\u4EBA\u5DE5\u667A\u80FD\u670D\u52A1\u7BA1\u7406\u6682\u884C\u529E\u6CD5\u300Bfor services offered in China.",'NEXT_PUBLIC_AIGC_FILING_NUMBER="" # e.g. \u7F51\u4FE1\u7B97\u5907XXXXXXXX\u53F7'].join(`
1321
+ `))}async function os(e){let t=X(e);if(!w.existsSync(t))return;let o=A.join(t,it,"aigc-disclosure","page.mdx");$(o,Wr)}async function rs(e){let t=X(e);if(!w.existsSync(t))return;let o=A.join(t,it,"cross-border-data","page.mdx");$(o,Hr)}async function ss(e){let t=X(e);if(!w.existsSync(t))return;let o=A.join(t,it,"pii-collection","page.mdx");$(o,Xr)}async function On(e,t){try{await zr(e,t),await Jr(e,t),await Qr(e,t),await Zr(e,t),(t==="cn"||t==="hybrid")&&(await es(e),await ts(e),await ns(e),await os(e),await rs(e),await ss(e))}catch(o){throw console.error("applyComplianceTemplates failed:",o),new Error(`Failed to apply compliance templates for region "${t}". Check that ${e} is writable.`)}}import is from"fs";import as from"path";async function Un(e,t){let o=as.join(e,"nebutra.config.json");is.writeFileSync(o,JSON.stringify(t,null,2)+`
1322
+ `)}import ae from"fs";import Gt from"path";function cs(e){ae.existsSync(e)&&ae.rmSync(e,{recursive:!0,force:!0})}function Ln(e,t){return e.replace(/provider\s*=\s*"postgresql"/,`provider = "${t}"`)}function ps(e){return e.replace(/^\s*directUrl\s*=\s*env\([^)]*\)\s*\n/gm,"")}function Mn(e){let t=e.replace(/^\s*extensions\s*=\s*\[[^\]]*\]\s*\n/gm,"");return t=t.replace(/previewFeatures\s*=\s*\[\s*"postgresqlExtensions"\s*\]\s*\n/g,""),t}function ls(e,t){let o=Gt.join(e,".env.example");ae.existsSync(o)?ae.appendFileSync(o,`
1323
+ `+t):ae.writeFileSync(o,t)}async function jn(e,t,o){let n=Gt.join(e,"packages","db");if(t==="none"){cs(n);return}let r=Gt.join(n,"prisma","schema.prisma"),s;if(t==="postgresql"?s=`postgresql://postgres:postgres@localhost:5432/${o}`:t==="mysql"?s=`mysql://root:root@localhost:3306/${o}`:s="file:./dev.db",ls(e,`# Database (${t})
1324
+ DATABASE_URL="${s}"
1325
+ `),!ae.existsSync(r))return;let i=ae.readFileSync(r,"utf8"),c=i;t==="mysql"?(c=Ln(c,"mysql"),c=Mn(c)):t==="sqlite"&&(c=Ln(c,"sqlite"),c=ps(c),c=Mn(c)),c!==i&&ae.writeFileSync(r,c)}import ct from"fs";import D from"path";import{fileURLToPath as ds}from"url";var us=ds(import.meta.url),ms=D.dirname(us);async function Fn(e,t){if(t==="none")return;let o=D.join(ms,"../../templates/deploy");t==="vercel"?await ct.promises.copyFile(D.join(o,"vercel.json"),D.join(e,"vercel.json")):t==="railway"?await ct.promises.copyFile(D.join(o,"railway.toml"),D.join(e,"railway.toml")):t==="cloudflare"?await ct.promises.copyFile(D.join(o,"wrangler.toml"),D.join(e,"wrangler.toml")):t==="selfhost"&&(await ct.promises.copyFile(D.join(o,"docker-compose.yml"),D.join(e,"docker-compose.yml")),await ct.promises.copyFile(D.join(o,"Dockerfile.web"),D.join(e,"Dockerfile.web")))}import ce from"fs";import Pe from"path";import{fileURLToPath as gs}from"url";var fs=gs(import.meta.url),Dn=Pe.dirname(fs),ys=/\.(md|mdx|json|ts|tsx|js|mjs|cjs|yaml|yml|css|html|vue)$/,Kn=["fumadocs","nextra","mintlify","docusaurus","vitepress"];function Ss(e){let t=[Pe.join(Dn,"..","templates","docs",e),Pe.join(Dn,"..","..","templates","docs",e)];for(let o of t)if(ce.existsSync(o))return o;return t[0]}async function Vn(e,t){if(t.framework==="none")return;if(!Kn.includes(t.framework))throw new Error(`Unsupported docs framework: "${t.framework}". Supported: ${Kn.join(", ")}, none.`);let o=Ss(t.framework),n=Pe.join(e,"apps","docs");if(!ce.existsSync(o))throw new Error(`Docs template not found: ${o}`);Bn(o,n),Yn(n,{"{PRODUCT_NAME}":t.projectName})}function Bn(e,t){ce.mkdirSync(t,{recursive:!0});for(let o of ce.readdirSync(e,{withFileTypes:!0})){let n=Pe.join(e,o.name),r=Pe.join(t,o.name);o.isDirectory()?Bn(n,r):ce.copyFileSync(n,r)}}function Yn(e,t){for(let o of ce.readdirSync(e,{withFileTypes:!0})){let n=Pe.join(e,o.name);if(o.isDirectory())Yn(n,t);else if(ys.test(o.name)){let r=ce.readFileSync(n,"utf-8");for(let[s,i]of Object.entries(t))r=r.split(s).join(i);ce.writeFileSync(n,r)}}}import Ie from"fs";import Ce from"path";var At=[{id:"resend",name:"Resend",region:"global",envVars:["RESEND_API_KEY","RESEND_FROM"],docs:"https://resend.com/docs",pkg:"resend",pkgVersion:"^4.0.1"},{id:"postmark",name:"Postmark",region:"global",envVars:["POSTMARK_API_KEY","POSTMARK_FROM"],docs:"https://postmarkapp.com/developer",pkg:"postmark",pkgVersion:"^4.0.5"},{id:"ses",name:"AWS SES",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_SES_REGION","SES_FROM"],docs:"https://docs.aws.amazon.com/ses",pkg:"@aws-sdk/client-sesv2",pkgVersion:"^3.658.0"},{id:"aliyun-dm",name:"\u963F\u91CC\u4E91\u90AE\u4EF6\u63A8\u9001",region:"cn",envVars:["ALIYUN_DM_ACCESS_KEY","ALIYUN_DM_ACCESS_SECRET","ALIYUN_DM_ACCOUNT_NAME","ALIYUN_DM_FROM_ALIAS"],docs:"https://help.aliyun.com/product/29412.html",pkg:"@alicloud/dm20151123",pkgVersion:"^3.0.0"},{id:"tencent-ses",name:"\u817E\u8BAF\u4E91 SES",region:"cn",envVars:["TENCENT_SECRET_ID","TENCENT_SECRET_KEY","TENCENT_SES_FROM_EMAIL"],docs:"https://cloud.tencent.com/document/product/1288",pkg:"tencentcloud-sdk-nodejs-ses",pkgVersion:"^4.0.900"},{id:"netease",name:"\u7F51\u6613\u4F01\u4E1A\u90AE\u7BB1",region:"cn",envVars:["NETEASE_USER","NETEASE_PASS","NETEASE_FROM"],docs:"https://qiye.163.com/help",pkg:"nodemailer",pkgVersion:"^6.9.15"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function $n(e){return At.find(t=>t.id===e)}var _c=At.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var Ae="@nebutra/email";function Wt(e,t){Ie.mkdirSync(Ce.dirname(e),{recursive:!0}),Ie.writeFileSync(e,t)}function hs(e,t){let o=Ce.join(e,".env.example");Ie.existsSync(o)?Ie.appendFileSync(o,`
1326
+ `+t):Ie.writeFileSync(o,t)}function Es(e){if(e.envVars.length===0)return"";let t=`# Email provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
1327
1327
  `);return`${t}
1328
1328
  ${o}
1329
- `}var ui=`/**
1329
+ `}var vs=`/**
1330
1330
  * Public inputs accepted by the \`sendEmail\` wrapper.
1331
1331
  * Keep the surface minimal \u2014 individual providers may accept more, but
1332
1332
  * consumers should code against this shape for portability.
@@ -1346,8 +1346,8 @@ export interface SendEmailResult {
1346
1346
  /** Raw provider response \u2014 useful for debugging, not a stable contract. */
1347
1347
  raw?: unknown;
1348
1348
  }
1349
- `;function mi(){return`/**
1350
- * @${_e.slice(1)} \u2014 Resend transactional email wrapper.
1349
+ `;function _s(){return`/**
1350
+ * @${Ae.slice(1)} \u2014 Resend transactional email wrapper.
1351
1351
  *
1352
1352
  * Docs: https://resend.com/docs
1353
1353
  */
@@ -1385,8 +1385,8 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1385
1385
  }
1386
1386
 
1387
1387
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1388
- `}function gi(){return`/**
1389
- * @${_e.slice(1)} \u2014 Postmark transactional email wrapper.
1388
+ `}function bs(){return`/**
1389
+ * @${Ae.slice(1)} \u2014 Postmark transactional email wrapper.
1390
1390
  *
1391
1391
  * Docs: https://postmarkapp.com/developer
1392
1392
  */
@@ -1423,8 +1423,8 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1423
1423
  }
1424
1424
 
1425
1425
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1426
- `}function fi(){return`/**
1427
- * @${_e.slice(1)} \u2014 AWS SES v2 transactional email wrapper.
1426
+ `}function Ps(){return`/**
1427
+ * @${Ae.slice(1)} \u2014 AWS SES v2 transactional email wrapper.
1428
1428
  *
1429
1429
  * Docs: https://docs.aws.amazon.com/ses
1430
1430
  */
@@ -1479,8 +1479,8 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1479
1479
  }
1480
1480
 
1481
1481
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1482
- `}function yi(){return`/**
1483
- * @${_e.slice(1)} \u2014 \u963F\u91CC\u4E91\u90AE\u4EF6\u63A8\u9001 (Aliyun DirectMail) wrapper.
1482
+ `}function Cs(){return`/**
1483
+ * @${Ae.slice(1)} \u2014 \u963F\u91CC\u4E91\u90AE\u4EF6\u63A8\u9001 (Aliyun DirectMail) wrapper.
1484
1484
  *
1485
1485
  * Docs: https://help.aliyun.com/product/29412.html
1486
1486
  */
@@ -1529,8 +1529,8 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1529
1529
  }
1530
1530
 
1531
1531
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1532
- `}function Si(){return`/**
1533
- * @${_e.slice(1)} \u2014 \u817E\u8BAF\u4E91 SES wrapper.
1532
+ `}function Is(){return`/**
1533
+ * @${Ae.slice(1)} \u2014 \u817E\u8BAF\u4E91 SES wrapper.
1534
1534
  *
1535
1535
  * Docs: https://cloud.tencent.com/document/product/1288
1536
1536
  */
@@ -1577,8 +1577,8 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1577
1577
  }
1578
1578
 
1579
1579
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1580
- `}function Ei(){return`/**
1581
- * @${_e.slice(1)} \u2014 \u7F51\u6613\u4F01\u4E1A\u90AE\u7BB1 via SMTP (nodemailer).
1580
+ `}function As(){return`/**
1581
+ * @${Ae.slice(1)} \u2014 \u7F51\u6613\u4F01\u4E1A\u90AE\u7BB1 via SMTP (nodemailer).
1582
1582
  *
1583
1583
  * Docs: https://qiye.163.com/help
1584
1584
  */
@@ -1615,23 +1615,24 @@ export async function sendEmail(input: SendEmailInput): Promise<SendEmailResult>
1615
1615
  }
1616
1616
 
1617
1617
  export type { SendEmailInput, SendEmailResult } from "./types.js";
1618
- `}function hi(e){switch(e){case"resend":return mi();case"postmark":return gi();case"ses":return fi();case"aliyun-dm":return yi();case"tencent-ses":return Si();case"netease":return Ei();case"none":return`export {};
1619
- `}}function vi(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),e.id==="aliyun-dm"&&(t["@alicloud/openapi-client"]="^0.4.12");let o={name:_e,version:"0.1.0",private:!0,description:`Transactional email via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
1620
- `}async function jn(e,t,o){if(t==="none")return;let n=Fn(t);if(!n)throw new Error(`Unknown email provider "${t}". Valid ids: ${bt.map(s=>s.id).join(", ")}`);let r=he.join(e,"packages","email"),i=he.join(r,"src");ve.existsSync(i)&&ve.rmSync(i,{recursive:!0,force:!0}),$t(he.join(r,"package.json"),vi(n)),$t(he.join(i,"types.ts"),ui),$t(he.join(i,"index.ts"),hi(n.id)),li(e,di(n))}import It from"fs";import Vn from"path";async function Kn(e,t){let o=`# Automatically injected by create-sailor
1618
+ `}function ws(e){switch(e){case"resend":return _s();case"postmark":return bs();case"ses":return Ps();case"aliyun-dm":return Cs();case"tencent-ses":return Is();case"netease":return As();case"none":return`export {};
1619
+ `}}function Rs(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),e.id==="aliyun-dm"&&(t["@alicloud/openapi-client"]="^0.4.12");let o={name:Ae,version:"0.1.0",private:!0,description:`Transactional email via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
1620
+ `}async function qn(e,t,o){if(t==="none")return;let n=$n(t);if(!n)throw new Error(`Unknown email provider "${t}". Valid ids: ${At.map(i=>i.id).join(", ")}`);let r=Ce.join(e,"packages","email"),s=Ce.join(r,"src");Ie.existsSync(s)&&Ie.rmSync(s,{recursive:!0,force:!0}),Wt(Ce.join(r,"package.json"),Rs(n)),Wt(Ce.join(s,"types.ts"),vs),Wt(Ce.join(s,"index.ts"),ws(n.id)),hs(e,Es(n))}import wt from"fs";import Gn from"path";async function Wn(e,t){let o=`# Automatically injected by create-sailor
1621
1621
  DATABASE_URL="${String(t.databaseUrl)}"
1622
1622
 
1623
1623
  NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="${String(t.clerkPublishable)}"
1624
1624
  CLERK_SECRET_KEY="${String(t.clerkSecret)}"
1625
1625
 
1626
1626
  NEXT_PUBLIC_SITE_URL="http://localhost:3000"
1627
- `,n=Vn.join(e,".env"),r=Vn.join(e,".env.local");!It.existsSync(n)&&!It.existsSync(r)?It.writeFileSync(r,o):It.appendFileSync(r,`
1628
- `+o)}import Yn from"crypto";import st from"fs";import Bn from"path";function Pe(e){return Yn.randomBytes(e).toString("base64").replace(/=+$/,"")}function _i(e){return Yn.randomBytes(e).toString("hex")}function Pi(){return{AUTH_SECRET:Pe(32),NEXTAUTH_SECRET:Pe(32),BETTER_AUTH_SECRET:Pe(32),JWT_SECRET:Pe(32),WEBHOOK_SECRET:_i(16),ENCRYPTION_KEY:Pe(32),API_SECRET_KEY:Pe(32),SESSION_SECRET:Pe(32)}}function bi(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Ii(e,t,o){let n=new RegExp(`^(?!#)\\s*${t}=.*$`,"gm"),r=bi(o);return e.replace(n,`${t}="${r}"`)}async function $n(e){let t=Bn.join(e,".env.example"),o=Bn.join(e,".env.local");if(!st.existsSync(t))return null;try{let n=st.readFileSync(t,"utf8"),r=Pi(),s=st.existsSync(o)?st.readFileSync(o,"utf8"):n;for(let c of Object.keys(r))s=Ii(s,c,r[c]);return st.writeFileSync(o,s),r}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate env secrets: ${r}`),new Error(`Unable to write .env.local: ${r}`)}}var At=[{id:"vercel-flags",name:"Vercel Flags SDK",region:"global",envVars:["FLAGS_SECRET"],docs:"https://vercel.com/docs/workflow-collaboration/feature-flags",description:"Native Vercel feature flags"},{id:"growthbook",name:"GrowthBook",region:"both",envVars:["GROWTHBOOK_API_HOST","GROWTHBOOK_CLIENT_KEY","GROWTHBOOK_DECRYPTION_KEY"],docs:"https://docs.growthbook.io",description:"Open-source A/B testing + flags"},{id:"configcat",name:"ConfigCat",region:"global",envVars:["CONFIGCAT_SDK_KEY"],docs:"https://configcat.com/docs/",description:"Feature flag & config management"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function qn(e){return At.find(t=>t.id===e)}var Ic=At.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Gn(e,t,o="global"){let n=qn(t);if(!n)throw new Error(`Unknown feature-flags provider "${t}". Valid ids: ${At.map(r=>r.id).join(", ")}`);if(n.id==="none"){K(e,"feature-flags");return}n.envVars.length>0&&q(e,{category:"Feature Flags",name:n.name,envVars:n.envVars,docs:n.docs}),G(e,"FEATURE_FLAGS_PROVIDER",n.id)}import{execFileSync as Xn}from"child_process";import x from"fs";import Ai from"os";import ie from"path";import Ci from"ignore";var wi={mirror:{repo:process.env.SAILOR_TEMPLATE_REPO||"Nebutra/Sailor-Template",ref:process.env.SAILOR_TEMPLATE_REF||"main",applyIgnore:!1,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"},main:{repo:"Nebutra/Nebutra-Sailor",ref:"main",applyIgnore:!0,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"}};function Ri(e,t){return`https://github.com/${e}/archive/refs/heads/${t}.tar.gz`}function xi(e,t){return`https://github.com/${e}/archive/${t}.tar.gz`}function zn(e){return/^[0-9a-f]{7,40}$/i.test(e)}function Ni(e,t){let o=`https://github.com/${e}.git`,n=[`refs/heads/${t}`,`refs/tags/${t}`];for(let r of n)try{let i=Xn("git",["ls-remote",o,r],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(!i)continue;let[s]=i.split(/\s+/);if(zn(s))return s}catch{}return null}async function ki(e,t){if(zn(t))return t;let o=await fetch(`https://api.github.com/repos/${e}/commits/${encodeURIComponent(t)}`,{headers:{Accept:"application/vnd.github+json","User-Agent":"create-sailor"}});if(!o.ok){let r=Ni(e,t);if(r)return r;throw new Error(`Failed to resolve ${e}@${t} (GitHub API ${o.status})`)}let n=await o.json();if(typeof n.sha!="string"||n.sha.length===0)throw new Error(`GitHub API did not return a commit SHA for ${e}@${t}`);return n.sha}function Qn(e,t,o){let n=x.readdirSync(t,{withFileTypes:!0});for(let r of n){if(r.name==="node_modules"||r.name===".git")continue;let i=ie.join(t,r.name),s=ie.relative(e,i).split(ie.sep).join("/");r.isDirectory()?(o.push(s+"/"),Qn(e,i,o)):o.push(s)}}function Ti(e){let t=ie.join(e,".templateignore");if(!x.existsSync(t))return;let o=x.readFileSync(t,"utf8"),n=Ci().add(o),r=[];Qn(e,e,r);let i=r.map(a=>a.endsWith("/")?a.slice(0,-1):a),s=new Set(n.filter(i)),c=i.filter(a=>!s.has(a)).sort((a,d)=>d.split("/").length-a.split("/").length);for(let a of c){let d=ie.join(e,a);try{x.existsSync(d)&&x.rmSync(d,{recursive:!0,force:!0})}catch{}}try{x.existsSync(t)&&x.rmSync(t,{force:!0})}catch{}}async function Hn(e,t){let o=await fetch(e,{headers:{Accept:"application/octet-stream","User-Agent":"create-sailor"}});if(!o.ok)throw new Error(`Failed to download archive (${o.status})`);let n=Buffer.from(await o.arrayBuffer());if(n.byteLength<1024)throw new Error(`Downloaded archive is unexpectedly small (${n.byteLength} bytes)`);x.writeFileSync(t,n);let r=x.statSync(t);if(r.size!==n.byteLength)throw new Error(`Archive write verification failed (${r.size} != ${n.byteLength})`);return r.size}function Wn(e,t){Xn("tar",["-xzf",e,"-C",t,"--strip-components=1"],{stdio:"ignore"})}function Jn(e){try{let t=x.readdirSync(e);for(let o of t)x.rmSync(ie.join(e,o),{recursive:!0,force:!0})}catch{}}async function Oi(e,t){let o=x.mkdtempSync(ie.join(Ai.tmpdir(),"create-sailor-")),n=ie.join(o,"template.tar.gz");try{let r=await ki(e.repo,e.ref);await Hn(xi(e.repo,r),n),Wn(n,t)}catch(r){if(!e.allowMutableFallback)throw r;Jn(t),await Hn(Ri(e.repo,e.ref),n),Wn(n,t)}finally{x.rmSync(o,{recursive:!0,force:!0})}}async function Zn(e){x.mkdirSync(e,{recursive:!0});let o=process.env.SAILOR_TEMPLATE_SOURCE==="main"?["main"]:["mirror","main"],n;for(let r of o){let i=wi[r];try{if(await Oi(i,e),i.applyIgnore)try{Ti(e)}catch(s){throw new Error(`Template cloned, but .templateignore processing failed: ${s instanceof Error?s.message:String(s)}`)}return}catch(s){n=s instanceof Error?s:new Error(String(s)),Jn(e)}}throw new Error(`Failed to download the template from any source. Last error: ${n?.message??"unknown"}
1627
+ `,n=Gn.join(e,".env"),r=Gn.join(e,".env.local");!wt.existsSync(n)&&!wt.existsSync(r)?wt.writeFileSync(r,o):wt.appendFileSync(r,`
1628
+ `+o)}import Xn from"crypto";import pt from"fs";import Hn from"path";function we(e){return Xn.randomBytes(e).toString("base64").replace(/=+$/,"")}function ks(e){return Xn.randomBytes(e).toString("hex")}function xs(){return{AUTH_SECRET:we(32),NEXTAUTH_SECRET:we(32),BETTER_AUTH_SECRET:we(32),JWT_SECRET:we(32),WEBHOOK_SECRET:ks(16),ENCRYPTION_KEY:we(32),API_SECRET_KEY:we(32),SESSION_SECRET:we(32)}}function Ns(e){return e.replace(/\\/g,"\\\\").replace(/"/g,'\\"')}function Ts(e,t,o){let n=new RegExp(`^(?!#)\\s*${t}=.*$`,"gm"),r=Ns(o);return e.replace(n,`${t}="${r}"`)}async function zn(e){let t=Hn.join(e,".env.example"),o=Hn.join(e,".env.local");if(!pt.existsSync(t))return null;try{let n=pt.readFileSync(t,"utf8"),r=xs(),i=pt.existsSync(o)?pt.readFileSync(o,"utf8"):n;for(let c of Object.keys(r))i=Ts(i,c,r[c]);return pt.writeFileSync(o,i),r}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate env secrets: ${r}`),new Error(`Unable to write .env.local: ${r}`)}}var Rt=[{id:"vercel-flags",name:"Vercel Flags SDK",region:"global",envVars:["FLAGS_SECRET"],docs:"https://vercel.com/docs/workflow-collaboration/feature-flags",description:"Native Vercel feature flags"},{id:"growthbook",name:"GrowthBook",region:"both",envVars:["GROWTHBOOK_API_HOST","GROWTHBOOK_CLIENT_KEY","GROWTHBOOK_DECRYPTION_KEY"],docs:"https://docs.growthbook.io",description:"Open-source A/B testing + flags"},{id:"configcat",name:"ConfigCat",region:"global",envVars:["CONFIGCAT_SDK_KEY"],docs:"https://configcat.com/docs/",description:"Feature flag & config management"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function Jn(e){return Rt.find(t=>t.id===e)}var Uc=Rt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Qn(e,t,o="global"){let n=Jn(t);if(!n)throw new Error(`Unknown feature-flags provider "${t}". Valid ids: ${Rt.map(r=>r.id).join(", ")}`);if(n.id==="none"){Y(e,"feature-flags");return}n.envVars.length>0&&W(e,{category:"Feature Flags",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"FEATURE_FLAGS_PROVIDER",n.id)}import{execFileSync as to}from"child_process";import O from"fs";import Os from"os";import pe from"path";import Us from"ignore";var Ls={mirror:{repo:process.env.SAILOR_TEMPLATE_REPO||"Nebutra/Sailor-Template",ref:process.env.SAILOR_TEMPLATE_REF||"main",applyIgnore:!1,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"},main:{repo:"Nebutra/Nebutra-Sailor",ref:"main",applyIgnore:!0,allowMutableFallback:process.env.SAILOR_TEMPLATE_ALLOW_MUTABLE_FALLBACK==="1"}};function Ms(e,t){return`https://github.com/${e}/archive/refs/heads/${t}.tar.gz`}function js(e,t){return`https://github.com/${e}/archive/${t}.tar.gz`}function no(e){return/^[0-9a-f]{7,40}$/i.test(e)}function Fs(e,t){let o=`https://github.com/${e}.git`,n=[`refs/heads/${t}`,`refs/tags/${t}`];for(let r of n)try{let s=to("git",["ls-remote",o,r],{encoding:"utf8",stdio:["ignore","pipe","ignore"]}).trim();if(!s)continue;let[i]=s.split(/\s+/);if(no(i))return i}catch{}return null}async function Ds(e,t){if(no(t))return t;let o=await fetch(`https://api.github.com/repos/${e}/commits/${encodeURIComponent(t)}`,{headers:{Accept:"application/vnd.github+json","User-Agent":"create-sailor"}});if(!o.ok){let r=Fs(e,t);if(r)return r;throw new Error(`Failed to resolve ${e}@${t} (GitHub API ${o.status})`)}let n=await o.json();if(typeof n.sha!="string"||n.sha.length===0)throw new Error(`GitHub API did not return a commit SHA for ${e}@${t}`);return n.sha}function oo(e,t,o){let n=O.readdirSync(t,{withFileTypes:!0});for(let r of n){if(r.name==="node_modules"||r.name===".git")continue;let s=pe.join(t,r.name),i=pe.relative(e,s).split(pe.sep).join("/");r.isDirectory()?(o.push(i+"/"),oo(e,s,o)):o.push(i)}}function Ks(e){let t=pe.join(e,".templateignore");if(!O.existsSync(t))return;let o=O.readFileSync(t,"utf8"),n=Us().add(o),r=[];oo(e,e,r);let s=r.map(a=>a.endsWith("/")?a.slice(0,-1):a),i=new Set(n.filter(s)),c=s.filter(a=>!i.has(a)).sort((a,l)=>l.split("/").length-a.split("/").length);for(let a of c){let l=pe.join(e,a);try{O.existsSync(l)&&O.rmSync(l,{recursive:!0,force:!0})}catch{}}try{O.existsSync(t)&&O.rmSync(t,{force:!0})}catch{}}async function Zn(e,t){let o=await fetch(e,{headers:{Accept:"application/octet-stream","User-Agent":"create-sailor"}});if(!o.ok)throw new Error(`Failed to download archive (${o.status})`);let n=Buffer.from(await o.arrayBuffer());if(n.byteLength<1024)throw new Error(`Downloaded archive is unexpectedly small (${n.byteLength} bytes)`);O.writeFileSync(t,n);let r=O.statSync(t);if(r.size!==n.byteLength)throw new Error(`Archive write verification failed (${r.size} != ${n.byteLength})`);return r.size}function eo(e,t){to("tar",["-xzf",e,"-C",t,"--strip-components=1"],{stdio:"ignore"})}function ro(e){try{let t=O.readdirSync(e);for(let o of t)O.rmSync(pe.join(e,o),{recursive:!0,force:!0})}catch{}}async function Vs(e,t){let o=O.mkdtempSync(pe.join(Os.tmpdir(),"create-sailor-")),n=pe.join(o,"template.tar.gz");try{let r=await Ds(e.repo,e.ref);await Zn(js(e.repo,r),n),eo(n,t)}catch(r){if(!e.allowMutableFallback)throw r;ro(t),await Zn(Ms(e.repo,e.ref),n),eo(n,t)}finally{O.rmSync(o,{recursive:!0,force:!0})}}async function so(e){O.mkdirSync(e,{recursive:!0});let o=process.env.SAILOR_TEMPLATE_SOURCE==="main"?["main"]:["mirror","main"],n;for(let r of o){let s=Ls[r];try{if(await Vs(s,e),s.applyIgnore)try{Ks(e)}catch(i){throw new Error(`Template cloned, but .templateignore processing failed: ${i instanceof Error?i.message:String(i)}`)}return}catch(i){n=i instanceof Error?i:new Error(String(i)),ro(e)}}throw new Error(`Failed to download the template from any source. Last error: ${n?.message??"unknown"}
1629
1629
 
1630
1630
  Ensure you have internet access and 'tar' installed.
1631
- You can override the source with SAILOR_TEMPLATE_REPO / SAILOR_TEMPLATE_REF env vars.`)}import be from"fs";import qt from"path";async function eo(e,t){let o=qt.join(e,"packages","mcp");if(t==="off"){be.existsSync(o)&&be.rmSync(o,{recursive:!0,force:!0});let r=qt.join(e,"packages","cli","src","commands","mcp-server.ts");be.existsSync(r)&&be.rmSync(r,{force:!0});return}let n=qt.join(e,".env.example");if(be.existsSync(n)){let r=be.readFileSync(n,"utf-8"),i="# MCP Server (Agent-friendly API)";if(!r.includes(i)){let s=["","# =============================================",i,"# Docs: https://modelcontextprotocol.io","# =============================================","# MCP server exposes your SaaS capabilities to AI agents via MCP protocol.","# Run: pnpm mcp-server (starts stdio server)","# No config required for stdio transport. HTTP transport needs:",'MCP_HTTP_PORT="3100"','MCP_API_KEY=""',""].join(`
1632
- `);be.appendFileSync(n,s)}}}import at from"fs";import to from"path";async function no(e,t,o){let n=to.join(e,"packages","metering"),r;if(t==="auto"?r=o!=="none"?"on":"off":t==="on"||t==="off"?r=t:r="off",r==="off"){at.existsSync(n)&&at.rmSync(n,{recursive:!0,force:!0});return}let i=to.join(e,".env.example");if(!at.existsSync(i))return;let s=at.readFileSync(i,"utf-8"),c="# Metering (usage-based billing)";if(!s.includes(c)){let a=["","# =============================================",c,"# Docs: see packages/metering/README.md","# =============================================","# ClickHouse-based metering pipeline for consumption billing.",'CLICKHOUSE_URL=""','CLICKHOUSE_USER="default"','CLICKHOUSE_PASSWORD=""','CLICKHOUSE_DATABASE="metering"',""].join(`
1633
- `);at.appendFileSync(i,a)}}import He from"fs";import T from"path";var oo=[{id:"sentry",name:"Sentry",region:"both",envVars:["SENTRY_DSN","NEXT_PUBLIC_SENTRY_DSN"],docs:"https://docs.sentry.io",pkg:"@sentry/nextjs",instrumentationFile:"apps/web/instrumentation.ts"},{id:"datadog",name:"Datadog",region:"global",envVars:["DD_API_KEY","DD_APP_KEY","DD_SITE"],docs:"https://docs.datadoghq.com",pkg:"dd-trace",instrumentationFile:"apps/web/instrumentation.ts"},{id:"bugsnag",name:"Bugsnag",region:"global",envVars:["BUGSNAG_API_KEY","NEXT_PUBLIC_BUGSNAG_API_KEY"],docs:"https://docs.bugsnag.com",pkg:"@bugsnag/js",instrumentationFile:"apps/web/src/lib/monitoring/bugsnag.ts"},{id:"aliyun-arms",name:"\u963F\u91CC\u4E91 ARMS",region:"cn",envVars:["ALIYUN_ARMS_LICENSE_KEY","ALIYUN_ARMS_APP_NAME","NEXT_PUBLIC_ARMS_PID"],docs:"https://help.aliyun.com/product/34364.html",instrumentationFile:"apps/web/src/components/monitoring/ArmsScript.tsx"},{id:"tingyun",name:"\u542C\u4E91 TingYun",region:"cn",envVars:["TINGYUN_LICENSE_KEY","NEXT_PUBLIC_TINGYUN_APP_KEY"],docs:"https://www.tingyun.com/docs",instrumentationFile:"apps/web/src/components/monitoring/TingYunScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],Kc=oo.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function ro(e){return oo.find(t=>t.id===e)}function Ui(e){He.mkdirSync(e,{recursive:!0})}function W(e,t){Ui(T.dirname(e)),He.writeFileSync(e,t)}function ct(e,t){let o=T.join(e,".env.example");He.existsSync(o)?He.appendFileSync(o,`
1634
- `+t):He.writeFileSync(o,t)}function Li(e){let t=`import * as Sentry from "@sentry/nextjs";
1631
+ You can override the source with SAILOR_TEMPLATE_REPO / SAILOR_TEMPLATE_REF env vars.`)}import Re from"fs";import Ht from"path";async function io(e,t){let o=Ht.join(e,"packages","mcp");if(t==="off"){Re.existsSync(o)&&Re.rmSync(o,{recursive:!0,force:!0});let r=Ht.join(e,"packages","cli","src","commands","mcp-server.ts");Re.existsSync(r)&&Re.rmSync(r,{force:!0});return}let n=Ht.join(e,".env.example");if(Re.existsSync(n)){let r=Re.readFileSync(n,"utf-8"),s="# MCP Server (Agent-friendly API)";if(!r.includes(s)){let i=["","# =============================================",s,"# Docs: https://modelcontextprotocol.io","# =============================================","# MCP server exposes your SaaS capabilities to AI agents via MCP protocol.","# Run: pnpm mcp-server (starts stdio server)","# No config required for stdio transport. HTTP transport needs:",'MCP_HTTP_PORT="3100"','MCP_API_KEY=""',""].join(`
1632
+ `);Re.appendFileSync(n,i)}}}import lt from"fs";import ao from"path";async function co(e,t,o){let n=ao.join(e,"packages","metering"),r;if(t==="auto"?r=o!=="none"?"on":"off":t==="on"||t==="off"?r=t:r="off",r==="off"){lt.existsSync(n)&&lt.rmSync(n,{recursive:!0,force:!0});return}let s=ao.join(e,".env.example");if(!lt.existsSync(s))return;let i=lt.readFileSync(s,"utf-8"),c="# Metering (usage-based billing)";if(!i.includes(c)){let a=["","# =============================================",c,"# Docs: see packages/metering/README.md","# =============================================","# ClickHouse-based metering pipeline for consumption billing.",'CLICKHOUSE_URL=""','CLICKHOUSE_USER="default"','CLICKHOUSE_PASSWORD=""','CLICKHOUSE_DATABASE="metering"',""].join(`
1633
+ `);lt.appendFileSync(s,a)}}import te from"fs";import U from"path";var po=[{id:"sentry",name:"Sentry",region:"both",envVars:["SENTRY_DSN","NEXT_PUBLIC_SENTRY_DSN"],docs:"https://docs.sentry.io",pkg:"@sentry/nextjs",instrumentationFile:"apps/web/instrumentation.ts"},{id:"datadog",name:"Datadog",region:"global",envVars:["DD_API_KEY","DD_APP_KEY","DD_SITE"],docs:"https://docs.datadoghq.com",pkg:"dd-trace",instrumentationFile:"apps/web/instrumentation.ts"},{id:"bugsnag",name:"Bugsnag",region:"global",envVars:["BUGSNAG_API_KEY","NEXT_PUBLIC_BUGSNAG_API_KEY"],docs:"https://docs.bugsnag.com",pkg:"@bugsnag/js",instrumentationFile:"apps/web/src/lib/monitoring/bugsnag.ts"},{id:"aliyun-arms",name:"\u963F\u91CC\u4E91 ARMS",region:"cn",envVars:["ALIYUN_ARMS_LICENSE_KEY","ALIYUN_ARMS_APP_NAME","NEXT_PUBLIC_ARMS_PID"],docs:"https://help.aliyun.com/product/34364.html",instrumentationFile:"apps/web/src/components/monitoring/ArmsScript.tsx"},{id:"tingyun",name:"\u542C\u4E91 TingYun",region:"cn",envVars:["TINGYUN_LICENSE_KEY","NEXT_PUBLIC_TINGYUN_APP_KEY"],docs:"https://www.tingyun.com/docs",instrumentationFile:"apps/web/src/components/monitoring/TingYunScript.tsx"},{id:"none",name:"None",region:"both",envVars:[],docs:""}],Jc=po.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function lo(e){return po.find(t=>t.id===e)}var Xt={sentry:{"@sentry/nextjs":"^8.45.0"},datadog:{"dd-trace":"^5.32.0","@datadog/browser-rum":"^5.30.0"},bugsnag:{"@bugsnag/js":"^8.2.0","@bugsnag/plugin-react":"^8.2.0"}};function Bs(e){te.mkdirSync(e,{recursive:!0})}function zt(e,t){let o=U.join(e,"package.json");if(!te.existsSync(o))return;let n;try{n=JSON.parse(te.readFileSync(o,"utf-8"))}catch(c){console.error(`Failed to parse ${o}:`,c);return}let s={...n.dependencies??{}};for(let[c,a]of Object.entries(t))s[c]||(s[c]=a);let i={...n,dependencies:s};te.writeFileSync(o,JSON.stringify(i,null,2)+`
1634
+ `)}function z(e,t){Bs(U.dirname(e)),te.writeFileSync(e,t)}function dt(e,t){let o=U.join(e,".env.example");te.existsSync(o)?te.appendFileSync(o,`
1635
+ `+t):te.writeFileSync(o,t)}function Ys(e){let t=`import * as Sentry from "@sentry/nextjs";
1635
1636
 
1636
1637
  Sentry.init({
1637
1638
  dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
@@ -1674,14 +1675,14 @@ export async function register() {
1674
1675
  }
1675
1676
 
1676
1677
  export { captureRequestError as onRequestError } from "@sentry/nextjs";
1677
- `;W(T.join(e,"sentry.client.config.ts"),t),W(T.join(e,"sentry.server.config.ts"),o),W(T.join(e,"sentry.edge.config.ts"),n),W(T.join(e,"instrumentation.ts"),r)}function Mi(){return`# Sentry \u2014 error tracking + performance monitoring
1678
+ `;z(U.join(e,"sentry.client.config.ts"),t),z(U.join(e,"sentry.server.config.ts"),o),z(U.join(e,"sentry.edge.config.ts"),n),z(U.join(e,"instrumentation.ts"),r)}function $s(){return`# Sentry \u2014 error tracking + performance monitoring
1678
1679
  # Get your DSN from https://sentry.io/settings/projects/<project>/keys/
1679
1680
  SENTRY_DSN=
1680
1681
  NEXT_PUBLIC_SENTRY_DSN=
1681
1682
  SENTRY_ORG=
1682
1683
  SENTRY_PROJECT=
1683
1684
  SENTRY_AUTH_TOKEN=
1684
- `}function Di(e){let t=`/**
1685
+ `}function qs(e){let t=`/**
1685
1686
  * Next.js instrumentation hook \u2014 wires Datadog APM (dd-trace) into Node runtime.
1686
1687
  * Edge runtime is not supported by dd-trace; only nodejs is initialized.
1687
1688
  */
@@ -1729,7 +1730,7 @@ export function initDatadogRum(): void {
1729
1730
  });
1730
1731
  initialized = true;
1731
1732
  }
1732
- `;W(T.join(e,"instrumentation.ts"),t),W(T.join(e,"src","lib","monitoring","datadog-rum.ts"),o)}function Fi(){return`# Datadog \u2014 APM + RUM
1733
+ `;z(U.join(e,"instrumentation.ts"),t),z(U.join(e,"src","lib","monitoring","datadog-rum.ts"),o)}function Gs(){return`# Datadog \u2014 APM + RUM
1733
1734
  # Server APM (dd-trace)
1734
1735
  DD_API_KEY=
1735
1736
  DD_APP_KEY=
@@ -1744,7 +1745,7 @@ NEXT_PUBLIC_DD_SITE=datadoghq.com
1744
1745
  NEXT_PUBLIC_DD_SERVICE=sailor-web
1745
1746
  NEXT_PUBLIC_DD_ENV=production
1746
1747
  NEXT_PUBLIC_DD_VERSION=
1747
- `}function ji(e){let t=`/**
1748
+ `}function Ws(e){let t=`/**
1748
1749
  * Bugsnag server-side initialization.
1749
1750
  * Import this once at the top of your server entrypoint or a shared init module.
1750
1751
  */
@@ -1793,11 +1794,11 @@ export function getBugsnagErrorBoundary() {
1793
1794
  errorBoundary = plugin.createErrorBoundary(React) as typeof errorBoundary;
1794
1795
  return errorBoundary;
1795
1796
  }
1796
- `;W(T.join(e,"src","lib","monitoring","bugsnag.server.ts"),t),W(T.join(e,"src","lib","monitoring","bugsnag.client.tsx"),o)}function Vi(){return`# Bugsnag \u2014 error tracking
1797
+ `;z(U.join(e,"src","lib","monitoring","bugsnag.server.ts"),t),z(U.join(e,"src","lib","monitoring","bugsnag.client.tsx"),o)}function Hs(){return`# Bugsnag \u2014 error tracking
1797
1798
  BUGSNAG_API_KEY=
1798
1799
  NEXT_PUBLIC_BUGSNAG_API_KEY=
1799
1800
  APP_VERSION=
1800
- `}function Ki(e){W(T.join(e,"src","components","monitoring","ArmsScript.tsx"),`"use client";
1801
+ `}function Xs(e){z(U.join(e,"src","components","monitoring","ArmsScript.tsx"),`"use client";
1801
1802
  /**
1802
1803
  * \u963F\u91CC\u4E91 ARMS (Application Real-time Monitoring Service) browser agent.
1803
1804
  * Injects the official JS agent via next/script.
@@ -1818,11 +1819,11 @@ export function ArmsScript() {
1818
1819
  />
1819
1820
  );
1820
1821
  }
1821
- `)}function Bi(){return`# \u963F\u91CC\u4E91 ARMS \u2014 APM (\u4E2D\u56FD\u533A)
1822
+ `)}function zs(){return`# \u963F\u91CC\u4E91 ARMS \u2014 APM (\u4E2D\u56FD\u533A)
1822
1823
  ALIYUN_ARMS_LICENSE_KEY=
1823
1824
  ALIYUN_ARMS_APP_NAME=
1824
1825
  NEXT_PUBLIC_ARMS_PID=
1825
- `}function Yi(e){W(T.join(e,"src","components","monitoring","TingYunScript.tsx"),`"use client";
1826
+ `}function Js(e){z(U.join(e,"src","components","monitoring","TingYunScript.tsx"),`"use client";
1826
1827
  /**
1827
1828
  * \u542C\u4E91 Browser Agent (\u524D\u7AEF\u6027\u80FD\u76D1\u63A7).
1828
1829
  * Docs: https://www.tingyun.com/docs
@@ -1840,12 +1841,12 @@ export function TingYunScript() {
1840
1841
  />
1841
1842
  );
1842
1843
  }
1843
- `)}function $i(){return`# \u542C\u4E91 TingYun \u2014 APM (\u4E2D\u56FD\u533A)
1844
+ `)}function Qs(){return`# \u542C\u4E91 TingYun \u2014 APM (\u4E2D\u56FD\u533A)
1844
1845
  TINGYUN_LICENSE_KEY=
1845
1846
  NEXT_PUBLIC_TINGYUN_APP_KEY=
1846
- `}async function io(e,t,o="global"){let n=ro(t);if(!n||n.id==="none")return;let r=T.join(e,"apps","web");if(!He.existsSync(r))return;let i=n.id;try{switch(i){case"sentry":Li(r),ct(e,Mi());return;case"datadog":Di(r),ct(e,Fi());return;case"bugsnag":ji(r),ct(e,Vi());return;case"aliyun-arms":Ki(r),ct(e,Bi());return;case"tingyun":Yi(r),ct(e,$i());return;default:return}}catch(s){throw console.error(`Failed to apply monitoring selection "${t}":`,s),new Error(`Monitoring scaffold for "${t}" failed \u2014 see stderr for details.`)}}var Ct=[{id:"novu",name:"Novu",region:"both",envVars:["NOVU_API_KEY","NOVU_APPLICATION_IDENTIFIER"],docs:"https://docs.novu.co",description:"Multi-channel notification infrastructure"},{id:"knock",name:"Knock",region:"global",envVars:["KNOCK_API_KEY","KNOCK_SIGNING_KEY","KNOCK_PUBLIC_API_KEY"],docs:"https://docs.knock.app",description:"Product notifications platform"},{id:"custom",name:"Custom (direct dispatchers)",region:"both",envVars:[],docs:"",description:"Use email + sms + push directly"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function so(e){return Ct.find(t=>t.id===e)}var Hc=Ct.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function ao(e,t,o="global"){let n=so(t);if(!n)throw new Error(`Unknown notifications provider "${t}". Valid ids: ${Ct.map(r=>r.id).join(", ")}`);if(n.id==="none"){K(e,"notifications");return}n.envVars.length>0&&q(e,{category:"Notifications",name:n.name,envVars:n.envVars,docs:n.docs}),G(e,"NOTIFICATIONS_PROVIDER",n.id)}import Gt from"fs";import qi from"path";async function co(e,t){let o=qi.join(e,"package.json");if(Gt.existsSync(o)){let n=Gt.readFileSync(o,"utf8"),r=JSON.parse(n);r.name=t,r.version="0.1.0",Gt.writeFileSync(o,JSON.stringify(r,null,2)+`
1847
- `)}}import Z from"fs";import pt from"path";var Gi=["stripe","lemonsqueezy","chinapay","polar"];function po(e){Z.existsSync(e)&&Z.rmSync(e,{recursive:!0,force:!0})}function Hi(e){switch(e){case"stripe":return["stripe"];case"lemon":return["lemonsqueezy"];case"wechat":case"alipay":return["chinapay"]}}function Wi(e,t){let o=pt.join(e,".env.example");Z.existsSync(o)?Z.appendFileSync(o,`
1848
- `+t):Z.writeFileSync(o,t)}function Xi(e){switch(e){case"stripe":return`# Stripe
1847
+ `}async function uo(e,t,o="global"){let n=lo(t);if(!n||n.id==="none")return;let r=U.join(e,"apps","web");if(!te.existsSync(r))return;let s=n.id;try{switch(s){case"sentry":Ys(r),zt(r,Xt.sentry),dt(e,$s());return;case"datadog":qs(r),zt(r,Xt.datadog),dt(e,Gs());return;case"bugsnag":Ws(r),zt(r,Xt.bugsnag),dt(e,Hs());return;case"aliyun-arms":Xs(r),dt(e,zs());return;case"tingyun":Js(r),dt(e,Qs());return;default:return}}catch(i){throw console.error(`Failed to apply monitoring selection "${t}":`,i),new Error(`Monitoring scaffold for "${t}" failed \u2014 see stderr for details.`)}}var kt=[{id:"novu",name:"Novu",region:"both",envVars:["NOVU_API_KEY","NOVU_APPLICATION_IDENTIFIER"],docs:"https://docs.novu.co",description:"Multi-channel notification infrastructure"},{id:"knock",name:"Knock",region:"global",envVars:["KNOCK_API_KEY","KNOCK_SIGNING_KEY","KNOCK_PUBLIC_API_KEY"],docs:"https://docs.knock.app",description:"Product notifications platform"},{id:"custom",name:"Custom (direct dispatchers)",region:"both",envVars:[],docs:"",description:"Use email + sms + push directly"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function mo(e){return kt.find(t=>t.id===e)}var op=kt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function go(e,t,o="global"){let n=mo(t);if(!n)throw new Error(`Unknown notifications provider "${t}". Valid ids: ${kt.map(r=>r.id).join(", ")}`);if(n.id==="none"){Y(e,"notifications");return}n.envVars.length>0&&W(e,{category:"Notifications",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"NOTIFICATIONS_PROVIDER",n.id)}import Jt from"fs";import Zs from"path";async function fo(e,t){let o=Zs.join(e,"package.json");if(Jt.existsSync(o)){let n=Jt.readFileSync(o,"utf8"),r=JSON.parse(n);r.name=t,r.version="0.1.0",Jt.writeFileSync(o,JSON.stringify(r,null,2)+`
1848
+ `)}}import ne from"fs";import ut from"path";var ei=["stripe","lemonsqueezy","chinapay","polar"];function yo(e){ne.existsSync(e)&&ne.rmSync(e,{recursive:!0,force:!0})}function ti(e){switch(e){case"stripe":return["stripe"];case"lemon":return["lemonsqueezy"];case"wechat":case"alipay":return["chinapay"]}}function ni(e,t){let o=ut.join(e,".env.example");ne.existsSync(o)?ne.appendFileSync(o,`
1849
+ `+t):ne.writeFileSync(o,t)}function oi(e){switch(e){case"stripe":return`# Stripe
1849
1850
  STRIPE_SECRET_KEY=
1850
1851
  STRIPE_WEBHOOK_SECRET=
1851
1852
  `;case"lemon":return`# Lemon Squeezy
@@ -1860,14 +1861,14 @@ CHINAPAY_WECHAT_ENABLED=true
1860
1861
  CHINAPAY_APP_ID=
1861
1862
  CHINAPAY_APP_SECRET=
1862
1863
  CHINAPAY_ALIPAY_ENABLED=true
1863
- `}}async function lo(e,t){let o=pt.join(e,"packages","billing");if(!Z.existsSync(o))return;if(t==="none"){po(o);return}let n=pt.join(o,"src"),r=new Set(Hi(t));for(let s of Gi)r.has(s)||po(pt.join(n,s));let i=pt.join(n,"checkout","types.ts");if(Z.existsSync(i)){let s=t==="stripe"?"stripe":t==="lemon"?"lemonsqueezy":"chinapay",c=Z.readFileSync(i,"utf8"),a=c.replace(/export type CheckoutProviderType\s*=\s*[^;]+;/,`export type CheckoutProviderType = "${s}";`);a!==c&&Z.writeFileSync(i,a)}Wi(e,Xi(t))}import se from"fs";import We from"path";var go=new Set(["siliconflow","volcengine-ark","bailian","moonshot"]),Ht=/@sailor:([^\s*]+)/;function zi(e,t){let{providerIds:o,customEndpoint:n}=t;if(e.startsWith("provider:")){let r=e.slice(9);return{marker:e,keep:o.includes(r)}}if(e==="cn-compatible"){let r=o.some(i=>go.has(i));return{marker:e,keep:r||!!n}}if(e.startsWith("cn-instance:")){let r=e.slice(12);return{marker:e,keep:o.includes(r)}}return e==="custom-endpoint"?{marker:e,keep:!!n}:e==="registry-entries"?{marker:e,keep:!0}:{marker:e,keep:!0}}function uo(e){return e.replace(/\s*\/\/\s*@sailor:[^\n]*$/,"")}function mo(e){return e.replace(/\s*#\s*@sailor:[^\n]*$/,"")}function fo(e,t){let o=e.split(`
1864
- `),n=[],r=e.includes("#"),i=0;for(;i<o.length;){let s=o[i],c=s.match(Ht);if(!c){n.push(s),i++;continue}let{marker:a,keep:d}=zi(c[1],t);if(a==="registry-entries"){n.push(r?mo(s):uo(s)),i++;continue}if(d){let u=r?mo(s):uo(s);u.trim().length>0&&n.push(u);let h=i+1;for(;h<o.length&&o[h].trim()!==""&&!Ht.test(o[h]);)n.push(o[h]),h++;h<o.length&&o[h].trim()===""&&(n.push(o[h]),h++),i=h}else{let u=i+1;for(;u<o.length&&o[u].trim()!==""&&!Ht.test(o[u]);)u++;u<o.length&&o[u].trim()===""&&u++,i=u}}return Qi(n.join(`
1865
- `),t)}function Qi(e,t){let{providerIds:o,customEndpoint:n}=t,r=new Set;for(let d of o)["openai","anthropic","google","mistral","xai"].includes(d)&&r.add(d),r.add(d.replace(/-/g,"_")),r.add(d);n&&r.add("custom");let i=/createProviderRegistry\(\{([\s\S]*?)\}\)/,s=e.match(i);if(!s)return e;let a=s[1].split(`
1866
- `).filter(d=>{let u=d.trim();if(u===""||u.startsWith("//"))return!0;let h=u.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*,?$/);return h?r.has(h[1]):!0}).join(`
1867
- `);return e.replace(i,`createProviderRegistry({${a}})`)}function Ji(e,t){let o=We.join(t,"registry.ts.template"),n=se.readFileSync(o,"utf-8");return fo(n,e)}function Zi(e,t){let o=We.join(t,".env.example.template"),n=se.readFileSync(o,"utf-8");return fo(n,e)}async function yo(e,t,o){let n=Ji(t,o),r=Zi(t,o),i=We.join(e,"packages/agents/src");await se.promises.mkdir(i,{recursive:!0}),await se.promises.writeFile(We.join(i,"registry.ts"),n),await se.promises.appendFile(We.join(e,".env.example"),`
1868
- `+r);let s={ai:"latest"},{providerIds:c,customEndpoint:a}=t;(c.includes("openai")||a||c.some(u=>go.has(u)))&&(s["@ai-sdk/openai"]="latest",s["@ai-sdk/openai-compatible"]="latest"),c.includes("anthropic")&&(s["@ai-sdk/anthropic"]="latest"),c.includes("google")&&(s["@ai-sdk/google"]="latest"),c.includes("mistral")&&(s["@ai-sdk/mistral"]="latest"),c.includes("xai")&&(s["@ai-sdk/openai"]="latest");let d=We.join(e,"package.json");if(se.existsSync(d)){let u=JSON.parse(await se.promises.readFile(d,"utf-8"));u.dependencies||(u.dependencies={});for(let[h,O]of Object.entries(s))u.dependencies[h]=O;await se.promises.writeFile(d,JSON.stringify(u,null,2)+`
1869
- `)}}import g from"fs";import P from"path";function So(e,t){if(!g.existsSync(e))return;let o=g.readdirSync(e);for(let n of o){let r=P.join(e,n);g.statSync(r).isDirectory()?So(r,t):t(r)}}async function Eo(e,t){let o=P.join(e,"package.json");if(!g.existsSync(o))return;let n=JSON.parse(g.readFileSync(o,"utf8"));if(t.orm!=="prisma"){let r=P.join(e,"packages","db");if(g.existsSync(r)){let i=P.join(r,"prisma");g.existsSync(i)&&g.rmSync(i,{recursive:!0,force:!0});let s=P.join(r,"package.json");if(g.existsSync(s)){let a=JSON.parse(g.readFileSync(s,"utf8"));a.dependencies&&delete a.dependencies["@prisma/client"],a.devDependencies&&delete a.devDependencies.prisma,g.writeFileSync(s,JSON.stringify(a,null,2)+`
1870
- `)}let c=P.join(r,"src","index.ts");g.existsSync(c)&&g.writeFileSync(c,`
1864
+ `}}async function So(e,t){let o=ut.join(e,"packages","billing");if(!ne.existsSync(o))return;if(t==="none"){yo(o);return}let n=ut.join(o,"src"),r=new Set(ti(t));for(let i of ei)r.has(i)||yo(ut.join(n,i));let s=ut.join(n,"checkout","types.ts");if(ne.existsSync(s)){let i=t==="stripe"?"stripe":t==="lemon"?"lemonsqueezy":"chinapay",c=ne.readFileSync(s,"utf8"),a=c.replace(/export type CheckoutProviderType\s*=\s*[^;]+;/,`export type CheckoutProviderType = "${i}";`);a!==c&&ne.writeFileSync(s,a)}ni(e,oi(t))}import le from"fs";import Qe from"path";var vo=new Set(["siliconflow","volcengine-ark","bailian","moonshot"]),Qt=/@sailor:([^\s*]+)/;function ri(e,t){let{providerIds:o,customEndpoint:n}=t;if(e.startsWith("provider:")){let r=e.slice(9);return{marker:e,keep:o.includes(r)}}if(e==="cn-compatible"){let r=o.some(s=>vo.has(s));return{marker:e,keep:r||!!n}}if(e.startsWith("cn-instance:")){let r=e.slice(12);return{marker:e,keep:o.includes(r)}}return e==="custom-endpoint"?{marker:e,keep:!!n}:e==="registry-entries"?{marker:e,keep:!0}:{marker:e,keep:!0}}function ho(e){return e.replace(/\s*\/\/\s*@sailor:[^\n]*$/,"")}function Eo(e){return e.replace(/\s*#\s*@sailor:[^\n]*$/,"")}function _o(e,t){let o=e.split(`
1865
+ `),n=[],r=e.includes("#"),s=0;for(;s<o.length;){let i=o[s],c=i.match(Qt);if(!c){n.push(i),s++;continue}let{marker:a,keep:l}=ri(c[1],t);if(a==="registry-entries"){n.push(r?Eo(i):ho(i)),s++;continue}if(l){let m=r?Eo(i):ho(i);m.trim().length>0&&n.push(m);let y=s+1;for(;y<o.length&&o[y].trim()!==""&&!Qt.test(o[y]);)n.push(o[y]),y++;y<o.length&&o[y].trim()===""&&(n.push(o[y]),y++),s=y}else{let m=s+1;for(;m<o.length&&o[m].trim()!==""&&!Qt.test(o[m]);)m++;m<o.length&&o[m].trim()===""&&m++,s=m}}return si(n.join(`
1866
+ `),t)}function si(e,t){let{providerIds:o,customEndpoint:n}=t,r=new Set;for(let l of o)["openai","anthropic","google","mistral","xai"].includes(l)&&r.add(l),r.add(l.replace(/-/g,"_")),r.add(l);n&&r.add("custom");let s=/createProviderRegistry\(\{([\s\S]*?)\}\)/,i=e.match(s);if(!i)return e;let a=i[1].split(`
1867
+ `).filter(l=>{let m=l.trim();if(m===""||m.startsWith("//"))return!0;let y=m.match(/^([a-zA-Z_][a-zA-Z0-9_]*)\s*,?$/);return y?r.has(y[1]):!0}).join(`
1868
+ `);return e.replace(s,`createProviderRegistry({${a}})`)}function ii(e,t){let o=Qe.join(t,"registry.ts.template"),n=le.readFileSync(o,"utf-8");return _o(n,e)}function ai(e,t){let o=Qe.join(t,".env.example.template"),n=le.readFileSync(o,"utf-8");return _o(n,e)}async function bo(e,t,o){let n=ii(t,o),r=ai(t,o),s=Qe.join(e,"packages/agents/src");await le.promises.mkdir(s,{recursive:!0}),await le.promises.writeFile(Qe.join(s,"registry.ts"),n),await le.promises.appendFile(Qe.join(e,".env.example"),`
1869
+ `+r);let i={ai:"latest"},{providerIds:c,customEndpoint:a}=t;(c.includes("openai")||a||c.some(m=>vo.has(m)))&&(i["@ai-sdk/openai"]="latest",i["@ai-sdk/openai-compatible"]="latest"),c.includes("anthropic")&&(i["@ai-sdk/anthropic"]="latest"),c.includes("google")&&(i["@ai-sdk/google"]="latest"),c.includes("mistral")&&(i["@ai-sdk/mistral"]="latest"),c.includes("xai")&&(i["@ai-sdk/openai"]="latest");let l=Qe.join(e,"package.json");if(le.existsSync(l)){let m=JSON.parse(await le.promises.readFile(l,"utf-8"));m.dependencies||(m.dependencies={});for(let[y,k]of Object.entries(i))m.dependencies[y]=k;await le.promises.writeFile(l,JSON.stringify(m,null,2)+`
1870
+ `)}}import f from"fs";import d from"path";function Po(e,t){if(!f.existsSync(e))return;let o=f.readdirSync(e);for(let n of o){let r=d.join(e,n);f.statSync(r).isDirectory()?Po(r,t):t(r)}}async function Co(e,t){let o=d.join(e,"package.json");if(!f.existsSync(o))return;let n=JSON.parse(f.readFileSync(o,"utf8"));if(t.orm!=="prisma"){let r=d.join(e,"packages","db");if(f.existsSync(r)){let s=d.join(r,"prisma");f.existsSync(s)&&f.rmSync(s,{recursive:!0,force:!0});let i=d.join(r,"package.json");if(f.existsSync(i)){let a=JSON.parse(f.readFileSync(i,"utf8"));a.dependencies&&delete a.dependencies["@prisma/client"],a.devDependencies&&delete a.devDependencies.prisma,f.writeFileSync(i,JSON.stringify(a,null,2)+`
1871
+ `)}let c=d.join(r,"src","index.ts");f.existsSync(c)&&f.writeFileSync(c,`
1871
1872
  export const prisma = {} as any;
1872
1873
  export const db = {} as any;
1873
1874
  export type PrismaClient = any;
@@ -1913,7 +1914,7 @@ export type UsageAggregate = any;
1913
1914
  export type UsageLedgerEntry = any;
1914
1915
  export type UsageType = any;
1915
1916
  export type UsageLedgerSource = any;
1916
- `)}n.scripts?.postinstall&&(n.scripts.postinstall=n.scripts.postinstall.replace(/prisma generate/g,'echo "ORM Disabled"'))}if(!t.i18n){let r=P.join(e,"apps");if(g.existsSync(r)){let i=g.readdirSync(r);for(let s of i){let c=P.join(r,s);if(!g.statSync(c).isDirectory())continue;let a=P.join(c,"src","app");if(!g.existsSync(a))continue;["[lang]","[locale]"].forEach(v=>{let l=P.join(a,v);if(g.existsSync(l)){let R=g.readdirSync(l);for(let mt of R)g.renameSync(P.join(l,mt),P.join(a,mt));g.rmdirSync(l)}}),["src/middleware.ts","middleware.ts"].forEach(v=>{let l=P.join(c,v);g.existsSync(l)&&g.rmSync(l)});let d=P.join(c,"src","lib");g.existsSync(d)||g.mkdirSync(d,{recursive:!0});let u=P.join(d,"mock-i18n.ts");g.writeFileSync(u,`
1917
+ `)}n.scripts?.postinstall&&(n.scripts.postinstall=n.scripts.postinstall.replace(/prisma generate/g,'echo "ORM Disabled"'))}if(!t.i18n){let r=d.join(e,"apps");if(f.existsSync(r)){let s=f.readdirSync(r);for(let i of s){let c=d.join(r,i);if(!f.statSync(c).isDirectory())continue;let a=d.join(c,"src","app");if(!f.existsSync(a))continue;["[lang]","[locale]"].forEach(b=>{let u=d.join(a,b);if(f.existsSync(u)){let T=f.readdirSync(u);for(let yt of T)f.renameSync(d.join(u,yt),d.join(a,yt));f.rmdirSync(u)}}),["src/middleware.ts","middleware.ts"].forEach(b=>{let u=d.join(c,b);f.existsSync(u)&&f.rmSync(u)});let l=d.join(c,"src","lib");f.existsSync(l)||f.mkdirSync(l,{recursive:!0});let m=d.join(l,"mock-i18n.ts");f.writeFileSync(m,`
1917
1918
  import React from 'react';
1918
1919
  export function useTranslations(namespace?: string): any { return (key: string) => key; }
1919
1920
  export function useLocale() { return 'en'; }
@@ -1931,7 +1932,7 @@ export const useRouter = () => ({ push: (...args: any[]) => {}, replace: (...arg
1931
1932
  export default function createMiddleware(...args: any[]) { return (req: any) => req; }
1932
1933
  export function createNavigation(...args: any[]) { return { Link, redirect, usePathname, useRouter, getPathname: () => '/' }; }
1933
1934
  export function defineRouting<T>(config: T): T { return config; }
1934
- `);let O=P.join(d,"mock-i18n.d.ts");g.writeFileSync(O,`declare module '@/lib/mock-i18n' {
1935
+ `);let k=d.join(l,"mock-i18n.d.ts");f.writeFileSync(k,`declare module '@/lib/mock-i18n' {
1935
1936
  export function useTranslations(namespace?: string): any;
1936
1937
  export function useLocale(): string;
1937
1938
  export const NextIntlClientProvider: React.FC<any>;
@@ -1949,18 +1950,19 @@ export function defineRouting<T>(config: T): T { return config; }
1949
1950
  export function createNavigation(...args: any[]): any;
1950
1951
  export function defineRouting<T>(config: T): T;
1951
1952
  }
1952
- `),g.writeFileSync(P.join(d,"mock-i18n-index.ts"),`
1953
+ `),f.writeFileSync(d.join(l,"mock-i18n-index.ts"),`
1953
1954
  export * from './mock-i18n';
1954
1955
  export { default } from './mock-i18n';
1955
- `);let M=P.join(c,"tsconfig.json");if(g.existsSync(M))try{let v=g.readFileSync(M,"utf8");if(v.includes('"paths": {')){let l=v.replace(/"paths":\s*\{/,`"paths": {
1956
+ `);let x=d.join(c,"tsconfig.json");if(f.existsSync(x))try{let b=f.readFileSync(x,"utf8");if(b.includes('"paths": {')){let u=b.replace(/"paths":\s*\{/,`"paths": {
1956
1957
  "next-intl": ["./src/lib/mock-i18n"],
1957
- "next-intl/*": ["./src/lib/mock-i18n"],`);g.writeFileSync(M,l)}}catch{}let D=P.join(c,"src");g.existsSync(D)&&So(D,v=>{if(!v.endsWith(".ts")&&!v.endsWith(".tsx"))return;let l=g.readFileSync(v,"utf8"),R=!1;v.endsWith("src/app/layout.tsx")&&l.includes("../providers")&&(l=l.replace(/from\s+['"]\.\.\/providers['"]/g,"from './providers'"),R=!0),l=l.replace(/params:\s*Promise<\{[^}]*(lang|locale)[^}]*\}>/g,"params: any"),l=l.replace(/\(\{\s*params\s*\}\s*:\s*\{\s*params:\s*any\s*\}\)/g,"({ params }: any)"),l.match(/locale\s*:\s*any/)&&(l=l.replace(/locale\s*:\s*any/g,"locale: string"),R=!0),l.match(/lang\s*:\s*any/)&&(l=l.replace(/lang\s*:\s*any/g,"lang: string"),R=!0),l.match(/requestLocale\s*:\s*any/)&&(l=l.replace(/requestLocale\s*:\s*any/g,"requestLocale: string"),R=!0),l.match(/\(locale\s*=\s*(.*)\)/)&&(l=l.replace(/\(locale\s*=\s*(.*)\)/g,"() "),R=!0),l.match(/export\s+default\s+async\s+function\s+LangLayout/)&&(l=l.replace(/export\s+default\s+async\s+function\s+LangLayout\s*\(\s*\{\s*children\s*,\s*params\s*\}\s*:\s*LangLayoutProps\s*\)/g,"export default async function LangLayout({ children }: { children: React.ReactNode })"),R=!0),(v.endsWith("src/app/layout.tsx")||v.endsWith("src/app/sitemap.ts")||v.endsWith("src/app/robots.ts")||v.endsWith("src/components/ui/locale-switcher.tsx")||v.endsWith("src/app/(marketing)/blog/[slug]/page.tsx"))&&(l=l.replace(/const\s+\{\s*lang\s*\}\s*=\s*(await\s+)?params;?/g,'const lang = "en";'),l=l.replace(/const\s+\{\s*locale\s*\}\s*=\s*(await\s+)?params;?/g,'const locale = "en";'),l=l.replace(/const\s+locale\s*=\s*lang\s+as\s+Locale;?/g,'const locale = "en";'),l=l.replace(/\(l\)\s*=>/g,"(l: any) =>"),R=!0),v.endsWith("src/i18n/request.ts")&&(l=l.replace(/async\s*\(\{\s*requestLocale\s*\}\)/g,"async ({ requestLocale }: any)"),R=!0),(l.match(/locale\s*:/)||l.match(/lang\s*:/))&&(R=!0),R&&g.writeFileSync(v,l)});let Xe=P.join(c,"package.json");if(g.existsSync(Xe)){let v=JSON.parse(g.readFileSync(Xe,"utf8"));v.dependencies&&delete v.dependencies["next-intl"],g.writeFileSync(Xe,JSON.stringify(v,null,2)+`
1958
- `)}}}}g.writeFileSync(o,JSON.stringify(n,null,2)+`
1959
- `)}import{getSchema as es,printSchema as ts}from"@mrleebo/prisma-ast";var ns=/^\/\/\/\s*@conditional\(([A-Za-z][A-Za-z0-9_-]*)=([^)]+)\)\s*$/;function os(e){return e.type==="comment"&&e.text.trim().startsWith("///")}function rs(e){let t=ns.exec(e.trim());if(!t)return null;let[,o,n]=t,r=n.split("|").map(i=>i.trim()).filter(i=>i.length>0);return{flag:o,values:r}}function is(e,t){for(let o=t-1;o>=0;o--){let n=e[o];if(n.type==="comment"){let r=rs(n.text);if(r)return{annIndex:o,parsed:r};continue}break}return null}function Wt(e,t){let o=es(e),n=new Set;for(let c=0;c<o.list.length;c++){if(o.list[c].type!=="model")continue;let d=is(o.list,c);if(!d)continue;let u=t[d.parsed.flag];if(u!==void 0&&d.parsed.values.includes(u))n.add(d.annIndex);else{n.add(c);for(let M=c-1;M>=0;M--){let D=o.list[M];if(D.type==="comment"&&os(D)){n.add(M);continue}break}let O=o.list[c+1];O&&O.type==="break"&&n.add(c+1)}}let r=o.list.filter((c,a)=>!n.has(a)),i=[];for(let c of r){let a=i[i.length-1];c.type==="break"&&a&&a.type==="break"||i.push(c)}return ts({type:"schema",list:i})}import ae from"fs";import Xt from"path";var wt=[{id:"qstash",name:"Upstash QStash",region:"both",envVars:["QSTASH_TOKEN","QSTASH_CURRENT_SIGNING_KEY","QSTASH_NEXT_SIGNING_KEY"],docs:"https://upstash.com/docs/qstash",description:"Serverless HTTP-based queue"},{id:"bullmq",name:"BullMQ",region:"both",envVars:["REDIS_URL"],docs:"https://docs.bullmq.io",description:"Redis-backed job queue"},{id:"upstash",name:"Upstash Kafka",region:"both",envVars:["UPSTASH_KAFKA_REST_URL","UPSTASH_KAFKA_REST_USERNAME","UPSTASH_KAFKA_REST_PASSWORD"],docs:"https://upstash.com/docs/kafka",description:"Serverless Kafka"},{id:"sqs",name:"AWS SQS",region:"global",envVars:["AWS_SQS_QUEUE_URL","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"],docs:"https://docs.aws.amazon.com/AWSSimpleQueueService/",description:"AWS managed queue"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip queue package"}];function ho(e){return wt.find(t=>t.id===e)}var up=wt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function vo(e){return ae.existsSync(e)?ae.readFileSync(e,"utf-8"):null}function ss(e,t){let o=Xt.join(e,".env.example"),n=vo(o);if(n===null)return;let r=`# Queue: ${t.name}`;if(n.includes(r))return;let i=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(s=>`${s}=""`),""].join(`
1960
- `);ae.appendFileSync(o,i)}function as(e,t,o){let n=Xt.join(e,".env.example"),r=vo(n);if(r===null)return;let i=new RegExp(`^${t}=.*$`,"m");i.test(r)?ae.writeFileSync(n,r.replace(i,`${t}="${o}"`)):ae.appendFileSync(n,`${t}="${o}"
1961
- `)}async function _o(e,t,o){let n=Xt.join(e,"packages","queue");if(t==="none"){ae.existsSync(n)&&ae.rmSync(n,{recursive:!0,force:!0});return}let r=ho(t);if(!r)throw new Error(`Unknown queue provider "${t}". Valid ids: ${wt.map(i=>i.id).join(", ")}`);ae.existsSync(n)&&(ss(e,r),as(e,"QUEUE_PROVIDER",t))}import ce from"fs";import zt from"path";var Rt=[{id:"meilisearch",name:"Meilisearch",region:"both",envVars:["MEILISEARCH_HOST","MEILISEARCH_MASTER_KEY"],docs:"https://docs.meilisearch.com",description:"Self-hostable search"},{id:"typesense",name:"Typesense",region:"both",envVars:["TYPESENSE_HOST","TYPESENSE_PORT","TYPESENSE_PROTOCOL","TYPESENSE_API_KEY"],docs:"https://typesense.org/docs",description:"Open-source search"},{id:"algolia",name:"Algolia",region:"global",envVars:["ALGOLIA_APP_ID","ALGOLIA_ADMIN_API_KEY","ALGOLIA_SEARCH_API_KEY"],docs:"https://www.algolia.com/doc/",description:"Managed search as a service"},{id:"pgvector",name:"pgvector (Postgres)",region:"both",envVars:["DATABASE_URL"],docs:"https://github.com/pgvector/pgvector",description:"Postgres vector + full-text"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip search package"}];function Po(e){return Rt.find(t=>t.id===e)}var Ep=Rt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function bo(e){return ce.existsSync(e)?ce.readFileSync(e,"utf-8"):null}function cs(e,t){let o=zt.join(e,".env.example"),n=bo(o);if(n===null)return;let r=`# Search: ${t.name}`;if(n.includes(r))return;let i=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(s=>`${s}=""`),""].join(`
1962
- `);ce.appendFileSync(o,i)}function ps(e,t,o){let n=zt.join(e,".env.example"),r=bo(n);if(r===null)return;let i=new RegExp(`^${t}=.*$`,"m");i.test(r)?ce.writeFileSync(n,r.replace(i,`${t}="${o}"`)):ce.appendFileSync(n,`${t}="${o}"
1963
- `)}async function Io(e,t,o){let n=zt.join(e,"packages","search");if(t==="none"){ce.existsSync(n)&&ce.rmSync(n,{recursive:!0,force:!0});return}let r=Po(t);if(!r)throw new Error(`Unknown search provider "${t}". Valid ids: ${Rt.map(i=>i.id).join(", ")}`);ce.existsSync(n)&&(cs(e,r),ps(e,"SEARCH_PROVIDER",t))}import pe from"fs";import Ie from"path";function ls(e){let t=[Ie.join(e,"packages","db"),Ie.join(e,"apps","web")];for(let o of t){let n=Ie.join(o,"prisma","schema.prisma");if(pe.existsSync(n))return{packageDir:o,seedPath:Ie.join(o,"prisma","seed.ts"),packageJsonPath:Ie.join(o,"package.json")}}return null}function ds(e){try{let t=pe.readFileSync(e,"utf8"),o=new Set,n=/^\s*model\s+(\w+)\s*\{/gm,r=n.exec(t);for(;r;)o.add(r[1]),r=n.exec(t);return o}catch{return new Set}}function us(e,t){return!t||e==="none"?` // Skipping admin user \u2014 auth=${JSON.stringify(e)} (or no User model).`:e==="clerk"?` try {
1958
+ "next-intl/*": ["./src/lib/mock-i18n"],`);f.writeFileSync(x,u)}}catch{}let L=d.join(c,"src");f.existsSync(L)&&Po(L,b=>{if(!b.endsWith(".ts")&&!b.endsWith(".tsx"))return;let u=f.readFileSync(b,"utf8"),T=!1;b.endsWith("src/app/layout.tsx")&&u.includes("../providers")&&(u=u.replace(/from\s+['"]\.\.\/providers['"]/g,"from './providers'"),T=!0),u=u.replace(/params:\s*Promise<\{[^}]*(lang|locale)[^}]*\}>/g,"params: any"),u=u.replace(/\(\{\s*params\s*\}\s*:\s*\{\s*params:\s*any\s*\}\)/g,"({ params }: any)"),u.match(/locale\s*:\s*any/)&&(u=u.replace(/locale\s*:\s*any/g,"locale: string"),T=!0),u.match(/lang\s*:\s*any/)&&(u=u.replace(/lang\s*:\s*any/g,"lang: string"),T=!0),u.match(/requestLocale\s*:\s*any/)&&(u=u.replace(/requestLocale\s*:\s*any/g,"requestLocale: string"),T=!0),u.match(/\(locale\s*=\s*(.*)\)/)&&(u=u.replace(/\(locale\s*=\s*(.*)\)/g,"() "),T=!0),u.match(/export\s+default\s+async\s+function\s+LangLayout/)&&(u=u.replace(/export\s+default\s+async\s+function\s+LangLayout\s*\(\s*\{\s*children\s*,\s*params\s*\}\s*:\s*LangLayoutProps\s*\)/g,"export default async function LangLayout({ children }: { children: React.ReactNode })"),T=!0),(b.endsWith("src/app/layout.tsx")||b.endsWith("src/app/sitemap.ts")||b.endsWith("src/app/robots.ts")||b.endsWith("src/components/ui/locale-switcher.tsx")||b.endsWith("src/app/(marketing)/blog/[slug]/page.tsx"))&&(u=u.replace(/const\s+\{\s*lang\s*\}\s*=\s*(await\s+)?params;?/g,'const lang = "en";'),u=u.replace(/const\s+\{\s*locale\s*\}\s*=\s*(await\s+)?params;?/g,'const locale = "en";'),u=u.replace(/const\s+locale\s*=\s*lang\s+as\s+Locale;?/g,'const locale = "en";'),u=u.replace(/\(l\)\s*=>/g,"(l: any) =>"),T=!0),b.endsWith("src/i18n/request.ts")&&(u=u.replace(/async\s*\(\{\s*requestLocale\s*\}\)/g,"async ({ requestLocale }: any)"),T=!0),(u.match(/locale\s*:/)||u.match(/lang\s*:/))&&(T=!0),T&&f.writeFileSync(b,u)});let oe=d.join(c,"package.json");if(f.existsSync(oe)){let b=JSON.parse(f.readFileSync(oe,"utf8"));b.dependencies&&delete b.dependencies["next-intl"],f.writeFileSync(oe,JSON.stringify(b,null,2)+`
1959
+ `)}}}}f.writeFileSync(o,JSON.stringify(n,null,2)+`
1960
+ `)}function E(e){try{f.rmSync(e,{recursive:!0,force:!0})}catch{}}function ci(e,t){if(!f.existsSync(e))return;let o;try{o=JSON.parse(f.readFileSync(e,"utf8"))}catch{return}let n=!1;if(o.dependencies&&t in o.dependencies){let{[t]:r,...s}=o.dependencies;o={...o,dependencies:s},n=!0}if(o.devDependencies&&t in o.devDependencies){let{[t]:r,...s}=o.devDependencies;o={...o,devDependencies:s},n=!0}n&&f.writeFileSync(e,JSON.stringify(o,null,2)+`
1961
+ `)}function Io(e,t){t.cronJobs||(E(d.join(e,"apps/web/src/app/api/cron")),E(d.join(e,"packages/queue/src/scheduled"))),t.auditLog||(E(d.join(e,"apps/web/src/app/[locale]/(app)/settings/audit-log")),E(d.join(e,"apps/web/src/app/api/audit-logs")),E(d.join(e,"apps/web/src/components/audit"))),t.apiKeys||(E(d.join(e,"apps/web/src/app/[locale]/(app)/settings/api-keys")),E(d.join(e,"apps/web/src/app/api/api-keys")),E(d.join(e,"apps/web/src/components/api-keys"))),t.webhooks||(E(d.join(e,"apps/web/src/app/[locale]/(app)/settings/webhooks")),E(d.join(e,"apps/web/src/app/api/webhooks")),E(d.join(e,"apps/web/src/components/webhooks")),E(d.join(e,"packages/webhooks"))),t.commandPalette||(E(d.join(e,"apps/web/src/components/command-palette")),E(d.join(e,"apps/web/src/app/[locale]/providers/command-palette-mount.tsx"))),t.cookieConsent||(E(d.join(e,"apps/landing-page/src/components/cookie-consent-banner.tsx")),E(d.join(e,"apps/landing-page/src/components/__tests__/cookie-consent-banner.test.tsx")),E(d.join(e,"apps/landing-page/src/lib/cookie-consent.ts")),E(d.join(e,"apps/landing-page/src/lib/__tests__/cookie-consent.test.ts")),E(d.join(e,"apps/web/src/app/api/cookie-consent"))),t.legalPages||(E(d.join(e,"apps/landing-page/src/app/[lang]/(legal)/legal")),E(d.join(e,"apps/landing-page/src/lib/legal-documents.ts")),E(d.join(e,"apps/landing-page/src/lib/__tests__/legal-documents.test.ts"))),t.chinaCompliance||(E(d.join(e,"packages/china-compliance")),E(d.join(e,"apps/landing-page/src/components/icp-footer.tsx")),E(d.join(e,"apps/landing-page/src/components/__tests__/icp-footer.test.tsx")),E(d.join(e,"apps/web/src/components/auth/wechat-login-button.tsx")),E(d.join(e,"apps/web/src/components/auth/__tests__/wechat-login-button.test.tsx")),ci(d.join(e,"apps/web/package.json"),"@nebutra/china-compliance"))}import{getSchema as pi,printSchema as li}from"@mrleebo/prisma-ast";var di=/^\/\/\/\s*@conditional\(([A-Za-z][A-Za-z0-9_-]*)=([^)]+)\)\s*$/;function ui(e){return e.type==="comment"&&e.text.trim().startsWith("///")}function mi(e){let t=di.exec(e.trim());if(!t)return null;let[,o,n]=t,r=n.split("|").map(s=>s.trim()).filter(s=>s.length>0);return{flag:o,values:r}}function gi(e,t){for(let o=t-1;o>=0;o--){let n=e[o];if(n.type==="comment"){let r=mi(n.text);if(r)return{annIndex:o,parsed:r};continue}break}return null}function Zt(e,t){let o=pi(e),n=new Set;for(let c=0;c<o.list.length;c++){if(o.list[c].type!=="model")continue;let l=gi(o.list,c);if(!l)continue;let m=t[l.parsed.flag];if(m!==void 0&&l.parsed.values.includes(m))n.add(l.annIndex);else{n.add(c);for(let x=c-1;x>=0;x--){let L=o.list[x];if(L.type==="comment"&&ui(L)){n.add(x);continue}break}let k=o.list[c+1];k&&k.type==="break"&&n.add(c+1)}}let r=o.list.filter((c,a)=>!n.has(a)),s=[];for(let c of r){let a=s[s.length-1];c.type==="break"&&a&&a.type==="break"||s.push(c)}return li({type:"schema",list:s})}import de from"fs";import en from"path";var xt=[{id:"qstash",name:"Upstash QStash",region:"both",envVars:["QSTASH_TOKEN","QSTASH_CURRENT_SIGNING_KEY","QSTASH_NEXT_SIGNING_KEY"],docs:"https://upstash.com/docs/qstash",description:"Serverless HTTP-based queue"},{id:"bullmq",name:"BullMQ",region:"both",envVars:["REDIS_URL"],docs:"https://docs.bullmq.io",description:"Redis-backed job queue"},{id:"upstash",name:"Upstash Kafka",region:"both",envVars:["UPSTASH_KAFKA_REST_URL","UPSTASH_KAFKA_REST_USERNAME","UPSTASH_KAFKA_REST_PASSWORD"],docs:"https://upstash.com/docs/kafka",description:"Serverless Kafka"},{id:"sqs",name:"AWS SQS",region:"global",envVars:["AWS_SQS_QUEUE_URL","AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_REGION"],docs:"https://docs.aws.amazon.com/AWSSimpleQueueService/",description:"AWS managed queue"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip queue package"}];function Ao(e){return xt.find(t=>t.id===e)}var bp=xt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function wo(e){return de.existsSync(e)?de.readFileSync(e,"utf-8"):null}function fi(e,t){let o=en.join(e,".env.example"),n=wo(o);if(n===null)return;let r=`# Queue: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(i=>`${i}=""`),""].join(`
1962
+ `);de.appendFileSync(o,s)}function yi(e,t,o){let n=en.join(e,".env.example"),r=wo(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?de.writeFileSync(n,r.replace(s,`${t}="${o}"`)):de.appendFileSync(n,`${t}="${o}"
1963
+ `)}async function Ro(e,t,o){let n=en.join(e,"packages","queue");if(t==="none"){de.existsSync(n)&&de.rmSync(n,{recursive:!0,force:!0});return}let r=Ao(t);if(!r)throw new Error(`Unknown queue provider "${t}". Valid ids: ${xt.map(s=>s.id).join(", ")}`);de.existsSync(n)&&(fi(e,r),yi(e,"QUEUE_PROVIDER",t))}import ue from"fs";import tn from"path";var Nt=[{id:"meilisearch",name:"Meilisearch",region:"both",envVars:["MEILISEARCH_HOST","MEILISEARCH_MASTER_KEY"],docs:"https://docs.meilisearch.com",description:"Self-hostable search"},{id:"typesense",name:"Typesense",region:"both",envVars:["TYPESENSE_HOST","TYPESENSE_PORT","TYPESENSE_PROTOCOL","TYPESENSE_API_KEY"],docs:"https://typesense.org/docs",description:"Open-source search"},{id:"algolia",name:"Algolia",region:"global",envVars:["ALGOLIA_APP_ID","ALGOLIA_ADMIN_API_KEY","ALGOLIA_SEARCH_API_KEY"],docs:"https://www.algolia.com/doc/",description:"Managed search as a service"},{id:"pgvector",name:"pgvector (Postgres)",region:"both",envVars:["DATABASE_URL"],docs:"https://github.com/pgvector/pgvector",description:"Postgres vector + full-text"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:"Skip search package"}];function ko(e){return Nt.find(t=>t.id===e)}var Rp=Nt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function xo(e){return ue.existsSync(e)?ue.readFileSync(e,"utf-8"):null}function Si(e,t){let o=tn.join(e,".env.example"),n=xo(o);if(n===null)return;let r=`# Search: ${t.name}`;if(n.includes(r))return;let s=["","# =============================================",r,`# Docs: ${t.docs}`,"# =============================================",...t.envVars.map(i=>`${i}=""`),""].join(`
1964
+ `);ue.appendFileSync(o,s)}function hi(e,t,o){let n=tn.join(e,".env.example"),r=xo(n);if(r===null)return;let s=new RegExp(`^${t}=.*$`,"m");s.test(r)?ue.writeFileSync(n,r.replace(s,`${t}="${o}"`)):ue.appendFileSync(n,`${t}="${o}"
1965
+ `)}async function No(e,t,o){let n=tn.join(e,"packages","search");if(t==="none"){ue.existsSync(n)&&ue.rmSync(n,{recursive:!0,force:!0});return}let r=ko(t);if(!r)throw new Error(`Unknown search provider "${t}". Valid ids: ${Nt.map(s=>s.id).join(", ")}`);ue.existsSync(n)&&(Si(e,r),hi(e,"SEARCH_PROVIDER",t))}import me from"fs";import ke from"path";function Ei(e){let t=[ke.join(e,"packages","db"),ke.join(e,"apps","web")];for(let o of t){let n=ke.join(o,"prisma","schema.prisma");if(me.existsSync(n))return{packageDir:o,seedPath:ke.join(o,"prisma","seed.ts"),packageJsonPath:ke.join(o,"package.json")}}return null}function vi(e){try{let t=me.readFileSync(e,"utf8"),o=new Set,n=/^\s*model\s+(\w+)\s*\{/gm,r=n.exec(t);for(;r;)o.add(r[1]),r=n.exec(t);return o}catch{return new Set}}function _i(e,t){return!t||e==="none"?` // Skipping admin user \u2014 auth=${JSON.stringify(e)} (or no User model).`:e==="clerk"?` try {
1964
1966
  const admin = await prisma.user.create({
1965
1967
  data: {
1966
1968
  clerkId: "user_mock_admin",
@@ -1991,7 +1993,7 @@ export { default } from './mock-i18n';
1991
1993
  console.log("\\u2713 Created admin user:", admin.email);
1992
1994
  } catch (err) {
1993
1995
  console.warn("\\u26A0 Admin user creation skipped:", (err as Error).message);
1994
- }`}function ms(e,t){let o=t.has("Tenant"),n=t.has("User"),r=t.has("Project"),i=us(e,n),s=o?` let tenants: Array<{ id: string; name: string }> = [];
1996
+ }`}function bi(e,t){let o=t.has("Tenant"),n=t.has("User"),r=t.has("Project"),s=_i(e,n),i=o?` let tenants: Array<{ id: string; name: string }> = [];
1995
1997
  try {
1996
1998
  tenants = await Promise.all([
1997
1999
  prisma.tenant.create({
@@ -2041,10 +2043,10 @@ async function main(): Promise<void> {
2041
2043
  console.log("\\uD83C\\uDF31 Seeding database...");
2042
2044
 
2043
2045
  // --- Tenants ---------------------------------------------------------
2044
- ${s}
2046
+ ${i}
2045
2047
 
2046
2048
  // --- Admin user ------------------------------------------------------
2047
- ${i}
2049
+ ${s}
2048
2050
 
2049
2051
  // --- Sample projects per tenant --------------------------------------
2050
2052
  ${c}
@@ -2060,12 +2062,12 @@ main()
2060
2062
  .finally(async () => {
2061
2063
  await prisma.$disconnect();
2062
2064
  });
2063
- `}function gs(e){if(pe.existsSync(e))try{let t=pe.readFileSync(e,"utf8"),o=JSON.parse(t),n=o.scripts??{},r=!1;n["db:seed"]||(n["db:seed"]="prisma db seed",r=!0);let i=o.prisma??{};if(i.seed||(i.seed="tsx prisma/seed.ts",r=!0),!r)return;let s={...o,scripts:n,prisma:i};pe.writeFileSync(e,JSON.stringify(s,null,2)+`
2064
- `)}catch(t){let o=t instanceof Error?t.message:String(t);console.warn(`[create-sailor] Failed to patch seed scripts in ${e}: ${o}`)}}async function Ao(e,t){let o=ls(e);if(o)try{let n=Ie.join(o.packageDir,"prisma","schema.prisma"),r=ds(n),i=ms(t,r),s=Ie.dirname(o.seedPath);pe.existsSync(s)||pe.mkdirSync(s,{recursive:!0}),pe.writeFileSync(o.seedPath,i),gs(o.packageJsonPath)}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate seed data: ${r}`),new Error(`Unable to write prisma/seed.ts: ${r}`)}}import le from"fs";import Ae from"path";var xt=[{id:"twilio",name:"Twilio",region:"global",envVars:["TWILIO_ACCOUNT_SID","TWILIO_AUTH_TOKEN","TWILIO_FROM_NUMBER"],docs:"https://www.twilio.com/docs/sms",pkgs:["twilio"]},{id:"messagebird",name:"MessageBird (Bird)",region:"global",envVars:["MESSAGEBIRD_ACCESS_KEY","MESSAGEBIRD_ORIGINATOR"],docs:"https://developers.messagebird.com/api/sms-messaging/",pkgs:["messagebird"]},{id:"plivo",name:"Plivo",region:"global",envVars:["PLIVO_AUTH_ID","PLIVO_AUTH_TOKEN","PLIVO_FROM_NUMBER"],docs:"https://www.plivo.com/docs/sms/",pkgs:["plivo"]},{id:"aliyun-sms",name:"\u963F\u91CC\u4E91\u77ED\u4FE1 Aliyun SMS",region:"cn",envVars:["ALIYUN_SMS_ACCESS_KEY","ALIYUN_SMS_ACCESS_SECRET","ALIYUN_SMS_SIGN_NAME","ALIYUN_SMS_TEMPLATE_CODE","ALIYUN_SMS_ENDPOINT"],docs:"https://help.aliyun.com/product/44282.html",pkgs:["@alicloud/dysmsapi20170525","@alicloud/openapi-client"]},{id:"tencent-sms",name:"\u817E\u8BAF\u4E91\u77ED\u4FE1 Tencent SMS",region:"cn",envVars:["TENCENT_SMS_SECRET_ID","TENCENT_SMS_SECRET_KEY","TENCENT_SMS_SDK_APP_ID","TENCENT_SMS_SIGN_NAME","TENCENT_SMS_TEMPLATE_ID","TENCENT_SMS_REGION"],docs:"https://cloud.tencent.com/document/product/382",pkgs:["tencentcloud-sdk-nodejs-sms"]},{id:"yunpian",name:"\u4E91\u7247 Yunpian",region:"cn",envVars:["YUNPIAN_API_KEY","YUNPIAN_SIGN"],docs:"https://www.yunpian.com/official/document/sms/zh_CN/introduction_product_intro",pkgs:["yunpian-nodejs-sdk"]},{id:"none",name:"None",region:"both",envVars:[],docs:""}],wp=xt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function Co(e){return xt.find(t=>t.id===e)}var fs="@nebutra/sms",ys={twilio:"^5.3.6",messagebird:"^4.0.1",plivo:"^4.73.0","@alicloud/dysmsapi20170525":"^2.0.24","@alicloud/openapi-client":"^0.4.12","tencentcloud-sdk-nodejs-sms":"^4.0.970","yunpian-nodejs-sdk":"^0.0.2"};function Qt(e,t){le.mkdirSync(Ae.dirname(e),{recursive:!0}),le.writeFileSync(e,t)}function Ss(e,t){let o=Ae.join(e,".env.example");le.existsSync(o)?le.appendFileSync(o,`
2065
- `+t):le.writeFileSync(o,t)}function Es(e){if(e.envVars.length===0)return"";let t=`# SMS provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2065
+ `}function Pi(e){if(me.existsSync(e))try{let t=me.readFileSync(e,"utf8"),o=JSON.parse(t),n=o.scripts??{},r=!1;n["db:seed"]||(n["db:seed"]="prisma db seed",r=!0);let s=o.prisma??{};if(s.seed||(s.seed="tsx prisma/seed.ts",r=!0),!r)return;let i={...o,scripts:n,prisma:s};me.writeFileSync(e,JSON.stringify(i,null,2)+`
2066
+ `)}catch(t){let o=t instanceof Error?t.message:String(t);console.warn(`[create-sailor] Failed to patch seed scripts in ${e}: ${o}`)}}async function To(e,t){let o=Ei(e);if(o)try{let n=ke.join(o.packageDir,"prisma","schema.prisma"),r=vi(n),s=bi(t,r),i=ke.dirname(o.seedPath);me.existsSync(i)||me.mkdirSync(i,{recursive:!0}),me.writeFileSync(o.seedPath,s),Pi(o.packageJsonPath)}catch(n){let r=n instanceof Error?n.message:String(n);throw console.error(`[create-sailor] Failed to generate seed data: ${r}`),new Error(`Unable to write prisma/seed.ts: ${r}`)}}import ge from"fs";import xe from"path";var Tt=[{id:"twilio",name:"Twilio",region:"global",envVars:["TWILIO_ACCOUNT_SID","TWILIO_AUTH_TOKEN","TWILIO_FROM_NUMBER"],docs:"https://www.twilio.com/docs/sms",pkgs:["twilio"]},{id:"messagebird",name:"MessageBird (Bird)",region:"global",envVars:["MESSAGEBIRD_ACCESS_KEY","MESSAGEBIRD_ORIGINATOR"],docs:"https://developers.messagebird.com/api/sms-messaging/",pkgs:["messagebird"]},{id:"plivo",name:"Plivo",region:"global",envVars:["PLIVO_AUTH_ID","PLIVO_AUTH_TOKEN","PLIVO_FROM_NUMBER"],docs:"https://www.plivo.com/docs/sms/",pkgs:["plivo"]},{id:"aliyun-sms",name:"\u963F\u91CC\u4E91\u77ED\u4FE1 Aliyun SMS",region:"cn",envVars:["ALIYUN_SMS_ACCESS_KEY","ALIYUN_SMS_ACCESS_SECRET","ALIYUN_SMS_SIGN_NAME","ALIYUN_SMS_TEMPLATE_CODE","ALIYUN_SMS_ENDPOINT"],docs:"https://help.aliyun.com/product/44282.html",pkgs:["@alicloud/dysmsapi20170525","@alicloud/openapi-client"]},{id:"tencent-sms",name:"\u817E\u8BAF\u4E91\u77ED\u4FE1 Tencent SMS",region:"cn",envVars:["TENCENT_SMS_SECRET_ID","TENCENT_SMS_SECRET_KEY","TENCENT_SMS_SDK_APP_ID","TENCENT_SMS_SIGN_NAME","TENCENT_SMS_TEMPLATE_ID","TENCENT_SMS_REGION"],docs:"https://cloud.tencent.com/document/product/382",pkgs:["tencentcloud-sdk-nodejs-sms"]},{id:"yunpian",name:"\u4E91\u7247 Yunpian",region:"cn",envVars:["YUNPIAN_API_KEY","YUNPIAN_SIGN"],docs:"https://www.yunpian.com/official/document/sms/zh_CN/introduction_product_intro",pkgs:["yunpian-nodejs-sdk"]},{id:"none",name:"None",region:"both",envVars:[],docs:""}],jp=Tt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});function Oo(e){return Tt.find(t=>t.id===e)}var Ci="@nebutra/sms",Ii={twilio:"^5.3.6",messagebird:"^4.0.1",plivo:"^4.73.0","@alicloud/dysmsapi20170525":"^2.0.24","@alicloud/openapi-client":"^0.4.12","tencentcloud-sdk-nodejs-sms":"^4.0.970","yunpian-nodejs-sdk":"^0.0.2"};function nn(e,t){ge.mkdirSync(xe.dirname(e),{recursive:!0}),ge.writeFileSync(e,t)}function Ai(e,t){let o=xe.join(e,".env.example");ge.existsSync(o)?ge.appendFileSync(o,`
2067
+ `+t):ge.writeFileSync(o,t)}function wi(e){if(e.envVars.length===0)return"";let t=`# SMS provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2066
2068
  `);return`${t}
2067
2069
  ${o}
2068
- `}var hs=`/**
2070
+ `}var Ri=`/**
2069
2071
  * Inputs for the \`sendSms\` wrapper. Keep this surface portable across
2070
2072
  * providers \u2014 provider-specific options belong in the wrapper itself.
2071
2073
  */
@@ -2085,7 +2087,7 @@ export interface SendSmsResult {
2085
2087
  provider: string;
2086
2088
  raw?: unknown;
2087
2089
  }
2088
- `;function vs(){return`import twilio from "twilio";
2090
+ `;function ki(){return`import twilio from "twilio";
2089
2091
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2090
2092
 
2091
2093
  let client: ReturnType<typeof twilio> | null = null;
@@ -2120,7 +2122,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2120
2122
  }
2121
2123
 
2122
2124
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2123
- `}function _s(){return`import messagebird from "messagebird";
2125
+ `}function xi(){return`import messagebird from "messagebird";
2124
2126
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2125
2127
 
2126
2128
  let client: ReturnType<typeof messagebird> | null = null;
@@ -2158,7 +2160,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2158
2160
  }
2159
2161
 
2160
2162
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2161
- `}function Ps(){return`import plivo from "plivo";
2163
+ `}function Ni(){return`import plivo from "plivo";
2162
2164
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2163
2165
 
2164
2166
  let client: InstanceType<typeof plivo.Client> | null = null;
@@ -2197,7 +2199,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2197
2199
  }
2198
2200
 
2199
2201
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2200
- `}function bs(){return`import Dysmsapi, { SendSmsRequest } from "@alicloud/dysmsapi20170525";
2202
+ `}function Ti(){return`import Dysmsapi, { SendSmsRequest } from "@alicloud/dysmsapi20170525";
2201
2203
  import * as $OpenApi from "@alicloud/openapi-client";
2202
2204
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2203
2205
 
@@ -2246,7 +2248,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2246
2248
  }
2247
2249
 
2248
2250
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2249
- `}function Is(){return`import * as tencentcloud from "tencentcloud-sdk-nodejs-sms";
2251
+ `}function Oi(){return`import * as tencentcloud from "tencentcloud-sdk-nodejs-sms";
2250
2252
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2251
2253
 
2252
2254
  const SmsClient = tencentcloud.sms.v20210111.Client;
@@ -2311,7 +2313,7 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2311
2313
  }
2312
2314
 
2313
2315
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2314
- `}function As(){return`// @ts-expect-error \u2014 yunpian-nodejs-sdk ships no type declarations
2316
+ `}function Ui(){return`// @ts-expect-error \u2014 yunpian-nodejs-sdk ships no type declarations
2315
2317
  import Yunpian from "yunpian-nodejs-sdk";
2316
2318
  import type { SendSmsInput, SendSmsResult } from "./types.js";
2317
2319
 
@@ -2363,13 +2365,13 @@ export async function sendSms(input: SendSmsInput): Promise<SendSmsResult> {
2363
2365
  }
2364
2366
 
2365
2367
  export type { SendSmsInput, SendSmsResult } from "./types.js";
2366
- `}function Cs(e){switch(e){case"twilio":return vs();case"messagebird":return _s();case"plivo":return Ps();case"aliyun-sms":return bs();case"tencent-sms":return Is();case"yunpian":return As();case"none":return`export {};
2367
- `}}function ws(e){let t={};for(let n of e.pkgs??[]){let r=ys[n];r&&(t[n]=r)}let o={name:fs,version:"0.1.0",private:!0,description:`Transactional SMS via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2368
- `}async function wo(e,t,o="global"){if(t==="none")return;let n=Co(t);if(!n)throw new Error(`Unknown SMS provider "${t}". Valid ids: ${xt.map(s=>s.id).join(", ")}`);let r=Ae.join(e,"packages","sms");if(!le.existsSync(r))return;let i=Ae.join(r,"src");le.existsSync(i)&&le.rmSync(i,{recursive:!0,force:!0});try{Qt(Ae.join(r,"package.json"),ws(n)),Qt(Ae.join(i,"types.ts"),hs),Qt(Ae.join(i,"index.ts"),Cs(n.id)),Ss(e,Es(n))}catch(s){throw console.error(`Failed to apply SMS selection "${t}":`,s),new Error(`SMS scaffold for "${t}" failed \u2014 see stderr for details.`)}}import we from"fs";import Ce from"path";var lt=[{id:"r2",name:"Cloudflare R2",region:"global",envVars:["R2_ACCOUNT_ID","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY","R2_BUCKET"],docs:"https://developers.cloudflare.com/r2/api/s3/api/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"s3",name:"AWS S3",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_S3_REGION","S3_BUCKET"],docs:"https://docs.aws.amazon.com/s3/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"supabase-storage",name:"Supabase Storage",region:"global",envVars:["SUPABASE_URL","SUPABASE_SERVICE_ROLE_KEY","SUPABASE_BUCKET"],docs:"https://supabase.com/docs/guides/storage",pkg:"@supabase/supabase-js",pkgVersion:"^2.45.4"},{id:"aliyun-oss",name:"\u963F\u91CC\u4E91 OSS",region:"cn",envVars:["ALIYUN_OSS_ACCESS_KEY","ALIYUN_OSS_ACCESS_SECRET","ALIYUN_OSS_REGION","ALIYUN_OSS_BUCKET"],docs:"https://help.aliyun.com/product/31815.html",pkg:"ali-oss",pkgVersion:"^6.21.0"},{id:"tencent-cos",name:"\u817E\u8BAF\u4E91 COS",region:"cn",envVars:["TENCENT_COS_SECRET_ID","TENCENT_COS_SECRET_KEY","TENCENT_COS_BUCKET","TENCENT_COS_REGION"],docs:"https://cloud.tencent.com/document/product/436",pkg:"cos-nodejs-sdk-v5",pkgVersion:"^2.13.7"},{id:"qiniu",name:"\u4E03\u725B\u4E91 Kodo",region:"cn",envVars:["QINIU_ACCESS_KEY","QINIU_SECRET_KEY","QINIU_BUCKET","QINIU_DOMAIN"],docs:"https://developer.qiniu.com/kodo",pkg:"qiniu",pkgVersion:"^7.14.0"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function Jt(e){let t=e==="supabase"?"supabase-storage":e;return lt.some(o=>o.id===t)?t:void 0}function Ro(e){let t=Jt(e);return t?lt.find(o=>o.id===t):void 0}var Op=lt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var Re="@nebutra/storage";function Zt(e,t){we.mkdirSync(Ce.dirname(e),{recursive:!0}),we.writeFileSync(e,t)}function Rs(e,t){let o=Ce.join(e,".env.example");we.existsSync(o)?we.appendFileSync(o,`
2369
- `+t):we.writeFileSync(o,t)}function xs(e){if(e.envVars.length===0)return"";let t=`# Storage provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2368
+ `}function Li(e){switch(e){case"twilio":return ki();case"messagebird":return xi();case"plivo":return Ni();case"aliyun-sms":return Ti();case"tencent-sms":return Oi();case"yunpian":return Ui();case"none":return`export {};
2369
+ `}}function Mi(e){let t={};for(let n of e.pkgs??[]){let r=Ii[n];r&&(t[n]=r)}let o={name:Ci,version:"0.1.0",private:!0,description:`Transactional SMS via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2370
+ `}async function Uo(e,t,o="global"){if(t==="none")return;let n=Oo(t);if(!n)throw new Error(`Unknown SMS provider "${t}". Valid ids: ${Tt.map(i=>i.id).join(", ")}`);let r=xe.join(e,"packages","sms");if(!ge.existsSync(r))return;let s=xe.join(r,"src");ge.existsSync(s)&&ge.rmSync(s,{recursive:!0,force:!0});try{nn(xe.join(r,"package.json"),Mi(n)),nn(xe.join(s,"types.ts"),Ri),nn(xe.join(s,"index.ts"),Li(n.id)),Ai(e,wi(n))}catch(i){throw console.error(`Failed to apply SMS selection "${t}":`,i),new Error(`SMS scaffold for "${t}" failed \u2014 see stderr for details.`)}}import Te from"fs";import Ne from"path";var mt=[{id:"r2",name:"Cloudflare R2",region:"global",envVars:["R2_ACCOUNT_ID","R2_ACCESS_KEY_ID","R2_SECRET_ACCESS_KEY","R2_BUCKET"],docs:"https://developers.cloudflare.com/r2/api/s3/api/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"s3",name:"AWS S3",region:"global",envVars:["AWS_ACCESS_KEY_ID","AWS_SECRET_ACCESS_KEY","AWS_S3_REGION","S3_BUCKET"],docs:"https://docs.aws.amazon.com/s3/",pkg:"@aws-sdk/client-s3",pkgVersion:"^3.658.0"},{id:"supabase-storage",name:"Supabase Storage",region:"global",envVars:["SUPABASE_URL","SUPABASE_SERVICE_ROLE_KEY","SUPABASE_BUCKET"],docs:"https://supabase.com/docs/guides/storage",pkg:"@supabase/supabase-js",pkgVersion:"^2.45.4"},{id:"aliyun-oss",name:"\u963F\u91CC\u4E91 OSS",region:"cn",envVars:["ALIYUN_OSS_ACCESS_KEY","ALIYUN_OSS_ACCESS_SECRET","ALIYUN_OSS_REGION","ALIYUN_OSS_BUCKET"],docs:"https://help.aliyun.com/product/31815.html",pkg:"ali-oss",pkgVersion:"^6.21.0"},{id:"tencent-cos",name:"\u817E\u8BAF\u4E91 COS",region:"cn",envVars:["TENCENT_COS_SECRET_ID","TENCENT_COS_SECRET_KEY","TENCENT_COS_BUCKET","TENCENT_COS_REGION"],docs:"https://cloud.tencent.com/document/product/436",pkg:"cos-nodejs-sdk-v5",pkgVersion:"^2.13.7"},{id:"qiniu",name:"\u4E03\u725B\u4E91 Kodo",region:"cn",envVars:["QINIU_ACCESS_KEY","QINIU_SECRET_KEY","QINIU_BUCKET","QINIU_DOMAIN"],docs:"https://developer.qiniu.com/kodo",pkg:"qiniu",pkgVersion:"^7.14.0"},{id:"none",name:"None",region:"global",envVars:[],docs:""}];function on(e){let t=e==="supabase"?"supabase-storage":e;return mt.some(o=>o.id===t)?t:void 0}function Lo(e){let t=on(e);return t?mt.find(o=>o.id===t):void 0}var Yp=mt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});var Oe="@nebutra/storage";function rn(e,t){Te.mkdirSync(Ne.dirname(e),{recursive:!0}),Te.writeFileSync(e,t)}function ji(e,t){let o=Ne.join(e,".env.example");Te.existsSync(o)?Te.appendFileSync(o,`
2371
+ `+t):Te.writeFileSync(o,t)}function Fi(e){if(e.envVars.length===0)return"";let t=`# Storage provider: ${e.name}`,o=e.envVars.map(n=>`${n}=`).join(`
2370
2372
  `);return`${t}
2371
2373
  ${o}
2372
- `}var Ns=`/**
2374
+ `}var Di=`/**
2373
2375
  * Inputs for the \`uploadFile\` wrapper. Keep this surface portable across
2374
2376
  * providers \u2014 provider-specific options belong in the wrapper itself.
2375
2377
  */
@@ -2395,8 +2397,8 @@ export interface SignedUrlOptions {
2395
2397
  operation?: "get" | "put";
2396
2398
  contentType?: string;
2397
2399
  }
2398
- `;function ks(){return`/**
2399
- * @${Re.slice(1)} \u2014 Cloudflare R2 via the S3-compatible API.
2400
+ `;function Ki(){return`/**
2401
+ * @${Oe.slice(1)} \u2014 Cloudflare R2 via the S3-compatible API.
2400
2402
  *
2401
2403
  * Docs: https://developers.cloudflare.com/r2/api/s3/api/
2402
2404
  */
@@ -2459,8 +2461,8 @@ export async function getSignedUrl(
2459
2461
  }
2460
2462
 
2461
2463
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2462
- `}function Ts(){return`/**
2463
- * @${Re.slice(1)} \u2014 AWS S3 wrapper.
2464
+ `}function Vi(){return`/**
2465
+ * @${Oe.slice(1)} \u2014 AWS S3 wrapper.
2464
2466
  *
2465
2467
  * Docs: https://docs.aws.amazon.com/s3/
2466
2468
  */
@@ -2524,8 +2526,8 @@ export async function getSignedUrl(
2524
2526
  }
2525
2527
 
2526
2528
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2527
- `}function Os(){return`/**
2528
- * @${Re.slice(1)} \u2014 Supabase Storage wrapper.
2529
+ `}function Bi(){return`/**
2530
+ * @${Oe.slice(1)} \u2014 Supabase Storage wrapper.
2529
2531
  *
2530
2532
  * Docs: https://supabase.com/docs/guides/storage
2531
2533
  */
@@ -2587,8 +2589,8 @@ export async function getSignedUrl(
2587
2589
  }
2588
2590
 
2589
2591
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2590
- `}function Us(){return`/**
2591
- * @${Re.slice(1)} \u2014 \u963F\u91CC\u4E91 OSS wrapper via ali-oss.
2592
+ `}function Yi(){return`/**
2593
+ * @${Oe.slice(1)} \u2014 \u963F\u91CC\u4E91 OSS wrapper via ali-oss.
2592
2594
  *
2593
2595
  * Docs: https://help.aliyun.com/product/31815.html
2594
2596
  */
@@ -2634,8 +2636,8 @@ export async function getSignedUrl(
2634
2636
  }
2635
2637
 
2636
2638
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2637
- `}function Ls(){return`/**
2638
- * @${Re.slice(1)} \u2014 \u817E\u8BAF\u4E91 COS wrapper via cos-nodejs-sdk-v5.
2639
+ `}function $i(){return`/**
2640
+ * @${Oe.slice(1)} \u2014 \u817E\u8BAF\u4E91 COS wrapper via cos-nodejs-sdk-v5.
2639
2641
  *
2640
2642
  * Docs: https://cloud.tencent.com/document/product/436
2641
2643
  */
@@ -2689,8 +2691,8 @@ export async function getSignedUrl(
2689
2691
  }
2690
2692
 
2691
2693
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2692
- `}function Ms(){return`/**
2693
- * @${Re.slice(1)} \u2014 \u4E03\u725B\u4E91 Kodo wrapper.
2694
+ `}function qi(){return`/**
2695
+ * @${Oe.slice(1)} \u2014 \u4E03\u725B\u4E91 Kodo wrapper.
2694
2696
  *
2695
2697
  * Docs: https://developer.qiniu.com/kodo
2696
2698
  */
@@ -2757,9 +2759,9 @@ export async function getSignedUrl(
2757
2759
  }
2758
2760
 
2759
2761
  export type { UploadFileInput, UploadFileResult, SignedUrlOptions } from "./types.js";
2760
- `}function Ds(e){switch(e){case"r2":return ks();case"s3":return Ts();case"supabase-storage":return Os();case"aliyun-oss":return Us();case"tencent-cos":return Ls();case"qiniu":return Ms();case"none":return`export {};
2761
- `}}function Fs(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),(e.id==="r2"||e.id==="s3")&&(t["@aws-sdk/s3-request-presigner"]="^3.658.0");let o={name:Re,version:"0.1.0",private:!0,description:`Object storage via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2762
- `}async function xo(e,t,o){if(t==="none")return;let n=Ro(t);if(!n)throw new Error(`Unknown storage provider "${t}". Valid ids: ${lt.map(s=>s.id).join(", ")}`);let r=Ce.join(e,"packages","storage"),i=Ce.join(r,"src");we.existsSync(i)&&we.rmSync(i,{recursive:!0,force:!0}),Zt(Ce.join(r,"package.json"),Fs(n)),Zt(Ce.join(i,"types.ts"),Ns),Zt(Ce.join(i,"index.ts"),Ds(n.id)),Rs(e,xs(n))}var Nt=[{id:"svix",name:"Svix",region:"global",envVars:["SVIX_API_TOKEN"],docs:"https://docs.svix.com",description:"Managed webhooks platform"},{id:"custom",name:"Custom (self-hosted)",region:"both",envVars:["WEBHOOK_SIGNING_SECRET"],docs:"",description:"Custom implementation with built-in package"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function No(e){return Nt.find(t=>t.id===e)}var jp=Nt.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function ko(e,t,o="global"){let n=No(t);if(!n)throw new Error(`Unknown webhooks provider "${t}". Valid ids: ${Nt.map(r=>r.id).join(", ")}`);if(n.id==="none"){K(e,"webhooks");return}n.envVars.length>0&&q(e,{category:"Webhooks",name:n.name,envVars:n.envVars,docs:n.docs}),G(e,"WEBHOOKS_PROVIDER",n.id)}import xe from"fs";import dt from"path";function js(e){return`import Link from "next/link";
2762
+ `}function Gi(e){switch(e){case"r2":return Ki();case"s3":return Vi();case"supabase-storage":return Bi();case"aliyun-oss":return Yi();case"tencent-cos":return $i();case"qiniu":return qi();case"none":return`export {};
2763
+ `}}function Wi(e){let t={};e.pkg&&e.pkgVersion&&(t[e.pkg]=e.pkgVersion),(e.id==="r2"||e.id==="s3")&&(t["@aws-sdk/s3-request-presigner"]="^3.658.0");let o={name:Oe,version:"0.1.0",private:!0,description:`Object storage via ${e.name}`,type:"module",main:"./dist/index.js",exports:{".":{import:"./dist/index.js",types:"./dist/index.d.ts"}},scripts:{build:"tsup",typecheck:"tsc --noEmit",clean:"rm -rf dist .turbo"},dependencies:t,devDependencies:{tsup:"^8.5.0",typescript:"catalog:"}};return JSON.stringify(o,null,2)+`
2764
+ `}async function Mo(e,t,o){if(t==="none")return;let n=Lo(t);if(!n)throw new Error(`Unknown storage provider "${t}". Valid ids: ${mt.map(i=>i.id).join(", ")}`);let r=Ne.join(e,"packages","storage"),s=Ne.join(r,"src");Te.existsSync(s)&&Te.rmSync(s,{recursive:!0,force:!0}),rn(Ne.join(r,"package.json"),Wi(n)),rn(Ne.join(s,"types.ts"),Di),rn(Ne.join(s,"index.ts"),Gi(n.id)),ji(e,Fi(n))}function fe(e,t){if(e===void 0)return t;let o=String(e).trim().toLowerCase();return o==="true"||o==="1"||o==="yes"||o==="on"?!0:o==="false"||o==="0"||o==="no"||o==="off"?!1:t}function jo(e,t){let o=t==="cn";return{cronJobs:fe(e.cronJobs,!0),auditLog:fe(e.auditLog,!0),apiKeys:fe(e.apiKeys,!0),webhooks:fe(e.webhooks,!0),commandPalette:fe(e.commandPalette,!0),cookieConsent:fe(e.cookieConsent,!0),legalPages:fe(e.legalPages,!0),chinaCompliance:fe(e.chinaCompliance,o)}}var Ot=[{id:"svix",name:"Svix",region:"global",envVars:["SVIX_API_TOKEN"],docs:"https://docs.svix.com",description:"Managed webhooks platform"},{id:"custom",name:"Custom (self-hosted)",region:"both",envVars:["WEBHOOK_SIGNING_SECRET"],docs:"",description:"Custom implementation with built-in package"},{id:"none",name:"None",region:"both",envVars:[],docs:"",description:""}];function Fo(e){return Ot.find(t=>t.id===e)}var zp=Ot.reduce((e,t)=>(e[t.region]||(e[t.region]=[]),e[t.region].push(t),e),{});async function Do(e,t,o="global"){let n=Fo(t);if(!n)throw new Error(`Unknown webhooks provider "${t}". Valid ids: ${Ot.map(r=>r.id).join(", ")}`);if(n.id==="none"){Y(e,"webhooks");return}n.envVars.length>0&&W(e,{category:"Webhooks",name:n.name,envVars:n.envVars,docs:n.docs}),H(e,"WEBHOOKS_PROVIDER",n.id)}import Ue from"fs";import gt from"path";function Hi(e){return`import Link from "next/link";
2763
2765
 
2764
2766
  export default function WelcomePage() {
2765
2767
  const projectName = ${JSON.stringify(e)};
@@ -2868,16 +2870,21 @@ function Step({
2868
2870
  </li>
2869
2871
  );
2870
2872
  }
2871
- `}function Vs(e=[]){return e.length===0?"":`
2873
+ `}function Xi(e={}){return`
2874
+ ## What you can do next
2875
+
2876
+ ${[e.apiKeys===!1?"- Manage API keys at `/settings/api-keys` (disabled \u2014 re-enable with `--api-keys=true`)":"- Manage API keys at `/settings/api-keys`",e.auditLog===!1?"- View audit log at `/settings/audit-log` (disabled \u2014 re-enable with `--audit-log=true`)":"- View audit log at `/settings/audit-log`","- Configure webhooks at `/settings/webhooks`",e.commandPalette===!1?"- Press \u2318K to open the command palette (disabled \u2014 re-enable with `--command-palette=true`)":"- Press \u2318K to open the command palette","- Edit notification preferences at `/settings/notifications`","- Export your data at `/settings/account/export`","- For China deployments, see `packages/china-compliance/README.md`"].join(`
2877
+ `)}
2878
+ `}function zi(e=[]){return e.length===0?"":`
2872
2879
  ## Production readiness holds
2873
2880
 
2874
2881
  Do not enable these in production until you replace stubs, add provider credentials, and verify the integration contract:
2875
2882
 
2876
- ${e.map(o=>{let n=qe(o.status);return`- ${o.flag}=${o.provider} ${n} \u2014 ${te(o.status)}`}).join(`
2883
+ ${e.map(o=>{let n=ze(o.status);return`- ${o.flag}=${o.provider} ${n} \u2014 ${se(o.status)}`}).join(`
2877
2884
  `)}
2878
2885
 
2879
2886
  Review the package readiness matrix before handoff: [docs/package-status.md](docs/package-status.md)
2880
- `}function Ks(e,t,o=[]){return`# Next steps \u2014 ${e}
2887
+ `}function Ji(e,t,o=[],n={}){return`# Next steps \u2014 ${e}
2881
2888
 
2882
2889
  Region: ${t}
2883
2890
 
@@ -2903,33 +2910,33 @@ Your AI-native SaaS scaffold is ready. Complete these four steps to go from temp
2903
2910
  \`\`\`
2904
2911
 
2905
2912
  After setup, delete the welcome route at \`apps/web/src/app/[locale]/welcome/\`.
2906
- ${Vs(o)}
2913
+ ${Xi(n)}${zi(o)}
2907
2914
 
2908
2915
  ## Resources
2909
2916
 
2910
2917
  - [Documentation](/docs)
2911
2918
  - [GitHub](https://github.com/nebutra/nebutra-sailor)
2912
2919
  - [Get free license (Individual/OPC)](https://nebutra.com/get-license)
2913
- `}async function To(e,t){let{projectName:o,region:n,previewSelections:r=[]}=t;try{let i=dt.join(e,".sailor");xe.existsSync(i)||xe.mkdirSync(i,{recursive:!0}),xe.writeFileSync(dt.join(i,"next-steps.md"),Ks(o,n,r))}catch(i){let s=i instanceof Error?i.message:String(i);console.warn(`[create-sailor] Failed to write .sailor/next-steps.md: ${s}`)}try{let i=dt.join(e,"apps","web");if(!xe.existsSync(i))return;let s=dt.join(i,"src","app","[locale]","welcome");xe.existsSync(s)||xe.mkdirSync(s,{recursive:!0}),xe.writeFileSync(dt.join(s,"page.tsx"),js(o))}catch(i){let s=i instanceof Error?i.message:String(i);console.warn(`[create-sailor] Failed to write welcome page: ${s}`)}}var Oo="create-sailor";function p(e,t){e&&process.stdout.write(JSON.stringify(t)+`
2914
- `)}function $s(){let e=process.env.npm_config_user_agent??"";return e.startsWith("pnpm")?"pnpm":e.startsWith("yarn")?"yarn":e.startsWith("bun")?"bun":"npm"}function Uo(e){switch(e){case"postgres":case"postgresql":return"postgresql";case"mysql":return"mysql";case"sqlite":return"sqlite";case"none":return"none";default:return"postgresql"}}function Lo(e){return e==="drizzle"?"drizzle":e==="none"?"none":"prisma"}function Mo(e){return e==="lemon"||e==="lemonsqueezy"?"lemon":e==="wechat"?"wechat":e==="alipay"?"alipay":e==="none"?"none":"stripe"}function Do(e){if(!e)return"stripe";let t=e.toLowerCase();return t==="lemon"||t==="lemonsqueezy"?"lemon":t==="wechat"?"wechat":t==="alipay"?"alipay":t==="none"?"none":"stripe"}function Fo(e){if(!e)return"clerk";let t=e.toLowerCase();return t==="betterauth"||t==="better-auth"?"betterauth":t==="none"?"none":"clerk"}function jo(e){if(!e)return["openai"];let t=e.split(",").map(o=>o.trim().toLowerCase());return t.includes("none")?[]:t}function qs(e,t){let o=e??t;return Jt(o)??o}var Vo={mintlify:"Mintlify",docusaurus:"Docusaurus",nextra:"Nextra",vitepress:"VitePress"};function Ko(e,t){if(!e)return"fumadocs";let o=e.toLowerCase();if(o==="fumadocs"||o==="none")return o;if(o in Vo){let n=Vo[o];return t?p(!0,{event:"notice",kind:"docs-fallback",requested:o,effective:"fumadocs"}):process.stdout.write(w.yellow(`\u26A0 ${n} support is coming in v1.2. Falling back to fumadocs.
2915
- `)+w.dim(` Track progress: https://github.com/Nebutra/Nebutra-Sailor/issues
2916
- `)),"fumadocs"}return"fumadocs"}function Bo(e){switch(e){case"vercel":return"vercel";case"railway":return"railway";case"cloudflare":return"cloudflare";case"selfhost":return"selfhost";case"none":return"none";default:return"vercel"}}function Yo(e){if(!e)return"global";let t=e.toLowerCase();return t==="cn"?"cn":t==="hybrid"?"hybrid":"global"}function Gs(e){return{...e==="cn"?{email:"aliyun-dm",storage:"aliyun-oss",monitoring:"sentry",analytics:"baidu",sms:"aliyun-sms"}:e==="hybrid"?{email:"resend",storage:"aliyun-oss",monitoring:"sentry",analytics:"posthog",sms:"aliyun-sms"}:{email:"resend",storage:"r2",monitoring:"sentry",analytics:"posthog",sms:"twilio"},queue:"none",search:"none",cache:e==="global"?"upstash-redis":e==="cn"?"redis":"upstash-redis",notifications:"none",webhooks:"none",cms:"none",featureFlags:"none",captcha:e==="cn"?"aliyun-slide":"turnstile",mcp:"on",metering:"auto",billingMode:"usage",idp:"clerk"}}function $o(e){return e==="cn"?"wechat":"stripe"}async function Hs(){let e=new Bs;e.name(Oo).description("Nebutra-Sailor \u2014 AI-Native SaaS template").version(ee,"-v, --version").helpOption(!1).argument("[name]","project directory",void 0).option("-p, --pm <id>","npm | pnpm | yarn | bun").option("--region <id>","global | cn | hybrid").option("--orm <id>","prisma | drizzle | none").option("--db <id>","postgres | mysql | sqlite | none").option("--auth <id>","clerk | betterauth | none").option("--social-login <ids>","CN social login providers \u2014 wechat | qq | dingtalk | workweixin | feishu | weibo (comma-separated)").option("--payment <id>","stripe | lemon | wechat | alipay | none").option("--ai <ids>","expert: comma-separated provider ids used as an AI provider seed").option("--deploy <target>","vercel | railway | cloudflare | selfhost").option("--docs <id>","fumadocs | mintlify | docusaurus | nextra | vitepress | none").option("--email <id>","resend | postmark | ses | aliyun-dm | tencent-ses | netease | none").option("--storage <id>","r2 | s3 | supabase-storage | aliyun-oss | tencent-cos | qiniu | none").option("--monitoring <id>","sentry | datadog | aliyun-arms | tingyun | none").option("--analytics <id>","posthog | plausible | umami | baidu | sensors | none").option("--sms <id>","twilio | aliyun-sms | tencent-sms | yunpian | none").option("--queue <id>","qstash | bullmq | upstash | sqs | none").option("--search <id>","meilisearch | typesense | algolia | pgvector | none").option("--cache <id>","upstash-redis | vercel-kv | redis | dragonfly | none").option("--notifications <id>","novu | knock | custom | none").option("--webhooks <id>","svix | custom | none").option("--cms <id>","sanity | contentful | strapi | none").option("--feature-flags <id>","vercel-flags | growthbook | configcat | none").option("--captcha <id>","turnstile | hcaptcha | aliyun-slide | none").option("--mcp <mode>","on | off (default: on)").option("--metering <mode>","auto | on | off (default: auto \u2014 auto-on when payment is set)").option("--billing-mode <mode>","usage | seat | credits (default: usage)").option("--idp <id>","clerk | oauth-server (default: clerk)").option("--i18n","enable i18n").option("--no-i18n","disable i18n").option("--no-install","skip package install").option("--no-git","skip git init").option("-y, --yes","accept all defaults (non-interactive)").option("--dry-run","preview actions without writing files").option("--json","machine-readable output").option("--no-color","disable color output").option("-h, --help","show help"),e.parse(process.argv);let t=e.opts(),[o]=e.args;t.help&&(an(),process.exit(0));let n=!!t.json,r=!!t.dryRun,i=!!t.yes,s=i||!process.stdin.isTTY;n||on(),p(n,{event:"start",version:ee});let c=o??(i?"./my-saas-app":void 0),a;if(c)a=c;else if(s)a="./my-saas-app";else{let m=await C.group({name:()=>C.text({message:"Where should we create your project?",placeholder:"./my-saas-app",defaultValue:"./my-saas-app",validate:f=>{if(f.length===0)return"Please enter a path."}})},{onCancel:()=>{process.stdout.write(w.red(`\u2718 Cancelled
2917
- `)),process.exit(130)}});a=String(m.name)}let d=ut.basename(ut.resolve(a)),u=t.pm??$s(),h=!!t.region,O=!!t.auth,M=!!t.payment,D=!!t.ai,Xe=!!t.email,v=!!t.storage,l=!!t.monitoring,R=!!t.analytics,mt=!!t.sms,en=t.i18n!==void 0,y,ze,X,Qe,F,N,Y=En(t.socialLogin),Je,Tt,ue,Ne,z,j,gt;if(s){y=Yo(t.region),ze=Lo(t.orm),X=Uo(t.db);let m=M?t.payment:$o(y);Qe=Mo(m),F=Do(m),N=Fo(t.auth);let f=Dt({mode:D?t.ai?.trim().toLowerCase()==="none"?"none":"direct":"gateway",providerIds:D?jo(t.ai):void 0});Je=f.mode,Tt=f.routing,ue=f.providerIds,z=Bo(t.deploy),j=Ko(t.docs,n),gt=en?!!t.i18n:!0}else{let m={};h||(m.region=()=>C.select({message:"Target region?",options:[{value:"global",label:"global \u2014 \u6D77\u5916\u4F18\u5148"},{value:"cn",label:"cn \u2014 \u56FD\u5185\u4F18\u5148"},{value:"hybrid",label:"hybrid \u2014 \u53CC\u8F68\uFF08\u56FD\u5185+\u51FA\u6D77\uFF09"}],initialValue:"global"})),O||(m.auth=()=>C.select({message:"Auth provider?",options:[{value:"clerk",label:"Clerk"},{value:"betterauth",label:"Better Auth"},{value:"none",label:"None"}],initialValue:"clerk"})),D||(m.aiMode=()=>C.select({message:"AI topology?",options:[{value:"gateway",label:"Multi-provider AI Gateway / router",hint:"recommended"},{value:"direct",label:"Direct SDK/provider adapters"},{value:"custom",label:"OpenAI-compatible endpoint"},{value:"none",label:"Skip AI"}],initialValue:"gateway"}),m.aiProviders=({results:E})=>{if(E.aiMode!=="direct")return Promise.resolve([]);let Q=Mt.map(Ut=>({value:Ut.id,label:`[${Ut.category}] ${Ut.name}`}));return C.multiselect({message:"Select direct AI provider adapters (expert path)",options:Q,initialValues:["openai"],required:!1})},m.customAiName=({results:E})=>E.aiMode==="custom"?C.text({message:"Custom endpoint name (e.g. proxy, local):",defaultValue:"custom",placeholder:"custom"}):Promise.resolve(void 0),m.customAiBaseUrl=({results:E})=>E.aiMode==="custom"?C.text({message:"Custom endpoint base URL (e.g. https://api.proxy.com/v1):",validate:Q=>{if(Q.length===0)return"Base URL is required."}}):Promise.resolve(void 0),m.customAiApiKeyEnv=({results:E})=>E.aiMode==="custom"?C.text({message:"Environment variable name for the API Key:",defaultValue:"CUSTOM_AI_API_KEY",placeholder:"CUSTOM_AI_API_KEY"}):Promise.resolve(void 0));let f=Object.keys(m).length>0?await C.group(m,{onCancel:()=>{process.stdout.write(w.red(`\u2718 Cancelled
2918
- `)),process.exit(130)}}):{};y=Yo(h?t.region:f.region),ze=Lo(t.orm),X=Uo(t.db);let V=M?t.payment:$o(y);Qe=Mo(V),F=Do(V),N=Fo(O?t.auth:f.auth);let St=f.aiMode==="custom"?{name:f.customAiName??"custom",baseURL:f.customAiBaseUrl??"",apiKeyEnvName:f.customAiApiKeyEnv??"CUSTOM_AI_API_KEY"}:void 0,S=Dt({mode:D?t.ai?.trim().toLowerCase()==="none"?"none":"direct":f.aiMode??"gateway",providerIds:D?jo(t.ai):f.aiProviders,customEndpoint:St});Je=S.mode,Tt=S.routing,ue=S.providerIds,S.customEndpoint&&(Ne={name:S.customEndpoint.name,baseURL:S.customEndpoint.baseURL,apiKeyEnvName:S.customEndpoint.apiKeyEnvName}),z=Bo(t.deploy),j=Ko(t.docs,n),gt=en?!!t.i18n:!0}let b=Gs(y),ke=Xe?t.email:b.email,Te=qs(v?t.storage:void 0,b.storage),Oe=l?t.monitoring:b.monitoring,Ue=R?t.analytics:b.analytics,Le=mt?t.sms:b.sms,Me=t.queue??b.queue,De=t.search??b.search,Ze=t.cache??b.cache,Fe=t.notifications??b.notifications,je=t.webhooks??b.webhooks,et=t.cms??b.cms,Ve=t.featureFlags??b.featureFlags,Ke=t.captcha??b.captcha,ft=t.mcp??b.mcp,tt=t.metering??b.metering,Be=t.billingMode??b.billingMode,Ye=t.idp??b.idp,$e=rn([{flag:"queue",provider:Me},{flag:"search",provider:De},{flag:"notifications",provider:Fe},{flag:"webhooks",provider:je},{flag:"feature-flags",provider:Ve},{flag:"captcha",provider:Ke}]);function Ot(){for(let m of $e)if(n)p(!0,{event:"warn",step:m.flag,provider:m.provider,packageStatus:m.status,message:te(m.status)});else{let f=qe(m.status);process.stdout.write(w.yellow(`\u26A0 ${m.flag}=${m.provider} ${f} \u2014 ${te(m.status)}
2919
- `))}}let me={region:y,orm:ze,database:X,payment:Qe,aiMode:Je,aiRouting:Tt,aiProviders:ue,customAiEndpoint:Ne,deployTarget:z,docs:j,i18n:gt,email:ke,storage:Te,monitoring:Oe,analytics:Ue,sms:Le,queue:Me,search:De,cache:Ze,notifications:Fe,webhooks:je,cms:et,featureFlags:Ve,captcha:Ke,mcp:ft,metering:tt,billingMode:Be,idp:Ye},yt=[["Project name",d],["Region",y],["Auth",N],["Social login",Y.length>0?Y.map(m=>nt.find(f=>f.id===m)?.name??m).join(", "):"none"],["ORM",ze],["Database",X],["Payment",F],["AI topology",`${Je}${ue.length>0?` (${ue.join(", ")} seed)`:""}${Ne?" + custom endpoint":""}`],["Email",ke],["Storage",Te],["Monitoring",Oe],["Analytics",Ue],["SMS",Le],["Deploy Target",z],["Docs Framework",j]];n?yt.forEach(([m,f],V)=>{p(!0,{event:"step",step:m,value:f,index:V+1,total:yt.length})}):yt.forEach(([m,f],V)=>{pn({index:V+1,total:yt.length,label:m,value:f})});let qo={databaseUrl:"postgresql://postgres:postgres@localhost:5432/nebutra",clerkPublishable:"",clerkSecret:""},tn=Date.now();if(r){let m=ue.length,f=[`clone template \u2192 ${a}`,"write nebutra.config.json",`prune template (orm=${ze}, i18n=${gt})`,`region \u2192 ${y}`,`auth \u2192 ${N==="none"?"skip (remove packages/auth)":`configure ${N}`}`,...Y.length>0?[`social-login \u2192 generate ${Y.length} callback route${Y.length===1?"":"s"} + SocialLoginButtons.tsx (${Y.join(", ")})`]:[],`db \u2192 ${X==="none"?"skip (remove packages/db)":`configure Prisma for ${X}`}`,`payment \u2192 ${F==="none"?"skip (remove packages/billing)":`configure ${F}`}`,...j!=="none"?[`docs \u2192 scaffold apps/docs (${j==="fumadocs"?"fumadocs":`${j} \u2192 fumadocs fallback`})`]:[],...m>0||Ne?[`ai-providers \u2192 generate ${Je} registry seed + env (${m}${Ne?" + custom":""} provider${m===1&&!Ne?"":"s"})`]:[],...ke!=="none"?[`email \u2192 configure ${ke}`]:[],...Te!=="none"?[`storage \u2192 configure ${Te}`]:[],...Oe!=="none"?[`monitoring \u2192 configure ${Oe}`]:[],...Ue!=="none"?[`analytics \u2192 configure ${Ue}`]:[],...Le!=="none"?[`sms \u2192 configure ${Le}`]:[],...Me!=="none"?[`queue \u2192 configure ${Me}`]:[],...De!=="none"?[`search \u2192 configure ${De}`]:[],...Ze!=="none"?[`cache \u2192 configure ${Ze}`]:[],...Fe!=="none"?[`notifications \u2192 configure ${Fe}`]:[],...je!=="none"?[`webhooks \u2192 configure ${je}`]:[],...et!=="none"?[`cms \u2192 configure ${et}`]:[],...Ve!=="none"?[`feature-flags \u2192 configure ${Ve}`]:[],...Ke!=="none"?[`captcha \u2192 configure ${Ke}`]:[],`mcp \u2192 ${ft==="on"?"enable MCP server":"remove packages/mcp"}`,`metering \u2192 ${tt==="off"?"disabled":tt==="auto"?Qe!=="none"?"enabled (auto: payment set)":"disabled (auto: no payment)":"enabled"}`,...Be!=="usage"?[`billing-mode \u2192 ${Be}`]:[],...Ye!=="clerk"?[`idp \u2192 ${Ye}`]:[],`compliance \u2192 inject ${y} boilerplate (ICP/Cookie/AIGC/Privacy)`,"welcome \u2192 generate dev welcome page","env \u2192 generate random secrets (AUTH_SECRET, JWT_SECRET)","seed \u2192 generate prisma/seed.ts (1 admin + 3 tenants)",...z!=="none"?[`deploy \u2192 inject ${z} config`]:[],"inject .env.local",t.install===!1?"skip install":`run ${u} install`,t.git===!1?"skip git init":"run git init"];if(n){for(let V of f)p(!0,{event:"plan",action:V});Ot(),p(!0,{event:"done",dryRun:!0})}else{process.stdout.write(`
2920
- `+w.bold(`Dry run \u2014 planned actions:
2921
- `));for(let V of f)process.stdout.write(` \u2022 ${V}
2922
- `);$e.length>0&&(process.stdout.write(`
2923
- `+w.bold(w.yellow(`Preview-status providers selected:
2924
- `))),Ot()),process.stdout.write(w.dim(`
2920
+ `}async function Ko(e,t){let{projectName:o,region:n,previewSelections:r=[],waveFeatures:s={}}=t;try{let i=gt.join(e,".sailor");Ue.existsSync(i)||Ue.mkdirSync(i,{recursive:!0}),Ue.writeFileSync(gt.join(i,"next-steps.md"),Ji(o,n,r,s))}catch(i){let c=i instanceof Error?i.message:String(i);console.warn(`[create-sailor] Failed to write .sailor/next-steps.md: ${c}`)}try{let i=gt.join(e,"apps","web");if(!Ue.existsSync(i))return;let c=gt.join(i,"src","app","[locale]","welcome");Ue.existsSync(c)||Ue.mkdirSync(c,{recursive:!0}),Ue.writeFileSync(gt.join(c,"page.tsx"),Hi(o))}catch(i){let c=i instanceof Error?i.message:String(i);console.warn(`[create-sailor] Failed to write welcome page: ${c}`)}}var Vo="create-sailor";function p(e,t){e&&process.stdout.write(JSON.stringify(t)+`
2921
+ `)}function ea(){let e=process.env.npm_config_user_agent??"";return e.startsWith("pnpm")?"pnpm":e.startsWith("yarn")?"yarn":e.startsWith("bun")?"bun":"npm"}function Bo(e){switch(e){case"postgres":case"postgresql":return"postgresql";case"mysql":return"mysql";case"sqlite":return"sqlite";case"none":return"none";default:return"postgresql"}}function Yo(e){return e==="drizzle"?"drizzle":e==="none"?"none":"prisma"}function $o(e){return e==="lemon"||e==="lemonsqueezy"?"lemon":e==="wechat"?"wechat":e==="alipay"?"alipay":e==="none"?"none":"stripe"}function qo(e){if(!e)return"stripe";let t=e.toLowerCase();return t==="lemon"||t==="lemonsqueezy"?"lemon":t==="wechat"?"wechat":t==="alipay"?"alipay":t==="none"?"none":"stripe"}function Go(e){if(!e)return"clerk";let t=e.toLowerCase();return t==="betterauth"||t==="better-auth"?"betterauth":t==="none"?"none":"clerk"}function Wo(e){if(!e)return["openai"];let t=e.split(",").map(o=>o.trim().toLowerCase());return t.includes("none")?[]:t}function ta(e,t){let o=e??t;return on(o)??o}var Ho={mintlify:"Mintlify",docusaurus:"Docusaurus",nextra:"Nextra",vitepress:"VitePress"};function Xo(e,t){if(!e)return"fumadocs";let o=e.toLowerCase();if(o==="fumadocs"||o==="none")return o;if(o in Ho){let n=Ho[o];return t?p(!0,{event:"notice",kind:"docs-fallback",requested:o,effective:"fumadocs"}):process.stdout.write(N.yellow(`\u26A0 ${n} support is coming in v1.2. Falling back to fumadocs.
2922
+ `)+N.dim(` Track progress: https://github.com/Nebutra/Nebutra-Sailor/issues
2923
+ `)),"fumadocs"}return"fumadocs"}function zo(e){switch(e){case"vercel":return"vercel";case"railway":return"railway";case"cloudflare":return"cloudflare";case"selfhost":return"selfhost";case"none":return"none";default:return"vercel"}}function Jo(e){if(!e)return"global";let t=e.toLowerCase();return t==="cn"?"cn":t==="hybrid"?"hybrid":"global"}function na(e){return{...e==="cn"?{email:"aliyun-dm",storage:"aliyun-oss",monitoring:"sentry",analytics:"baidu",sms:"aliyun-sms"}:e==="hybrid"?{email:"resend",storage:"aliyun-oss",monitoring:"sentry",analytics:"posthog",sms:"aliyun-sms"}:{email:"resend",storage:"r2",monitoring:"sentry",analytics:"posthog",sms:"twilio"},queue:"none",search:"none",cache:e==="global"?"upstash-redis":e==="cn"?"redis":"upstash-redis",notifications:"none",webhooks:"none",cms:"none",featureFlags:"none",captcha:e==="cn"?"aliyun-slide":"turnstile",mcp:"on",metering:"auto",billingMode:"usage",idp:"clerk"}}function Qo(e){return e==="cn"?"wechat":"stripe"}async function oa(){let e=new Qi;e.name(Vo).description("Nebutra-Sailor \u2014 AI-Native SaaS template").version(re,"-v, --version").helpOption(!1).argument("[name]","project directory",void 0).option("-p, --pm <id>","npm | pnpm | yarn | bun").option("--region <id>","global | cn | hybrid").option("--orm <id>","prisma | drizzle | none").option("--db <id>","postgres | mysql | sqlite | none").option("--auth <id>","clerk | betterauth | none").option("--social-login <ids>","CN social login providers \u2014 wechat | qq | dingtalk | workweixin | feishu | weibo (comma-separated)").option("--payment <id>","stripe | lemon | wechat | alipay | none").option("--ai <ids>","expert: comma-separated provider ids used as an AI provider seed").option("--deploy <target>","vercel | railway | cloudflare | selfhost").option("--docs <id>","fumadocs | mintlify | docusaurus | nextra | vitepress | none").option("--email <id>","resend | postmark | ses | aliyun-dm | tencent-ses | netease | none").option("--storage <id>","r2 | s3 | supabase-storage | aliyun-oss | tencent-cos | qiniu | none").option("--monitoring <id>","sentry | datadog | aliyun-arms | tingyun | none").option("--analytics <id>","posthog | plausible | umami | baidu | sensors | none").option("--sms <id>","twilio | aliyun-sms | tencent-sms | yunpian | none").option("--queue <id>","qstash | bullmq | upstash | sqs | none").option("--search <id>","meilisearch | typesense | algolia | pgvector | none").option("--cache <id>","upstash-redis | vercel-kv | redis | dragonfly | none").option("--notifications <id>","novu | knock | custom | none").option("--webhooks <id>","svix | custom | none").option("--cms <id>","sanity | contentful | strapi | none").option("--feature-flags <id>","vercel-flags | growthbook | configcat | none").option("--captcha <id>","turnstile | hcaptcha | aliyun-slide | none").option("--mcp <mode>","on | off (default: on)").option("--metering <mode>","auto | on | off (default: auto \u2014 auto-on when payment is set)").option("--billing-mode <mode>","usage | seat | credits (default: usage)").option("--idp <id>","clerk | oauth-server (default: clerk)").option("--cron-jobs <bool>","true | false \u2014 scaffold scheduled cron handlers (default: true)").option("--audit-log <bool>","true | false \u2014 enable /settings/audit-log + arch test (default: true)").option("--api-keys <bool>","true | false \u2014 enable /settings/api-keys page (default: true)").option("--command-palette <bool>","true | false \u2014 enable \u2318K command palette (default: true)").option("--cookie-consent <bool>","true | false \u2014 enable GDPR/CCPA cookie banner (default: true)").option("--legal-pages <bool>","true | false \u2014 enable dynamic /legal/[slug] route (default: true)").option("--china-compliance <bool>","true | false \u2014 enable @nebutra/china-compliance + ICP footer (default: true when --region=cn, otherwise false)").option("--i18n","enable i18n").option("--no-i18n","disable i18n").option("--no-install","skip package install").option("--no-git","skip git init").option("-y, --yes","accept all defaults (non-interactive)").option("--dry-run","preview actions without writing files").option("--json","machine-readable output").option("--no-color","disable color output").option("-h, --help","show help"),e.parse(process.argv);let t=e.opts(),[o]=e.args;t.help&&(un(),process.exit(0));let n=!!t.json,r=!!t.dryRun,s=!!t.yes,i=s||!process.stdin.isTTY;n||pn(),p(n,{event:"start",version:re});let c=o??(s?"./my-saas-app":void 0),a;if(c)a=c;else if(i)a="./my-saas-app";else{let g=await R.group({name:()=>R.text({message:"Where should we create your project?",placeholder:"./my-saas-app",defaultValue:"./my-saas-app",validate:S=>{if(S.length===0)return"Please enter a path."}})},{onCancel:()=>{process.stdout.write(N.red(`\u2718 Cancelled
2924
+ `)),process.exit(130)}});a=String(g.name)}let l=ft.basename(ft.resolve(a)),m=t.pm??ea(),y=!!t.region,k=!!t.auth,x=!!t.payment,L=!!t.ai,oe=!!t.email,b=!!t.storage,u=!!t.monitoring,T=!!t.analytics,yt=!!t.sms,sn=t.i18n!==void 0,h,Ze,J,et,K,M,q=Pn(t.socialLogin),tt,Lt,Se,Le,Q,V,St;if(i){h=Jo(t.region),Ze=Yo(t.orm),J=Bo(t.db);let g=x?t.payment:Qo(h);et=$o(g),K=qo(g),M=Go(t.auth);let S=Kt({mode:L?t.ai?.trim().toLowerCase()==="none"?"none":"direct":"gateway",providerIds:L?Wo(t.ai):void 0});tt=S.mode,Lt=S.routing,Se=S.providerIds,Q=zo(t.deploy),V=Xo(t.docs,n),St=sn?!!t.i18n:!0}else{let g={};y||(g.region=()=>R.select({message:"Target region?",options:[{value:"global",label:"global \u2014 \u6D77\u5916\u4F18\u5148"},{value:"cn",label:"cn \u2014 \u56FD\u5185\u4F18\u5148"},{value:"hybrid",label:"hybrid \u2014 \u53CC\u8F68\uFF08\u56FD\u5185+\u51FA\u6D77\uFF09"}],initialValue:"global"})),k||(g.auth=()=>R.select({message:"Auth provider?",options:[{value:"clerk",label:"Clerk"},{value:"betterauth",label:"Better Auth"},{value:"none",label:"None"}],initialValue:"clerk"})),L||(g.aiMode=()=>R.select({message:"AI topology?",options:[{value:"gateway",label:"Multi-provider AI Gateway / router",hint:"recommended"},{value:"direct",label:"Direct SDK/provider adapters"},{value:"custom",label:"OpenAI-compatible endpoint"},{value:"none",label:"Skip AI"}],initialValue:"gateway"}),g.aiProviders=({results:_})=>{if(_.aiMode!=="direct")return Promise.resolve([]);let Z=Dt.map(jt=>({value:jt.id,label:`[${jt.category}] ${jt.name}`}));return R.multiselect({message:"Select direct AI provider adapters (expert path)",options:Z,initialValues:["openai"],required:!1})},g.customAiName=({results:_})=>_.aiMode==="custom"?R.text({message:"Custom endpoint name (e.g. proxy, local):",defaultValue:"custom",placeholder:"custom"}):Promise.resolve(void 0),g.customAiBaseUrl=({results:_})=>_.aiMode==="custom"?R.text({message:"Custom endpoint base URL (e.g. https://api.proxy.com/v1):",validate:Z=>{if(Z.length===0)return"Base URL is required."}}):Promise.resolve(void 0),g.customAiApiKeyEnv=({results:_})=>_.aiMode==="custom"?R.text({message:"Environment variable name for the API Key:",defaultValue:"CUSTOM_AI_API_KEY",placeholder:"CUSTOM_AI_API_KEY"}):Promise.resolve(void 0));let S=Object.keys(g).length>0?await R.group(g,{onCancel:()=>{process.stdout.write(N.red(`\u2718 Cancelled
2925
+ `)),process.exit(130)}}):{};h=Jo(y?t.region:S.region),Ze=Yo(t.orm),J=Bo(t.db);let B=x?t.payment:Qo(h);et=$o(B),K=qo(B),M=Go(k?t.auth:S.auth);let vt=S.aiMode==="custom"?{name:S.customAiName??"custom",baseURL:S.customAiBaseUrl??"",apiKeyEnvName:S.customAiApiKeyEnv??"CUSTOM_AI_API_KEY"}:void 0,v=Kt({mode:L?t.ai?.trim().toLowerCase()==="none"?"none":"direct":S.aiMode??"gateway",providerIds:L?Wo(t.ai):S.aiProviders,customEndpoint:vt});tt=v.mode,Lt=v.routing,Se=v.providerIds,v.customEndpoint&&(Le={name:v.customEndpoint.name,baseURL:v.customEndpoint.baseURL,apiKeyEnvName:v.customEndpoint.apiKeyEnvName}),Q=zo(t.deploy),V=Xo(t.docs,n),St=sn?!!t.i18n:!0}let I=na(h),Me=oe?t.email:I.email,je=ta(b?t.storage:void 0,I.storage),Fe=u?t.monitoring:I.monitoring,De=T?t.analytics:I.analytics,Ke=yt?t.sms:I.sms,Ve=t.queue??I.queue,Be=t.search??I.search,nt=t.cache??I.cache,Ye=t.notifications??I.notifications,$e=t.webhooks??I.webhooks,ot=t.cms??I.cms,qe=t.featureFlags??I.featureFlags,Ge=t.captcha??I.captcha,ht=t.mcp??I.mcp,rt=t.metering??I.metering,We=t.billingMode??I.billingMode,He=t.idp??I.idp,C=jo({cronJobs:t.cronJobs,auditLog:t.auditLog,apiKeys:t.apiKeys,commandPalette:t.commandPalette,cookieConsent:t.cookieConsent,legalPages:t.legalPages,chinaCompliance:t.chinaCompliance},h),Xe=ln([{flag:"queue",provider:Ve},{flag:"search",provider:Be},{flag:"notifications",provider:Ye},{flag:"webhooks",provider:$e},{flag:"feature-flags",provider:qe},{flag:"captcha",provider:Ge}]);function Mt(){for(let g of Xe)if(n)p(!0,{event:"warn",step:g.flag,provider:g.provider,packageStatus:g.status,message:se(g.status)});else{let S=ze(g.status);process.stdout.write(N.yellow(`\u26A0 ${g.flag}=${g.provider} ${S} \u2014 ${se(g.status)}
2926
+ `))}}let he={region:h,orm:Ze,database:J,payment:et,aiMode:tt,aiRouting:Lt,aiProviders:Se,customAiEndpoint:Le,deployTarget:Q,docs:V,i18n:St,email:Me,storage:je,monitoring:Fe,analytics:De,sms:Ke,queue:Ve,search:Be,cache:nt,notifications:Ye,webhooks:$e,cms:ot,featureFlags:qe,captcha:Ge,mcp:ht,metering:rt,billingMode:We,idp:He,cronJobs:C.cronJobs,auditLog:C.auditLog,apiKeys:C.apiKeys,commandPalette:C.commandPalette,cookieConsent:C.cookieConsent,legalPages:C.legalPages,chinaCompliance:C.chinaCompliance},Et=[["Project name",l],["Region",h],["Auth",M],["Social login",q.length>0?q.map(g=>st.find(S=>S.id===g)?.name??g).join(", "):"none"],["ORM",Ze],["Database",J],["Payment",K],["AI topology",`${tt}${Se.length>0?` (${Se.join(", ")} seed)`:""}${Le?" + custom endpoint":""}`],["Email",Me],["Storage",je],["Monitoring",Fe],["Analytics",De],["SMS",Ke],["Deploy Target",Q],["Docs Framework",V]];n?Et.forEach(([g,S],B)=>{p(!0,{event:"step",step:g,value:S,index:B+1,total:Et.length})}):Et.forEach(([g,S],B)=>{gn({index:B+1,total:Et.length,label:g,value:S})});let Zo={databaseUrl:"postgresql://postgres:postgres@localhost:5432/nebutra",clerkPublishable:"",clerkSecret:""},an=Date.now();if(r){let g=Se.length,S=[`clone template \u2192 ${a}`,"write nebutra.config.json",`prune template (orm=${Ze}, i18n=${St})`,`region \u2192 ${h}`,`auth \u2192 ${M==="none"?"skip (remove packages/auth)":`configure ${M}`}`,...q.length>0?[`social-login \u2192 generate ${q.length} callback route${q.length===1?"":"s"} + SocialLoginButtons.tsx (${q.join(", ")})`]:[],`db \u2192 ${J==="none"?"skip (remove packages/db)":`configure Prisma for ${J}`}`,`payment \u2192 ${K==="none"?"skip (remove packages/billing)":`configure ${K}`}`,...V!=="none"?[`docs \u2192 scaffold apps/docs (${V==="fumadocs"?"fumadocs":`${V} \u2192 fumadocs fallback`})`]:[],...g>0||Le?[`ai-providers \u2192 generate ${tt} registry seed + env (${g}${Le?" + custom":""} provider${g===1&&!Le?"":"s"})`]:[],...Me!=="none"?[`email \u2192 configure ${Me}`]:[],...je!=="none"?[`storage \u2192 configure ${je}`]:[],...Fe!=="none"?[`monitoring \u2192 configure ${Fe}`]:[],...De!=="none"?[`analytics \u2192 configure ${De}`]:[],...Ke!=="none"?[`sms \u2192 configure ${Ke}`]:[],...Ve!=="none"?[`queue \u2192 configure ${Ve}`]:[],...Be!=="none"?[`search \u2192 configure ${Be}`]:[],...nt!=="none"?[`cache \u2192 configure ${nt}`]:[],...Ye!=="none"?[`notifications \u2192 configure ${Ye}`]:[],...$e!=="none"?[`webhooks \u2192 configure ${$e}`]:[],...ot!=="none"?[`cms \u2192 configure ${ot}`]:[],...qe!=="none"?[`feature-flags \u2192 configure ${qe}`]:[],...Ge!=="none"?[`captcha \u2192 configure ${Ge}`]:[],`mcp \u2192 ${ht==="on"?"enable MCP server":"remove packages/mcp"}`,`metering \u2192 ${rt==="off"?"disabled":rt==="auto"?et!=="none"?"enabled (auto: payment set)":"disabled (auto: no payment)":"enabled"}`,...We!=="usage"?[`billing-mode \u2192 ${We}`]:[],...He!=="clerk"?[`idp \u2192 ${He}`]:[],`cron-jobs \u2192 ${C.cronJobs?"enabled":"disabled"}`,`audit-log \u2192 ${C.auditLog?"enabled":"disabled"}`,`api-keys \u2192 ${C.apiKeys?"enabled":"disabled"}`,`command-palette \u2192 ${C.commandPalette?"enabled":"disabled"}`,`cookie-consent \u2192 ${C.cookieConsent?"enabled":"disabled"}`,`legal-pages \u2192 ${C.legalPages?"enabled":"disabled"}`,`china-compliance \u2192 ${C.chinaCompliance?"enabled (@nebutra/china-compliance + ICP footer)":"disabled"}`,`compliance \u2192 inject ${h} boilerplate (ICP/Cookie/AIGC/Privacy)`,"welcome \u2192 generate dev welcome page","env \u2192 generate random secrets (AUTH_SECRET, JWT_SECRET)","seed \u2192 generate prisma/seed.ts (1 admin + 3 tenants)",...Q!=="none"?[`deploy \u2192 inject ${Q} config`]:[],"inject .env.local",t.install===!1?"skip install":`run ${m} install`,t.git===!1?"skip git init":"run git init"];if(n){for(let B of S)p(!0,{event:"plan",action:B});Mt(),p(!0,{event:"done",dryRun:!0})}else{process.stdout.write(`
2927
+ `+N.bold(`Dry run \u2014 planned actions:
2928
+ `));for(let B of S)process.stdout.write(` \u2022 ${B}
2929
+ `);Xe.length>0&&(process.stdout.write(`
2930
+ `+N.bold(N.yellow(`Preview-status providers selected:
2931
+ `))),Mt()),process.stdout.write(N.dim(`
2925
2932
  No files were written.
2926
- `))}process.exit(0)}let Go=async()=>{process.stdout.write(`
2927
- `+w.red(`\u2718 Cancelled
2928
- `)),de.existsSync(a)&&await C.confirm({message:`Cleanup partial install at ${a}?`,initialValue:!0})===!0&&(de.rmSync(a,{recursive:!0,force:!0}),process.stdout.write(w.dim(` \u2713 Removed ${a}
2929
- `))),process.exit(130)};process.on("SIGINT",Go);try{p(n,{event:"step",step:"clone",status:"start"}),await Zn(a),p(n,{event:"step",step:"clone",status:"ok"}),p(n,{event:"step",step:"package",status:"start"}),await co(a,d),p(n,{event:"step",step:"package",status:"ok"}),p(n,{event:"step",step:"config",status:"start"}),await xn(a,me),p(n,{event:"step",step:"config",status:"ok"}),p(n,{event:"step",step:"prune",status:"start"}),await Eo(a,me),p(n,{event:"step",step:"prune",status:"ok"});let m=ut.join(a,"packages/db/prisma/schema.prisma");if(de.existsSync(m)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let S=de.readFileSync(m,"utf-8"),E=Wt(S,{auth:N,payment:F,"billing-mode":Be,idp:Ye,template:"saas"});de.writeFileSync(m,E),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(S){let E=S instanceof Error?S.message:String(S);p(n,{event:"step",step:"schema-prune",status:"error",error:E})}}else p(n,{event:"step",step:"schema-prune",status:"skip"});if(p(n,{event:"step",step:"auth",choice:N,status:"start"}),await yn(a,N),p(n,{event:"step",step:"auth",choice:N,status:"ok"}),Y.length>0?(p(n,{event:"step",step:"social-login",providers:Y,status:"start"}),await vn(a,Y,N),p(n,{event:"step",step:"social-login",providers:Y,status:"ok"})):p(n,{event:"step",step:"social-login",status:"skip"}),p(n,{event:"step",step:"db",choice:X,status:"start"}),await Tn(a,X,d),p(n,{event:"step",step:"db",choice:X,status:"ok"}),p(n,{event:"step",step:"payment",choice:F,status:"start"}),await lo(a,F),p(n,{event:"step",step:"payment",choice:F,status:"ok"}),await jn(a,ke,y),n&&p(!0,{event:"step",step:"email",choice:ke,status:"ok"}),await xo(a,Te,y),n&&p(!0,{event:"step",step:"storage",choice:Te,status:"ok"}),await io(a,Oe,y),n&&p(!0,{event:"step",step:"monitoring",choice:Oe,status:"ok"}),await un(a,Ue,y),n&&p(!0,{event:"step",step:"analytics",choice:Ue,status:"ok"}),await wo(a,Le,y),n&&p(!0,{event:"step",step:"sms",choice:Le,status:"ok"}),await _o(a,Me,y),n&&p(!0,{event:"step",step:"queue",choice:Me,status:"ok"}),await Io(a,De,y),n&&p(!0,{event:"step",step:"search",choice:De,status:"ok"}),await bn(a,Ze,y),n&&p(!0,{event:"step",step:"cache",choice:Ze,status:"ok"}),await ao(a,Fe,y),n&&p(!0,{event:"step",step:"notifications",choice:Fe,status:"ok"}),await ko(a,je,y),n&&p(!0,{event:"step",step:"webhooks",choice:je,status:"ok"}),await wn(a,et,y),n&&p(!0,{event:"step",step:"cms",choice:et,status:"ok"}),await Gn(a,Ve,y),n&&p(!0,{event:"step",step:"feature-flags",choice:Ve,status:"ok"}),await An(a,Ke,y),n&&p(!0,{event:"step",step:"captcha",choice:Ke,status:"ok"}),await eo(a,ft),n&&p(!0,{event:"step",step:"mcp",mode:ft,status:"ok"}),await no(a,tt,Qe),n&&p(!0,{event:"step",step:"metering",mode:tt,status:"ok"}),me.orm==="prisma"&&me.database!=="none"){let S=ut.join(a,"packages/db/prisma/schema.prisma");if(de.existsSync(S)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let E=de.readFileSync(S,"utf8"),Q=Wt(E,{auth:N,payment:F,"billing-mode":Be,idp:Ye,template:"saas"});de.writeFileSync(S,Q),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(E){let Q=E instanceof Error?E.message:String(E);p(n,{event:"step",step:"schema-prune",status:"error",error:Q})}}else p(n,{event:"step",step:"schema-prune",status:"skip"})}else p(n,{event:"step",step:"schema-prune",status:"skip"});if(p(n,{event:"step",step:"billing-mode",choice:Be,status:"ok"}),p(n,{event:"step",step:"idp",choice:Ye,status:"ok"}),await Rn(a,y),n&&p(!0,{event:"step",step:"compliance",region:y,status:"ok"}),await $n(a),await Ao(a,N),await To(a,{projectName:d,region:y,previewSelections:$e}),me.aiMode!=="none"){p(n,{event:"step",step:"ai-providers",status:"start"});let S={providerIds:me.aiProviders,customEndpoint:me.customAiEndpoint},E=ut.join(a,"packages/ai-providers/templates");await yo(a,S,E),p(n,{event:"step",step:"ai-providers",status:"ok"})}else p(n,{event:"step",step:"ai-providers",status:"skip"});if(p(n,{event:"step",step:"docs",status:"start"}),j!=="none"?(await Ln(a,{framework:j,projectName:d}),p(n,{event:"step",step:"docs",framework:"fumadocs",requested:j,status:"ok"})):p(n,{event:"step",step:"docs",status:"skip"}),p(n,{event:"step",step:"deploy-target",status:"start"}),z!=="none"&&await On(a,z),p(n,{event:"step",step:"deploy-target",status:"ok"}),p(n,{event:"step",step:"env",status:"start"}),await Kn(a,qo),p(n,{event:"step",step:"env",status:"ok"}),t.install!==!1){let S=u==="bun"?"bun install":`${u} install`;n?p(!0,{event:"step",step:"install",pm:u,status:"start"}):process.stdout.write(w.dim(` Installing dependencies with ${u}\u2026
2930
- `));try{kt(S,{cwd:a,stdio:n?"ignore":"inherit"}),p(n,{event:"step",step:"install",status:"ok"})}catch(E){let Q=E instanceof Error?E.message:String(E);n?p(!0,{event:"step",step:"install",status:"error",error:Q}):process.stdout.write(w.yellow(` \u26A0 install failed \u2014 run '${S}' manually.
2931
- `))}}else p(n,{event:"step",step:"install",status:"skip"});if(t.git!==!1){n&&p(!0,{event:"step",step:"git-init",status:"start"});try{kt("git init -q",{cwd:a,stdio:"ignore"}),kt("git add -A",{cwd:a,stdio:"ignore"}),kt('git -c user.email=you@example.com -c user.name="You" commit -q -m "chore: initial scaffold from create-sailor"',{cwd:a,stdio:"ignore"}),p(n,{event:"step",step:"git-init",status:"ok"})}catch(S){let E=S instanceof Error?S.message:String(S);n?p(!0,{event:"step",step:"git-init",status:"error",error:E}):process.stdout.write(w.yellow(` \u26A0 git init skipped \u2014 not fatal.
2932
- `))}}else p(n,{event:"step",step:"git-init",status:"skip"});let St=Math.max(1,Math.round((Date.now()-tn)/1e3));mn({template_version:ee,package_manager:u,region:y,auth:N,payment:F,ai_providers:ue,deploy_target:z,duration_ms:Date.now()-tn}),$e.length>0&&Ot(),n?p(!0,{event:"done",status:"ok",elapsedSec:St,targetDir:a,previewSelections:$e}):sn({elapsedSec:St,targetDir:a,skippedInstall:t.install===!1,previewSelections:$e});try{Ys({pkg:{name:Oo,version:ee},updateCheckInterval:1e3*60*60*24}).notify({defer:!1,isGlobal:!0})}catch{}process.exit(0)}catch(m){let f=m instanceof Error?m.message:String(m);n?p(!0,{event:"error",message:f}):process.stdout.write(w.red(`
2933
- \u2718 Failed: ${f}
2934
- `)),process.exit(1)}}Hs().catch(e=>{process.stderr.write(String(e)+`
2933
+ `))}process.exit(0)}let er=async()=>{process.stdout.write(`
2934
+ `+N.red(`\u2718 Cancelled
2935
+ `)),ye.existsSync(a)&&await R.confirm({message:`Cleanup partial install at ${a}?`,initialValue:!0})===!0&&(ye.rmSync(a,{recursive:!0,force:!0}),process.stdout.write(N.dim(` \u2713 Removed ${a}
2936
+ `))),process.exit(130)};process.on("SIGINT",er);try{p(n,{event:"step",step:"clone",status:"start"}),await so(a),p(n,{event:"step",step:"clone",status:"ok"}),p(n,{event:"step",step:"package",status:"start"}),await fo(a,l),p(n,{event:"step",step:"package",status:"ok"}),p(n,{event:"step",step:"config",status:"start"}),await Un(a,he),p(n,{event:"step",step:"config",status:"ok"}),p(n,{event:"step",step:"prune",status:"start"}),await Co(a,he),p(n,{event:"step",step:"prune",status:"ok"});let g=ft.join(a,"packages/db/prisma/schema.prisma");if(ye.existsSync(g)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let v=ye.readFileSync(g,"utf-8"),_=Zt(v,{auth:M,payment:K,"billing-mode":We,idp:He,template:"saas"});ye.writeFileSync(g,_),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(v){let _=v instanceof Error?v.message:String(v);p(n,{event:"step",step:"schema-prune",status:"error",error:_})}}else p(n,{event:"step",step:"schema-prune",status:"skip"});if(p(n,{event:"step",step:"auth",choice:M,status:"start"}),await _n(a,M),p(n,{event:"step",step:"auth",choice:M,status:"ok"}),q.length>0?(p(n,{event:"step",step:"social-login",providers:q,status:"start"}),await In(a,q,M),p(n,{event:"step",step:"social-login",providers:q,status:"ok"})):p(n,{event:"step",step:"social-login",status:"skip"}),p(n,{event:"step",step:"db",choice:J,status:"start"}),await jn(a,J,l),p(n,{event:"step",step:"db",choice:J,status:"ok"}),p(n,{event:"step",step:"payment",choice:K,status:"start"}),await So(a,K),p(n,{event:"step",step:"payment",choice:K,status:"ok"}),await qn(a,Me,h),n&&p(!0,{event:"step",step:"email",choice:Me,status:"ok"}),await Mo(a,je,h),n&&p(!0,{event:"step",step:"storage",choice:je,status:"ok"}),await uo(a,Fe,h),n&&p(!0,{event:"step",step:"monitoring",choice:Fe,status:"ok"}),await Sn(a,De,h),n&&p(!0,{event:"step",step:"analytics",choice:De,status:"ok"}),await Uo(a,Ke,h),n&&p(!0,{event:"step",step:"sms",choice:Ke,status:"ok"}),await Ro(a,Ve,h),n&&p(!0,{event:"step",step:"queue",choice:Ve,status:"ok"}),await No(a,Be,h),n&&p(!0,{event:"step",step:"search",choice:Be,status:"ok"}),await Rn(a,nt,h),n&&p(!0,{event:"step",step:"cache",choice:nt,status:"ok"}),await go(a,Ye,h),n&&p(!0,{event:"step",step:"notifications",choice:Ye,status:"ok"}),await Do(a,$e,h),n&&p(!0,{event:"step",step:"webhooks",choice:$e,status:"ok"}),await Tn(a,ot,h),n&&p(!0,{event:"step",step:"cms",choice:ot,status:"ok"}),await Qn(a,qe,h),n&&p(!0,{event:"step",step:"feature-flags",choice:qe,status:"ok"}),await xn(a,Ge,h),n&&p(!0,{event:"step",step:"captcha",choice:Ge,status:"ok"}),await io(a,ht),n&&p(!0,{event:"step",step:"mcp",mode:ht,status:"ok"}),await co(a,rt,et),n&&p(!0,{event:"step",step:"metering",mode:rt,status:"ok"}),p(n,{event:"step",step:"prune-wave-features",status:"start"}),Io(a,C),p(n,{event:"step",step:"prune-wave-features",status:"ok",toggles:C}),he.orm==="prisma"&&he.database!=="none"){let v=ft.join(a,"packages/db/prisma/schema.prisma");if(ye.existsSync(v)){p(n,{event:"step",step:"schema-prune",status:"start"});try{let _=ye.readFileSync(v,"utf8"),Z=Zt(_,{auth:M,payment:K,"billing-mode":We,idp:He,template:"saas"});ye.writeFileSync(v,Z),p(n,{event:"step",step:"schema-prune",status:"ok"})}catch(_){let Z=_ instanceof Error?_.message:String(_);p(n,{event:"step",step:"schema-prune",status:"error",error:Z})}}else p(n,{event:"step",step:"schema-prune",status:"skip"})}else p(n,{event:"step",step:"schema-prune",status:"skip"});if(p(n,{event:"step",step:"billing-mode",choice:We,status:"ok"}),p(n,{event:"step",step:"idp",choice:He,status:"ok"}),await On(a,h),n&&p(!0,{event:"step",step:"compliance",region:h,status:"ok"}),await zn(a),await To(a,M),await Ko(a,{projectName:l,region:h,previewSelections:Xe,waveFeatures:C}),he.aiMode!=="none"){p(n,{event:"step",step:"ai-providers",status:"start"});let v={providerIds:he.aiProviders,customEndpoint:he.customAiEndpoint},_=ft.join(a,"packages/ai-providers/templates");await bo(a,v,_),p(n,{event:"step",step:"ai-providers",status:"ok"})}else p(n,{event:"step",step:"ai-providers",status:"skip"});if(p(n,{event:"step",step:"docs",status:"start"}),V!=="none"?(await Vn(a,{framework:V,projectName:l}),p(n,{event:"step",step:"docs",framework:"fumadocs",requested:V,status:"ok"})):p(n,{event:"step",step:"docs",status:"skip"}),p(n,{event:"step",step:"deploy-target",status:"start"}),Q!=="none"&&await Fn(a,Q),p(n,{event:"step",step:"deploy-target",status:"ok"}),p(n,{event:"step",step:"env",status:"start"}),await Wn(a,Zo),p(n,{event:"step",step:"env",status:"ok"}),t.install!==!1){let v=m==="bun"?"bun install":`${m} install`;n?p(!0,{event:"step",step:"install",pm:m,status:"start"}):process.stdout.write(N.dim(` Installing dependencies with ${m}\u2026
2937
+ `));try{Ut(v,{cwd:a,stdio:n?"ignore":"inherit"}),p(n,{event:"step",step:"install",status:"ok"})}catch(_){let Z=_ instanceof Error?_.message:String(_);n?p(!0,{event:"step",step:"install",status:"error",error:Z}):process.stdout.write(N.yellow(` \u26A0 install failed \u2014 run '${v}' manually.
2938
+ `))}}else p(n,{event:"step",step:"install",status:"skip"});if(t.git!==!1){n&&p(!0,{event:"step",step:"git-init",status:"start"});try{Ut("git init -q",{cwd:a,stdio:"ignore"}),Ut("git add -A",{cwd:a,stdio:"ignore"}),Ut('git -c user.email=you@example.com -c user.name="You" commit -q -m "chore: initial scaffold from create-sailor"',{cwd:a,stdio:"ignore"}),p(n,{event:"step",step:"git-init",status:"ok"})}catch(v){let _=v instanceof Error?v.message:String(v);n?p(!0,{event:"step",step:"git-init",status:"error",error:_}):process.stdout.write(N.yellow(` \u26A0 git init skipped \u2014 not fatal.
2939
+ `))}}else p(n,{event:"step",step:"git-init",status:"skip"});let vt=Math.max(1,Math.round((Date.now()-an)/1e3));hn({template_version:re,package_manager:m,region:h,auth:M,payment:K,ai_providers:Se,deploy_target:Q,duration_ms:Date.now()-an}),Xe.length>0&&Mt(),n?p(!0,{event:"done",status:"ok",elapsedSec:vt,targetDir:a,previewSelections:Xe,waveFeatures:C}):dn({elapsedSec:vt,targetDir:a,skippedInstall:t.install===!1,previewSelections:Xe,waveFeatures:C});try{Zi({pkg:{name:Vo,version:re},updateCheckInterval:1e3*60*60*24}).notify({defer:!1,isGlobal:!0})}catch{}process.exit(0)}catch(g){let S=g instanceof Error?g.message:String(g);n?p(!0,{event:"error",message:S}):process.stdout.write(N.red(`
2940
+ \u2718 Failed: ${S}
2941
+ `)),process.exit(1)}}oa().catch(e=>{process.stderr.write(String(e)+`
2935
2942
  `),process.exit(1)});