@seed-design/cli 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/index.mjs CHANGED
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env node
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")}
2
+ import*as X from"@clack/prompts";import{cosmiconfig as rt}from"cosmiconfig";import{z as te}from"zod";import*as H from"@clack/prompts";import{ZodError as Ze}from"zod";import Qe from"picocolors";var a=e=>Qe.cyan(e);var $=class extends Error{hint;details;constructor({message:t,hint:s,details:o=[],cause:n}){super(t,{cause:n}),this.name="CliError",this.hint=s,this.details=o}},k=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function z(e){return e instanceof k}function F(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function et(e,t){if(e instanceof $)return{reason:e.message,hint:e.hint??t,details:e.details,stack:tt(e.cause??e)};if(e instanceof Ze){let s=e.issues.map(o=>`${o.path.join(".")||"(root)"}: ${o.message}`);return{reason:"\uC785\uB825\uAC12 \uB610\uB294 \uC124\uC815 \uD30C\uC77C \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC544\uC694.",hint:t,details:s,stack:e.stack}}if(e instanceof Error){let s=e,o=[];return(s.escapedCommand||s.command)&&o.push(`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${s.escapedCommand??s.command}`),typeof s.exitCode=="number"&&o.push(`\uC885\uB8CC \uCF54\uB4DC: ${s.exitCode}`),s.stderr?.trim()?o.push(`stderr: ${s.stderr.trim()}`):s.stdout?.trim()&&o.push(`stdout: ${s.stdout.trim()}`),{reason:s.shortMessage??e.message,hint:t,details:o,stack:e.stack}}return typeof e=="string"?{reason:e,hint:t,details:[]}:{reason:"\uC54C \uC218 \uC5C6\uB294 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC5B4\uC694.",hint:t,details:[]}}function tt(e){if(e instanceof Error)return e.stack}function V(e,{defaultMessage:t,defaultHint:s,verbose:o=!1}){let n=et(e,s);H.log.error(t),H.log.error(`\uC6D0\uC778: ${n.reason}`);for(let r of n.details)H.log.info(r);n.hint&&H.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${n.hint}`),o&&n.stack&&(H.log.message(a(`
3
+ [verbose] stack trace`)),H.log.message(n.stack)),H.outro(a("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as W from"@clack/prompts";import st from"fs-extra";import Pe from"path";var K={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function Se(){return await W.group({tsx:()=>W.confirm({message:`${a("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.tsx}),rsc:()=>W.confirm({message:`${a("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.rsc}),path:()=>W.text({message:`${a("seed-design \uD3F4\uB354")} \uACBD\uB85C\uB97C \uC785\uB825\uD574\uC8FC\uC138\uC694. (\uAE30\uBCF8\uAC12\uC740 \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0 \uC0DD\uC131\uB429\uB2C8\uB2E4.)`,initialValue:K.path,defaultValue:K.path,placeholder:K.path}),telemetry:()=>W.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${a("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:K.telemetry})},{onCancel:()=>{throw new k}})}async function fe({cwd:e,config:t}){let s=Pe.resolve(e,"seed-design.json");return await st.writeFile(s,`${JSON.stringify(t,null,2)}
4
+ `,"utf-8"),{relativePath:Pe.relative(process.cwd(),s),targetPath:s}}var Re="seed-design",it=rt(Re,{searchPlaces:[`${Re}.json`]}),Ee=te.object({$schema:te.string().optional(),rsc:te.coerce.boolean().default(!1),tsx:te.coerce.boolean().default(!0),path:te.string(),telemetry:te.coerce.boolean().optional().default(!0)}).strict();async function ge(e){let t=await le(e);if(t)return t;X.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let s=await X.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(X.isCancel(s)||!s)throw new k;try{return await fe({cwd:e,config:K}),X.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),Ee.parse(K)}catch(o){throw new $({message:"seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",hint:"\uB514\uB809\uD1A0\uB9AC \uC4F0\uAE30 \uAD8C\uD55C\uACFC \uACBD\uB85C\uB97C \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uBCF4\uC138\uC694.",cause:o})}}async function le(e){let t=await it.search(e);if(!t||t.isEmpty)return null;try{return Ee.parse(t.config)}catch(s){throw new $({message:"seed-design.json \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC544\uC694.",hint:"https://seed-design.com/react/getting-started/cli/configuration \uBB38\uC11C\uB97C \uCC38\uACE0\uD574 \uC8FC\uC138\uC694.",cause:s})}}function ue({selectedItemKeys:e,publicRegistries:t}){let s=[],o=new Set;function n(r,i){let c=s.find(m=>m.registryId===r);if(!c?.items.some(m=>m.id===i.id)){if(c?c.items.push(i):s.push({registryId:r,items:[i]}),i.dependencies?.length)for(let m of i.dependencies)o.add(m);if(i.innerDependencies?.length)for(let m of i.innerDependencies)for(let y of m.itemIds){let C=t.find(b=>b.id===m.registryId)?.items.find(b=>b.id===y);if(!C)throw new Error(`Cannot find dependency item: ${m.registryId}:${y}`);n(m.registryId,C)}}}for(let r of e){let[i,...c]=r.split(":"),m=c.join(":");if(!i||!m)throw new Error(`Invalid snippet format: "${r}"`);let y=t.find(C=>C.id===i)?.items.find(C=>C.id===m);if(!y)throw new Error(`Cannot find snippet: "${r}"`);n(i,y)}return{registryItemsToAdd:s,npmDependenciesToAdd:o}}import*as $e from"@clack/prompts";import{z as p}from"zod";var Ce=p.object({id:p.string(),description:p.string().optional(),deprecated:p.boolean().optional(),hideFromCLICatalog:p.boolean().optional(),dependencies:p.array(p.string()).optional(),innerDependencies:p.array(p.object({registryId:p.string(),itemIds:p.array(p.string())})).optional(),snippets:p.array(p.object({path:p.string(),dependencies:p.record(p.string(),p.string()).optional(),content:p.string()}))}),Ie=p.object({id:p.string(),hideFromCLICatalog:p.boolean().optional(),items:p.array(Ce.omit({snippets:!0}).extend({snippets:p.array(p.object({path:p.string(),dependencies:p.record(p.string(),p.string()).optional()}))}))}),ke=p.array(p.object({id:p.string()})),ot=p.object({label:p.string(),path:p.string()}),nt=p.object({id:p.string(),title:p.string(),description:p.string().optional(),docUrl:p.string(),deprecated:p.boolean().optional(),snippetKey:p.string().optional(),snippets:p.array(ot).optional()}),at=p.object({id:p.string(),label:p.string(),items:p.array(nt)}),ct=p.object({id:p.string(),label:p.string(),sections:p.array(at)}),ve=p.object({categories:p.array(ct)});async function je({baseUrl:e}){let t=await fetch(`${e}/__docs__/index.json`);if(!t.ok)throw new $({message:`\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${t.status} ${t.statusText}`});let s=await t.json(),{success:o,data:n,error:r}=ve.safeParse(s);if(!o)throw new $({message:`\uBB38\uC11C \uBAA9\uB85D \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694: ${r?.message}`});return n}async function se({baseUrl:e}){let t=await fetch(`${e}/__registry__/index.json`);if(!t.ok)throw new Error(`Failed to fetch registries: ${t.status} ${t.statusText}`);let s=await t.json(),{success:o,data:n,error:r}=ke.safeParse(s);if(!o)throw new Error(`Failed to parse registries: ${r?.message}`);return n}async function re({baseUrl:e,registryId:t}){let s=await fetch(`${e}/__registry__/${t}/index.json`);if(!s.ok)throw new Error(`Failed to fetch ${t} registry: ${s.status} ${s.statusText}`);let o=await s.json(),{success:n,data:r,error:i}=Ie.safeParse(o);if(!n)throw new Error(`Failed to parse ${t} registry: ${i?.message}`);return r}async function pt({baseUrl:e,registryId:t,registryItemId:s}){let o=await fetch(`${e}/__registry__/${t}/${s}.json`);if(!o.ok)throw new Error(`Failed to fetch ${s}: ${o.status} ${o.statusText}`);let n=await o.json(),{success:r,data:i,error:c}=Ce.safeParse(n);if(!r)throw new Error(`Failed to parse ${s}: ${c?.message}`);return i}async function Ae({baseUrl:e,registryId:t,registryItemIds:s}){return await Promise.all(s.map(async o=>{try{return await pt({baseUrl:e,registryId:t,registryItemId:o})}catch(n){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${r.status} ${r.statusText}`);let i=await r.json(),{success:c,data:m}=Ie.safeParse(i);throw c?($e.log.error(`${o} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),$e.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
5
+ ${m.items.map(y=>y.id).join(`
6
+ `)}`),n):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as ut}from"fs";import{tmpdir as yt}from"os";import _e from"path";import{transformFromAstSync as lt}from"@babel/core";import mt from"@babel/plugin-transform-typescript";import*as ye from"recast";import{parse as dt}from"@babel/parser";var ft={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},De=async({sourceFile:e,config:t})=>{let s=e.getFullText();if(t.tsx)return s;let o=ye.parse(s,{parser:{parse:r=>dt(r,ft)}}),n=lt(o,s,{cloneInputAst:!1,code:!1,ast:!0,plugins:[mt],configFile:!1});if(!n||!n.ast)throw new Error("Failed to transform JSX");return ye.print(n.ast).code};import{SyntaxKind as gt}from"ts-morph";var Te=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let s=e.getFirstChildByKind(gt.ExpressionStatement);if(!s)return e;let o=s.getExpression();if(!o)return e;let n=o.getText().trim();if(n!=='"use client"'&&n!=="'use client'")return e;let r=s.getText(),i=s.getFullText();if(r.trim()===i.trim())return e;let m=i.replace(r,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return s.replaceWithText(m),e};import{Project as ht,ScriptKind as wt}from"ts-morph";var bt=[Te],Ct=new ht({compilerOptions:{}});async function It(e){let t=await ut.mkdtemp(_e.join(yt(),"seed-design-"));return _e.join(t,e)}async function Oe(e){let t=await It(e.filename),s=Ct.createSourceFile(t,e.raw,{scriptKind:wt.TSX});for(let o of bt)o({sourceFile:s,...e});return await De({sourceFile:s,...e})}import*as L from"@clack/prompts";import ie from"fs-extra";import q from"path";import{createPatch as $t}from"diff";import xt from"@npmcli/disparity-colors";async function he({registryItemsToAdd:e,rootPath:t,cwd:s,baseUrl:o,config:n,onDiff:r}){let i=[];for(let{registryId:c,items:m}of e){let y=q.join(t,c);ie.ensureDirSync(y);let C=await Ae({baseUrl:o,registryId:c,registryItemIds:m.map(b=>b.id)});for(let{id:b,snippets:h}of C){let j=await Promise.all(h.map(async g=>{let d=await Oe({filename:g.path,config:n,raw:g.content}),w=q.join(y,g.path);return n.tsx||(w=w.replace(/\.tsx$/,".jsx"),w=w.replace(/\.ts$/,".js")),{filePath:w,content:d,relativePath:q.relative(s,w),name:`${c}:${b}`}})),f=[];for(let g of j){let{filePath:d,content:w,relativePath:I}=g;if(await ie.ensureDir(q.dirname(d)),ie.existsSync(d)){let E=await ie.readFile(d,"utf-8");if(E===w){L.log.info(`${a(I)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let P=q.basename(d),O=q.extname(d),ee=q.basename(d,O),pe=Date.now(),x=`legacy-${ee}-${pe}${O}`,l=await(async()=>{if(r)return r;let u=$t(I,E,w),A=xt(u);return L.log.message(`
7
+ ${a(I)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
8
+ `),L.log.message(A),L.select({message:"\uD604\uC7AC \uD30C\uC77C\uC5D0 \uC2A4\uD0C0\uC77C \uBCC0\uACBD, \uB85C\uAE45 \uB4F1 \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC774 \uC801\uC6A9\uB418\uC5B4 \uC788\uB294 \uACBD\uC6B0 \uC2E0\uADDC \uD30C\uC77C\uC5D0 \uB3D9\uC77C\uD55C \uCEE4\uC2A4\uD130\uB9C8\uC774\uC9D5\uC744 \uC801\uC6A9\uD558\uB294 \uAC83\uC744 \uAC80\uD1A0\uD574\uBCF4\uC138\uC694.",options:[{value:"overwrite",label:`${P} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${x}\uC73C\uB85C \uC62E\uAE30\uACE0 ${P} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(L.isCancel(l)||l==="skip"){L.log.info(`${a(I)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(l==="backup"){let u=q.dirname(d),A=q.join(u,x);await ie.rename(d,A),L.log.info(`${a(I)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${a(q.relative(s,A))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await ie.writeFile(d,w),f.push(g)}if(f.length>0){let g=f.map(({name:d,relativePath:w})=>({name:d,path:w}));i.push(...g),L.log.success(`${a(`${c}:${b}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${a(g.map(d=>d.path).join(", "))}`)}}}}import*as S from"@clack/prompts";import Gt from"path";import{z as Z}from"zod";var B="https://seed-design.io";import*as Ke from"@clack/prompts";import{execa as vt}from"execa";import{detect as Pt}from"@antfu/ni";async function Me(e){let t=await Pt({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import St from"findup-sync";import Rt from"fs-extra";var Et="package.json";function kt(e=process.cwd()){let t=St(Et,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function oe(e=process.cwd()){let t=kt(e);return Rt.readJSONSync(t)}async function we({cwd:e,deps:t,dev:s=!1}){let{start:o,stop:n}=Ke.spinner(),r=await Me(e),c={...oe(e).dependencies},m=new Set(t.filter(f=>!c[f])),y=new Set(t.filter(f=>c[f]));if(!m.size)return{installed:new Set,filtered:m};o("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let h=[r==="npm"?"install":"add",s?"-D":null,...m].filter(Boolean),j=`${r} ${h.join(" ")}`;try{await vt(r,h,{cwd:e})}catch(f){throw n("\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."),new $({message:"\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",hint:"\uB124\uD2B8\uC6CC\uD06C \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0, \uC124\uCE58 \uBA85\uB839\uC5B4\uB97C \uC9C1\uC811 \uC2E4\uD589\uD574 \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",details:[`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${j}`],cause:f})}return n("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:m,filtered:y}}import{randomUUID as jt}from"node:crypto";import*as Ue from"@clack/prompts";var At="seed_cli";async function Dt(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await le(e))?.telemetry===!1)return!1}catch{}return!0}function Tt(){return jt()}var _t=Tt(),Le=!1;async function Ot(e,{event:t,properties:s={}}){if(!await Dt(e))return;let n=`${At}.${t}`;Le||(Ue.log.info("\u{1F4CA} \uC0AC\uC6A9 \uB370\uC774\uD130 \uC218\uC9D1 \uC911 (\uBE44\uD65C\uC131\uD654: seed-design.json \uB610\uB294 DISABLE_TELEMETRY \uD658\uACBD \uBCC0\uC218)"),Le=!0);try{let r="https://us.i.posthog.com/capture",i={"Content-Type":"application/json"},c={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:n,distinct_id:_t,properties:{...s,$process_person_profile:!1},timestamp:new Date().toISOString()},m=new AbortController,y=setTimeout(()=>m.abort(),5e3);try{await fetch(r,{method:"POST",headers:i,body:JSON.stringify(c),signal:m.signal})}finally{clearTimeout(y)}}catch{}}var U={track:Ot};import*as Q from"@clack/prompts";import Mt from"fs-extra";import Kt from"path";import{intersects as Lt,satisfies as Ut,valid as ze,validRange as Fe}from"semver";var me=["@seed-design/react","@seed-design/css"],Ne="workspace:",Nt="npm:";function ne(e){try{let t=oe(e),s={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},o={};for(let n of me){let r=s[n];typeof r=="string"&&(o[n]=r)}return o}catch{return{}}}function ae({publicRegistries:e,itemKeys:t,projectPackageVersions:s}){let o=Array.from(new Set(t)),n=new Map(e.flatMap(i=>i.items.map(c=>[`${i.id}:${c.id}`,c]))),r=[];for(let i of o){let c=n.get(i);if(!c)continue;let m=zt(c);for(let y of me){let C=Array.from(m[y]??[]);if(!C.length)continue;let b=s[y];if(!b){r.push({itemKey:i,packageName:y,requiredRanges:C,type:"missing-package"});continue}let h=Ft(b);if(!h){r.push({itemKey:i,packageName:y,requiredRanges:C,installedVersionSpec:b,type:"invalid-version-spec"});continue}C.every(f=>Vt({currentVersionSpec:h,requiredRange:f}))||r.push({itemKey:i,packageName:y,requiredRanges:C,installedVersionSpec:b,type:"incompatible-version"})}}return{checkedItemKeys:o,projectPackageVersions:s,issues:r}}function ce({report:e,title:t}){if(!e.issues.length)return;Q.log.warn(t),Q.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${me.map(o=>`${o}@${a(e.projectPackageVersions[o]??"\uBBF8\uC124\uCE58")}`).join(", ")}`);let s=new Map;for(let o of e.issues){let n=s.get(o.itemKey)??[];n.push(o),s.set(o.itemKey,n)}for(let[o,n]of s.entries()){Q.log.warn(a(o));for(let r of n){let i=r.requiredRanges.join(" | ");if(r.type==="missing-package"){Q.log.info(` - ${r.packageName}: \uD328\uD0A4\uC9C0\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC694. \uD544\uC694 \uBC94\uC704: ${i}`);continue}if(r.type==="invalid-version-spec"){Q.log.info(` - ${r.packageName}: \uD604\uC7AC \uBC84\uC804 \uD615\uC2DD\uC744 \uD574\uC11D\uD558\uC9C0 \uBABB\uD588\uC5B4\uC694 (${r.installedVersionSpec}). \uD544\uC694 \uBC94\uC704: ${i}`);continue}Q.log.info(` - ${r.packageName}: \uD604\uC7AC ${r.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${i}`)}}}function Ve({publicRegistries:e,rootPath:t}){let s=[];for(let o of e)for(let n of o.items)n.snippets.some(i=>qt(i.path).some(c=>Mt.existsSync(Kt.join(t,o.id,c))))&&s.push(`${o.id}:${n.id}`);return s}function zt(e){let t=Object.fromEntries(me.map(s=>[s,new Set]));for(let s of e.snippets)for(let[o,n]of Object.entries(s.dependencies??{}))Bt(o)&&t[o].add(n);return t}function Ft(e){let t=e.trim();if(t.startsWith(Ne)&&(t=t.slice(Ne.length).trim()),t.startsWith(Nt)){let s=t.split("@").at(-1);if(!s)return null;t=s}return!t||t==="*"?null:ze(t)||Fe(t)?t:null}function Vt({currentVersionSpec:e,requiredRange:t}){let s=Fe(t);return s?ze(e)?Ut(e,s,{includePrerelease:!0}):Lt(e,s,{includePrerelease:!0}):!1}function qt(e){let t=new Set([e]);return e.endsWith(".tsx")&&t.add(`${e.slice(0,-4)}.jsx`),e.endsWith(".ts")&&t.add(`${e.slice(0,-3)}.js`),e.endsWith(".jsx")&&t.add(`${e.slice(0,-4)}.tsx`),e.endsWith(".js")&&t.add(`${e.slice(0,-3)}.ts`),Array.from(t)}function Bt(e){return me.includes(e)}var Ht=Z.object({itemIds:Z.array(Z.string()).optional(),all:Z.boolean(),cwd:Z.string(),baseUrl:Z.string().optional(),onDiff:Z.enum(["overwrite","backup"]).optional()}),qe=e=>{e.command("add [...item-ids]","add items").option("-a, --all","[Deprecated] Add all items",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add ui:action-button").example("seed-design add ui:alert-dialog").action(async(t,s)=>{let o=Date.now(),n=F(s);S.intro("seed-design add");try{let r=Ht.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:{all:i,...c}}=r;if(i)throw new $({message:"`--all` \uC635\uC158\uC740 \uB354 \uC774\uC0C1 \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uC544\uC694. \uB300\uC2E0 `seed-design add-all` \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."});let m=c.cwd,y=c.baseUrl,C=await ge(m),b=Gt.resolve(m,C.path),{start:h,stop:j}=S.spinner();h("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let f=await(async()=>{try{let l=await Promise.all((await se({baseUrl:y})).map(async({id:u})=>re({baseUrl:y,registryId:u})));return j("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),l}catch(l){throw j("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),l}})(),g=await(async()=>{if(c.itemIds?.length)return c.itemIds;let l=await S.multiselect({message:"\uCD94\uAC00\uD560 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:f.filter(({hideFromCLICatalog:u})=>!u).flatMap(({id:u,items:A})=>A.filter(({hideFromCLICatalog:M})=>!M).sort((M,T)=>M.id.localeCompare(T.id)).map(({id:M,description:T,deprecated:G})=>({label:`${G?"(deprecated) ":""}${a(u)}:${M}`,value:`${u}:${M}`,hint:T,deprecated:G,registryItemCount:A.length}))).sort((u,A)=>u.deprecated!==A.deprecated?u.deprecated?1:-1:A.registryItemCount-u.registryItemCount)});if(S.isCancel(l))throw new k;return l})();if(!g?.length)throw new k("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");S.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${a(g.join(", "))}`);let d=[];for(let l of g){let[u,...A]=l.split(":"),M=A.join(":");if(!u||!M)throw new $({message:`${a(l)}: \uD56D\uBAA9 \uC774\uB984\uC774 \uC798\uBABB\uB418\uC5C8\uC5B4\uC694.`,hint:`${a("ui:action-button")}\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});let T=f.find(G=>G.id===u)?.items.find(G=>G.id===M);if(!T)throw new $({message:`${a(l)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(T.deprecated){let G=await S.confirm({message:`${a(T.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(S.isCancel(G))throw new k;if(G===!1){S.log.info(`${a(T.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}d.push(l)}let{registryItemsToAdd:w,npmDependenciesToAdd:I}=ue({selectedItemKeys:d,publicRegistries:f}),E=ae({publicRegistries:f,itemKeys:w.flatMap(({registryId:l,items:u})=>u.map(A=>`${l}:${A.id}`)),projectPackageVersions:ne(c.cwd)});ce({report:E,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),S.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${a(w.map(l=>l.items.map(u=>`${l.registryId}:${u.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
9
9
 
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
+ \uC124\uCE58\uD560 \uC758\uC874\uC131: ${a(Array.from(I).join(", ")||"\uC5C6\uC74C")}`),await he({registryItemsToAdd:w,rootPath:b,cwd:m,baseUrl:y,config:C,onDiff:c.onDiff});let{installed:P,filtered:O}=await we({cwd:m,deps:Array.from(I)});P.size===0&&S.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),P.size&&(S.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(P).join(", "))}`),O.size&&S.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(O).join(", "))}`)),S.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let ee=Date.now()-o,pe=new Set(w.map(l=>l.registryId)),x=g.some(l=>{let[u,...A]=l.split(":"),M=A.join(":");return f.find(T=>T.id===u)?.items.find(T=>T.id===M)?.deprecated});try{await U.track(c.cwd,{event:"add",properties:{items_count:d.length,registries:Array.from(pe),has_deprecated:x,dependencies_count:I.size,duration_ms:ee}})}catch(l){n&&console.error("[Telemetry] add tracking failed:",l)}}catch(r){z(r)&&(S.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as v from"@clack/prompts";import Jt from"path";import{z as Y}from"zod";var Wt=Y.object({registryIds:Y.array(Y.string()).optional(),all:Y.boolean(),includeDeprecated:Y.boolean().optional(),cwd:Y.string(),baseUrl:Y.string().optional(),onDiff:Y.enum(["overwrite","backup"]).optional()}),Be=e=>{e.command("add-all [...registry-ids]","add all items from registries").option("-a, --all","Add all items from all registries",{default:!1}).option("--include-deprecated","Include deprecated items when used with `--all`",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add-all ui --include-deprecated").example("seed-design add-all ui lib breeze").action(async(t,s)=>{let o=Date.now(),n=F(s);v.intro("seed-design add-all");try{let r=Wt.safeParse({registryIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.cwd,m=i.baseUrl,y=await ge(c),C=Jt.resolve(c,y.path),{start:b,stop:h}=v.spinner();b("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let j=await(async()=>{try{let x=await Promise.all((await se({baseUrl:m})).map(async({id:l})=>re({baseUrl:m,registryId:l})));return h("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),x}catch(x){throw h("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),x}})(),f=await(async()=>{if(i.all){let l=j.map(u=>u.id);return v.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(l.join(", "))}`),l}if(i.registryIds?.length){let l=j.map(u=>u.id);for(let u of i.registryIds)if(!l.includes(u))throw new $({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${u}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${l.join(", ")}`]});return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(i.registryIds.join(", "))}`),i.registryIds}let x=await v.multiselect({message:"\uCD94\uAC00\uD560 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:j.filter(({hideFromCLICatalog:l})=>!l).sort((l,u)=>u.items.length-l.items.length).map(l=>{let u=l.items[0]?.id,A=u?`${l.items.length}\uAC1C \uD56D\uBAA9 (${u} \uB4F1)`:`${l.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:l.id,value:l.id,hint:A}})});if(v.isCancel(x))throw new k;return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(x.join(", "))}`),x})(),g=j.filter(x=>f.includes(x.id)),d=g.flatMap(x=>x.items.filter(l=>l.deprecated?i.includeDeprecated:!0).map(l=>`${x.id}:${l.id}`)),w=g.reduce((x,l)=>x+l.items.filter(u=>u.deprecated).length,0);if(!i.includeDeprecated&&w>0&&v.log.info(`${w}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),!d.length)throw new k("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");v.log.message(`\uCD1D ${a(d.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:I,npmDependenciesToAdd:E}=ue({selectedItemKeys:d,publicRegistries:j}),P=ae({publicRegistries:j,itemKeys:I.flatMap(({registryId:x,items:l})=>l.map(u=>`${x}:${u.id}`)),projectPackageVersions:ne(i.cwd)});ce({report:P,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),await he({registryItemsToAdd:I,rootPath:C,cwd:c,baseUrl:m,config:y,onDiff:i.onDiff});let{installed:O,filtered:ee}=await we({cwd:c,deps:Array.from(E)});O.size===0&&v.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),O.size&&(v.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(O).join(", "))}`),ee.size&&v.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(ee).join(", "))}`)),v.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let pe=Date.now()-o;try{await U.track(i.cwd,{event:"add-all",properties:{registries:f,items_count:d.length,include_deprecated:i.includeDeprecated||!1,dependencies_count:E.size,duration_ms:pe}})}catch(x){n&&console.error("[Telemetry] add-all tracking failed:",x)}}catch(r){z(r)&&(v.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as D from"@clack/prompts";import Ge from"path";import{z as N}from"zod";var Yt=N.object({itemIds:N.array(N.string()).optional(),component:N.union([N.string(),N.array(N.string())]).optional(),all:N.boolean(),registry:N.string().optional(),cwd:N.string(),baseUrl:N.string().optional()});function Xt({itemIds:e,component:t}){let s=r=>r.trim().replace(/\s+/g,"-"),o=(e??[]).map(s).filter(Boolean),n=(Array.isArray(t)?t:[t]).filter(r=>!!r).flatMap(r=>r.split(",")).map(s).filter(Boolean);return Array.from(new Set([...o,...n]))}function Qt({publicRegistries:e,targetInputs:t,defaultRegistry:s}){let o=e.filter(r=>typeof r.id=="string"&&Array.isArray(r.items)).flatMap(r=>r.items.filter(i=>typeof i.id=="string").map(i=>`${r.id}:${i.id}`)),n=new Set;for(let r of t){let i=r.includes(":")?r:s?`${s}:${r}`:(()=>{let c=o.filter(m=>m.endsWith(`:${r}`));if(!c.length)throw new $({message:`${a(r)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});if(c.length>1)throw new $({message:`${a(r)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:c.map(m=>`- ${m}`),hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});return c[0]})();if(!o.includes(i))throw new $({message:`${a(i)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});n.add(i)}return Array.from(n)}var He=e=>{e.command("compat [...item-ids]","check snippet compatibility").option("-c, --component <component>","\uAC80\uC0AC\uD560 \uCEF4\uD3EC\uB10C\uD2B8. \uC5EC\uB7EC \uBC88 \uB610\uB294 \uC27C\uD45C\uB85C \uC9C0\uC815 \uAC00\uB2A5").option("-a, --all","\uBAA8\uB4E0 registry \uD56D\uBAA9\uC744 \uAC80\uC0AC",{default:!1}).option("-r, --registry <registryId>","\uCEF4\uD3EC\uB10C\uD2B8 shorthand \uC785\uB825 \uC2DC \uAE30\uBCF8 registry").option("--cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).example("seed-design compat").example("seed-design compat -c action-button").example("seed-design compat ui:action-button ui:alert-dialog").example("seed-design compat --all").action(async(t,s)=>{let o=Date.now(),n=F(s);D.intro("seed-design compat");try{let r=Yt.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,{start:c,stop:m}=D.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let g=await Promise.all((await se({baseUrl:i.baseUrl})).map(async({id:d})=>re({baseUrl:i.baseUrl,registryId:d})));return m("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),g}catch(g){throw m("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),g}})(),C=Xt({itemIds:i.itemIds,component:i.component}),b=i.all?y.flatMap(d=>d.items.map(w=>`${d.id}:${w.id}`)):C.length>0?Qt({publicRegistries:y,targetInputs:C,defaultRegistry:i.registry}):le(i.cwd),h=Array.isArray(b)?b:await(async()=>{let g=await b;if(!g)throw new $({message:"seed-design.json \uD30C\uC77C\uC774 \uC5C6\uC5B4 \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB \uACBD\uB85C\uB97C \uC54C \uC218 \uC5C6\uC5B4\uC694.",hint:"`seed-design init`\uC73C\uB85C \uC124\uC815\uC744 \uB9CC\uB4E0 \uB4A4 \uC2E4\uD589\uD558\uAC70\uB098, `--all`/`-c`\uB85C \uAC80\uC0AC \uB300\uC0C1\uC744 \uC9C1\uC811 \uC9C0\uC815\uD574\uC8FC\uC138\uC694."});let d=Ge.resolve(i.cwd,g.path),w=Ve({publicRegistries:y,rootPath:d});return w.length?w:(D.log.info(`${a(Ge.relative(i.cwd,d)||g.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();h.length||(D.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let j=ne(i.cwd),f=ae({publicRegistries:y,itemKeys:h,projectPackageVersions:j});if(D.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${a(f.checkedItemKeys.join(", "))}`),!f.issues.length){D.outro("\uBAA8\uB4E0 \uC2A4\uB2C8\uD3AB\uC774 \uD604\uC7AC @seed-design/react, @seed-design/css\uC640 \uD638\uD658\uB3FC\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(0)}ce({report:f,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),D.log.info("\uD544\uC694\uD55C \uBC84\uC804\uC73C\uB85C @seed-design/react \uB610\uB294 @seed-design/css\uB97C \uB9DE\uCD98 \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD574\uBCF4\uC138\uC694."),D.outro("\uD638\uD658\uC131 \uC774\uC288\uAC00 \uC788\uC5B4\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:new Set(f.issues.map(g=>g.itemKey)).size,issue_count:f.issues.length,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(1)}catch(r){z(r)&&(D.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uD638\uD658\uC131 \uAC80\uC0AC\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as R from"@clack/prompts";import{z as xe}from"zod";var Zt="https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry",es=xe.object({query:xe.string().optional(),baseUrl:xe.string().optional()});function Je(e,t){return`${Zt}/${e}/${t}`}function ts(e,t){let s=`${t}${e.docUrl}`,o=`${t}/llms${e.docUrl}.txt`,n=[e.id,`- docs: ${s}`,`- llms.txt: ${o}`];if(e.snippetKey&&e.snippets&&e.snippets.length>0){let[r]=e.snippetKey.split(":");if(r==="ui"||r==="breeze")if(e.snippets.length===1)n.push(`- snippet: ${Je(r,e.snippets[0].path)}`);else{n.push("- snippet:");for(let i of e.snippets)n.push(` - ${i.label}: ${Je(r,i.path)}`)}}R.log.message(n.join(`
11
+ `))}function ss(e){return e.split("/").map(t=>t.trim()).filter(Boolean)}function rs(e,t){let s=t.toLowerCase();return e.flatMap(o=>o.sections.flatMap(n=>n.items.filter(r=>r.id.toLowerCase().includes(s)||r.title.toLowerCase().includes(s)).map(r=>({item:r,categoryLabel:o.label,sectionLabel:n.label}))))}async function de(e){let t=await R.select({message:"\uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:`${s.deprecated?"(deprecated) ":""}${s.title}`,value:s,hint:s.description}))});if(R.isCancel(t))throw new k;return t}async function We(e){let t=await R.select({message:"\uC139\uC158\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.items.length}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}async function is(e){let t=await R.select({message:"\uCE74\uD14C\uACE0\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.sections.reduce((o,n)=>o+n.items.length,0)}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}var Ye=e=>{e.command("docs [query]","\uBB38\uC11C \uB9C1\uD06C, llms.txt \uB9C1\uD06C, \uC2A4\uB2C8\uD3AB \uB9C1\uD06C\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4").option("-u, --baseUrl <baseUrl>",`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uAE30\uBCF8 URL (\uAE30\uBCF8\uAC12: ${B})`,{default:B}).example("seed-design docs").example("seed-design docs action-button").example("seed-design docs react").example("seed-design docs react/components").example("seed-design docs react/components/action-button").action(async(t,s)=>{let o=Date.now(),n=F(s);R.intro("seed-design docs");try{let r=es.safeParse({query:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.baseUrl??B,{start:m,stop:y}=R.spinner();m("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let C=await(async()=>{try{let f=await je({baseUrl:c});return y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),{categories:b}=C,h;if(i.query){let f=ss(i.query),g=b.find(d=>d.id===f[0]);if(g&&f.length>=2){let d=g.sections.find(w=>w.id===f[1]);if(d&&f.length>=3){let w=d.items.find(I=>I.id===f[2]);if(w)h=w;else{let I=f[2].toLowerCase(),E=d.items.filter(P=>P.id.toLowerCase().includes(I)||P.title.toLowerCase().includes(I));if(E.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}/${d.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});E.length===1?h=E[0]:h=await de(E)}}else if(d)h=await de(d.items);else{let w=f[1].toLowerCase(),I=g.sections.flatMap(E=>E.items.filter(P=>P.id.toLowerCase().includes(w)||P.title.toLowerCase().includes(w)).map(P=>({item:P,sectionLabel:E.label})));if(I.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});if(I.length===1)h=I[0].item;else{let E=await R.select({message:`${a(f[1])}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:I.map(({item:P,sectionLabel:O})=>({label:`[${O}] ${P.title}`,value:P,hint:P.description}))});if(R.isCancel(E))throw new k;h=E}}}else if(g)if(g.sections.length===1)h=await de(g.sections[0].items);else{let d=await We(g.sections);h=await de(d.items)}else{let d=rs(b,i.query);if(d.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:"`seed-design docs`\uB85C \uC804\uCCB4 \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694."});if(d.length===1)h=d[0].item;else{let w=await R.select({message:`${a(i.query)}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:d.map(({item:I,categoryLabel:E,sectionLabel:P})=>({label:`[${E} > ${P}] ${I.title}`,value:I,hint:I.description}))});if(R.isCancel(w))throw new k;h=w}}}else{let f=await is(b),g;f.sections.length===1?g=f.sections[0]:g=await We(f.sections),h=await de(g.items)}ts(h,c),R.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let j=Date.now()-o;try{await U.track(process.cwd(),{event:"docs",properties:{query:i.query??null,item_id:h.id,has_snippet:!!(h.snippets&&h.snippets.length>0),duration_ms:j}})}catch(f){n&&console.error("[Telemetry] docs tracking failed:",f)}}catch(r){z(r)&&(R.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uBB38\uC11C \uC870\uD68C\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as _ from"@clack/prompts";import{z as be}from"zod";import os from"dedent";var ns=be.object({cwd:be.string(),yes:be.boolean().optional(),default:be.boolean().optional()}),Xe=e=>{e.command("init","seed-design.json \uD30C\uC77C \uC0DD\uC131").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC.",{default:process.cwd()}).option("-y, --yes","\uBAA8\uB4E0 \uC9C8\uBB38\uC5D0 \uB300\uD574 \uAE30\uBCF8\uAC12\uC73C\uB85C \uB2F5\uBCC0\uD569\uB2C8\uB2E4.").option("--default","Deprecated. --yes\uC640 \uB3D9\uC77C\uD558\uAC8C \uAE30\uBCF8\uAC12\uC73C\uB85C \uC0DD\uC131\uD569\uB2C8\uB2E4.").action(async t=>{let s=Date.now(),o=F(t);_.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let n=ns.safeParse(t);if(!n.success)throw n.error;let r=n.data,i=r.yes||r.default,c=i?K:await Se(),{start:m,stop:y}=_.spinner();m("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let C=await(async()=>{try{return(await fe({cwd:r.cwd,config:c})).relativePath}catch(h){throw y("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),h}})();y(`seed-design.json \uD30C\uC77C\uC774 ${a(C)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),_.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),_.log.info(a("seed-design add \uBA85\uB839\uC5B4\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.")),_.note(os(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
11
12
 
12
13
  \uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
13
14
  \u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
14
15
  \u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
15
16
 
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();
17
+ \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),_.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let b=Date.now()-s;try{await U.track(r.cwd,{event:"init",properties:{tsx:c.tsx,rsc:c.rsc,telemetry:c.telemetry,yes_option:i,duration_ms:b}})}catch(h){o&&console.error("[Telemetry] init tracking failed:",h)}}catch(n){z(n)&&(_.outro(a(n.message)),process.exit(0)),V(n,{defaultMessage:"seed-design.json \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:o}),process.exit(1)}})};import{cac as as}from"cac";var cs="seed-design",J=as(cs);async function ps(){let e=oe();J.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),qe(J),Be(J),He(J),Ye(J),Xe(J),J.version(e.version||"1.0.0","-v, --version"),J.help(),J.parse()}ps();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-design/cli",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -0,0 +1,312 @@
1
+ import { fetchDocsIndex } from "@/src/utils/fetch";
2
+ import * as p from "@clack/prompts";
3
+ import type { CAC } from "cac";
4
+ import { z } from "zod";
5
+ import { BASE_URL } from "../constants";
6
+ import { analytics } from "../utils/analytics";
7
+ import { highlight } from "../utils/color";
8
+ import {
9
+ CliCancelError,
10
+ CliError,
11
+ handleCliError,
12
+ isCliCancelError,
13
+ isVerboseMode,
14
+ } from "../utils/error";
15
+ import type { DocsCategory, DocsItem, DocsSection } from "../schema";
16
+
17
+ const GITHUB_SNIPPET_BASE =
18
+ "https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry";
19
+
20
+ const docsOptionsSchema = z.object({
21
+ query: z.string().optional(),
22
+ baseUrl: z.string().optional(),
23
+ });
24
+
25
+ function buildSnippetUrl(registryId: string, snippetPath: string): string {
26
+ return `${GITHUB_SNIPPET_BASE}/${registryId}/${snippetPath}`;
27
+ }
28
+
29
+ function printDocsResult(item: DocsItem, baseUrl: string) {
30
+ const docLink = `${baseUrl}${item.docUrl}`;
31
+ const llmsLink = `${baseUrl}/llms${item.docUrl}.txt`;
32
+
33
+ const lines = [item.id, `- docs: ${docLink}`, `- llms.txt: ${llmsLink}`];
34
+
35
+ if (item.snippetKey && item.snippets && item.snippets.length > 0) {
36
+ const [registryId] = item.snippetKey.split(":");
37
+ if (registryId === "ui" || registryId === "breeze") {
38
+ if (item.snippets.length === 1) {
39
+ lines.push(`- snippet: ${buildSnippetUrl(registryId, item.snippets[0].path)}`);
40
+ } else {
41
+ lines.push("- snippet:");
42
+ for (const snippet of item.snippets) {
43
+ lines.push(` - ${snippet.label}: ${buildSnippetUrl(registryId, snippet.path)}`);
44
+ }
45
+ }
46
+ }
47
+ }
48
+
49
+ p.log.message(lines.join("\n"));
50
+ }
51
+
52
+ /**
53
+ * Parse a path-style query into segments.
54
+ * e.g. "react/components/action-button" → ["react", "components", "action-button"]
55
+ */
56
+ function parseQueryPath(query: string): string[] {
57
+ return query
58
+ .split("/")
59
+ .map((s) => s.trim())
60
+ .filter(Boolean);
61
+ }
62
+
63
+ /**
64
+ * Search all items across all categories/sections.
65
+ */
66
+ function searchAllItems(
67
+ categories: DocsCategory[],
68
+ query: string,
69
+ ): { item: DocsItem; categoryLabel: string; sectionLabel: string }[] {
70
+ const q = query.toLowerCase();
71
+ return categories.flatMap((cat) =>
72
+ cat.sections.flatMap((sec) =>
73
+ sec.items
74
+ .filter((item) => item.id.toLowerCase().includes(q) || item.title.toLowerCase().includes(q))
75
+ .map((item) => ({
76
+ item,
77
+ categoryLabel: cat.label,
78
+ sectionLabel: sec.label,
79
+ })),
80
+ ),
81
+ );
82
+ }
83
+
84
+ async function selectItem(items: DocsItem[]): Promise<DocsItem> {
85
+ const selected = await p.select({
86
+ message: "항목을 선택해주세요",
87
+ options: items.map((item) => ({
88
+ label: `${item.deprecated ? "(deprecated) " : ""}${item.title}`,
89
+ value: item,
90
+ hint: item.description,
91
+ })),
92
+ });
93
+ if (p.isCancel(selected)) throw new CliCancelError();
94
+ return selected;
95
+ }
96
+
97
+ async function selectSection(sections: DocsSection[]): Promise<DocsSection> {
98
+ const selected = await p.select({
99
+ message: "섹션을 선택해주세요",
100
+ options: sections.map((sec) => ({
101
+ label: sec.label,
102
+ value: sec,
103
+ hint: `${sec.items.length}개 항목`,
104
+ })),
105
+ });
106
+ if (p.isCancel(selected)) throw new CliCancelError();
107
+ return selected;
108
+ }
109
+
110
+ async function selectCategory(categories: DocsCategory[]): Promise<DocsCategory> {
111
+ const selected = await p.select({
112
+ message: "카테고리를 선택해주세요",
113
+ options: categories.map((cat) => ({
114
+ label: cat.label,
115
+ value: cat,
116
+ hint: `${cat.sections.reduce((sum, s) => sum + s.items.length, 0)}개 항목`,
117
+ })),
118
+ });
119
+ if (p.isCancel(selected)) throw new CliCancelError();
120
+ return selected;
121
+ }
122
+
123
+ export const docsCommand = (cli: CAC) => {
124
+ cli
125
+ .command("docs [query]", "문서 링크, llms.txt 링크, 스니펫 링크를 조회합니다")
126
+ .option("-u, --baseUrl <baseUrl>", `레지스트리의 기본 URL (기본값: ${BASE_URL})`, {
127
+ default: BASE_URL,
128
+ })
129
+ .example("seed-design docs")
130
+ .example("seed-design docs action-button")
131
+ .example("seed-design docs react")
132
+ .example("seed-design docs react/components")
133
+ .example("seed-design docs react/components/action-button")
134
+ .action(async (query, opts) => {
135
+ const startTime = Date.now();
136
+ const verbose = isVerboseMode(opts);
137
+ p.intro("seed-design docs");
138
+
139
+ try {
140
+ const parsed = docsOptionsSchema.safeParse({ query, ...opts });
141
+ if (!parsed.success) {
142
+ throw parsed.error;
143
+ }
144
+
145
+ const { data: options } = parsed;
146
+ const baseUrl = options.baseUrl ?? BASE_URL;
147
+
148
+ const { start, stop } = p.spinner();
149
+ start("문서 목록을 가져오고 있어요...");
150
+
151
+ const docsIndex = await (async () => {
152
+ try {
153
+ const index = await fetchDocsIndex({ baseUrl });
154
+ stop("문서 목록을 가져왔어요.");
155
+ return index;
156
+ } catch (error) {
157
+ stop("문서 목록을 가져오지 못했어요.");
158
+ throw error;
159
+ }
160
+ })();
161
+
162
+ const { categories } = docsIndex;
163
+ let selectedItem: DocsItem;
164
+
165
+ if (options.query) {
166
+ const segments = parseQueryPath(options.query);
167
+
168
+ // Try to resolve as path: category / section / item
169
+ const matchedCategory = categories.find((c) => c.id === segments[0]);
170
+
171
+ if (matchedCategory && segments.length >= 2) {
172
+ const matchedSection = matchedCategory.sections.find((s) => s.id === segments[1]);
173
+
174
+ if (matchedSection && segments.length >= 3) {
175
+ // Full path: category/section/item
176
+ const matchedItem = matchedSection.items.find((i) => i.id === segments[2]);
177
+ if (matchedItem) {
178
+ selectedItem = matchedItem;
179
+ } else {
180
+ // Item not found in section — search within the section
181
+ const q = segments[2].toLowerCase();
182
+ const matched = matchedSection.items.filter(
183
+ (i) => i.id.toLowerCase().includes(q) || i.title.toLowerCase().includes(q),
184
+ );
185
+ if (matched.length === 0) {
186
+ throw new CliError({
187
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
188
+ hint: `\`seed-design docs ${matchedCategory.id}/${matchedSection.id}\`로 목록을 확인해보세요.`,
189
+ });
190
+ }
191
+ if (matched.length === 1) {
192
+ selectedItem = matched[0];
193
+ } else {
194
+ selectedItem = await selectItem(matched);
195
+ }
196
+ }
197
+ } else if (matchedSection) {
198
+ // category/section — select item within section
199
+ selectedItem = await selectItem(matchedSection.items);
200
+ } else {
201
+ // category/??? — search within category
202
+ const q = segments[1].toLowerCase();
203
+ const matched = matchedCategory.sections.flatMap((s) =>
204
+ s.items
205
+ .filter(
206
+ (i) => i.id.toLowerCase().includes(q) || i.title.toLowerCase().includes(q),
207
+ )
208
+ .map((item) => ({ item, sectionLabel: s.label })),
209
+ );
210
+
211
+ if (matched.length === 0) {
212
+ throw new CliError({
213
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
214
+ hint: `\`seed-design docs ${matchedCategory.id}\`로 목록을 확인해보세요.`,
215
+ });
216
+ }
217
+ if (matched.length === 1) {
218
+ selectedItem = matched[0].item;
219
+ } else {
220
+ const selected = await p.select({
221
+ message: `${highlight(segments[1])}에 해당하는 항목을 선택해주세요`,
222
+ options: matched.map(({ item, sectionLabel }) => ({
223
+ label: `[${sectionLabel}] ${item.title}`,
224
+ value: item,
225
+ hint: item.description,
226
+ })),
227
+ });
228
+ if (p.isCancel(selected)) throw new CliCancelError();
229
+ selectedItem = selected;
230
+ }
231
+ }
232
+ } else if (matchedCategory) {
233
+ // Single segment matching a category — drill into it
234
+ if (matchedCategory.sections.length === 1) {
235
+ selectedItem = await selectItem(matchedCategory.sections[0].items);
236
+ } else {
237
+ const section = await selectSection(matchedCategory.sections);
238
+ selectedItem = await selectItem(section.items);
239
+ }
240
+ } else {
241
+ // No category match — global search
242
+ const matched = searchAllItems(categories, options.query);
243
+
244
+ if (matched.length === 0) {
245
+ throw new CliError({
246
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
247
+ hint: "`seed-design docs`로 전체 목록을 확인해보세요.",
248
+ });
249
+ }
250
+ if (matched.length === 1) {
251
+ selectedItem = matched[0].item;
252
+ } else {
253
+ const selected = await p.select({
254
+ message: `${highlight(options.query)}에 해당하는 항목을 선택해주세요`,
255
+ options: matched.map(({ item, categoryLabel, sectionLabel }) => ({
256
+ label: `[${categoryLabel} > ${sectionLabel}] ${item.title}`,
257
+ value: item,
258
+ hint: item.description,
259
+ })),
260
+ });
261
+ if (p.isCancel(selected)) throw new CliCancelError();
262
+ selectedItem = selected;
263
+ }
264
+ }
265
+ } else {
266
+ // Full interactive flow: category → section → item
267
+ const category = await selectCategory(categories);
268
+
269
+ let section: DocsSection;
270
+ if (category.sections.length === 1) {
271
+ section = category.sections[0];
272
+ } else {
273
+ section = await selectSection(category.sections);
274
+ }
275
+
276
+ selectedItem = await selectItem(section.items);
277
+ }
278
+
279
+ printDocsResult(selectedItem, baseUrl);
280
+ p.outro("완료했어요.");
281
+
282
+ const duration = Date.now() - startTime;
283
+ try {
284
+ await analytics.track(process.cwd(), {
285
+ event: "docs",
286
+ properties: {
287
+ query: options.query ?? null,
288
+ item_id: selectedItem.id,
289
+ has_snippet: !!(selectedItem.snippets && selectedItem.snippets.length > 0),
290
+ duration_ms: duration,
291
+ },
292
+ });
293
+ } catch (telemetryError) {
294
+ if (verbose) {
295
+ console.error("[Telemetry] docs tracking failed:", telemetryError);
296
+ }
297
+ }
298
+ } catch (error) {
299
+ if (isCliCancelError(error)) {
300
+ p.outro(highlight(error.message));
301
+ process.exit(0);
302
+ }
303
+
304
+ handleCliError(error, {
305
+ defaultMessage: "문서 조회에 실패했어요.",
306
+ defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
307
+ verbose,
308
+ });
309
+ process.exit(1);
310
+ }
311
+ });
312
+ };
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  import { addCommand } from "@/src/commands/add";
4
4
  import { addAllCommand } from "@/src/commands/add-all";
5
5
  import { compatCommand } from "@/src/commands/compat";
6
+ import { docsCommand } from "@/src/commands/docs";
6
7
  import { initCommand } from "@/src/commands/init";
7
8
  import { getPackageInfo } from "@/src/utils/get-package-info";
8
9
  import { cac } from "cac";
@@ -19,6 +20,7 @@ async function main() {
19
20
  addCommand(CLI);
20
21
  addAllCommand(CLI);
21
22
  compatCommand(CLI);
23
+ docsCommand(CLI);
22
24
  initCommand(CLI);
23
25
 
24
26
  CLI.version(packageInfo.version || "1.0.0", "-v, --version");
package/src/schema.ts CHANGED
@@ -45,16 +45,14 @@ export const publicRegistrySchema = z.object({
45
45
  hideFromCLICatalog: z.boolean().optional(),
46
46
 
47
47
  items: z.array(
48
- publicRegistryItemSchema
49
- .omit({ snippets: true })
50
- .extend({
51
- snippets: z.array(
52
- z.object({
53
- path: z.string(),
54
- dependencies: z.record(z.string(), z.string()).optional(),
55
- }),
56
- ),
57
- }),
48
+ publicRegistryItemSchema.omit({ snippets: true }).extend({
49
+ snippets: z.array(
50
+ z.object({
51
+ path: z.string(),
52
+ dependencies: z.record(z.string(), z.string()).optional(),
53
+ }),
54
+ ),
55
+ }),
58
56
  ),
59
57
  });
60
58
 
@@ -66,3 +64,41 @@ export const publicAvailableRegistriesSchema = z.array(z.object({ id: z.string()
66
64
  export type PublicRegistryItem = z.infer<typeof publicRegistryItemSchema>;
67
65
  export type PublicRegistry = z.infer<typeof publicRegistrySchema>;
68
66
  export type PublicAvailableRegistries = z.infer<typeof publicAvailableRegistriesSchema>;
67
+
68
+ ///////////////////////////////////////////////////////////////
69
+
70
+ export const docsSnippetSchema = z.object({
71
+ label: z.string(),
72
+ path: z.string(),
73
+ });
74
+
75
+ export const docsItemSchema = z.object({
76
+ id: z.string(),
77
+ title: z.string(),
78
+ description: z.string().optional(),
79
+ docUrl: z.string(),
80
+ deprecated: z.boolean().optional(),
81
+ snippetKey: z.string().optional(),
82
+ snippets: z.array(docsSnippetSchema).optional(),
83
+ });
84
+
85
+ export const docsSectionSchema = z.object({
86
+ id: z.string(),
87
+ label: z.string(),
88
+ items: z.array(docsItemSchema),
89
+ });
90
+
91
+ export const docsCategorySchema = z.object({
92
+ id: z.string(),
93
+ label: z.string(),
94
+ sections: z.array(docsSectionSchema),
95
+ });
96
+
97
+ export const docsIndexSchema = z.object({
98
+ categories: z.array(docsCategorySchema),
99
+ });
100
+
101
+ export type DocsItem = z.infer<typeof docsItemSchema>;
102
+ export type DocsSection = z.infer<typeof docsSectionSchema>;
103
+ export type DocsCategory = z.infer<typeof docsCategorySchema>;
104
+ export type DocsIndex = z.infer<typeof docsIndexSchema>;
@@ -3,7 +3,7 @@ import { resolveDependencies } from "../utils/resolve-dependencies";
3
3
  import type { PublicRegistry } from "@/src/schema";
4
4
 
5
5
  describe("resolveDependencies", () => {
6
- it("should resolve a simple item without dependencies", () => {
6
+ it("의존성이 없는 단일 아이템을 해석해야 한다", () => {
7
7
  const publicRegistries: PublicRegistry[] = [
8
8
  {
9
9
  id: "ui",
@@ -36,7 +36,7 @@ describe("resolveDependencies", () => {
36
36
  expect(result.npmDependenciesToAdd.size).toBe(0);
37
37
  });
38
38
 
39
- it("should resolve npm dependencies", () => {
39
+ it("npm 의존성을 수집해야 한다", () => {
40
40
  const publicRegistries: PublicRegistry[] = [
41
41
  {
42
42
  id: "ui",
@@ -61,7 +61,7 @@ describe("resolveDependencies", () => {
61
61
  expect(result.npmDependenciesToAdd.has("clsx")).toBe(true);
62
62
  });
63
63
 
64
- it("should resolve inner dependencies recursively", () => {
64
+ it("innerDependencies를 재귀적으로 해석해야 한다", () => {
65
65
  const publicRegistries: PublicRegistry[] = [
66
66
  {
67
67
  id: "ui",
@@ -131,7 +131,7 @@ describe("resolveDependencies", () => {
131
131
  expect(result.npmDependenciesToAdd.has("framer-motion")).toBe(true);
132
132
  });
133
133
 
134
- it("should handle multiple selected items", () => {
134
+ it("여러 선택 아이템을 함께 처리해야 한다", () => {
135
135
  const publicRegistries: PublicRegistry[] = [
136
136
  {
137
137
  id: "ui",
@@ -161,7 +161,7 @@ describe("resolveDependencies", () => {
161
161
  expect(result.registryItemsToAdd[0].items.map((i) => i.id)).toEqual(["button", "chip"]);
162
162
  });
163
163
 
164
- it("should prevent duplicate items", () => {
164
+ it("중복 아이템을 제거해야 한다", () => {
165
165
  const publicRegistries: PublicRegistry[] = [
166
166
  {
167
167
  id: "ui",
@@ -186,7 +186,7 @@ describe("resolveDependencies", () => {
186
186
  },
187
187
  ];
188
188
 
189
- // Select both dialog and button, but button is already a dependency of dialog
189
+ // dialog button 동시에 선택해도 button dialog 의존성으로 이미 포함된다.
190
190
  const result = resolveDependencies({
191
191
  selectedItemKeys: ["ui:dialog", "ui:button"],
192
192
  publicRegistries,
@@ -194,12 +194,12 @@ describe("resolveDependencies", () => {
194
194
 
195
195
  expect(result.registryItemsToAdd).toHaveLength(1);
196
196
  expect(result.registryItemsToAdd[0].items).toHaveLength(2);
197
- // Button should appear only once
197
+ // button은 번만 포함되어야 한다.
198
198
  const buttonCount = result.registryItemsToAdd[0].items.filter((i) => i.id === "button").length;
199
199
  expect(buttonCount).toBe(1);
200
200
  });
201
201
 
202
- it("should handle nested inner dependencies", () => {
202
+ it("중첩된 innerDependencies를 처리해야 한다", () => {
203
203
  const publicRegistries: PublicRegistry[] = [
204
204
  {
205
205
  id: "ui",
@@ -268,7 +268,7 @@ describe("resolveDependencies", () => {
268
268
  expect(result.npmDependenciesToAdd.has("lodash")).toBe(true);
269
269
  });
270
270
 
271
- it("should throw error for invalid snippet format", () => {
271
+ it("잘못된 스니펫 포맷이면 에러를 던져야 한다", () => {
272
272
  const publicRegistries: PublicRegistry[] = [];
273
273
 
274
274
  expect(() =>
@@ -279,7 +279,7 @@ describe("resolveDependencies", () => {
279
279
  ).toThrowError('Invalid snippet format: "invalid-format"');
280
280
  });
281
281
 
282
- it("should throw error for non-existent snippet", () => {
282
+ it("존재하지 않는 스니펫이면 에러를 던져야 한다", () => {
283
283
  const publicRegistries: PublicRegistry[] = [
284
284
  {
285
285
  id: "ui",
@@ -295,7 +295,7 @@ describe("resolveDependencies", () => {
295
295
  ).toThrowError('Cannot find snippet: "ui:non-existent"');
296
296
  });
297
297
 
298
- it("should throw error for missing inner dependency", () => {
298
+ it("inner dependency가 누락되면 에러를 던져야 한다", () => {
299
299
  const publicRegistries: PublicRegistry[] = [
300
300
  {
301
301
  id: "ui",
@@ -327,7 +327,7 @@ describe("resolveDependencies", () => {
327
327
  ).toThrowError("Cannot find dependency item: breeze:missing");
328
328
  });
329
329
 
330
- it("should handle multiple registries with multiple items", () => {
330
+ it("여러 레지스트리와 아이템을 함께 처리해야 한다", () => {
331
331
  const publicRegistries: PublicRegistry[] = [
332
332
  {
333
333
  id: "ui",
@@ -378,7 +378,7 @@ describe("resolveDependencies", () => {
378
378
  expect(result.npmDependenciesToAdd.has("framer-motion")).toBe(true);
379
379
  });
380
380
 
381
- it("should collect all npm dependencies from nested dependencies", () => {
381
+ it("중첩 의존성의 npm 패키지를 모두 수집해야 한다", () => {
382
382
  const publicRegistries: PublicRegistry[] = [
383
383
  {
384
384
  id: "ui",
@@ -60,9 +60,8 @@ async function track(cwd: string, { event, properties = {} }: TrackOptions): Pro
60
60
 
61
61
  const fullEvent = `${EVENT_PREFIX}.${event}`;
62
62
 
63
- // Dev 모드: 콘솔에만 출력
63
+ // Dev 모드: 텔레메트리 전송 생략
64
64
  if (process.env.NODE_ENV === "dev") {
65
- console.log(`📊 [Telemetry] ${fullEvent}`, properties);
66
65
  return;
67
66
  }
68
67
 
@@ -7,7 +7,29 @@ import {
7
7
  publicRegistryItemSchema,
8
8
  type PublicAvailableRegistries,
9
9
  publicAvailableRegistriesSchema,
10
+ type DocsIndex,
11
+ docsIndexSchema,
10
12
  } from "@/src/schema";
13
+ import { CliError } from "@/src/utils/error";
14
+
15
+ export async function fetchDocsIndex({ baseUrl }: { baseUrl: string }): Promise<DocsIndex> {
16
+ const response = await fetch(`${baseUrl}/__docs__/index.json`);
17
+
18
+ if (!response.ok)
19
+ throw new CliError({
20
+ message: `문서 목록을 가져오지 못했어요: ${response.status} ${response.statusText}`,
21
+ });
22
+
23
+ const data = await response.json();
24
+ const { success, data: parsed, error } = docsIndexSchema.safeParse(data);
25
+
26
+ if (!success)
27
+ throw new CliError({
28
+ message: `문서 목록 파싱에 실패했어요: ${error?.message}`,
29
+ });
30
+
31
+ return parsed;
32
+ }
11
33
 
12
34
  export async function fetchAvailableRegistries({
13
35
  baseUrl,