@seed-design/cli 1.2.0 → 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 $e}from"cosmiconfig";import{execa as Ie}from"execa";import{z}from"zod";import be from"picocolors";var i=e=>be.cyan(e);import{detect as xe}from"@antfu/ni";async function B(e){let t=await xe({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}var se="seed-design",Pe=$e(se,{searchPlaces:[`${se}.json`]}),oe=z.object({$schema:z.string().optional(),rsc:z.coerce.boolean().default(!1),tsx:z.coerce.boolean().default(!0),path:z.string(),telemetry:z.coerce.boolean().optional().default(!0)}).strict();async function M(e){let t=await Se(e);return t?oe.parse(t):null}async function Se(e){try{let t=await Pe.search(e);return oe.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 Ie(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(S=>S.id===n.registryId)?.items.find(S=>S.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()}))}))}),ie=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}=ie.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 ve({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 ne({baseUrl:e,registryId:t,registryItemIds:o}){return await Promise.all(o.map(async c=>{try{return await ve({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 Ae}from"fs";import{tmpdir as _e}from"os";import pe from"path";import{transformFromAstSync as Re}from"@babel/core";import Te from"@babel/plugin-transform-typescript";import*as G from"recast";import{parse as je}from"@babel/parser";var Ce={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"]},ae=async({sourceFile:e,config:t})=>{let o=e.getFullText();if(t.tsx)return o;let c=G.parse(o,{parser:{parse:r=>je(r,Ce)}}),l=Re(c,o,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Te],configFile:!1});if(!l||!l.ast)throw new Error("Failed to transform JSX");return G.print(l.ast).code};import{SyntaxKind as Ee}from"ts-morph";var ce=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let o=e.getFirstChildByKind(Ee.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 De,ScriptKind as Oe}from"ts-morph";var ke=[ce],Fe=new De({compilerOptions:{}});async function ze(e){let t=await Ae.mkdtemp(pe.join(_e(),"seed-design-"));return pe.join(t,e)}async function le(e){let t=await ze(e.filename),o=Fe.createSourceFile(t,e.raw,{scriptKind:Oe.TSX});for(let c of ke)c({sourceFile:o,...e});return await ae({sourceFile:o,...e})}import*as E from"@clack/prompts";import U from"fs-extra";import A from"path";import{createPatch as Me}from"diff";import Ue from"@npmcli/disparity-colors";async function Y({registryItemsToAdd:e,rootPath:t,cwd:o,baseUrl:c,config:l,overwrite:r=!1}){let a=[];for(let{registryId:p,items:n}of e){let u=A.join(t,p);U.ensureDirSync(u);let $=await ne({baseUrl:c,registryId:p,registryItemIds:n.map(S=>S.id)});for(let{id:S,snippets:D}of $){let I=await Promise.all(D.map(async x=>{let y=await le({filename:x.path,config:l,raw:x.content}),b=A.join(u,x.path);return l.tsx||(b=b.replace(/\.tsx$/,".jsx"),b=b.replace(/\.ts$/,".js")),{filePath:b,content:y,relativePath:A.relative(o,b),name:`${p}:${S}`}})),T=[];for(let x of I){let{filePath:y,content:b,relativePath:j}=x;if(await U.ensureDir(A.dirname(y)),U.existsSync(y)){let O=await U.readFile(y,"utf-8");if(O===b){E.log.info(`${i(j)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}if(!r){let N=Me(j,O,b),w=Ue(N);E.log.message(`
5
- ${i(j)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
6
- `),E.log.message(w);let s=A.basename(y),m=A.extname(y),C=A.basename(y,m),v=Date.now(),P=`legacy-${C}-${v}${m}`,R=await E.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:`${s} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${P}\uC73C\uB85C \uC62E\uAE30\uACE0 ${s} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]});if(E.isCancel(R)||R==="skip"){E.log.info(`${i(j)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(R==="backup"){let we=A.dirname(y),re=A.join(we,P);await U.rename(y,re),E.log.info(`${i(j)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${i(A.relative(o,re))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}}await U.writeFile(y,b),T.push(x)}if(T.length>0){let x=T.map(({name:y,relativePath:b})=>({name:y,path:b}));a.push(...x),E.log.success(`${i(`${p}:${S}`)} \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 We from"path";import{z as F}from"zod";var X="https://seed-design.io";import*as me from"@clack/prompts";import{execa as Je}from"execa";import Le from"findup-sync";import Ke from"fs-extra";var Ne="package.json";function Be(){let e=Le(Ne);if(!e)throw new Error("No package.json file found in the project.");return e}function q(){let e=Be();return Ke.readJSONSync(e)}async function W({cwd:e,deps:t,dev:o=!1}){let{start:c,stop:l}=me.spinner(),r=await B(e),p={...q().dependencies},n=new Set(t.filter(I=>!p[I])),u=new Set(t.filter(I=>p[I]));if(!n.size)return{installed:new Set,filtered:n};c("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let D=[r==="npm"?"install":"add",o?"-D":null,...n].filter(Boolean);try{await Je(r,D,{cwd:e})}catch(I){console.error(`\uC758\uC874\uC131 \uC124\uCE58 \uC2E4\uD328: ${I}`),process.exit(1)}return l("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:n,filtered:u}}import{randomUUID as He}from"node:crypto";import*as fe from"@clack/prompts";var Ve="seed_cli";async function Ge(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await M(e))?.telemetry===!1)return!1}catch{}return!0}function Ye(){return He()}var Xe=Ye(),de=!1;async function qe(e,{event:t,properties:o={}}){if(!await Ge(e))return;let l=`${Ve}.${t}`;de||(fe.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)"),de=!0);try{let r="https://us.i.posthog.com/capture",a={"Content-Type":"application/json"},p={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:l,distinct_id:Xe,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 L={track:qe};var Qe=F.object({itemIds:F.array(F.string()).optional(),all:F.boolean(),cwd:F.string(),baseUrl:F.string().optional(),overwrite:F.boolean().optional()}),ge=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("--overwrite","Overwrite existing files without confirmation",{default:!1}).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 M(n),S=We.resolve(n,$.path),{start:D,stop:I}=d.spinner();D("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let T=await Promise.all((await H({baseUrl:u})).map(async({id:s})=>V({baseUrl:u,registryId:s})));I("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:T.filter(({hideFromCLICatalog:m})=>!m).flatMap(({id:m,items:C})=>C.filter(({hideFromCLICatalog:v})=>!v).sort((v,P)=>v.id.localeCompare(P.id)).map(({id:v,description:P,deprecated:R})=>({label:`${R?"(deprecated) ":""}${i(m)}:${v}`,value:`${m}:${v}`,hint:P,deprecated:R,registryItemCount:C.length}))).sort((m,C)=>m.deprecated!==C.deprecated?m.deprecated?1:-1:C.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,...C]=s.split(":"),v=C.join(":");(!m||!v)&&(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 P=T.find(R=>R.id===m)?.items.find(R=>R.id===v);if(P||(d.log.error(`${i(s)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`),process.exit(1)),P.deprecated){let R=await d.confirm({message:`${i(P.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(R===!1||d.isCancel(R)){d.log.info(`${i(P.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}y.push(s)}let{registryItemsToAdd:b,npmDependenciesToAdd:j}=J({selectedItemKeys:y,publicRegistries:T});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(j).join(", ")||"\uC5C6\uC74C")}`),await Y({registryItemsToAdd:b,rootPath:S,cwd:n,baseUrl:u,config:$,overwrite:a.overwrite});try{let{installed:s,filtered:m}=await W({cwd:n,deps:Array.from(j)});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,N=new Set(b.map(s=>s.registryId)),w=x.some(s=>{let[m,...C]=s.split(":"),v=C.join(":");return T.find(P=>P.id===m)?.items.find(P=>P.id===v)?.deprecated});await L.track(a.cwd,{event:"add",properties:{items_count:y.length,registries:Array.from(N),has_deprecated:w,dependencies_count:j.size,duration_ms:O}})})};import*as g from"@clack/prompts";import Ze from"path";import{z as _}from"zod";var et=_.object({registryIds:_.array(_.string()).optional(),all:_.boolean(),includeDeprecated:_.boolean().optional(),cwd:_.string(),baseUrl:_.string().optional(),overwrite:_.boolean().optional()}),ue=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("--overwrite","Overwrite existing files without confirmation",{default:!1}).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}=et.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 M(p),$=Ze.resolve(p,u.path),{start:S,stop:D}=g.spinner();S("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let I=await Promise.all((await H({baseUrl:n})).map(async({id:w})=>V({baseUrl:n,registryId:w})));D("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694.");let T=await(async()=>{if(r.all){let s=I.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=I.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 w=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:I.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(w)&&(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(w.join(", "))}`),w})(),x=I.filter(w=>T.includes(w.id)),y=x.flatMap(w=>w.items.filter(s=>s.deprecated?r.includeDeprecated:!0).map(s=>`${w.id}:${s.id}`)),b=x.flatMap(w=>w.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:j,npmDependenciesToAdd:O}=J({selectedItemKeys:y,publicRegistries:I});await Y({registryItemsToAdd:j,rootPath:$,cwd:p,baseUrl:n,config:u,overwrite:r.overwrite});try{let{installed:w,filtered:s}=await W({cwd:p,deps:Array.from(O)});w.size===0&&g.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),w.size&&(g.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${i(Array.from(w).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(w){g.log.error(`\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${w}`),g.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let N=Date.now()-c;await L.track(r.cwd,{event:"add-all",properties:{registries:T,items_count:y.length,include_deprecated:r.includeDeprecated||!1,dependencies_count:O.size,duration_ms:N}})})};import*as h from"@clack/prompts";import tt from"fs-extra";import ye from"path";import{z as te}from"zod";import rt from"dedent";var st=te.object({cwd:te.string(),yes:te.boolean().optional()}),he=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();h.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");let c=st.parse(t),l=c.yes,r={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};l||(r={...await h.group({tsx:()=>h.confirm({message:`${i("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!0}),rsc:()=>h.confirm({message:`${i("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:!1}),path:()=>h.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:()=>h.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${i("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:!0})},{onCancel:()=>{h.cancel("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."),process.exit(0)}})});try{let{start:p,stop:n}=h.spinner();p("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let u=ye.resolve(c.cwd,"seed-design.json");await tt.writeFile(u,`${JSON.stringify(r,null,2)}
9
- `,"utf-8");let $=ye.relative(process.cwd(),u);n(`seed-design.json \uD30C\uC77C\uC774 ${i($)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),h.log.info(i("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),h.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.")),h.note(rt(`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"),h.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.")}catch(p){h.log.error(`seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694. ${p}`),h.outro(i("\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694.")),process.exit(1)}let a=Date.now()-o;await L.track(c.cwd,{event:"init",properties:{tsx:r.tsx,rsc:r.rsc,telemetry:r.telemetry,yes_option:l,duration_ms:a}})})};import{cac as ot}from"cac";var it="seed-design",K=ot(it);async function nt(){let e=q();ge(K),ue(K),he(K),K.version(e.version||"1.0.0","-v, --version"),K.help(),K.parse()}nt();
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.0",
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({
@@ -18,7 +30,7 @@ const addAllOptionsSchema = z.object({
18
30
  includeDeprecated: z.boolean().optional(),
19
31
  cwd: z.string(),
20
32
  baseUrl: z.string().optional(),
21
- overwrite: z.boolean().optional(),
33
+ onDiff: z.enum(["overwrite", "backup"]).optional(),
22
34
  });
23
35
 
24
36
  export const addAllCommand = (cli: CAC) => {
@@ -38,138 +50,159 @@ export const addAllCommand = (cli: CAC) => {
38
50
  "the base url of the registry. defaults to the current directory.",
39
51
  { default: BASE_URL },
40
52
  )
41
- .option("--overwrite", "Overwrite existing files without confirmation", {
42
- default: false,
43
- })
53
+ .option("--on-diff <mode>", "Action when file differs: overwrite or backup")
44
54
  .example("seed-design add-all ui --include-deprecated")
45
55
  .example("seed-design add-all ui lib breeze")
46
56
  .action(async (registryIds, opts) => {
47
57
  const startTime = Date.now();
58
+ const verbose = isVerboseMode(opts);
48
59
  p.intro("seed-design add-all");
49
60
 
50
- const {
51
- success,
52
- data: options,
53
- error,
54
- } = addAllOptionsSchema.safeParse({ registryIds, ...opts });
55
-
56
- if (!success) {
57
- p.log.error(`잘못된 옵션이에요: ${error?.message}`);
58
-
59
- process.exit(1);
60
- }
61
-
62
- const cwd = options.cwd;
63
- const baseUrl = options.baseUrl;
64
- const config = await getConfig(cwd);
65
- 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
+ }
66
66
 
67
- const { start, stop } = p.spinner();
67
+ const { data: options } = parsed;
68
68
 
69
- 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);
70
73
 
71
- const publicRegistries = await Promise.all(
72
- (await fetchAvailableRegistries({ baseUrl })).map(async ({ id }) =>
73
- fetchRegistry({ baseUrl, registryId: id }),
74
- ),
75
- );
74
+ const { start, stop } = p.spinner();
75
+ start("Registry를 가져오고 있어요...");
76
76
 
77
- 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를 가져왔어요.");
78
85
 
79
- const selectedRegistryIds: string[] = await (async () => {
80
- if (options.all) {
81
- const ids = publicRegistries.map((r) => r.id);
82
- p.log.message(`모든 레지스트리의 모든 항목을 추가합니다: ${highlight(ids.join(", "))}`);
86
+ return registries;
87
+ } catch (error) {
88
+ stop("Registry를 가져오지 못했어요.");
89
+ throw error;
90
+ }
91
+ })();
83
92
 
84
- return ids;
85
- }
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(", "))}`);
86
97
 
87
- if (options.registryIds?.length) {
88
- const availableIds = publicRegistries.map((r) => r.id);
98
+ return ids;
99
+ }
89
100
 
90
- for (const registryId of options.registryIds) {
91
- if (!availableIds.includes(registryId)) {
92
- p.log.error(`레지스트리 '${registryId}'를 찾을 수 없어요.`);
93
- p.log.info(`사용 가능한 레지스트리: ${availableIds.join(", ")}`);
101
+ if (options.registryIds?.length) {
102
+ const availableIds = publicRegistries.map((r) => r.id);
94
103
 
95
- 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
+ }
96
111
  }
97
- }
98
112
 
99
- p.log.message(
100
- `선택된 레지스트리의 모든 항목을 추가합니다: ${highlight(options.registryIds.join(", "))}`,
101
- );
113
+ p.log.message(
114
+ `선택된 레지스트리의 모든 항목을 추가합니다: ${highlight(options.registryIds.join(", "))}`,
115
+ );
102
116
 
103
- return options.registryIds;
104
- }
117
+ return options.registryIds;
118
+ }
105
119
 
106
- const selected = await p.multiselect({
107
- message: "추가할 레지스트리를 선택해주세요 (스페이스 바로 여러 개 선택 가능)",
108
- options: publicRegistries
109
- .filter(({ hideFromCLICatalog }) => !hideFromCLICatalog)
110
- .sort((a, b) => b.items.length - a.items.length)
111
- .map((registry) => ({
112
- label: registry.id,
113
- value: registry.id,
114
- hint: `${registry.items.length}개 항목 (${registry.items[0].id} 등)`,
115
- })),
116
- });
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
+ }
117
142
 
118
- if (p.isCancel(selected)) {
119
- p.log.error("취소되었어요.");
120
- process.exit(0);
121
- }
143
+ p.log.message(`선택된 레지스트리의 항목을 추가합니다: ${highlight(selected.join(", "))}`);
122
144
 
123
- p.log.message(`선택된 레지스트리의 항목을 추가합니다: ${highlight(selected.join(", "))}`);
145
+ return selected;
146
+ })();
124
147
 
125
- return selected;
126
- })();
148
+ const selectedRegistries = publicRegistries.filter((r) =>
149
+ selectedRegistryIds.includes(r.id),
150
+ );
127
151
 
128
- 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;
129
156
 
130
- const itemKeys = selectedRegistries.flatMap((registry) =>
131
- registry.items
132
- .filter((item) => {
133
- if (item.deprecated) return options.includeDeprecated;
157
+ return true;
158
+ })
159
+ .map((item) => `${registry.id}:${item.id}`),
160
+ );
134
161
 
135
- return true;
136
- })
137
- .map((item) => `${registry.id}:${item.id}`),
138
- );
162
+ const deprecatedCount = selectedRegistries.reduce(
163
+ (count, r) => count + r.items.filter((item) => item.deprecated).length,
164
+ 0,
165
+ );
139
166
 
140
- const deprecatedCount = selectedRegistries.flatMap((r) =>
141
- r.items.filter((item) => item.deprecated).map(() => 1),
142
- ).length;
167
+ if (!options.includeDeprecated && deprecatedCount > 0) {
168
+ p.log.info(
169
+ `${deprecatedCount}개의 deprecated 항목은 제외되었어요. --include-deprecated 옵션을 사용하면 추가할 수 있어요.`,
170
+ );
171
+ }
143
172
 
144
- if (!options.includeDeprecated && deprecatedCount > 0) {
145
- p.log.info(
146
- `${deprecatedCount}개의 deprecated 항목은 제외되었어요. --include-deprecated 옵션을 사용하면 추가할 수 있어요.`,
147
- );
148
- }
173
+ if (!itemKeys.length) {
174
+ throw new CliCancelError("추가할 항목이 없어요.");
175
+ }
149
176
 
150
- if (!itemKeys.length) {
151
- p.log.error("추가할 항목이 없어요.");
177
+ p.log.message(`총 ${highlight(itemKeys.length.toString())}개의 항목을 추가합니다.`);
152
178
 
153
- process.exit(0);
154
- }
179
+ const { registryItemsToAdd, npmDependenciesToAdd } = resolveDependencies({
180
+ selectedItemKeys: itemKeys,
181
+ publicRegistries,
182
+ });
155
183
 
156
- 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
+ });
157
191
 
158
- const { registryItemsToAdd, npmDependenciesToAdd } = resolveDependencies({
159
- selectedItemKeys: itemKeys,
160
- publicRegistries,
161
- });
192
+ logCompatibilityReport({
193
+ report: compatibilityReport,
194
+ title: "현재 프로젝트 버전과 호환되지 않을 수 있는 스니펫이 있어요.",
195
+ });
162
196
 
163
- await writeRegistryItemSnippets({
164
- registryItemsToAdd,
165
- rootPath,
166
- cwd,
167
- baseUrl,
168
- config,
169
- overwrite: options.overwrite,
170
- });
197
+ await writeRegistryItemSnippets({
198
+ registryItemsToAdd,
199
+ rootPath,
200
+ cwd,
201
+ baseUrl,
202
+ config,
203
+ onDiff: options.onDiff,
204
+ });
171
205
 
172
- try {
173
206
  const { installed, filtered } = await installDependencies({
174
207
  cwd,
175
208
  deps: Array.from(npmDependenciesToAdd),
@@ -190,23 +223,37 @@ export const addAllCommand = (cli: CAC) => {
190
223
  }
191
224
 
192
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
+ }
193
245
  } catch (error) {
194
- p.log.error(`추가에 실패했어요. ${error}`);
195
- 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
+ });
196
256
  process.exit(1);
197
257
  }
198
-
199
- // add-all 성공 이벤트 추적
200
- const duration = Date.now() - startTime;
201
- await analytics.track(options.cwd, {
202
- event: "add-all",
203
- properties: {
204
- registries: selectedRegistryIds,
205
- items_count: itemKeys.length,
206
- include_deprecated: options.includeDeprecated || false,
207
- dependencies_count: npmDependenciesToAdd.size,
208
- duration_ms: duration,
209
- },
210
- });
211
258
  });
212
259
  };