@seed-design/cli 1.2.1 → 1.2.2

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,16 @@
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 W from"@clack/prompts";import{cosmiconfig as We}from"cosmiconfig";import{z as Q}from"zod";import*as F from"@clack/prompts";import{ZodError as Ge}from"zod";import Be from"picocolors";var a=e=>Be.cyan(e);var x=class extends Error{hint;details;constructor({message:t,hint:r,details:s=[],cause:n}){super(t,{cause:n}),this.name="CliError",this.hint=r,this.details=s}},E=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function U(e){return e instanceof E}function L(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function He(e,t){if(e instanceof x)return{reason:e.message,hint:e.hint??t,details:e.details,stack:qe(e.cause??e)};if(e instanceof Ge){let r=e.issues.map(s=>`${s.path.join(".")||"(root)"}: ${s.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:r,stack:e.stack}}if(e instanceof Error){let r=e,s=[];return(r.escapedCommand||r.command)&&s.push(`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${r.escapedCommand??r.command}`),typeof r.exitCode=="number"&&s.push(`\uC885\uB8CC \uCF54\uB4DC: ${r.exitCode}`),r.stderr?.trim()?s.push(`stderr: ${r.stderr.trim()}`):r.stdout?.trim()&&s.push(`stdout: ${r.stdout.trim()}`),{reason:r.shortMessage??e.message,hint:t,details:s,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 qe(e){if(e instanceof Error)return e.stack}function B(e,{defaultMessage:t,defaultHint:r,verbose:s=!1}){let n=He(e,r);F.log.error(t),F.log.error(`\uC6D0\uC778: ${n.reason}`);for(let i of n.details)F.log.info(i);n.hint&&F.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${n.hint}`),s&&n.stack&&(F.log.message(a(`
3
+ [verbose] stack trace`)),F.log.message(n.stack)),F.outro(a("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as G from"@clack/prompts";import Je from"fs-extra";import Ce from"path";var _={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function $e(){return await G.group({tsx:()=>G.confirm({message:`${a("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:_.tsx}),rsc:()=>G.confirm({message:`${a("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:_.rsc}),path:()=>G.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:_.path,defaultValue:_.path,placeholder:_.path}),telemetry:()=>G.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${a("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:_.telemetry})},{onCancel:()=>{throw new E}})}async function me({cwd:e,config:t}){let r=Ce.resolve(e,"seed-design.json");return await Je.writeFile(r,`${JSON.stringify(t,null,2)}
4
+ `,"utf-8"),{relativePath:Ce.relative(process.cwd(),r),targetPath:r}}var Pe="seed-design",Ye=We(Pe,{searchPlaces:[`${Pe}.json`]}),xe=Q.object({$schema:Q.string().optional(),rsc:Q.coerce.boolean().default(!1),tsx:Q.coerce.boolean().default(!0),path:Q.string(),telemetry:Q.coerce.boolean().optional().default(!0)}).strict();async function de(e){let t=await pe(e);if(t)return t;W.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let r=await W.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(W.isCancel(r)||!r)throw new E;try{return await me({cwd:e,config:_}),W.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),xe.parse(_)}catch(s){throw new x({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:s})}}async function pe(e){let t=await Ye.search(e);if(!t||t.isEmpty)return null;try{return xe.parse(t.config)}catch(r){throw new x({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:r})}}function fe({selectedItemKeys:e,publicRegistries:t}){let r=[],s=new Set;function n(i,o){let c=r.find(l=>l.registryId===i);if(!c?.items.some(l=>l.id===o.id)){if(c?c.items.push(o):r.push({registryId:i,items:[o]}),o.dependencies?.length)for(let l of o.dependencies)s.add(l);if(o.innerDependencies?.length)for(let l of o.innerDependencies)for(let d of l.itemIds){let h=t.find(b=>b.id===l.registryId)?.items.find(b=>b.id===d);if(!h)throw new Error(`Cannot find dependency item: ${l.registryId}:${d}`);n(l.registryId,h)}}}for(let i of e){let[o,...c]=i.split(":"),l=c.join(":");if(!o||!l)throw new Error(`Invalid snippet format: "${i}"`);let d=t.find(h=>h.id===o)?.items.find(h=>h.id===l);if(!d)throw new Error(`Cannot find snippet: "${i}"`);n(o,d)}return{registryItemsToAdd:r,npmDependenciesToAdd:s}}import*as Ie from"@clack/prompts";import{z as u}from"zod";var we=u.object({id:u.string(),description:u.string().optional(),deprecated:u.boolean().optional(),hideFromCLICatalog:u.boolean().optional(),dependencies:u.array(u.string()).optional(),innerDependencies:u.array(u.object({registryId:u.string(),itemIds:u.array(u.string())})).optional(),snippets:u.array(u.object({path:u.string(),dependencies:u.record(u.string(),u.string()).optional(),content:u.string()}))}),be=u.object({id:u.string(),hideFromCLICatalog:u.boolean().optional(),items:u.array(we.omit({snippets:!0}).extend({snippets:u.array(u.object({path:u.string(),dependencies:u.record(u.string(),u.string()).optional()}))}))}),Re=u.array(u.object({id:u.string()}));async function ee({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 r=await t.json(),{success:s,data:n,error:i}=Re.safeParse(r);if(!s)throw new Error(`Failed to parse registries: ${i?.message}`);return n}async function te({baseUrl:e,registryId:t}){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`Failed to fetch ${t} registry: ${r.status} ${r.statusText}`);let s=await r.json(),{success:n,data:i,error:o}=be.safeParse(s);if(!n)throw new Error(`Failed to parse ${t} registry: ${o?.message}`);return i}async function Xe({baseUrl:e,registryId:t,registryItemId:r}){let s=await fetch(`${e}/__registry__/${t}/${r}.json`);if(!s.ok)throw new Error(`Failed to fetch ${r}: ${s.status} ${s.statusText}`);let n=await s.json(),{success:i,data:o,error:c}=we.safeParse(n);if(!i)throw new Error(`Failed to parse ${r}: ${c?.message}`);return o}async function ke({baseUrl:e,registryId:t,registryItemIds:r}){return await Promise.all(r.map(async s=>{try{return await Xe({baseUrl:e,registryId:t,registryItemId:s})}catch(n){let i=await fetch(`${e}/__registry__/${t}/index.json`);if(!i.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${i.status} ${i.statusText}`);let o=await i.json(),{success:c,data:l}=be.safeParse(o);throw c?(Ie.log.error(`${s} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),Ie.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
5
+ ${l.items.map(d=>d.id).join(`
6
+ `)}`),n):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as it}from"fs";import{tmpdir as st}from"os";import ve from"path";import{transformFromAstSync as Ze}from"@babel/core";import Qe from"@babel/plugin-transform-typescript";import*as ge from"recast";import{parse as et}from"@babel/parser";var tt={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"]},Ee=async({sourceFile:e,config:t})=>{let r=e.getFullText();if(t.tsx)return r;let s=ge.parse(r,{parser:{parse:i=>et(i,tt)}}),n=Ze(s,r,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Qe],configFile:!1});if(!n||!n.ast)throw new Error("Failed to transform JSX");return ge.print(n.ast).code};import{SyntaxKind as rt}from"ts-morph";var Se=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let r=e.getFirstChildByKind(rt.ExpressionStatement);if(!r)return e;let s=r.getExpression();if(!s)return e;let n=s.getText().trim();if(n!=='"use client"'&&n!=="'use client'")return e;let i=r.getText(),o=r.getFullText();if(i.trim()===o.trim())return e;let l=o.replace(i,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return r.replaceWithText(l),e};import{Project as ot,ScriptKind as nt}from"ts-morph";var at=[Se],ct=new ot({compilerOptions:{}});async function pt(e){let t=await it.mkdtemp(ve.join(st(),"seed-design-"));return ve.join(t,e)}async function Ae(e){let t=await pt(e.filename),r=ct.createSourceFile(t,e.raw,{scriptKind:nt.TSX});for(let s of at)s({sourceFile:r,...e});return await Ee({sourceFile:r,...e})}import*as D from"@clack/prompts";import re from"fs-extra";import M from"path";import{createPatch as lt}from"diff";import mt from"@npmcli/disparity-colors";async function ue({registryItemsToAdd:e,rootPath:t,cwd:r,baseUrl:s,config:n,onDiff:i}){let o=[];for(let{registryId:c,items:l}of e){let d=M.join(t,c);re.ensureDirSync(d);let h=await ke({baseUrl:s,registryId:c,registryItemIds:l.map(b=>b.id)});for(let{id:b,snippets:$}of h){let k=await Promise.all($.map(async f=>{let g=await Ae({filename:f.path,config:n,raw:f.content}),w=M.join(d,f.path);return n.tsx||(w=w.replace(/\.tsx$/,".jsx"),w=w.replace(/\.ts$/,".js")),{filePath:w,content:g,relativePath:M.relative(r,w),name:`${c}:${b}`}})),y=[];for(let f of k){let{filePath:g,content:w,relativePath:v}=f;if(await re.ensureDir(M.dirname(g)),re.existsSync(g)){let J=await re.readFile(g,"utf-8");if(J===w){D.log.info(`${a(v)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let V=M.basename(g),K=M.extname(g),Z=M.basename(g,K),ce=Date.now(),I=`legacy-${Z}-${ce}${K}`,p=await(async()=>{if(i)return i;let m=lt(v,J,w),R=mt(m);return D.log.message(`
7
+ ${a(v)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
8
+ `),D.log.message(R),D.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:`${V} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${I}\uC73C\uB85C \uC62E\uAE30\uACE0 ${V} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(D.isCancel(p)||p==="skip"){D.log.info(`${a(v)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(p==="backup"){let m=M.dirname(g),R=M.join(m,I);await re.rename(g,R),D.log.info(`${a(v)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${a(M.relative(r,R))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await re.writeFile(g,w),y.push(f)}if(y.length>0){let f=y.map(({name:g,relativePath:w})=>({name:g,path:w}));o.push(...f),D.log.success(`${a(`${c}:${b}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${a(f.map(g=>g.path).join(", "))}`)}}}}import*as C from"@clack/prompts";import Dt from"path";import{z as X}from"zod";var ie="https://seed-design.io";import*as Te from"@clack/prompts";import{execa as ht}from"execa";import{detect as dt}from"@antfu/ni";async function je(e){let t=await dt({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import ft from"findup-sync";import gt from"fs-extra";var ut="package.json";function yt(e=process.cwd()){let t=ft(ut,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function se(e=process.cwd()){let t=yt(e);return gt.readJSONSync(t)}async function ye({cwd:e,deps:t,dev:r=!1}){let{start:s,stop:n}=Te.spinner(),i=await je(e),c={...se(e).dependencies},l=new Set(t.filter(y=>!c[y])),d=new Set(t.filter(y=>c[y]));if(!l.size)return{installed:new Set,filtered:l};s("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let $=[i==="npm"?"install":"add",r?"-D":null,...l].filter(Boolean),k=`${i} ${$.join(" ")}`;try{await ht(i,$,{cwd:e})}catch(y){throw n("\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."),new x({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: ${k}`],cause:y})}return n("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:l,filtered:d}}import{randomUUID as wt}from"node:crypto";import*as De from"@clack/prompts";var bt="seed_cli";async function It(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await pe(e))?.telemetry===!1)return!1}catch{}return!0}function Ct(){return wt()}var $t=Ct(),_e=!1;async function Pt(e,{event:t,properties:r={}}){if(!await It(e))return;let n=`${bt}.${t}`;_e||(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)"),_e=!0);try{let i="https://us.i.posthog.com/capture",o={"Content-Type":"application/json"},c={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:n,distinct_id:$t,properties:{...r,$process_person_profile:!1},timestamp:new Date().toISOString()},l=new AbortController,d=setTimeout(()=>l.abort(),5e3);try{await fetch(i,{method:"POST",headers:o,body:JSON.stringify(c),signal:l.signal})}finally{clearTimeout(d)}}catch{}}var z={track:Pt};import*as Y from"@clack/prompts";import xt from"fs-extra";import Rt from"path";import{intersects as kt,satisfies as Et,valid as Me,validRange as Ke}from"semver";var le=["@seed-design/react","@seed-design/css"],Oe="workspace:",St="npm:";function oe(e){try{let t=se(e),r={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},s={};for(let n of le){let i=r[n];typeof i=="string"&&(s[n]=i)}return s}catch{return{}}}function ne({publicRegistries:e,itemKeys:t,projectPackageVersions:r}){let s=Array.from(new Set(t)),n=new Map(e.flatMap(o=>o.items.map(c=>[`${o.id}:${c.id}`,c]))),i=[];for(let o of s){let c=n.get(o);if(!c)continue;let l=vt(c);for(let d of le){let h=Array.from(l[d]??[]);if(!h.length)continue;let b=r[d];if(!b){i.push({itemKey:o,packageName:d,requiredRanges:h,type:"missing-package"});continue}let $=At(b);if(!$){i.push({itemKey:o,packageName:d,requiredRanges:h,installedVersionSpec:b,type:"invalid-version-spec"});continue}h.every(y=>jt({currentVersionSpec:$,requiredRange:y}))||i.push({itemKey:o,packageName:d,requiredRanges:h,installedVersionSpec:b,type:"incompatible-version"})}}return{checkedItemKeys:s,projectPackageVersions:r,issues:i}}function ae({report:e,title:t}){if(!e.issues.length)return;Y.log.warn(t),Y.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${le.map(s=>`${s}@${a(e.projectPackageVersions[s]??"\uBBF8\uC124\uCE58")}`).join(", ")}`);let r=new Map;for(let s of e.issues){let n=r.get(s.itemKey)??[];n.push(s),r.set(s.itemKey,n)}for(let[s,n]of r.entries()){Y.log.warn(a(s));for(let i of n){let o=i.requiredRanges.join(" | ");if(i.type==="missing-package"){Y.log.info(` - ${i.packageName}: \uD328\uD0A4\uC9C0\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC694. \uD544\uC694 \uBC94\uC704: ${o}`);continue}if(i.type==="invalid-version-spec"){Y.log.info(` - ${i.packageName}: \uD604\uC7AC \uBC84\uC804 \uD615\uC2DD\uC744 \uD574\uC11D\uD558\uC9C0 \uBABB\uD588\uC5B4\uC694 (${i.installedVersionSpec}). \uD544\uC694 \uBC94\uC704: ${o}`);continue}Y.log.info(` - ${i.packageName}: \uD604\uC7AC ${i.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${o}`)}}}function Ne({publicRegistries:e,rootPath:t}){let r=[];for(let s of e)for(let n of s.items)n.snippets.some(o=>Tt(o.path).some(c=>xt.existsSync(Rt.join(t,s.id,c))))&&r.push(`${s.id}:${n.id}`);return r}function vt(e){let t=Object.fromEntries(le.map(r=>[r,new Set]));for(let r of e.snippets)for(let[s,n]of Object.entries(r.dependencies??{}))_t(s)&&t[s].add(n);return t}function At(e){let t=e.trim();if(t.startsWith(Oe)&&(t=t.slice(Oe.length).trim()),t.startsWith(St)){let r=t.split("@").at(-1);if(!r)return null;t=r}return!t||t==="*"?null:Me(t)||Ke(t)?t:null}function jt({currentVersionSpec:e,requiredRange:t}){let r=Ke(t);return r?Me(e)?Et(e,r,{includePrerelease:!0}):kt(e,r,{includePrerelease:!0}):!1}function Tt(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 _t(e){return le.includes(e)}var Ot=X.object({itemIds:X.array(X.string()).optional(),all:X.boolean(),cwd:X.string(),baseUrl:X.string().optional(),onDiff:X.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:ie}).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,r)=>{let s=Date.now(),n=L(r);C.intro("seed-design add");try{let i=Ot.safeParse({itemIds:t,...r});if(!i.success)throw i.error;let{data:{all:o,...c}}=i;if(o)throw new x({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 l=c.cwd,d=c.baseUrl,h=await de(l),b=Dt.resolve(l,h.path),{start:$,stop:k}=C.spinner();$("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let p=await Promise.all((await ee({baseUrl:d})).map(async({id:m})=>te({baseUrl:d,registryId:m})));return k("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),p}catch(p){throw k("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),p}})(),f=await(async()=>{if(c.itemIds?.length)return c.itemIds;let p=await C.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:y.filter(({hideFromCLICatalog:m})=>!m).flatMap(({id:m,items:R})=>R.filter(({hideFromCLICatalog:T})=>!T).sort((T,A)=>T.id.localeCompare(A.id)).map(({id:T,description:A,deprecated:N})=>({label:`${N?"(deprecated) ":""}${a(m)}:${T}`,value:`${m}:${T}`,hint:A,deprecated:N,registryItemCount:R.length}))).sort((m,R)=>m.deprecated!==R.deprecated?m.deprecated?1:-1:R.registryItemCount-m.registryItemCount)});if(C.isCancel(p))throw new E;return p})();if(!f?.length)throw new E("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");C.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${a(f.join(", "))}`);let g=[];for(let p of f){let[m,...R]=p.split(":"),T=R.join(":");if(!m||!T)throw new x({message:`${a(p)}: \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 A=y.find(N=>N.id===m)?.items.find(N=>N.id===T);if(!A)throw new x({message:`${a(p)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(A.deprecated){let N=await C.confirm({message:`${a(A.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(C.isCancel(N))throw new E;if(N===!1){C.log.info(`${a(A.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}g.push(p)}let{registryItemsToAdd:w,npmDependenciesToAdd:v}=fe({selectedItemKeys:g,publicRegistries:y}),J=ne({publicRegistries:y,itemKeys:w.flatMap(({registryId:p,items:m})=>m.map(R=>`${p}:${R.id}`)),projectPackageVersions:oe(c.cwd)});ae({report:J,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."}),C.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${a(w.map(p=>p.items.map(m=>`${p.registryId}:${m.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(v).join(", ")||"\uC5C6\uC74C")}`),await ue({registryItemsToAdd:w,rootPath:b,cwd:l,baseUrl:d,config:h,onDiff:c.onDiff});let{installed:V,filtered:K}=await ye({cwd:l,deps:Array.from(v)});V.size===0&&C.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),V.size&&(C.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(V).join(", "))}`),K.size&&C.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(K).join(", "))}`)),C.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let Z=Date.now()-s,ce=new Set(w.map(p=>p.registryId)),I=f.some(p=>{let[m,...R]=p.split(":"),T=R.join(":");return y.find(A=>A.id===m)?.items.find(A=>A.id===T)?.deprecated});try{await z.track(c.cwd,{event:"add",properties:{items_count:g.length,registries:Array.from(ce),has_deprecated:I,dependencies_count:v.size,duration_ms:Z}})}catch(p){n&&console.error("[Telemetry] add tracking failed:",p)}}catch(i){U(i)&&(C.outro(a(i.message)),process.exit(0)),B(i,{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 P from"@clack/prompts";import Mt from"path";import{z as H}from"zod";var Kt=H.object({registryIds:H.array(H.string()).optional(),all:H.boolean(),includeDeprecated:H.boolean().optional(),cwd:H.string(),baseUrl:H.string().optional(),onDiff:H.enum(["overwrite","backup"]).optional()}),ze=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:ie}).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,r)=>{let s=Date.now(),n=L(r);P.intro("seed-design add-all");try{let i=Kt.safeParse({registryIds:t,...r});if(!i.success)throw i.error;let{data:o}=i,c=o.cwd,l=o.baseUrl,d=await de(c),h=Mt.resolve(c,d.path),{start:b,stop:$}=P.spinner();b("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let k=await(async()=>{try{let I=await Promise.all((await ee({baseUrl:l})).map(async({id:p})=>te({baseUrl:l,registryId:p})));return $("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),I}catch(I){throw $("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),I}})(),y=await(async()=>{if(o.all){let p=k.map(m=>m.id);return P.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(p.join(", "))}`),p}if(o.registryIds?.length){let p=k.map(m=>m.id);for(let m of o.registryIds)if(!p.includes(m))throw new x({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${m}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${p.join(", ")}`]});return P.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(o.registryIds.join(", "))}`),o.registryIds}let I=await P.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:k.filter(({hideFromCLICatalog:p})=>!p).sort((p,m)=>m.items.length-p.items.length).map(p=>{let m=p.items[0]?.id,R=m?`${p.items.length}\uAC1C \uD56D\uBAA9 (${m} \uB4F1)`:`${p.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:p.id,value:p.id,hint:R}})});if(P.isCancel(I))throw new E;return P.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(I.join(", "))}`),I})(),f=k.filter(I=>y.includes(I.id)),g=f.flatMap(I=>I.items.filter(p=>p.deprecated?o.includeDeprecated:!0).map(p=>`${I.id}:${p.id}`)),w=f.reduce((I,p)=>I+p.items.filter(m=>m.deprecated).length,0);if(!o.includeDeprecated&&w>0&&P.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.`),!g.length)throw new E("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");P.log.message(`\uCD1D ${a(g.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:v,npmDependenciesToAdd:J}=fe({selectedItemKeys:g,publicRegistries:k}),V=ne({publicRegistries:k,itemKeys:v.flatMap(({registryId:I,items:p})=>p.map(m=>`${I}:${m.id}`)),projectPackageVersions:oe(o.cwd)});ae({report:V,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 ue({registryItemsToAdd:v,rootPath:h,cwd:c,baseUrl:l,config:d,onDiff:o.onDiff});let{installed:K,filtered:Z}=await ye({cwd:c,deps:Array.from(J)});K.size===0&&P.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),K.size&&(P.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(K).join(", "))}`),Z.size&&P.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(Z).join(", "))}`)),P.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let ce=Date.now()-s;try{await z.track(o.cwd,{event:"add-all",properties:{registries:y,items_count:g.length,include_deprecated:o.includeDeprecated||!1,dependencies_count:J.size,duration_ms:ce}})}catch(I){n&&console.error("[Telemetry] add-all tracking failed:",I)}}catch(i){U(i)&&(P.outro(a(i.message)),process.exit(0)),B(i,{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 S from"@clack/prompts";import Ve from"path";import{z as O}from"zod";var Nt=O.object({itemIds:O.array(O.string()).optional(),component:O.union([O.string(),O.array(O.string())]).optional(),all:O.boolean(),registry:O.string().optional(),cwd:O.string(),baseUrl:O.string().optional()});function Ft({itemIds:e,component:t}){let r=i=>i.trim().replace(/\s+/g,"-"),s=(e??[]).map(r).filter(Boolean),n=(Array.isArray(t)?t:[t]).filter(i=>!!i).flatMap(i=>i.split(",")).map(r).filter(Boolean);return Array.from(new Set([...s,...n]))}function zt({publicRegistries:e,targetInputs:t,defaultRegistry:r}){let s=e.filter(i=>typeof i.id=="string"&&Array.isArray(i.items)).flatMap(i=>i.items.filter(o=>typeof o.id=="string").map(o=>`${i.id}:${o.id}`)),n=new Set;for(let i of t){let o=i.includes(":")?i:r?`${r}:${i}`:(()=>{let c=s.filter(l=>l.endsWith(`:${i}`));if(!c.length)throw new x({message:`${a(i)}: \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 x({message:`${a(i)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:c.map(l=>`- ${l}`),hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});return c[0]})();if(!s.includes(o))throw new x({message:`${a(o)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});n.add(o)}return Array.from(n)}var Ue=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:ie}).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,r)=>{let s=Date.now(),n=L(r);S.intro("seed-design compat");try{let i=Nt.safeParse({itemIds:t,...r});if(!i.success)throw i.error;let{data:o}=i,{start:c,stop:l}=S.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let d=await(async()=>{try{let f=await Promise.all((await ee({baseUrl:o.baseUrl})).map(async({id:g})=>te({baseUrl:o.baseUrl,registryId:g})));return l("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw l("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),h=Ft({itemIds:o.itemIds,component:o.component}),b=o.all?d.flatMap(g=>g.items.map(w=>`${g.id}:${w.id}`)):h.length>0?zt({publicRegistries:d,targetInputs:h,defaultRegistry:o.registry}):pe(o.cwd),$=Array.isArray(b)?b:await(async()=>{let f=await b;if(!f)throw new x({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 g=Ve.resolve(o.cwd,f.path),w=Ne({publicRegistries:d,rootPath:g});return w.length?w:(S.log.info(`${a(Ve.relative(o.cwd,g)||f.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();$.length||(S.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let k=oe(o.cwd),y=ne({publicRegistries:d,itemKeys:$,projectPackageVersions:k});if(S.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${a(y.checkedItemKeys.join(", "))}`),!y.issues.length){S.outro("\uBAA8\uB4E0 \uC2A4\uB2C8\uD3AB\uC774 \uD604\uC7AC @seed-design/react, @seed-design/css\uC640 \uD638\uD658\uB3FC\uC694.");try{await z.track(o.cwd,{event:"compat",properties:{checked_items_count:y.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-s}})}catch(f){n&&console.error("[Telemetry] compat tracking failed:",f)}process.exit(0)}ae({report:y,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),S.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."),S.outro("\uD638\uD658\uC131 \uC774\uC288\uAC00 \uC788\uC5B4\uC694.");try{await z.track(o.cwd,{event:"compat",properties:{checked_items_count:y.checkedItemKeys.length,incompatible_items_count:new Set(y.issues.map(f=>f.itemKey)).size,issue_count:y.issues.length,duration_ms:Date.now()-s}})}catch(f){n&&console.error("[Telemetry] compat tracking failed:",f)}process.exit(1)}catch(i){U(i)&&(S.outro(a(i.message)),process.exit(0)),B(i,{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 j from"@clack/prompts";import{z as he}from"zod";import Vt from"dedent";var Ut=he.object({cwd:he.string(),yes:he.boolean().optional(),default:he.boolean().optional()}),Le=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 r=Date.now(),s=L(t);j.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let n=Ut.safeParse(t);if(!n.success)throw n.error;let i=n.data,o=i.yes||i.default,c=o?_:await $e(),{start:l,stop:d}=j.spinner();l("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let h=await(async()=>{try{return(await me({cwd:i.cwd,config:c})).relativePath}catch($){throw d("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),$}})();d(`seed-design.json \uD30C\uC77C\uC774 ${a(h)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),j.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),j.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.")),j.note(Vt(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
10
11
 
11
12
  \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
13
+ \u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
14
+ \u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
14
15
 
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();
16
+ \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),j.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let b=Date.now()-r;try{await z.track(i.cwd,{event:"init",properties:{tsx:c.tsx,rsc:c.rsc,telemetry:c.telemetry,yes_option:o,duration_ms:b}})}catch($){s&&console.error("[Telemetry] init tracking failed:",$)}}catch(n){U(n)&&(j.outro(a(n.message)),process.exit(0)),B(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:s}),process.exit(1)}})};import{cac as Lt}from"cac";var Bt="seed-design",q=Lt(Bt);async function Gt(){let e=se();q.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),Fe(q),ze(q),Ue(q),Le(q),q.version(e.version||"1.0.0","-v, --version"),q.help(),q.parse()}Gt();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-design/cli",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
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
  };