@seed-design/cli 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/index.mjs CHANGED
@@ -1,15 +1,17 @@
1
1
  #!/usr/bin/env node
2
- import*as k from"@clack/prompts";import{cosmiconfig as be}from"cosmiconfig";import{execa as xe}from"execa";import{z as M}from"zod";import he from"picocolors";var i=e=>he.cyan(e);import{detect as we}from"@antfu/ni";async function B(e){let t=await we({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}var re="seed-design",$e=be(re,{searchPlaces:[`${re}.json`]}),se=M.object({$schema:M.string().optional(),rsc:M.coerce.boolean().default(!1),tsx:M.coerce.boolean().default(!0),path:M.string(),telemetry:M.coerce.boolean().optional().default(!0)}).strict();async function U(e){let t=await Ie(e);return t?se.parse(t):null}async function Ie(e){try{let t=await $e.search(e);return se.parse(t.config)}catch{k.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694."),await k.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"})||(k.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1));let o=await B(e);await xe(o,["seed-design","init","--default"],{cwd:e}),k.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694.")}}function J({selectedItemKeys:e,publicRegistries:t}){let o=[],c=new Set;function l(r,a){let p=o.find(n=>n.registryId===r);if(!p?.items.some(n=>n.id===a.id)){if(p?p.items.push(a):o.push({registryId:r,items:[a]}),a.dependencies?.length)for(let n of a.dependencies)c.add(n);if(a.innerDependencies?.length)for(let n of a.innerDependencies)for(let u of n.itemIds){let $=t.find(T=>T.id===n.registryId)?.items.find(T=>T.id===u);if(!$)throw new Error(`Cannot find dependency item: ${n.registryId}:${u}`);l(n.registryId,$)}}}for(let r of e){let[a,...p]=r.split(":"),n=p.join(":");if(!a||!n)throw new Error(`Invalid snippet format: "${r}"`);let u=t.find($=>$.id===a)?.items.find($=>$.id===n);if(!u)throw new Error(`Cannot find snippet: "${r}"`);l(a,u)}return{registryItemsToAdd:o,npmDependenciesToAdd:c}}import*as ee from"@clack/prompts";import{z as f}from"zod";var Q=f.object({id:f.string(),description:f.string().optional(),deprecated:f.boolean().optional(),hideFromCLICatalog:f.boolean().optional(),dependencies:f.array(f.string()).optional(),innerDependencies:f.array(f.object({registryId:f.string(),itemIds:f.array(f.string())})).optional(),snippets:f.array(f.object({path:f.string(),content:f.string()}))}),Z=f.object({id:f.string(),hideFromCLICatalog:f.boolean().optional(),items:f.array(Q.omit({snippets:!0}).extend({snippets:f.array(f.object({path:f.string()}))}))}),oe=f.array(f.object({id:f.string()}));async function H({baseUrl:e}){let t=await fetch(`${e}/__registry__/index.json`);if(!t.ok)throw new Error(`Failed to fetch registries: ${t.status} ${t.statusText}`);let o=await t.json(),{success:c,data:l,error:r}=oe.safeParse(o);if(!c)throw new Error(`Failed to parse registries: ${r?.message}`);return l}async function V({baseUrl:e,registryId:t}){let o=await fetch(`${e}/__registry__/${t}/index.json`);if(!o.ok)throw new Error(`Failed to fetch ${t} registry: ${o.status} ${o.statusText}`);let c=await o.json(),{success:l,data:r,error:a}=Z.safeParse(c);if(!l)throw new Error(`Failed to parse ${t} registry: ${a?.message}`);return r}async function Pe({baseUrl:e,registryId:t,registryItemId:o}){let c=await fetch(`${e}/__registry__/${t}/${o}.json`);if(!c.ok)throw new Error(`Failed to fetch ${o}: ${c.status} ${c.statusText}`);let l=await c.json(),{success:r,data:a,error:p}=Q.safeParse(l);if(!r)throw new Error(`Failed to parse ${o}: ${p?.message}`);return a}async function ie({baseUrl:e,registryId:t,registryItemIds:o}){return await Promise.all(o.map(async c=>{try{return await Pe({baseUrl:e,registryId:t,registryItemId:c})}catch(l){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${r.status} ${r.statusText}`);let a=await r.json(),{success:p,data:n}=Z.safeParse(a);throw p?(ee.log.error(`${c} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),ee.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
3
- ${n.items.map(u=>u.id).join(`
4
- `)}`),l):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as Ce}from"fs";import{tmpdir as Ae}from"os";import ce from"path";import{transformFromAstSync as Se}from"@babel/core";import Re from"@babel/plugin-transform-typescript";import*as G from"recast";import{parse as Te}from"@babel/parser";var ve={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},ne=async({sourceFile:e,config:t})=>{let o=e.getFullText();if(t.tsx)return o;let c=G.parse(o,{parser:{parse:r=>Te(r,ve)}}),l=Se(c,o,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Re],configFile:!1});if(!l||!l.ast)throw new Error("Failed to transform JSX");return G.print(l.ast).code};import{SyntaxKind as je}from"ts-morph";var ae=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let o=e.getFirstChildByKind(je.ExpressionStatement);if(!o)return e;let c=o.getExpression();if(!c)return e;let l=c.getText().trim();if(l!=='"use client"'&&l!=="'use client'")return e;let r=o.getText(),a=o.getFullText();if(r.trim()===a.trim())return e;let n=a.replace(r,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return o.replaceWithText(n),e};import{Project as Ee,ScriptKind as De}from"ts-morph";var _e=[ae],Oe=new Ee({compilerOptions:{}});async function ke(e){let t=await Ce.mkdtemp(ce.join(Ae(),"seed-design-"));return ce.join(t,e)}async function pe(e){let t=await ke(e.filename),o=Oe.createSourceFile(t,e.raw,{scriptKind:De.TSX});for(let c of _e)c({sourceFile:o,...e});return await ne({sourceFile:o,...e})}import*as A from"@clack/prompts";import L from"fs-extra";import E from"path";import{createPatch as Fe}from"diff";import ze from"@npmcli/disparity-colors";async function Y({registryItemsToAdd:e,rootPath:t,cwd:o,baseUrl:c,config:l,onDiff:r}){let a=[];for(let{registryId:p,items:n}of e){let u=E.join(t,p);L.ensureDirSync(u);let $=await ie({baseUrl:c,registryId:p,registryItemIds:n.map(T=>T.id)});for(let{id:T,snippets:_}of $){let P=await Promise.all(_.map(async x=>{let y=await pe({filename:x.path,config:l,raw:x.content}),b=E.join(u,x.path);return l.tsx||(b=b.replace(/\.tsx$/,".jsx"),b=b.replace(/\.ts$/,".js")),{filePath:b,content:y,relativePath:E.relative(o,b),name:`${p}:${T}`}})),j=[];for(let x of P){let{filePath:y,content:b,relativePath:C}=x;if(await L.ensureDir(E.dirname(y)),L.existsSync(y)){let O=await L.readFile(y,"utf-8");if(O===b){A.log.info(`${i(C)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let z=E.basename(y),h=E.extname(y),s=E.basename(y,h),m=Date.now(),v=`legacy-${s}-${m}${h}`,S=await(async()=>{if(r)return r;let I=Fe(C,O,b),R=ze(I);return A.log.message(`
5
- ${i(C)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
6
- `),A.log.message(R),A.select({message:"\uD604\uC7AC \uD30C\uC77C\uC5D0 \uC2A4\uD0C0\uC77C \uBCC0\uACBD, \uB85C\uAE45 \uB4F1 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC774 \uC801\uC6A9\uB418\uC5B4 \uC788\uB294 \uACBD\uC6B0 \uC2E0\uADDC \uD30C\uC77C\uC5D0 \uB3D9\uC77C\uD55C \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC744 \uC801\uC6A9\uD558\uB294 \uAC83\uC744 \uAC80\uD1A0\uD574\uBCF4\uC138\uC694.",options:[{value:"overwrite",label:`${z} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${v}\uC73C\uB85C \uC62E\uAE30\uACE0 ${z} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(A.isCancel(S)||S==="skip"){A.log.info(`${i(C)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(S==="backup"){let I=E.dirname(y),R=E.join(I,v);await L.rename(y,R),A.log.info(`${i(C)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${i(E.relative(o,R))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await L.writeFile(y,b),j.push(x)}if(j.length>0){let x=j.map(({name:y,relativePath:b})=>({name:y,path:b}));a.push(...x),A.log.success(`${i(`${p}:${T}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${i(x.map(y=>y.path).join(", "))}`)}}}}import*as d from"@clack/prompts";import Xe from"path";import{z as F}from"zod";var X="https://seed-design.io";import*as le from"@clack/prompts";import{execa as Ne}from"execa";import Me from"findup-sync";import Ue from"fs-extra";var Le="package.json";function Ke(){let e=Me(Le);if(!e)throw new Error("No package.json file found in the project.");return e}function q(){let e=Ke();return Ue.readJSONSync(e)}async function W({cwd:e,deps:t,dev:o=!1}){let{start:c,stop:l}=le.spinner(),r=await B(e),p={...q().dependencies},n=new Set(t.filter(P=>!p[P])),u=new Set(t.filter(P=>p[P]));if(!n.size)return{installed:new Set,filtered:n};c("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let _=[r==="npm"?"install":"add",o?"-D":null,...n].filter(Boolean);try{await Ne(r,_,{cwd:e})}catch(P){console.error(`\uC758\uC874\uC131 \uC124\uCE58 \uC2E4\uD328: ${P}`),process.exit(1)}return l("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:n,filtered:u}}import{randomUUID as Be}from"node:crypto";import*as de from"@clack/prompts";var Je="seed_cli";async function He(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await U(e))?.telemetry===!1)return!1}catch{}return!0}function Ve(){return Be()}var Ge=Ve(),me=!1;async function Ye(e,{event:t,properties:o={}}){if(!await He(e))return;let l=`${Je}.${t}`;me||(de.log.info("\u{1F4CA} \uC0AC\uC6A9 \uB370\uC774\uD130 \uC218\uC9D1 \uC911 (\uBE44\uD65C\uC131\uD654: seed-design.json \uB610\uB294 DISABLE_TELEMETRY \uD658\uACBD \uBCC0\uC218)"),me=!0);try{let r="https://us.i.posthog.com/capture",a={"Content-Type":"application/json"},p={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:l,distinct_id:Ge,properties:{...o,$process_person_profile:!1},timestamp:new Date().toISOString()},n=new AbortController,u=setTimeout(()=>n.abort(),5e3);try{await fetch(r,{method:"POST",headers:a,body:JSON.stringify(p),signal:n.signal})}finally{clearTimeout(u)}}catch{}}var K={track:Ye};var qe=F.object({itemIds:F.array(F.string()).optional(),all:F.boolean(),cwd:F.string(),baseUrl:F.string().optional(),onDiff:F.enum(["overwrite","backup"]).optional()}),fe=e=>{e.command("add [...item-ids]","add items").option("-a, --all","[Deprecated] Add all items",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:X}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add ui:action-button").example("seed-design add ui:alert-dialog").action(async(t,o)=>{let c=Date.now();d.intro("seed-design add");let{success:l,data:{all:r,...a},error:p}=qe.safeParse({itemIds:t,...o});l||(d.log.error(`\uC798\uBABB\uB41C \uC635\uC158\uC774\uC5D0\uC694: ${p?.message}`),process.exit(1)),r&&(d.log.error("`--all` \uC635\uC158\uC740 \uB354 \uC774\uC0C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC544\uC694. \uB300\uC2E0 `seed-design add-all` \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."),process.exit(1));let n=a.cwd,u=a.baseUrl,$=await U(n),T=Xe.resolve(n,$.path),{start:_,stop:P}=d.spinner();_("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let j=await Promise.all((await H({baseUrl:u})).map(async({id:s})=>V({baseUrl:u,registryId:s})));P("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694.");let x=await(async()=>{if(a.itemIds.length>0)return a.itemIds;let s=await d.multiselect({message:"\uCD94\uAC00\uD560 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:j.filter(({hideFromCLICatalog:m})=>!m).flatMap(({id:m,items:v})=>v.filter(({hideFromCLICatalog:S})=>!S).sort((S,I)=>S.id.localeCompare(I.id)).map(({id:S,description:I,deprecated:R})=>({label:`${R?"(deprecated) ":""}${i(m)}:${S}`,value:`${m}:${S}`,hint:I,deprecated:R,registryItemCount:v.length}))).sort((m,v)=>m.deprecated!==v.deprecated?m.deprecated?1:-1:v.registryItemCount-m.registryItemCount)});return d.isCancel(s)&&(d.log.error("\uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694."),process.exit(0)),s})();x?.length||(d.log.error("\uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694."),process.exit(0)),d.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${i(x.join(", "))}`);let y=[];for(let s of x){let[m,...v]=s.split(":"),S=v.join(":");(!m||!S)&&(d.log.error(`${i(s)}: \uD56D\uBAA9 \uC774\uB984\uC774 \uC798\uBABB\uB418\uC5C8\uC5B4\uC694. ${i("ui:action-button")}\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uC785\uB825\uD574\uBCF4\uC138\uC694.`),process.exit(1));let I=j.find(R=>R.id===m)?.items.find(R=>R.id===S);if(I||(d.log.error(`${i(s)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`),process.exit(1)),I.deprecated){let R=await d.confirm({message:`${i(I.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(R===!1||d.isCancel(R)){d.log.info(`${i(I.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}y.push(s)}let{registryItemsToAdd:b,npmDependenciesToAdd:C}=J({selectedItemKeys:y,publicRegistries:j});d.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${i(b.map(s=>s.items.map(m=>`${s.registryId}:${m.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
2
+ import*as X from"@clack/prompts";import{cosmiconfig as rt}from"cosmiconfig";import{z as te}from"zod";import*as H from"@clack/prompts";import{ZodError as Ze}from"zod";import Qe from"picocolors";var a=e=>Qe.cyan(e);var $=class extends Error{hint;details;constructor({message:t,hint:s,details:o=[],cause:n}){super(t,{cause:n}),this.name="CliError",this.hint=s,this.details=o}},k=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function z(e){return e instanceof k}function F(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function et(e,t){if(e instanceof $)return{reason:e.message,hint:e.hint??t,details:e.details,stack:tt(e.cause??e)};if(e instanceof Ze){let s=e.issues.map(o=>`${o.path.join(".")||"(root)"}: ${o.message}`);return{reason:"\uC785\uB825\uAC12 \uB610\uB294 \uC124\uC815 \uD30C\uC77C \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC544\uC694.",hint:t,details:s,stack:e.stack}}if(e instanceof Error){let s=e,o=[];return(s.escapedCommand||s.command)&&o.push(`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${s.escapedCommand??s.command}`),typeof s.exitCode=="number"&&o.push(`\uC885\uB8CC \uCF54\uB4DC: ${s.exitCode}`),s.stderr?.trim()?o.push(`stderr: ${s.stderr.trim()}`):s.stdout?.trim()&&o.push(`stdout: ${s.stdout.trim()}`),{reason:s.shortMessage??e.message,hint:t,details:o,stack:e.stack}}return typeof e=="string"?{reason:e,hint:t,details:[]}:{reason:"\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC5B4\uC694.",hint:t,details:[]}}function tt(e){if(e instanceof Error)return e.stack}function V(e,{defaultMessage:t,defaultHint:s,verbose:o=!1}){let n=et(e,s);H.log.error(t),H.log.error(`\uC6D0\uC778: ${n.reason}`);for(let r of n.details)H.log.info(r);n.hint&&H.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${n.hint}`),o&&n.stack&&(H.log.message(a(`
3
+ [verbose] stack trace`)),H.log.message(n.stack)),H.outro(a("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as W from"@clack/prompts";import st from"fs-extra";import Pe from"path";var K={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function Se(){return await W.group({tsx:()=>W.confirm({message:`${a("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.tsx}),rsc:()=>W.confirm({message:`${a("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.rsc}),path:()=>W.text({message:`${a("seed-design \uD3F4\uB354")} \uACBD\uB85C\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694. (\uAE30\uBCF8\uAC12\uC740 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131\uB429\uB2C8\uB2E4.)`,initialValue:K.path,defaultValue:K.path,placeholder:K.path}),telemetry:()=>W.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${a("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:K.telemetry})},{onCancel:()=>{throw new k}})}async function fe({cwd:e,config:t}){let s=Pe.resolve(e,"seed-design.json");return await st.writeFile(s,`${JSON.stringify(t,null,2)}
4
+ `,"utf-8"),{relativePath:Pe.relative(process.cwd(),s),targetPath:s}}var Re="seed-design",it=rt(Re,{searchPlaces:[`${Re}.json`]}),Ee=te.object({$schema:te.string().optional(),rsc:te.coerce.boolean().default(!1),tsx:te.coerce.boolean().default(!0),path:te.string(),telemetry:te.coerce.boolean().optional().default(!0)}).strict();async function ge(e){let t=await le(e);if(t)return t;X.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let s=await X.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(X.isCancel(s)||!s)throw new k;try{return await fe({cwd:e,config:K}),X.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),Ee.parse(K)}catch(o){throw new $({message:"seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",hint:"\uB514\uB809\uD1A0\uB9AC \uC4F0\uAE30 \uAD8C\uD55C\uACFC \uACBD\uB85C\uB97C \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uBCF4\uC138\uC694.",cause:o})}}async function le(e){let t=await it.search(e);if(!t||t.isEmpty)return null;try{return Ee.parse(t.config)}catch(s){throw new $({message:"seed-design.json \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC544\uC694.",hint:"https://seed-design.com/react/getting-started/cli/configuration \uBB38\uC11C\uB97C \uCC38\uACE0\uD574 \uC8FC\uC138\uC694.",cause:s})}}function ue({selectedItemKeys:e,publicRegistries:t}){let s=[],o=new Set;function n(r,i){let c=s.find(m=>m.registryId===r);if(!c?.items.some(m=>m.id===i.id)){if(c?c.items.push(i):s.push({registryId:r,items:[i]}),i.dependencies?.length)for(let m of i.dependencies)o.add(m);if(i.innerDependencies?.length)for(let m of i.innerDependencies)for(let y of m.itemIds){let C=t.find(b=>b.id===m.registryId)?.items.find(b=>b.id===y);if(!C)throw new Error(`Cannot find dependency item: ${m.registryId}:${y}`);n(m.registryId,C)}}}for(let r of e){let[i,...c]=r.split(":"),m=c.join(":");if(!i||!m)throw new Error(`Invalid snippet format: "${r}"`);let y=t.find(C=>C.id===i)?.items.find(C=>C.id===m);if(!y)throw new Error(`Cannot find snippet: "${r}"`);n(i,y)}return{registryItemsToAdd:s,npmDependenciesToAdd:o}}import*as $e from"@clack/prompts";import{z as p}from"zod";var Ce=p.object({id:p.string(),description:p.string().optional(),deprecated:p.boolean().optional(),hideFromCLICatalog:p.boolean().optional(),dependencies:p.array(p.string()).optional(),innerDependencies:p.array(p.object({registryId:p.string(),itemIds:p.array(p.string())})).optional(),snippets:p.array(p.object({path:p.string(),dependencies:p.record(p.string(),p.string()).optional(),content:p.string()}))}),Ie=p.object({id:p.string(),hideFromCLICatalog:p.boolean().optional(),items:p.array(Ce.omit({snippets:!0}).extend({snippets:p.array(p.object({path:p.string(),dependencies:p.record(p.string(),p.string()).optional()}))}))}),ke=p.array(p.object({id:p.string()})),ot=p.object({label:p.string(),path:p.string()}),nt=p.object({id:p.string(),title:p.string(),description:p.string().optional(),docUrl:p.string(),deprecated:p.boolean().optional(),snippetKey:p.string().optional(),snippets:p.array(ot).optional()}),at=p.object({id:p.string(),label:p.string(),items:p.array(nt)}),ct=p.object({id:p.string(),label:p.string(),sections:p.array(at)}),ve=p.object({categories:p.array(ct)});async function je({baseUrl:e}){let t=await fetch(`${e}/__docs__/index.json`);if(!t.ok)throw new $({message:`\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${t.status} ${t.statusText}`});let s=await t.json(),{success:o,data:n,error:r}=ve.safeParse(s);if(!o)throw new $({message:`\uBB38\uC11C \uBAA9\uB85D \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694: ${r?.message}`});return n}async function se({baseUrl:e}){let t=await fetch(`${e}/__registry__/index.json`);if(!t.ok)throw new Error(`Failed to fetch registries: ${t.status} ${t.statusText}`);let s=await t.json(),{success:o,data:n,error:r}=ke.safeParse(s);if(!o)throw new Error(`Failed to parse registries: ${r?.message}`);return n}async function re({baseUrl:e,registryId:t}){let s=await fetch(`${e}/__registry__/${t}/index.json`);if(!s.ok)throw new Error(`Failed to fetch ${t} registry: ${s.status} ${s.statusText}`);let o=await s.json(),{success:n,data:r,error:i}=Ie.safeParse(o);if(!n)throw new Error(`Failed to parse ${t} registry: ${i?.message}`);return r}async function pt({baseUrl:e,registryId:t,registryItemId:s}){let o=await fetch(`${e}/__registry__/${t}/${s}.json`);if(!o.ok)throw new Error(`Failed to fetch ${s}: ${o.status} ${o.statusText}`);let n=await o.json(),{success:r,data:i,error:c}=Ce.safeParse(n);if(!r)throw new Error(`Failed to parse ${s}: ${c?.message}`);return i}async function Ae({baseUrl:e,registryId:t,registryItemIds:s}){return await Promise.all(s.map(async o=>{try{return await pt({baseUrl:e,registryId:t,registryItemId:o})}catch(n){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${r.status} ${r.statusText}`);let i=await r.json(),{success:c,data:m}=Ie.safeParse(i);throw c?($e.log.error(`${o} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),$e.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
5
+ ${m.items.map(y=>y.id).join(`
6
+ `)}`),n):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as ut}from"fs";import{tmpdir as yt}from"os";import _e from"path";import{transformFromAstSync as lt}from"@babel/core";import mt from"@babel/plugin-transform-typescript";import*as ye from"recast";import{parse as dt}from"@babel/parser";var ft={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},De=async({sourceFile:e,config:t})=>{let s=e.getFullText();if(t.tsx)return s;let o=ye.parse(s,{parser:{parse:r=>dt(r,ft)}}),n=lt(o,s,{cloneInputAst:!1,code:!1,ast:!0,plugins:[mt],configFile:!1});if(!n||!n.ast)throw new Error("Failed to transform JSX");return ye.print(n.ast).code};import{SyntaxKind as gt}from"ts-morph";var Te=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let s=e.getFirstChildByKind(gt.ExpressionStatement);if(!s)return e;let o=s.getExpression();if(!o)return e;let n=o.getText().trim();if(n!=='"use client"'&&n!=="'use client'")return e;let r=s.getText(),i=s.getFullText();if(r.trim()===i.trim())return e;let m=i.replace(r,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return s.replaceWithText(m),e};import{Project as ht,ScriptKind as wt}from"ts-morph";var bt=[Te],Ct=new ht({compilerOptions:{}});async function It(e){let t=await ut.mkdtemp(_e.join(yt(),"seed-design-"));return _e.join(t,e)}async function Oe(e){let t=await It(e.filename),s=Ct.createSourceFile(t,e.raw,{scriptKind:wt.TSX});for(let o of bt)o({sourceFile:s,...e});return await De({sourceFile:s,...e})}import*as L from"@clack/prompts";import ie from"fs-extra";import q from"path";import{createPatch as $t}from"diff";import xt from"@npmcli/disparity-colors";async function he({registryItemsToAdd:e,rootPath:t,cwd:s,baseUrl:o,config:n,onDiff:r}){let i=[];for(let{registryId:c,items:m}of e){let y=q.join(t,c);ie.ensureDirSync(y);let C=await Ae({baseUrl:o,registryId:c,registryItemIds:m.map(b=>b.id)});for(let{id:b,snippets:h}of C){let j=await Promise.all(h.map(async g=>{let d=await Oe({filename:g.path,config:n,raw:g.content}),w=q.join(y,g.path);return n.tsx||(w=w.replace(/\.tsx$/,".jsx"),w=w.replace(/\.ts$/,".js")),{filePath:w,content:d,relativePath:q.relative(s,w),name:`${c}:${b}`}})),f=[];for(let g of j){let{filePath:d,content:w,relativePath:I}=g;if(await ie.ensureDir(q.dirname(d)),ie.existsSync(d)){let E=await ie.readFile(d,"utf-8");if(E===w){L.log.info(`${a(I)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let P=q.basename(d),O=q.extname(d),ee=q.basename(d,O),pe=Date.now(),x=`legacy-${ee}-${pe}${O}`,l=await(async()=>{if(r)return r;let u=$t(I,E,w),A=xt(u);return L.log.message(`
7
+ ${a(I)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
8
+ `),L.log.message(A),L.select({message:"\uD604\uC7AC \uD30C\uC77C\uC5D0 \uC2A4\uD0C0\uC77C \uBCC0\uACBD, \uB85C\uAE45 \uB4F1 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC774 \uC801\uC6A9\uB418\uC5B4 \uC788\uB294 \uACBD\uC6B0 \uC2E0\uADDC \uD30C\uC77C\uC5D0 \uB3D9\uC77C\uD55C \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC744 \uC801\uC6A9\uD558\uB294 \uAC83\uC744 \uAC80\uD1A0\uD574\uBCF4\uC138\uC694.",options:[{value:"overwrite",label:`${P} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${x}\uC73C\uB85C \uC62E\uAE30\uACE0 ${P} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(L.isCancel(l)||l==="skip"){L.log.info(`${a(I)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(l==="backup"){let u=q.dirname(d),A=q.join(u,x);await ie.rename(d,A),L.log.info(`${a(I)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${a(q.relative(s,A))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await ie.writeFile(d,w),f.push(g)}if(f.length>0){let g=f.map(({name:d,relativePath:w})=>({name:d,path:w}));i.push(...g),L.log.success(`${a(`${c}:${b}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${a(g.map(d=>d.path).join(", "))}`)}}}}import*as S from"@clack/prompts";import Gt from"path";import{z as Z}from"zod";var B="https://seed-design.io";import*as Ke from"@clack/prompts";import{execa as vt}from"execa";import{detect as Pt}from"@antfu/ni";async function Me(e){let t=await Pt({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import St from"findup-sync";import Rt from"fs-extra";var Et="package.json";function kt(e=process.cwd()){let t=St(Et,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function oe(e=process.cwd()){let t=kt(e);return Rt.readJSONSync(t)}async function we({cwd:e,deps:t,dev:s=!1}){let{start:o,stop:n}=Ke.spinner(),r=await Me(e),c={...oe(e).dependencies},m=new Set(t.filter(f=>!c[f])),y=new Set(t.filter(f=>c[f]));if(!m.size)return{installed:new Set,filtered:m};o("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let h=[r==="npm"?"install":"add",s?"-D":null,...m].filter(Boolean),j=`${r} ${h.join(" ")}`;try{await vt(r,h,{cwd:e})}catch(f){throw n("\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."),new $({message:"\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",hint:"\uB124\uD2B8\uC6CC\uD06C \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, \uC124\uCE58 \uBA85\uB839\uC5B4\uB97C \uC9C1\uC811 \uC2E4\uD589\uD574 \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",details:[`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${j}`],cause:f})}return n("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:m,filtered:y}}import{randomUUID as jt}from"node:crypto";import*as Ue from"@clack/prompts";var At="seed_cli";async function Dt(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await le(e))?.telemetry===!1)return!1}catch{}return!0}function Tt(){return jt()}var _t=Tt(),Le=!1;async function Ot(e,{event:t,properties:s={}}){if(!await Dt(e))return;let n=`${At}.${t}`;Le||(Ue.log.info("\u{1F4CA} \uC0AC\uC6A9 \uB370\uC774\uD130 \uC218\uC9D1 \uC911 (\uBE44\uD65C\uC131\uD654: seed-design.json \uB610\uB294 DISABLE_TELEMETRY \uD658\uACBD \uBCC0\uC218)"),Le=!0);try{let r="https://us.i.posthog.com/capture",i={"Content-Type":"application/json"},c={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:n,distinct_id:_t,properties:{...s,$process_person_profile:!1},timestamp:new Date().toISOString()},m=new AbortController,y=setTimeout(()=>m.abort(),5e3);try{await fetch(r,{method:"POST",headers:i,body:JSON.stringify(c),signal:m.signal})}finally{clearTimeout(y)}}catch{}}var U={track:Ot};import*as Q from"@clack/prompts";import Mt from"fs-extra";import Kt from"path";import{intersects as Lt,satisfies as Ut,valid as ze,validRange as Fe}from"semver";var me=["@seed-design/react","@seed-design/css"],Ne="workspace:",Nt="npm:";function ne(e){try{let t=oe(e),s={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},o={};for(let n of me){let r=s[n];typeof r=="string"&&(o[n]=r)}return o}catch{return{}}}function ae({publicRegistries:e,itemKeys:t,projectPackageVersions:s}){let o=Array.from(new Set(t)),n=new Map(e.flatMap(i=>i.items.map(c=>[`${i.id}:${c.id}`,c]))),r=[];for(let i of o){let c=n.get(i);if(!c)continue;let m=zt(c);for(let y of me){let C=Array.from(m[y]??[]);if(!C.length)continue;let b=s[y];if(!b){r.push({itemKey:i,packageName:y,requiredRanges:C,type:"missing-package"});continue}let h=Ft(b);if(!h){r.push({itemKey:i,packageName:y,requiredRanges:C,installedVersionSpec:b,type:"invalid-version-spec"});continue}C.every(f=>Vt({currentVersionSpec:h,requiredRange:f}))||r.push({itemKey:i,packageName:y,requiredRanges:C,installedVersionSpec:b,type:"incompatible-version"})}}return{checkedItemKeys:o,projectPackageVersions:s,issues:r}}function ce({report:e,title:t}){if(!e.issues.length)return;Q.log.warn(t),Q.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${me.map(o=>`${o}@${a(e.projectPackageVersions[o]??"\uBBF8\uC124\uCE58")}`).join(", ")}`);let s=new Map;for(let o of e.issues){let n=s.get(o.itemKey)??[];n.push(o),s.set(o.itemKey,n)}for(let[o,n]of s.entries()){Q.log.warn(a(o));for(let r of n){let i=r.requiredRanges.join(" | ");if(r.type==="missing-package"){Q.log.info(` - ${r.packageName}: \uD328\uD0A4\uC9C0\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC694. \uD544\uC694 \uBC94\uC704: ${i}`);continue}if(r.type==="invalid-version-spec"){Q.log.info(` - ${r.packageName}: \uD604\uC7AC \uBC84\uC804 \uD615\uC2DD\uC744 \uD574\uC11D\uD558\uC9C0 \uBABB\uD588\uC5B4\uC694 (${r.installedVersionSpec}). \uD544\uC694 \uBC94\uC704: ${i}`);continue}Q.log.info(` - ${r.packageName}: \uD604\uC7AC ${r.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${i}`)}}}function Ve({publicRegistries:e,rootPath:t}){let s=[];for(let o of e)for(let n of o.items)n.snippets.some(i=>qt(i.path).some(c=>Mt.existsSync(Kt.join(t,o.id,c))))&&s.push(`${o.id}:${n.id}`);return s}function zt(e){let t=Object.fromEntries(me.map(s=>[s,new Set]));for(let s of e.snippets)for(let[o,n]of Object.entries(s.dependencies??{}))Bt(o)&&t[o].add(n);return t}function Ft(e){let t=e.trim();if(t.startsWith(Ne)&&(t=t.slice(Ne.length).trim()),t.startsWith(Nt)){let s=t.split("@").at(-1);if(!s)return null;t=s}return!t||t==="*"?null:ze(t)||Fe(t)?t:null}function Vt({currentVersionSpec:e,requiredRange:t}){let s=Fe(t);return s?ze(e)?Ut(e,s,{includePrerelease:!0}):Lt(e,s,{includePrerelease:!0}):!1}function qt(e){let t=new Set([e]);return e.endsWith(".tsx")&&t.add(`${e.slice(0,-4)}.jsx`),e.endsWith(".ts")&&t.add(`${e.slice(0,-3)}.js`),e.endsWith(".jsx")&&t.add(`${e.slice(0,-4)}.tsx`),e.endsWith(".js")&&t.add(`${e.slice(0,-3)}.ts`),Array.from(t)}function Bt(e){return me.includes(e)}var Ht=Z.object({itemIds:Z.array(Z.string()).optional(),all:Z.boolean(),cwd:Z.string(),baseUrl:Z.string().optional(),onDiff:Z.enum(["overwrite","backup"]).optional()}),qe=e=>{e.command("add [...item-ids]","add items").option("-a, --all","[Deprecated] Add all items",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add ui:action-button").example("seed-design add ui:alert-dialog").action(async(t,s)=>{let o=Date.now(),n=F(s);S.intro("seed-design add");try{let r=Ht.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:{all:i,...c}}=r;if(i)throw new $({message:"`--all` \uC635\uC158\uC740 \uB354 \uC774\uC0C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC544\uC694. \uB300\uC2E0 `seed-design add-all` \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."});let m=c.cwd,y=c.baseUrl,C=await ge(m),b=Gt.resolve(m,C.path),{start:h,stop:j}=S.spinner();h("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let f=await(async()=>{try{let l=await Promise.all((await se({baseUrl:y})).map(async({id:u})=>re({baseUrl:y,registryId:u})));return j("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),l}catch(l){throw j("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),l}})(),g=await(async()=>{if(c.itemIds?.length)return c.itemIds;let l=await S.multiselect({message:"\uCD94\uAC00\uD560 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:f.filter(({hideFromCLICatalog:u})=>!u).flatMap(({id:u,items:A})=>A.filter(({hideFromCLICatalog:M})=>!M).sort((M,T)=>M.id.localeCompare(T.id)).map(({id:M,description:T,deprecated:G})=>({label:`${G?"(deprecated) ":""}${a(u)}:${M}`,value:`${u}:${M}`,hint:T,deprecated:G,registryItemCount:A.length}))).sort((u,A)=>u.deprecated!==A.deprecated?u.deprecated?1:-1:A.registryItemCount-u.registryItemCount)});if(S.isCancel(l))throw new k;return l})();if(!g?.length)throw new k("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");S.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${a(g.join(", "))}`);let d=[];for(let l of g){let[u,...A]=l.split(":"),M=A.join(":");if(!u||!M)throw new $({message:`${a(l)}: \uD56D\uBAA9 \uC774\uB984\uC774 \uC798\uBABB\uB418\uC5C8\uC5B4\uC694.`,hint:`${a("ui:action-button")}\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});let T=f.find(G=>G.id===u)?.items.find(G=>G.id===M);if(!T)throw new $({message:`${a(l)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(T.deprecated){let G=await S.confirm({message:`${a(T.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(S.isCancel(G))throw new k;if(G===!1){S.log.info(`${a(T.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}d.push(l)}let{registryItemsToAdd:w,npmDependenciesToAdd:I}=ue({selectedItemKeys:d,publicRegistries:f}),E=ae({publicRegistries:f,itemKeys:w.flatMap(({registryId:l,items:u})=>u.map(A=>`${l}:${A.id}`)),projectPackageVersions:ne(c.cwd)});ce({report:E,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),S.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${a(w.map(l=>l.items.map(u=>`${l.registryId}:${u.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
7
9
 
8
- \uC124\uCE58\uD560 \uC758\uC874\uC131: ${i(Array.from(C).join(", ")||"\uC5C6\uC74C")}`),await Y({registryItemsToAdd:b,rootPath:T,cwd:n,baseUrl:u,config:$,onDiff:a.onDiff});try{let{installed:s,filtered:m}=await W({cwd:n,deps:Array.from(C)});s.size===0&&d.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),s.size&&(d.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${i(Array.from(s).join(", "))}`),m.size&&d.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${i(Array.from(m).join(", "))}`)),d.outro("\uC644\uB8CC\uD588\uC5B4\uC694.")}catch(s){d.log.error(`\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${s}`),d.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let O=Date.now()-c,z=new Set(b.map(s=>s.registryId)),h=x.some(s=>{let[m,...v]=s.split(":"),S=v.join(":");return j.find(I=>I.id===m)?.items.find(I=>I.id===S)?.deprecated});await K.track(a.cwd,{event:"add",properties:{items_count:y.length,registries:Array.from(z),has_deprecated:h,dependencies_count:C.size,duration_ms:O}})})};import*as g from"@clack/prompts";import We from"path";import{z as D}from"zod";var Qe=D.object({registryIds:D.array(D.string()).optional(),all:D.boolean(),includeDeprecated:D.boolean().optional(),cwd:D.string(),baseUrl:D.string().optional(),onDiff:D.enum(["overwrite","backup"]).optional()}),ge=e=>{e.command("add-all [...registry-ids]","add all items from registries").option("-a, --all","Add all items from all registries",{default:!1}).option("--include-deprecated","Include deprecated items when used with `--all`",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:X}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add-all ui --include-deprecated").example("seed-design add-all ui lib breeze").action(async(t,o)=>{let c=Date.now();g.intro("seed-design add-all");let{success:l,data:r,error:a}=Qe.safeParse({registryIds:t,...o});l||(g.log.error(`\uC798\uBABB\uB41C \uC635\uC158\uC774\uC5D0\uC694: ${a?.message}`),process.exit(1));let p=r.cwd,n=r.baseUrl,u=await U(p),$=We.resolve(p,u.path),{start:T,stop:_}=g.spinner();T("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let P=await Promise.all((await H({baseUrl:n})).map(async({id:h})=>V({baseUrl:n,registryId:h})));_("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694.");let j=await(async()=>{if(r.all){let s=P.map(m=>m.id);return g.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${i(s.join(", "))}`),s}if(r.registryIds?.length){let s=P.map(m=>m.id);for(let m of r.registryIds)s.includes(m)||(g.log.error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${m}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`),g.log.info(`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${s.join(", ")}`),process.exit(1));return g.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${i(r.registryIds.join(", "))}`),r.registryIds}let h=await g.multiselect({message:"\uCD94\uAC00\uD560 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:P.filter(({hideFromCLICatalog:s})=>!s).sort((s,m)=>m.items.length-s.items.length).map(s=>({label:s.id,value:s.id,hint:`${s.items.length}\uAC1C \uD56D\uBAA9 (${s.items[0].id} \uB4F1)`}))});return g.isCancel(h)&&(g.log.error("\uCDE8\uC18C\uB418\uC5C8\uC5B4\uC694."),process.exit(0)),g.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${i(h.join(", "))}`),h})(),x=P.filter(h=>j.includes(h.id)),y=x.flatMap(h=>h.items.filter(s=>s.deprecated?r.includeDeprecated:!0).map(s=>`${h.id}:${s.id}`)),b=x.flatMap(h=>h.items.filter(s=>s.deprecated).map(()=>1)).length;!r.includeDeprecated&&b>0&&g.log.info(`${b}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),y.length||(g.log.error("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694."),process.exit(0)),g.log.message(`\uCD1D ${i(y.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:C,npmDependenciesToAdd:O}=J({selectedItemKeys:y,publicRegistries:P});await Y({registryItemsToAdd:C,rootPath:$,cwd:p,baseUrl:n,config:u,onDiff:r.onDiff});try{let{installed:h,filtered:s}=await W({cwd:p,deps:Array.from(O)});h.size===0&&g.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),h.size&&(g.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${i(Array.from(h).join(", "))}`),s.size&&g.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${i(Array.from(s).join(", "))}`)),g.outro("\uC644\uB8CC\uD588\uC5B4\uC694.")}catch(h){g.log.error(`\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${h}`),g.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let z=Date.now()-c;await K.track(r.cwd,{event:"add-all",properties:{registries:j,items_count:y.length,include_deprecated:r.includeDeprecated||!1,dependencies_count:O.size,duration_ms:z}})})};import*as w from"@clack/prompts";import Ze from"fs-extra";import ue from"path";import{z as te}from"zod";import et from"dedent";var tt=te.object({cwd:te.string(),yes:te.boolean().optional()}),ye=e=>{e.command("init","seed-design.json \uD30C\uC77C \uC0DD\uC131").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC.",{default:process.cwd()}).option("-y, --yes","\uBAA8\uB4E0 \uC9C8\uBB38\uC5D0 \uB300\uD574 \uAE30\uBCF8\uAC12\uC73C\uB85C \uB2F5\uBCC0\uD569\uB2C8\uB2E4.").action(async t=>{let o=Date.now();w.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");let c=tt.parse(t),l=c.yes,r={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};l||(r={...await w.group({tsx:()=>w.confirm({message:`${i("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!0}),rsc:()=>w.confirm({message:`${i("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!1}),path:()=>w.text({message:`${i("seed-design \uD3F4\uB354")} \uACBD\uB85C\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694. (\uAE30\uBCF8\uAC12\uC740 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131\uB429\uB2C8\uB2E4.)`,initialValue:"./seed-design",defaultValue:"./seed-design",placeholder:"./seed-design"}),telemetry:()=>w.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${i("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:!0})},{onCancel:()=>{w.cancel("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."),process.exit(0)}})});try{let{start:p,stop:n}=w.spinner();p("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let u=ue.resolve(c.cwd,"seed-design.json");await Ze.writeFile(u,`${JSON.stringify(r,null,2)}
9
- `,"utf-8");let $=ue.relative(process.cwd(),u);n(`seed-design.json \uD30C\uC77C\uC774 ${i($)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),w.log.info(i("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),w.log.info(i("seed-design add \uBA85\uB839\uC5B4\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.")),w.note(et(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
10
+ \uC124\uCE58\uD560 \uC758\uC874\uC131: ${a(Array.from(I).join(", ")||"\uC5C6\uC74C")}`),await he({registryItemsToAdd:w,rootPath:b,cwd:m,baseUrl:y,config:C,onDiff:c.onDiff});let{installed:P,filtered:O}=await we({cwd:m,deps:Array.from(I)});P.size===0&&S.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),P.size&&(S.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(P).join(", "))}`),O.size&&S.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(O).join(", "))}`)),S.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let ee=Date.now()-o,pe=new Set(w.map(l=>l.registryId)),x=g.some(l=>{let[u,...A]=l.split(":"),M=A.join(":");return f.find(T=>T.id===u)?.items.find(T=>T.id===M)?.deprecated});try{await U.track(c.cwd,{event:"add",properties:{items_count:d.length,registries:Array.from(pe),has_deprecated:x,dependencies_count:I.size,duration_ms:ee}})}catch(l){n&&console.error("[Telemetry] add tracking failed:",l)}}catch(r){z(r)&&(S.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as v from"@clack/prompts";import Jt from"path";import{z as Y}from"zod";var Wt=Y.object({registryIds:Y.array(Y.string()).optional(),all:Y.boolean(),includeDeprecated:Y.boolean().optional(),cwd:Y.string(),baseUrl:Y.string().optional(),onDiff:Y.enum(["overwrite","backup"]).optional()}),Be=e=>{e.command("add-all [...registry-ids]","add all items from registries").option("-a, --all","Add all items from all registries",{default:!1}).option("--include-deprecated","Include deprecated items when used with `--all`",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add-all ui --include-deprecated").example("seed-design add-all ui lib breeze").action(async(t,s)=>{let o=Date.now(),n=F(s);v.intro("seed-design add-all");try{let r=Wt.safeParse({registryIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.cwd,m=i.baseUrl,y=await ge(c),C=Jt.resolve(c,y.path),{start:b,stop:h}=v.spinner();b("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let j=await(async()=>{try{let x=await Promise.all((await se({baseUrl:m})).map(async({id:l})=>re({baseUrl:m,registryId:l})));return h("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),x}catch(x){throw h("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),x}})(),f=await(async()=>{if(i.all){let l=j.map(u=>u.id);return v.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(l.join(", "))}`),l}if(i.registryIds?.length){let l=j.map(u=>u.id);for(let u of i.registryIds)if(!l.includes(u))throw new $({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${u}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${l.join(", ")}`]});return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(i.registryIds.join(", "))}`),i.registryIds}let x=await v.multiselect({message:"\uCD94\uAC00\uD560 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:j.filter(({hideFromCLICatalog:l})=>!l).sort((l,u)=>u.items.length-l.items.length).map(l=>{let u=l.items[0]?.id,A=u?`${l.items.length}\uAC1C \uD56D\uBAA9 (${u} \uB4F1)`:`${l.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:l.id,value:l.id,hint:A}})});if(v.isCancel(x))throw new k;return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(x.join(", "))}`),x})(),g=j.filter(x=>f.includes(x.id)),d=g.flatMap(x=>x.items.filter(l=>l.deprecated?i.includeDeprecated:!0).map(l=>`${x.id}:${l.id}`)),w=g.reduce((x,l)=>x+l.items.filter(u=>u.deprecated).length,0);if(!i.includeDeprecated&&w>0&&v.log.info(`${w}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),!d.length)throw new k("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");v.log.message(`\uCD1D ${a(d.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:I,npmDependenciesToAdd:E}=ue({selectedItemKeys:d,publicRegistries:j}),P=ae({publicRegistries:j,itemKeys:I.flatMap(({registryId:x,items:l})=>l.map(u=>`${x}:${u.id}`)),projectPackageVersions:ne(i.cwd)});ce({report:P,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),await he({registryItemsToAdd:I,rootPath:C,cwd:c,baseUrl:m,config:y,onDiff:i.onDiff});let{installed:O,filtered:ee}=await we({cwd:c,deps:Array.from(E)});O.size===0&&v.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),O.size&&(v.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(O).join(", "))}`),ee.size&&v.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(ee).join(", "))}`)),v.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let pe=Date.now()-o;try{await U.track(i.cwd,{event:"add-all",properties:{registries:f,items_count:d.length,include_deprecated:i.includeDeprecated||!1,dependencies_count:E.size,duration_ms:pe}})}catch(x){n&&console.error("[Telemetry] add-all tracking failed:",x)}}catch(r){z(r)&&(v.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as D from"@clack/prompts";import Ge from"path";import{z as N}from"zod";var Yt=N.object({itemIds:N.array(N.string()).optional(),component:N.union([N.string(),N.array(N.string())]).optional(),all:N.boolean(),registry:N.string().optional(),cwd:N.string(),baseUrl:N.string().optional()});function Xt({itemIds:e,component:t}){let s=r=>r.trim().replace(/\s+/g,"-"),o=(e??[]).map(s).filter(Boolean),n=(Array.isArray(t)?t:[t]).filter(r=>!!r).flatMap(r=>r.split(",")).map(s).filter(Boolean);return Array.from(new Set([...o,...n]))}function Qt({publicRegistries:e,targetInputs:t,defaultRegistry:s}){let o=e.filter(r=>typeof r.id=="string"&&Array.isArray(r.items)).flatMap(r=>r.items.filter(i=>typeof i.id=="string").map(i=>`${r.id}:${i.id}`)),n=new Set;for(let r of t){let i=r.includes(":")?r:s?`${s}:${r}`:(()=>{let c=o.filter(m=>m.endsWith(`:${r}`));if(!c.length)throw new $({message:`${a(r)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});if(c.length>1)throw new $({message:`${a(r)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:c.map(m=>`- ${m}`),hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});return c[0]})();if(!o.includes(i))throw new $({message:`${a(i)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});n.add(i)}return Array.from(n)}var He=e=>{e.command("compat [...item-ids]","check snippet compatibility").option("-c, --component <component>","\uAC80\uC0AC\uD560 \uCEF4\uD3EC\uB10C\uD2B8. \uC5EC\uB7EC \uBC88 \uB610\uB294 \uC27C\uD45C\uB85C \uC9C0\uC815 \uAC00\uB2A5").option("-a, --all","\uBAA8\uB4E0 registry \uD56D\uBAA9\uC744 \uAC80\uC0AC",{default:!1}).option("-r, --registry <registryId>","\uCEF4\uD3EC\uB10C\uD2B8 shorthand \uC785\uB825 \uC2DC \uAE30\uBCF8 registry").option("--cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).example("seed-design compat").example("seed-design compat -c action-button").example("seed-design compat ui:action-button ui:alert-dialog").example("seed-design compat --all").action(async(t,s)=>{let o=Date.now(),n=F(s);D.intro("seed-design compat");try{let r=Yt.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,{start:c,stop:m}=D.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let g=await Promise.all((await se({baseUrl:i.baseUrl})).map(async({id:d})=>re({baseUrl:i.baseUrl,registryId:d})));return m("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),g}catch(g){throw m("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),g}})(),C=Xt({itemIds:i.itemIds,component:i.component}),b=i.all?y.flatMap(d=>d.items.map(w=>`${d.id}:${w.id}`)):C.length>0?Qt({publicRegistries:y,targetInputs:C,defaultRegistry:i.registry}):le(i.cwd),h=Array.isArray(b)?b:await(async()=>{let g=await b;if(!g)throw new $({message:"seed-design.json \uD30C\uC77C\uC774 \uC5C6\uC5B4 \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB \uACBD\uB85C\uB97C \uC54C \uC218 \uC5C6\uC5B4\uC694.",hint:"`seed-design init`\uC73C\uB85C \uC124\uC815\uC744 \uB9CC\uB4E0 \uB4A4 \uC2E4\uD589\uD558\uAC70\uB098, `--all`/`-c`\uB85C \uAC80\uC0AC \uB300\uC0C1\uC744 \uC9C1\uC811 \uC9C0\uC815\uD574\uC8FC\uC138\uC694."});let d=Ge.resolve(i.cwd,g.path),w=Ve({publicRegistries:y,rootPath:d});return w.length?w:(D.log.info(`${a(Ge.relative(i.cwd,d)||g.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();h.length||(D.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let j=ne(i.cwd),f=ae({publicRegistries:y,itemKeys:h,projectPackageVersions:j});if(D.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${a(f.checkedItemKeys.join(", "))}`),!f.issues.length){D.outro("\uBAA8\uB4E0 \uC2A4\uB2C8\uD3AB\uC774 \uD604\uC7AC @seed-design/react, @seed-design/css\uC640 \uD638\uD658\uB3FC\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(0)}ce({report:f,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),D.log.info("\uD544\uC694\uD55C \uBC84\uC804\uC73C\uB85C @seed-design/react \uB610\uB294 @seed-design/css\uB97C \uB9DE\uCD98 \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD574\uBCF4\uC138\uC694."),D.outro("\uD638\uD658\uC131 \uC774\uC288\uAC00 \uC788\uC5B4\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:new Set(f.issues.map(g=>g.itemKey)).size,issue_count:f.issues.length,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(1)}catch(r){z(r)&&(D.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uD638\uD658\uC131 \uAC80\uC0AC\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as R from"@clack/prompts";import{z as xe}from"zod";var Zt="https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry",es=xe.object({query:xe.string().optional(),baseUrl:xe.string().optional()});function Je(e,t){return`${Zt}/${e}/${t}`}function ts(e,t){let s=`${t}${e.docUrl}`,o=`${t}/llms${e.docUrl}.txt`,n=[e.id,`- docs: ${s}`,`- llms.txt: ${o}`];if(e.snippetKey&&e.snippets&&e.snippets.length>0){let[r]=e.snippetKey.split(":");if(r==="ui"||r==="breeze")if(e.snippets.length===1)n.push(`- snippet: ${Je(r,e.snippets[0].path)}`);else{n.push("- snippet:");for(let i of e.snippets)n.push(` - ${i.label}: ${Je(r,i.path)}`)}}R.log.message(n.join(`
11
+ `))}function ss(e){return e.split("/").map(t=>t.trim()).filter(Boolean)}function rs(e,t){let s=t.toLowerCase();return e.flatMap(o=>o.sections.flatMap(n=>n.items.filter(r=>r.id.toLowerCase().includes(s)||r.title.toLowerCase().includes(s)).map(r=>({item:r,categoryLabel:o.label,sectionLabel:n.label}))))}async function de(e){let t=await R.select({message:"\uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:`${s.deprecated?"(deprecated) ":""}${s.title}`,value:s,hint:s.description}))});if(R.isCancel(t))throw new k;return t}async function We(e){let t=await R.select({message:"\uC139\uC158\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.items.length}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}async function is(e){let t=await R.select({message:"\uCE74\uD14C\uACE0\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.sections.reduce((o,n)=>o+n.items.length,0)}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}var Ye=e=>{e.command("docs [query]","\uBB38\uC11C \uB9C1\uD06C, llms.txt \uB9C1\uD06C, \uC2A4\uB2C8\uD3AB \uB9C1\uD06C\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4").option("-u, --baseUrl <baseUrl>",`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uAE30\uBCF8 URL (\uAE30\uBCF8\uAC12: ${B})`,{default:B}).example("seed-design docs").example("seed-design docs action-button").example("seed-design docs react").example("seed-design docs react/components").example("seed-design docs react/components/action-button").action(async(t,s)=>{let o=Date.now(),n=F(s);R.intro("seed-design docs");try{let r=es.safeParse({query:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.baseUrl??B,{start:m,stop:y}=R.spinner();m("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let C=await(async()=>{try{let f=await je({baseUrl:c});return y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),{categories:b}=C,h;if(i.query){let f=ss(i.query),g=b.find(d=>d.id===f[0]);if(g&&f.length>=2){let d=g.sections.find(w=>w.id===f[1]);if(d&&f.length>=3){let w=d.items.find(I=>I.id===f[2]);if(w)h=w;else{let I=f[2].toLowerCase(),E=d.items.filter(P=>P.id.toLowerCase().includes(I)||P.title.toLowerCase().includes(I));if(E.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}/${d.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});E.length===1?h=E[0]:h=await de(E)}}else if(d)h=await de(d.items);else{let w=f[1].toLowerCase(),I=g.sections.flatMap(E=>E.items.filter(P=>P.id.toLowerCase().includes(w)||P.title.toLowerCase().includes(w)).map(P=>({item:P,sectionLabel:E.label})));if(I.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});if(I.length===1)h=I[0].item;else{let E=await R.select({message:`${a(f[1])}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:I.map(({item:P,sectionLabel:O})=>({label:`[${O}] ${P.title}`,value:P,hint:P.description}))});if(R.isCancel(E))throw new k;h=E}}}else if(g)if(g.sections.length===1)h=await de(g.sections[0].items);else{let d=await We(g.sections);h=await de(d.items)}else{let d=rs(b,i.query);if(d.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:"`seed-design docs`\uB85C \uC804\uCCB4 \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694."});if(d.length===1)h=d[0].item;else{let w=await R.select({message:`${a(i.query)}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:d.map(({item:I,categoryLabel:E,sectionLabel:P})=>({label:`[${E} > ${P}] ${I.title}`,value:I,hint:I.description}))});if(R.isCancel(w))throw new k;h=w}}}else{let f=await is(b),g;f.sections.length===1?g=f.sections[0]:g=await We(f.sections),h=await de(g.items)}ts(h,c),R.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let j=Date.now()-o;try{await U.track(process.cwd(),{event:"docs",properties:{query:i.query??null,item_id:h.id,has_snippet:!!(h.snippets&&h.snippets.length>0),duration_ms:j}})}catch(f){n&&console.error("[Telemetry] docs tracking failed:",f)}}catch(r){z(r)&&(R.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uBB38\uC11C \uC870\uD68C\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as _ from"@clack/prompts";import{z as be}from"zod";import os from"dedent";var ns=be.object({cwd:be.string(),yes:be.boolean().optional(),default:be.boolean().optional()}),Xe=e=>{e.command("init","seed-design.json \uD30C\uC77C \uC0DD\uC131").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC.",{default:process.cwd()}).option("-y, --yes","\uBAA8\uB4E0 \uC9C8\uBB38\uC5D0 \uB300\uD574 \uAE30\uBCF8\uAC12\uC73C\uB85C \uB2F5\uBCC0\uD569\uB2C8\uB2E4.").option("--default","Deprecated. --yes\uC640 \uB3D9\uC77C\uD558\uAC8C \uAE30\uBCF8\uAC12\uC73C\uB85C \uC0DD\uC131\uD569\uB2C8\uB2E4.").action(async t=>{let s=Date.now(),o=F(t);_.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let n=ns.safeParse(t);if(!n.success)throw n.error;let r=n.data,i=r.yes||r.default,c=i?K:await Se(),{start:m,stop:y}=_.spinner();m("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let C=await(async()=>{try{return(await fe({cwd:r.cwd,config:c})).relativePath}catch(h){throw y("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),h}})();y(`seed-design.json \uD30C\uC77C\uC774 ${a(C)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),_.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),_.log.info(a("seed-design add \uBA85\uB839\uC5B4\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.")),_.note(os(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
10
12
 
11
13
  \uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
12
- \u2022 seed-design.json\uC5D0\uC11C ${i('"telemetry": false')}\uB85C \uC124\uC815
13
- \u2022 ${i("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
14
+ \u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
15
+ \u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
14
16
 
15
- \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),w.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.")}catch(p){w.log.error(`seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${p}`),w.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let a=Date.now()-o;await K.track(c.cwd,{event:"init",properties:{tsx:r.tsx,rsc:r.rsc,telemetry:r.telemetry,yes_option:l,duration_ms:a}})})};import{cac as rt}from"cac";var st="seed-design",N=rt(st);async function ot(){let e=q();fe(N),ge(N),ye(N),N.version(e.version||"1.0.0","-v, --version"),N.help(),N.parse()}ot();
17
+ \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),_.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let b=Date.now()-s;try{await U.track(r.cwd,{event:"init",properties:{tsx:c.tsx,rsc:c.rsc,telemetry:c.telemetry,yes_option:i,duration_ms:b}})}catch(h){o&&console.error("[Telemetry] init tracking failed:",h)}}catch(n){z(n)&&(_.outro(a(n.message)),process.exit(0)),V(n,{defaultMessage:"seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:o}),process.exit(1)}})};import{cac as as}from"cac";var cs="seed-design",J=as(cs);async function ps(){let e=oe();J.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),qe(J),Be(J),He(J),Ye(J),Xe(J),J.version(e.version||"1.0.0","-v, --version"),J.help(),J.parse()}ps();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-design/cli",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -21,7 +21,6 @@
21
21
  "scripts": {
22
22
  "build": "ENV=prod bun ./build.mjs",
23
23
  "dev": "ENV=dev bun ./dev.mjs",
24
- "test": "bun vitest",
25
24
  "lint:publish": "bun publint"
26
25
  },
27
26
  "dependencies": {
@@ -29,7 +28,7 @@
29
28
  "@babel/core": "^7.26.10",
30
29
  "@babel/parser": "^7.27.0",
31
30
  "@babel/plugin-transform-typescript": "^7.27.0",
32
- "@clack/prompts": "^0.11.0",
31
+ "@clack/prompts": "^1.0.0",
33
32
  "@npmcli/disparity-colors": "^3.0.1",
34
33
  "cac": "^6.7.14",
35
34
  "cosmiconfig": "^9.0.0",
@@ -40,6 +39,7 @@
40
39
  "fs-extra": "^11.3.0",
41
40
  "picocolors": "^1.1.1",
42
41
  "recast": "^0.23.11",
42
+ "semver": "^7.7.2",
43
43
  "ts-morph": "^27.0.0",
44
44
  "zod": "^3.24.3"
45
45
  },
package/src/AGENTS.md ADDED
@@ -0,0 +1,17 @@
1
+ ## 디렉토리 개요
2
+
3
+ `packages/cli/src`는 CLI 실행 엔트리, 명령어 구현, 공통 유틸, 테스트를 포함한다. 상위 규칙은 `packages/cli/AGENTS.md`를 따르고, 이 문서는 `src` 내부 구조 전용 컨벤션만 정의한다.
4
+
5
+ ## 파일 작성 컨벤션
6
+
7
+ - `commands/`: 사용자가 직접 호출하는 커맨드 액션(`init`, `add`, `add-all`, `compat`)
8
+ - `utils/`: 명령 간 공유 로직(설정, fetch, write, install, analytics, error)
9
+ - `tests/`: 독립 단위 테스트
10
+ - 파일명은 역할 중심 소문자 kebab-case를 유지하고, barrel file은 만들지 않는다.
11
+
12
+ ## 코드 작성 컨벤션
13
+
14
+ - 명령어 파일에서 사용자 입출력(`@clack/prompts`)과 종료 코드(`process.exit`)를 최종 처리한다.
15
+ - 유틸 파일은 사이드이펙트 종료 대신 예외를 throw하고, 명령어 계층에서 공통 핸들러로 변환한다.
16
+ - 사용자 취소는 `CliCancelError`, 오류는 `CliError`로 구분한다.
17
+ - 옵션 검증은 zod schema를 명령어 파일 상단에 정의하고 `safeParse/parse`로 검증한다.
@@ -10,6 +10,18 @@ import type { CAC } from "cac";
10
10
  import { BASE_URL } from "../constants";
11
11
  import { analytics } from "../utils/analytics";
12
12
  import { highlight } from "../utils/color";
13
+ import {
14
+ analyzeRegistryItemCompatibility,
15
+ getProjectSeedPackageVersionSpecs,
16
+ logCompatibilityReport,
17
+ } from "../utils/compatibility";
18
+ import {
19
+ CliCancelError,
20
+ CliError,
21
+ handleCliError,
22
+ isCliCancelError,
23
+ isVerboseMode,
24
+ } from "../utils/error";
13
25
  import { installDependencies } from "../utils/install";
14
26
 
15
27
  const addAllOptionsSchema = z.object({
@@ -43,131 +55,154 @@ export const addAllCommand = (cli: CAC) => {
43
55
  .example("seed-design add-all ui lib breeze")
44
56
  .action(async (registryIds, opts) => {
45
57
  const startTime = Date.now();
58
+ const verbose = isVerboseMode(opts);
46
59
  p.intro("seed-design add-all");
47
60
 
48
- const {
49
- success,
50
- data: options,
51
- error,
52
- } = addAllOptionsSchema.safeParse({ registryIds, ...opts });
53
-
54
- if (!success) {
55
- p.log.error(`잘못된 옵션이에요: ${error?.message}`);
56
-
57
- process.exit(1);
58
- }
59
-
60
- const cwd = options.cwd;
61
- const baseUrl = options.baseUrl;
62
- const config = await getConfig(cwd);
63
- const rootPath = path.resolve(cwd, config.path);
61
+ try {
62
+ const parsed = addAllOptionsSchema.safeParse({ registryIds, ...opts });
63
+ if (!parsed.success) {
64
+ throw parsed.error;
65
+ }
64
66
 
65
- const { start, stop } = p.spinner();
67
+ const { data: options } = parsed;
66
68
 
67
- start("Registry를 가져오고 있어요...");
69
+ const cwd = options.cwd;
70
+ const baseUrl = options.baseUrl;
71
+ const config = await getConfig(cwd);
72
+ const rootPath = path.resolve(cwd, config.path);
68
73
 
69
- const publicRegistries = await Promise.all(
70
- (await fetchAvailableRegistries({ baseUrl })).map(async ({ id }) =>
71
- fetchRegistry({ baseUrl, registryId: id }),
72
- ),
73
- );
74
+ const { start, stop } = p.spinner();
75
+ start("Registry를 가져오고 있어요...");
74
76
 
75
- stop("Registry를 가져왔어요.");
77
+ const publicRegistries = await (async () => {
78
+ try {
79
+ const registries = await Promise.all(
80
+ (await fetchAvailableRegistries({ baseUrl })).map(async ({ id }) =>
81
+ fetchRegistry({ baseUrl, registryId: id }),
82
+ ),
83
+ );
84
+ stop("Registry를 가져왔어요.");
76
85
 
77
- const selectedRegistryIds: string[] = await (async () => {
78
- if (options.all) {
79
- const ids = publicRegistries.map((r) => r.id);
80
- p.log.message(`모든 레지스트리의 모든 항목을 추가합니다: ${highlight(ids.join(", "))}`);
86
+ return registries;
87
+ } catch (error) {
88
+ stop("Registry를 가져오지 못했어요.");
89
+ throw error;
90
+ }
91
+ })();
81
92
 
82
- return ids;
83
- }
93
+ const selectedRegistryIds: string[] = await (async () => {
94
+ if (options.all) {
95
+ const ids = publicRegistries.map((r) => r.id);
96
+ p.log.message(`모든 레지스트리의 모든 항목을 추가합니다: ${highlight(ids.join(", "))}`);
84
97
 
85
- if (options.registryIds?.length) {
86
- const availableIds = publicRegistries.map((r) => r.id);
98
+ return ids;
99
+ }
87
100
 
88
- for (const registryId of options.registryIds) {
89
- if (!availableIds.includes(registryId)) {
90
- p.log.error(`레지스트리 '${registryId}'를 찾을 수 없어요.`);
91
- p.log.info(`사용 가능한 레지스트리: ${availableIds.join(", ")}`);
101
+ if (options.registryIds?.length) {
102
+ const availableIds = publicRegistries.map((r) => r.id);
92
103
 
93
- process.exit(1);
104
+ for (const registryId of options.registryIds) {
105
+ if (!availableIds.includes(registryId)) {
106
+ throw new CliError({
107
+ message: `레지스트리 '${registryId}'를 찾을 수 없어요.`,
108
+ details: [`사용 가능한 레지스트리: ${availableIds.join(", ")}`],
109
+ });
110
+ }
94
111
  }
95
- }
96
112
 
97
- p.log.message(
98
- `선택된 레지스트리의 모든 항목을 추가합니다: ${highlight(options.registryIds.join(", "))}`,
99
- );
113
+ p.log.message(
114
+ `선택된 레지스트리의 모든 항목을 추가합니다: ${highlight(options.registryIds.join(", "))}`,
115
+ );
100
116
 
101
- return options.registryIds;
102
- }
117
+ return options.registryIds;
118
+ }
103
119
 
104
- const selected = await p.multiselect({
105
- message: "추가할 레지스트리를 선택해주세요 (스페이스 바로 여러 개 선택 가능)",
106
- options: publicRegistries
107
- .filter(({ hideFromCLICatalog }) => !hideFromCLICatalog)
108
- .sort((a, b) => b.items.length - a.items.length)
109
- .map((registry) => ({
110
- label: registry.id,
111
- value: registry.id,
112
- hint: `${registry.items.length}개 항목 (${registry.items[0].id} 등)`,
113
- })),
114
- });
120
+ const selected = await p.multiselect({
121
+ message: "추가할 레지스트리를 선택해주세요 (스페이스 바로 여러 개 선택 가능)",
122
+ options: publicRegistries
123
+ .filter(({ hideFromCLICatalog }) => !hideFromCLICatalog)
124
+ .sort((a, b) => b.items.length - a.items.length)
125
+ .map((registry) => {
126
+ const firstItemId = registry.items[0]?.id;
127
+ const hint = firstItemId
128
+ ? `${registry.items.length}개 항목 (${firstItemId} 등)`
129
+ : `${registry.items.length}개 항목 (항목 없음)`;
130
+
131
+ return {
132
+ label: registry.id,
133
+ value: registry.id,
134
+ hint,
135
+ };
136
+ }),
137
+ });
138
+
139
+ if (p.isCancel(selected)) {
140
+ throw new CliCancelError();
141
+ }
115
142
 
116
- if (p.isCancel(selected)) {
117
- p.log.error("취소되었어요.");
118
- process.exit(0);
119
- }
143
+ p.log.message(`선택된 레지스트리의 항목을 추가합니다: ${highlight(selected.join(", "))}`);
120
144
 
121
- p.log.message(`선택된 레지스트리의 항목을 추가합니다: ${highlight(selected.join(", "))}`);
145
+ return selected;
146
+ })();
122
147
 
123
- return selected;
124
- })();
148
+ const selectedRegistries = publicRegistries.filter((r) =>
149
+ selectedRegistryIds.includes(r.id),
150
+ );
125
151
 
126
- const selectedRegistries = publicRegistries.filter((r) => selectedRegistryIds.includes(r.id));
152
+ const itemKeys = selectedRegistries.flatMap((registry) =>
153
+ registry.items
154
+ .filter((item) => {
155
+ if (item.deprecated) return options.includeDeprecated;
127
156
 
128
- const itemKeys = selectedRegistries.flatMap((registry) =>
129
- registry.items
130
- .filter((item) => {
131
- if (item.deprecated) return options.includeDeprecated;
157
+ return true;
158
+ })
159
+ .map((item) => `${registry.id}:${item.id}`),
160
+ );
132
161
 
133
- return true;
134
- })
135
- .map((item) => `${registry.id}:${item.id}`),
136
- );
162
+ const deprecatedCount = selectedRegistries.reduce(
163
+ (count, r) => count + r.items.filter((item) => item.deprecated).length,
164
+ 0,
165
+ );
137
166
 
138
- const deprecatedCount = selectedRegistries.flatMap((r) =>
139
- r.items.filter((item) => item.deprecated).map(() => 1),
140
- ).length;
167
+ if (!options.includeDeprecated && deprecatedCount > 0) {
168
+ p.log.info(
169
+ `${deprecatedCount}개의 deprecated 항목은 제외되었어요. --include-deprecated 옵션을 사용하면 추가할 수 있어요.`,
170
+ );
171
+ }
141
172
 
142
- if (!options.includeDeprecated && deprecatedCount > 0) {
143
- p.log.info(
144
- `${deprecatedCount}개의 deprecated 항목은 제외되었어요. --include-deprecated 옵션을 사용하면 추가할 수 있어요.`,
145
- );
146
- }
173
+ if (!itemKeys.length) {
174
+ throw new CliCancelError("추가할 항목이 없어요.");
175
+ }
147
176
 
148
- if (!itemKeys.length) {
149
- p.log.error("추가할 항목이 없어요.");
177
+ p.log.message(`총 ${highlight(itemKeys.length.toString())}개의 항목을 추가합니다.`);
150
178
 
151
- process.exit(0);
152
- }
179
+ const { registryItemsToAdd, npmDependenciesToAdd } = resolveDependencies({
180
+ selectedItemKeys: itemKeys,
181
+ publicRegistries,
182
+ });
153
183
 
154
- p.log.message(`총 ${highlight(itemKeys.length.toString())}개의 항목을 추가합니다.`);
184
+ const compatibilityReport = analyzeRegistryItemCompatibility({
185
+ publicRegistries,
186
+ itemKeys: registryItemsToAdd.flatMap(({ registryId, items }) =>
187
+ items.map((item) => `${registryId}:${item.id}`),
188
+ ),
189
+ projectPackageVersions: getProjectSeedPackageVersionSpecs(options.cwd),
190
+ });
155
191
 
156
- const { registryItemsToAdd, npmDependenciesToAdd } = resolveDependencies({
157
- selectedItemKeys: itemKeys,
158
- publicRegistries,
159
- });
192
+ logCompatibilityReport({
193
+ report: compatibilityReport,
194
+ title: "현재 프로젝트 버전과 호환되지 않을 수 있는 스니펫이 있어요.",
195
+ });
160
196
 
161
- await writeRegistryItemSnippets({
162
- registryItemsToAdd,
163
- rootPath,
164
- cwd,
165
- baseUrl,
166
- config,
167
- onDiff: options.onDiff,
168
- });
197
+ await writeRegistryItemSnippets({
198
+ registryItemsToAdd,
199
+ rootPath,
200
+ cwd,
201
+ baseUrl,
202
+ config,
203
+ onDiff: options.onDiff,
204
+ });
169
205
 
170
- try {
171
206
  const { installed, filtered } = await installDependencies({
172
207
  cwd,
173
208
  deps: Array.from(npmDependenciesToAdd),
@@ -188,23 +223,37 @@ export const addAllCommand = (cli: CAC) => {
188
223
  }
189
224
 
190
225
  p.outro("완료했어요.");
226
+
227
+ // add-all 성공 이벤트 추적
228
+ const duration = Date.now() - startTime;
229
+ try {
230
+ await analytics.track(options.cwd, {
231
+ event: "add-all",
232
+ properties: {
233
+ registries: selectedRegistryIds,
234
+ items_count: itemKeys.length,
235
+ include_deprecated: options.includeDeprecated || false,
236
+ dependencies_count: npmDependenciesToAdd.size,
237
+ duration_ms: duration,
238
+ },
239
+ });
240
+ } catch (telemetryError) {
241
+ if (verbose) {
242
+ console.error("[Telemetry] add-all tracking failed:", telemetryError);
243
+ }
244
+ }
191
245
  } catch (error) {
192
- p.log.error(`추가에 실패했어요. ${error}`);
193
- p.outro(highlight("작업이 취소됐어요."));
246
+ if (isCliCancelError(error)) {
247
+ p.outro(highlight(error.message));
248
+ process.exit(0);
249
+ }
250
+
251
+ handleCliError(error, {
252
+ defaultMessage: "추가에 실패했어요.",
253
+ defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
254
+ verbose,
255
+ });
194
256
  process.exit(1);
195
257
  }
196
-
197
- // add-all 성공 이벤트 추적
198
- const duration = Date.now() - startTime;
199
- await analytics.track(options.cwd, {
200
- event: "add-all",
201
- properties: {
202
- registries: selectedRegistryIds,
203
- items_count: itemKeys.length,
204
- include_deprecated: options.includeDeprecated || false,
205
- dependencies_count: npmDependenciesToAdd.size,
206
- duration_ms: duration,
207
- },
208
- });
209
258
  });
210
259
  };