@seed-design/cli 1.3.0 → 1.3.1

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,17 +1,30 @@
1
1
  #!/usr/bin/env node
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")}
2
+ import*as se from"@clack/prompts";import{cosmiconfig as ut}from"cosmiconfig";import{z as oe}from"zod";import*as Y from"@clack/prompts";import{ZodError as dt}from"zod";import lt from"picocolors";var a=e=>lt.cyan(e);var I=class extends Error{hint;details;constructor({message:t,hint:s,details:n=[],cause:o}){super(t,{cause:o}),this.name="CliError",this.hint=s,this.details=n}},E=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function L(e){return e instanceof E}function K(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function mt(e,t){if(e instanceof I)return{reason:e.message,hint:e.hint??t,details:e.details,stack:gt(e.cause??e)};if(e instanceof dt){let s=e.issues.map(n=>`${n.path.join(".")||"(root)"}: ${n.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,n=[];return(s.escapedCommand||s.command)&&n.push(`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${s.escapedCommand??s.command}`),typeof s.exitCode=="number"&&n.push(`\uC885\uB8CC \uCF54\uB4DC: ${s.exitCode}`),s.stderr?.trim()?n.push(`stderr: ${s.stderr.trim()}`):s.stdout?.trim()&&n.push(`stdout: ${s.stdout.trim()}`),{reason:s.shortMessage??e.message,hint:t,details:n,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 gt(e){if(e instanceof Error)return e.stack}function O(e,{defaultMessage:t,defaultHint:s,verbose:n=!1}){let o=mt(e,s);Y.log.error(t),Y.log.error(`\uC6D0\uC778: ${o.reason}`);for(let r of o.details)Y.log.info(r);o.hint&&Y.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${o.hint}`),n&&o.stack&&(Y.log.message(a(`
3
+ [verbose] stack trace`)),Y.log.message(o.stack)),Y.outro(a("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as Q from"@clack/prompts";import ft from"fs-extra";import je from"path";var q={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function Te(){return await Q.group({tsx:()=>Q.confirm({message:`${a("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:q.tsx}),rsc:()=>Q.confirm({message:`${a("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:q.rsc}),path:()=>Q.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:q.path,defaultValue:q.path,placeholder:q.path}),telemetry:()=>Q.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${a("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:q.telemetry})},{onCancel:()=>{throw new E}})}async function he({cwd:e,config:t}){let s=je.resolve(e,"seed-design.json");return await ft.writeFile(s,`${JSON.stringify(t,null,2)}
4
+ `,"utf-8"),{relativePath:je.relative(process.cwd(),s),targetPath:s}}var De="seed-design",ht=ut(De,{searchPlaces:[`${De}.json`]}),Ae=oe.object({$schema:oe.string().optional(),rsc:oe.coerce.boolean().default(!1),tsx:oe.coerce.boolean().default(!0),path:oe.string(),telemetry:oe.coerce.boolean().optional().default(!0)}).strict();async function ye(e){let t=await ge(e);if(t)return t;se.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let s=await se.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(se.isCancel(s)||!s)throw new E;try{return await he({cwd:e,config:q}),se.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),Ae.parse(q)}catch(n){throw new I({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:n})}}async function ge(e){let t=await ht.search(e);if(!t||t.isEmpty)return null;try{return Ae.parse(t.config)}catch(s){throw new I({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 we({selectedItemKeys:e,publicRegistries:t}){let s=[],n=new Set;function o(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)n.add(m);if(i.innerDependencies?.length)for(let m of i.innerDependencies)for(let p of m.itemIds){let y=t.find(h=>h.id===m.registryId)?.items.find(h=>h.id===p);if(!y)throw new Error(`Cannot find dependency item: ${m.registryId}:${p}`);o(m.registryId,y)}}}for(let r of e){let[i,...c]=r.split(":"),m=c.join(":");if(!i||!m)throw new Error(`Invalid snippet format: "${r}"`);let p=t.find(y=>y.id===i)?.items.find(y=>y.id===m);if(!p)throw new Error(`Cannot find snippet: "${r}"`);o(i,p)}return{registryItemsToAdd:s,npmDependenciesToAdd:n}}import*as Ee from"@clack/prompts";import{z as u}from"zod";var Se=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()}))}),Re=u.object({id:u.string(),hideFromCLICatalog:u.boolean().optional(),items:u.array(Se.omit({snippets:!0}).extend({snippets:u.array(u.object({path:u.string(),dependencies:u.record(u.string(),u.string()).optional()}))}))}),_e=u.array(u.object({id:u.string()})),yt=u.object({label:u.string(),path:u.string()}),wt=u.object({id:u.string(),title:u.string(),description:u.string().optional(),docUrl:u.string(),deprecated:u.boolean().optional(),snippetKey:u.string().optional(),snippets:u.array(yt).optional()}),bt=u.object({id:u.string(),label:u.string(),items:u.array(wt)}),$t=u.object({id:u.string(),label:u.string(),sections:u.array(bt)}),Oe=u.object({categories:u.array($t)});var Ct=1e4;async function Ue(e,t=Ct){let s=new AbortController,n=setTimeout(()=>s.abort(),t);try{return await fetch(e,{signal:s.signal})}catch(o){throw o instanceof Error&&o.name==="AbortError"?new I({message:`\uC694\uCCAD \uC2DC\uAC04\uC774 \uCD08\uACFC\uB418\uC5C8\uC5B4\uC694 (${t}ms): ${e}`,hint:"\uB124\uD2B8\uC6CC\uD06C \uC0C1\uD0DC\uB97C \uD655\uC778\uD558\uACE0 \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694."}):o}finally{clearTimeout(n)}}async function Me({baseUrl:e}){let t=await fetch(`${e}/__docs__/index.json`);if(!t.ok)throw new I({message:`\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${t.status} ${t.statusText}`});let s=await t.json(),{success:n,data:o,error:r}=Oe.safeParse(s);if(!n)throw new I({message:`\uBB38\uC11C \uBAA9\uB85D \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694: ${r?.message}`});return o}async function ne({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:n,data:o,error:r}=_e.safeParse(s);if(!n)throw new Error(`Failed to parse registries: ${r?.message}`);return o}async function ae({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 n=await s.json(),{success:o,data:r,error:i}=Re.safeParse(n);if(!o)throw new Error(`Failed to parse ${t} registry: ${i?.message}`);return r}async function It({baseUrl:e,registryId:t,registryItemId:s}){let n=await fetch(`${e}/__registry__/${t}/${s}.json`);if(!n.ok)throw new Error(`Failed to fetch ${s}: ${n.status} ${n.statusText}`);let o=await n.json(),{success:r,data:i,error:c}=Se.safeParse(o);if(!r)throw new Error(`Failed to parse ${s}: ${c?.message}`);return i}async function Ve(e){let t=await Ue(`https://registry.npmjs.org/${e}/latest`);if(!t.ok)throw new I({message:`${e}\uC758 \uCD5C\uC2E0 \uBC84\uC804\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${t.status} ${t.statusText}`});let s=await t.json();if(!s||typeof s!="object"||typeof s.version!="string")throw new I({message:`${e} \uCD5C\uC2E0 \uBC84\uC804 \uC751\uB2F5 \uD615\uC2DD\uC774 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC544\uC694.`});return s.version}async function Le({baseUrl:e,packageSlug:t,version:s}){let n=`${e}/llms/react/updates/changelog/${t}/${encodeURIComponent(s)}.txt`,o=await Ue(n);if(!o.ok)throw new I({message:`\uBCC0\uACBD\uC0AC\uD56D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${o.status} ${o.statusText}`,hint:`${n} \uC5D0 \uC811\uADFC\uD560 \uC218 \uC788\uB294\uC9C0 \uD655\uC778\uD574\uC8FC\uC138\uC694.`});return o.text()}async function Ke({baseUrl:e,registryId:t,registryItemIds:s}){return await Promise.all(s.map(async n=>{try{return await It({baseUrl:e,registryId:t,registryItemId:n})}catch(o){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}=Re.safeParse(i);throw c?(Ee.log.error(`${n} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),Ee.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
5
+ ${m.items.map(p=>p.id).join(`
6
+ `)}`),o):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as Et}from"fs";import{tmpdir as vt}from"os";import Fe from"path";import{transformFromAstSync as xt}from"@babel/core";import Pt from"@babel/plugin-transform-typescript";import*as be from"recast";import{parse as kt}from"@babel/parser";var St={sourceType:"module",allowImportExportEverywhere:!0,allowReturnOutsideFunction:!0,startLine:1,tokens:!0,plugins:["asyncGenerators","bigInt","classPrivateMethods","classPrivateProperties","classProperties","classStaticBlock","decimal","decorators-legacy","doExpressions","dynamicImport","exportDefaultFrom","exportNamespaceFrom","functionBind","functionSent","importAssertions","importMeta","nullishCoalescingOperator","numericSeparator","objectRestSpread","optionalCatchBinding","optionalChaining",["pipelineOperator",{proposal:"minimal"}],["recordAndTuple",{syntaxType:"hash"}],"throwExpressions","topLevelAwait","v8intrinsic","typescript","jsx"]},Ne=async({sourceFile:e,config:t})=>{let s=e.getFullText();if(t.tsx)return s;let n=be.parse(s,{parser:{parse:r=>kt(r,St)}}),o=xt(n,s,{cloneInputAst:!1,code:!1,ast:!0,plugins:[Pt],configFile:!1});if(!o||!o.ast)throw new Error("Failed to transform JSX");return be.print(o.ast).code};import{SyntaxKind as Rt}from"ts-morph";var ze=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let s=e.getFirstChildByKind(Rt.ExpressionStatement);if(!s)return e;let n=s.getExpression();if(!n)return e;let o=n.getText().trim();if(o!=='"use client"'&&o!=="'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 jt,ScriptKind as Tt}from"ts-morph";var Dt=[ze],At=new jt({compilerOptions:{}});async function _t(e){let t=await Et.mkdtemp(Fe.join(vt(),"seed-design-"));return Fe.join(t,e)}async function qe(e){let t=await _t(e.filename),s=At.createSourceFile(t,e.raw,{scriptKind:Tt.TSX});for(let n of Dt)n({sourceFile:s,...e});return await Ne({sourceFile:s,...e})}import*as B from"@clack/prompts";import ce from"fs-extra";import G from"path";import{createPatch as Ot}from"diff";import Ut from"@npmcli/disparity-colors";async function $e({registryItemsToAdd:e,rootPath:t,cwd:s,baseUrl:n,config:o,onDiff:r}){let i=[];for(let{registryId:c,items:m}of e){let p=G.join(t,c);ce.ensureDirSync(p);let y=await Ke({baseUrl:n,registryId:c,registryItemIds:m.map(h=>h.id)});for(let{id:h,snippets:w}of y){let R=await Promise.all(w.map(async d=>{let g=await qe({filename:d.path,config:o,raw:d.content}),$=G.join(p,d.path);return o.tsx||($=$.replace(/\.tsx$/,".jsx"),$=$.replace(/\.ts$/,".js")),{filePath:$,content:g,relativePath:G.relative(s,$),name:`${c}:${h}`}})),f=[];for(let d of R){let{filePath:g,content:$,relativePath:P}=d;if(await ce.ensureDir(G.dirname(g)),ce.existsSync(g)){let C=await ce.readFile(g,"utf-8");if(C===$){B.log.info(`${a(P)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let x=G.basename(g),k=G.extname(g),_=G.basename(g,k),X=Date.now(),S=`legacy-${_}-${X}${k}`,l=await(async()=>{if(r)return r;let b=Ot(P,C,$),A=Ut(b);return B.log.message(`
7
+ ${a(P)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
8
+ `),B.log.message(A),B.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:`${x} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${S}\uC73C\uB85C \uC62E\uAE30\uACE0 ${x} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(B.isCancel(l)||l==="skip"){B.log.info(`${a(P)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(l==="backup"){let b=G.dirname(g),A=G.join(b,S);await ce.rename(g,A),B.log.info(`${a(P)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${a(G.relative(s,A))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await ce.writeFile(g,$),f.push(d)}if(f.length>0){let d=f.map(({name:g,relativePath:$})=>({name:g,path:$}));i.push(...d),B.log.success(`${a(`${c}:${h}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${a(d.map(g=>g.path).join(", "))}`)}}}}import*as v from"@clack/prompts";import os from"path";import{z as ie}from"zod";var N="https://seed-design.io";import*as He from"@clack/prompts";import{execa as zt}from"execa";import{detect as Mt}from"@antfu/ni";async function Be(e){let t=await Mt({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import Vt from"findup-sync";import Lt from"fs-extra";var Kt="package.json";function Nt(e=process.cwd()){let t=Vt(Kt,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function Z(e=process.cwd()){let t=Nt(e);return Lt.readJSONSync(t)}async function Ce({cwd:e,deps:t,dev:s=!1}){let{start:n,stop:o}=He.spinner(),r=await Be(e),c={...Z(e).dependencies},m=new Set(t.filter(f=>!c[f])),p=new Set(t.filter(f=>c[f]));if(!m.size)return{installed:new Set,filtered:m};n("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let w=[r==="npm"?"install":"add",s?"-D":null,...m].filter(Boolean),R=`${r} ${w.join(" ")}`;try{await zt(r,w,{cwd:e})}catch(f){throw o("\uC758\uC874\uC131 \uC124\uCE58\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."),new I({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: ${R}`],cause:f})}return o("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:m,filtered:p}}import{randomUUID as Ft}from"node:crypto";import*as We from"@clack/prompts";var qt="seed_cli";async function Bt(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await ge(e))?.telemetry===!1)return!1}catch{}return!0}function Ht(){return Ft()}var Gt=Ht(),Ge=!1;async function Wt(e,{event:t,properties:s={}}){if(!await Bt(e))return;let o=`${qt}.${t}`;Ge||(We.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)"),Ge=!0);try{let r="https://us.i.posthog.com/capture",i={"Content-Type":"application/json"},c={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:o,distinct_id:Gt,properties:{...s,$process_person_profile:!1},timestamp:new Date().toISOString()},m=new AbortController,p=setTimeout(()=>m.abort(),5e3);try{await fetch(r,{method:"POST",headers:i,body:JSON.stringify(c),signal:m.signal})}finally{clearTimeout(p)}}catch{}}var U={track:Wt};import*as re from"@clack/prompts";import Jt from"fs-extra";import Yt from"path";import{intersects as Xt,satisfies as Qt,valid as Ye,validRange as Xe}from"semver";var fe=["@seed-design/react","@seed-design/css"],Je="workspace:",Zt="npm:";function pe(e){try{let t=Z(e),s={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},n={};for(let o of fe){let r=s[o];typeof r=="string"&&(n[o]=r)}return n}catch{return{}}}function le({publicRegistries:e,itemKeys:t,projectPackageVersions:s}){let n=Array.from(new Set(t)),o=new Map(e.flatMap(i=>i.items.map(c=>[`${i.id}:${c.id}`,c]))),r=[];for(let i of n){let c=o.get(i);if(!c)continue;let m=es(c);for(let p of fe){let y=Array.from(m[p]??[]);if(!y.length)continue;let h=s[p];if(!h){r.push({itemKey:i,packageName:p,requiredRanges:y,type:"missing-package"});continue}let w=ts(h);if(!w){r.push({itemKey:i,packageName:p,requiredRanges:y,installedVersionSpec:h,type:"invalid-version-spec"});continue}y.every(f=>ss({currentVersionSpec:w,requiredRange:f}))||r.push({itemKey:i,packageName:p,requiredRanges:y,installedVersionSpec:h,type:"incompatible-version"})}}return{checkedItemKeys:n,projectPackageVersions:s,issues:r}}function de({report:e,title:t}){if(!e.issues.length)return;re.log.warn(t),re.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${fe.map(n=>`${n}@${a(e.projectPackageVersions[n]??"\uBBF8\uC124\uCE58")}`).join(", ")}`);let s=new Map;for(let n of e.issues){let o=s.get(n.itemKey)??[];o.push(n),s.set(n.itemKey,o)}for(let[n,o]of s.entries()){re.log.warn(a(n));for(let r of o){let i=r.requiredRanges.join(" | ");if(r.type==="missing-package"){re.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"){re.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}re.log.info(` - ${r.packageName}: \uD604\uC7AC ${r.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${i}`)}}}function Qe({publicRegistries:e,rootPath:t}){let s=[];for(let n of e)for(let o of n.items)o.snippets.some(i=>rs(i.path).some(c=>Jt.existsSync(Yt.join(t,n.id,c))))&&s.push(`${n.id}:${o.id}`);return s}function es(e){let t=Object.fromEntries(fe.map(s=>[s,new Set]));for(let s of e.snippets)for(let[n,o]of Object.entries(s.dependencies??{}))is(n)&&t[n].add(o);return t}function ts(e){let t=e.trim();if(t.startsWith(Je)&&(t=t.slice(Je.length).trim()),t.startsWith(Zt)){let s=t.split("@").at(-1);if(!s)return null;t=s}return!t||t==="*"?null:Ye(t)||Xe(t)?t:null}function ss({currentVersionSpec:e,requiredRange:t}){let s=Xe(t);return s?Ye(e)?Qt(e,s,{includePrerelease:!0}):Xt(e,s,{includePrerelease:!0}):!1}function rs(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 is(e){return fe.includes(e)}var ns=ie.object({itemIds:ie.array(ie.string()).optional(),all:ie.boolean(),cwd:ie.string(),baseUrl:ie.string().optional(),onDiff:ie.enum(["overwrite","backup"]).optional()}),Ze=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:N}).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 n=Date.now(),o=K(s);v.intro("seed-design add");try{let r=ns.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:{all:i,...c}}=r;if(i)throw new I({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,p=c.baseUrl,y=await ye(m),h=os.resolve(m,y.path),{start:w,stop:R}=v.spinner();w("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let f=await(async()=>{try{let l=await Promise.all((await ne({baseUrl:p})).map(async({id:b})=>ae({baseUrl:p,registryId:b})));return R("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),l}catch(l){throw R("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),l}})(),d=await(async()=>{if(c.itemIds?.length)return c.itemIds;let l=await v.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:b})=>!b).flatMap(({id:b,items:A})=>A.filter(({hideFromCLICatalog:F})=>!F).sort((F,V)=>F.id.localeCompare(V.id)).map(({id:F,description:V,deprecated:J})=>({label:`${J?"(deprecated) ":""}${a(b)}:${F}`,value:`${b}:${F}`,hint:V,deprecated:J,registryItemCount:A.length}))).sort((b,A)=>b.deprecated!==A.deprecated?b.deprecated?1:-1:A.registryItemCount-b.registryItemCount)});if(v.isCancel(l))throw new E;return l})();if(!d?.length)throw new E("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");v.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${a(d.join(", "))}`);let g=[];for(let l of d){let[b,...A]=l.split(":"),F=A.join(":");if(!b||!F)throw new I({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 V=f.find(J=>J.id===b)?.items.find(J=>J.id===F);if(!V)throw new I({message:`${a(l)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(V.deprecated){let J=await v.confirm({message:`${a(V.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(v.isCancel(J))throw new E;if(J===!1){v.log.info(`${a(V.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}g.push(l)}let{registryItemsToAdd:$,npmDependenciesToAdd:P}=we({selectedItemKeys:g,publicRegistries:f}),C=le({publicRegistries:f,itemKeys:$.flatMap(({registryId:l,items:b})=>b.map(A=>`${l}:${A.id}`)),projectPackageVersions:pe(c.cwd)});de({report:C,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."}),v.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${a($.map(l=>l.items.map(b=>`${l.registryId}:${b.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
9
9
 
10
- \uC124\uCE58\uD560 \uC758\uC874\uC131: ${a(Array.from(I).join(", ")||"\uC5C6\uC74C")}`),await he({registryItemsToAdd:w,rootPath:b,cwd:m,baseUrl:y,config:C,onDiff:c.onDiff});let{installed:P,filtered:O}=await we({cwd:m,deps:Array.from(I)});P.size===0&&S.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),P.size&&(S.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(P).join(", "))}`),O.size&&S.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(O).join(", "))}`)),S.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let ee=Date.now()-o,pe=new Set(w.map(l=>l.registryId)),x=g.some(l=>{let[u,...A]=l.split(":"),M=A.join(":");return f.find(T=>T.id===u)?.items.find(T=>T.id===M)?.deprecated});try{await U.track(c.cwd,{event:"add",properties:{items_count:d.length,registries:Array.from(pe),has_deprecated:x,dependencies_count:I.size,duration_ms:ee}})}catch(l){n&&console.error("[Telemetry] add tracking failed:",l)}}catch(r){z(r)&&(S.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as v from"@clack/prompts";import Jt from"path";import{z as Y}from"zod";var Wt=Y.object({registryIds:Y.array(Y.string()).optional(),all:Y.boolean(),includeDeprecated:Y.boolean().optional(),cwd:Y.string(),baseUrl:Y.string().optional(),onDiff:Y.enum(["overwrite","backup"]).optional()}),Be=e=>{e.command("add-all [...registry-ids]","add all items from registries").option("-a, --all","Add all items from all registries",{default:!1}).option("--include-deprecated","Include deprecated items when used with `--all`",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add-all ui --include-deprecated").example("seed-design add-all ui lib breeze").action(async(t,s)=>{let o=Date.now(),n=F(s);v.intro("seed-design add-all");try{let r=Wt.safeParse({registryIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.cwd,m=i.baseUrl,y=await ge(c),C=Jt.resolve(c,y.path),{start:b,stop:h}=v.spinner();b("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let j=await(async()=>{try{let x=await Promise.all((await se({baseUrl:m})).map(async({id:l})=>re({baseUrl:m,registryId:l})));return h("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),x}catch(x){throw h("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),x}})(),f=await(async()=>{if(i.all){let l=j.map(u=>u.id);return v.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(l.join(", "))}`),l}if(i.registryIds?.length){let l=j.map(u=>u.id);for(let u of i.registryIds)if(!l.includes(u))throw new $({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${u}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${l.join(", ")}`]});return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(i.registryIds.join(", "))}`),i.registryIds}let x=await v.multiselect({message:"\uCD94\uAC00\uD560 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:j.filter(({hideFromCLICatalog:l})=>!l).sort((l,u)=>u.items.length-l.items.length).map(l=>{let u=l.items[0]?.id,A=u?`${l.items.length}\uAC1C \uD56D\uBAA9 (${u} \uB4F1)`:`${l.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:l.id,value:l.id,hint:A}})});if(v.isCancel(x))throw new k;return v.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(x.join(", "))}`),x})(),g=j.filter(x=>f.includes(x.id)),d=g.flatMap(x=>x.items.filter(l=>l.deprecated?i.includeDeprecated:!0).map(l=>`${x.id}:${l.id}`)),w=g.reduce((x,l)=>x+l.items.filter(u=>u.deprecated).length,0);if(!i.includeDeprecated&&w>0&&v.log.info(`${w}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),!d.length)throw new k("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");v.log.message(`\uCD1D ${a(d.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:I,npmDependenciesToAdd:E}=ue({selectedItemKeys:d,publicRegistries:j}),P=ae({publicRegistries:j,itemKeys:I.flatMap(({registryId:x,items:l})=>l.map(u=>`${x}:${u.id}`)),projectPackageVersions:ne(i.cwd)});ce({report:P,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),await he({registryItemsToAdd:I,rootPath:C,cwd:c,baseUrl:m,config:y,onDiff:i.onDiff});let{installed:O,filtered:ee}=await we({cwd:c,deps:Array.from(E)});O.size===0&&v.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),O.size&&(v.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(O).join(", "))}`),ee.size&&v.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(ee).join(", "))}`)),v.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let pe=Date.now()-o;try{await U.track(i.cwd,{event:"add-all",properties:{registries:f,items_count:d.length,include_deprecated:i.includeDeprecated||!1,dependencies_count:E.size,duration_ms:pe}})}catch(x){n&&console.error("[Telemetry] add-all tracking failed:",x)}}catch(r){z(r)&&(v.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as D from"@clack/prompts";import Ge from"path";import{z as N}from"zod";var Yt=N.object({itemIds:N.array(N.string()).optional(),component:N.union([N.string(),N.array(N.string())]).optional(),all:N.boolean(),registry:N.string().optional(),cwd:N.string(),baseUrl:N.string().optional()});function Xt({itemIds:e,component:t}){let s=r=>r.trim().replace(/\s+/g,"-"),o=(e??[]).map(s).filter(Boolean),n=(Array.isArray(t)?t:[t]).filter(r=>!!r).flatMap(r=>r.split(",")).map(s).filter(Boolean);return Array.from(new Set([...o,...n]))}function Qt({publicRegistries:e,targetInputs:t,defaultRegistry:s}){let o=e.filter(r=>typeof r.id=="string"&&Array.isArray(r.items)).flatMap(r=>r.items.filter(i=>typeof i.id=="string").map(i=>`${r.id}:${i.id}`)),n=new Set;for(let r of t){let i=r.includes(":")?r:s?`${s}:${r}`:(()=>{let c=o.filter(m=>m.endsWith(`:${r}`));if(!c.length)throw new $({message:`${a(r)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});if(c.length>1)throw new $({message:`${a(r)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:c.map(m=>`- ${m}`),hint:`${a("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});return c[0]})();if(!o.includes(i))throw new $({message:`${a(i)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});n.add(i)}return Array.from(n)}var He=e=>{e.command("compat [...item-ids]","check snippet compatibility").option("-c, --component <component>","\uAC80\uC0AC\uD560 \uCEF4\uD3EC\uB10C\uD2B8. \uC5EC\uB7EC \uBC88 \uB610\uB294 \uC27C\uD45C\uB85C \uC9C0\uC815 \uAC00\uB2A5").option("-a, --all","\uBAA8\uB4E0 registry \uD56D\uBAA9\uC744 \uAC80\uC0AC",{default:!1}).option("-r, --registry <registryId>","\uCEF4\uD3EC\uB10C\uD2B8 shorthand \uC785\uB825 \uC2DC \uAE30\uBCF8 registry").option("--cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:B}).example("seed-design compat").example("seed-design compat -c action-button").example("seed-design compat ui:action-button ui:alert-dialog").example("seed-design compat --all").action(async(t,s)=>{let o=Date.now(),n=F(s);D.intro("seed-design compat");try{let r=Yt.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,{start:c,stop:m}=D.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let g=await Promise.all((await se({baseUrl:i.baseUrl})).map(async({id:d})=>re({baseUrl:i.baseUrl,registryId:d})));return m("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),g}catch(g){throw m("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),g}})(),C=Xt({itemIds:i.itemIds,component:i.component}),b=i.all?y.flatMap(d=>d.items.map(w=>`${d.id}:${w.id}`)):C.length>0?Qt({publicRegistries:y,targetInputs:C,defaultRegistry:i.registry}):le(i.cwd),h=Array.isArray(b)?b:await(async()=>{let g=await b;if(!g)throw new $({message:"seed-design.json \uD30C\uC77C\uC774 \uC5C6\uC5B4 \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB \uACBD\uB85C\uB97C \uC54C \uC218 \uC5C6\uC5B4\uC694.",hint:"`seed-design init`\uC73C\uB85C \uC124\uC815\uC744 \uB9CC\uB4E0 \uB4A4 \uC2E4\uD589\uD558\uAC70\uB098, `--all`/`-c`\uB85C \uAC80\uC0AC \uB300\uC0C1\uC744 \uC9C1\uC811 \uC9C0\uC815\uD574\uC8FC\uC138\uC694."});let d=Ge.resolve(i.cwd,g.path),w=Ve({publicRegistries:y,rootPath:d});return w.length?w:(D.log.info(`${a(Ge.relative(i.cwd,d)||g.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();h.length||(D.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let j=ne(i.cwd),f=ae({publicRegistries:y,itemKeys:h,projectPackageVersions:j});if(D.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${a(f.checkedItemKeys.join(", "))}`),!f.issues.length){D.outro("\uBAA8\uB4E0 \uC2A4\uB2C8\uD3AB\uC774 \uD604\uC7AC @seed-design/react, @seed-design/css\uC640 \uD638\uD658\uB3FC\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(0)}ce({report:f,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),D.log.info("\uD544\uC694\uD55C \uBC84\uC804\uC73C\uB85C @seed-design/react \uB610\uB294 @seed-design/css\uB97C \uB9DE\uCD98 \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD574\uBCF4\uC138\uC694."),D.outro("\uD638\uD658\uC131 \uC774\uC288\uAC00 \uC788\uC5B4\uC694.");try{await U.track(i.cwd,{event:"compat",properties:{checked_items_count:f.checkedItemKeys.length,incompatible_items_count:new Set(f.issues.map(g=>g.itemKey)).size,issue_count:f.issues.length,duration_ms:Date.now()-o}})}catch(g){n&&console.error("[Telemetry] compat tracking failed:",g)}process.exit(1)}catch(r){z(r)&&(D.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uD638\uD658\uC131 \uAC80\uC0AC\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as R from"@clack/prompts";import{z as xe}from"zod";var Zt="https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry",es=xe.object({query:xe.string().optional(),baseUrl:xe.string().optional()});function Je(e,t){return`${Zt}/${e}/${t}`}function ts(e,t){let s=`${t}${e.docUrl}`,o=`${t}/llms${e.docUrl}.txt`,n=[e.id,`- docs: ${s}`,`- llms.txt: ${o}`];if(e.snippetKey&&e.snippets&&e.snippets.length>0){let[r]=e.snippetKey.split(":");if(r==="ui"||r==="breeze")if(e.snippets.length===1)n.push(`- snippet: ${Je(r,e.snippets[0].path)}`);else{n.push("- snippet:");for(let i of e.snippets)n.push(` - ${i.label}: ${Je(r,i.path)}`)}}R.log.message(n.join(`
11
- `))}function ss(e){return e.split("/").map(t=>t.trim()).filter(Boolean)}function rs(e,t){let s=t.toLowerCase();return e.flatMap(o=>o.sections.flatMap(n=>n.items.filter(r=>r.id.toLowerCase().includes(s)||r.title.toLowerCase().includes(s)).map(r=>({item:r,categoryLabel:o.label,sectionLabel:n.label}))))}async function de(e){let t=await R.select({message:"\uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:`${s.deprecated?"(deprecated) ":""}${s.title}`,value:s,hint:s.description}))});if(R.isCancel(t))throw new k;return t}async function We(e){let t=await R.select({message:"\uC139\uC158\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.items.length}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}async function is(e){let t=await R.select({message:"\uCE74\uD14C\uACE0\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(s=>({label:s.label,value:s,hint:`${s.sections.reduce((o,n)=>o+n.items.length,0)}\uAC1C \uD56D\uBAA9`}))});if(R.isCancel(t))throw new k;return t}var Ye=e=>{e.command("docs [query]","\uBB38\uC11C \uB9C1\uD06C, llms.txt \uB9C1\uD06C, \uC2A4\uB2C8\uD3AB \uB9C1\uD06C\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4").option("-u, --baseUrl <baseUrl>",`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uAE30\uBCF8 URL (\uAE30\uBCF8\uAC12: ${B})`,{default:B}).example("seed-design docs").example("seed-design docs action-button").example("seed-design docs react").example("seed-design docs react/components").example("seed-design docs react/components/action-button").action(async(t,s)=>{let o=Date.now(),n=F(s);R.intro("seed-design docs");try{let r=es.safeParse({query:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.baseUrl??B,{start:m,stop:y}=R.spinner();m("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let C=await(async()=>{try{let f=await je({baseUrl:c});return y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),{categories:b}=C,h;if(i.query){let f=ss(i.query),g=b.find(d=>d.id===f[0]);if(g&&f.length>=2){let d=g.sections.find(w=>w.id===f[1]);if(d&&f.length>=3){let w=d.items.find(I=>I.id===f[2]);if(w)h=w;else{let I=f[2].toLowerCase(),E=d.items.filter(P=>P.id.toLowerCase().includes(I)||P.title.toLowerCase().includes(I));if(E.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}/${d.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});E.length===1?h=E[0]:h=await de(E)}}else if(d)h=await de(d.items);else{let w=f[1].toLowerCase(),I=g.sections.flatMap(E=>E.items.filter(P=>P.id.toLowerCase().includes(w)||P.title.toLowerCase().includes(w)).map(P=>({item:P,sectionLabel:E.label})));if(I.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`\`seed-design docs ${g.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`});if(I.length===1)h=I[0].item;else{let E=await R.select({message:`${a(f[1])}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:I.map(({item:P,sectionLabel:O})=>({label:`[${O}] ${P.title}`,value:P,hint:P.description}))});if(R.isCancel(E))throw new k;h=E}}}else if(g)if(g.sections.length===1)h=await de(g.sections[0].items);else{let d=await We(g.sections);h=await de(d.items)}else{let d=rs(b,i.query);if(d.length===0)throw new $({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:"`seed-design docs`\uB85C \uC804\uCCB4 \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694."});if(d.length===1)h=d[0].item;else{let w=await R.select({message:`${a(i.query)}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:d.map(({item:I,categoryLabel:E,sectionLabel:P})=>({label:`[${E} > ${P}] ${I.title}`,value:I,hint:I.description}))});if(R.isCancel(w))throw new k;h=w}}}else{let f=await is(b),g;f.sections.length===1?g=f.sections[0]:g=await We(f.sections),h=await de(g.items)}ts(h,c),R.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let j=Date.now()-o;try{await U.track(process.cwd(),{event:"docs",properties:{query:i.query??null,item_id:h.id,has_snippet:!!(h.snippets&&h.snippets.length>0),duration_ms:j}})}catch(f){n&&console.error("[Telemetry] docs tracking failed:",f)}}catch(r){z(r)&&(R.outro(a(r.message)),process.exit(0)),V(r,{defaultMessage:"\uBB38\uC11C \uC870\uD68C\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:n}),process.exit(1)}})};import*as _ from"@clack/prompts";import{z as be}from"zod";import os from"dedent";var ns=be.object({cwd:be.string(),yes:be.boolean().optional(),default:be.boolean().optional()}),Xe=e=>{e.command("init","seed-design.json \uD30C\uC77C \uC0DD\uC131").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC.",{default:process.cwd()}).option("-y, --yes","\uBAA8\uB4E0 \uC9C8\uBB38\uC5D0 \uB300\uD574 \uAE30\uBCF8\uAC12\uC73C\uB85C \uB2F5\uBCC0\uD569\uB2C8\uB2E4.").option("--default","Deprecated. --yes\uC640 \uB3D9\uC77C\uD558\uAC8C \uAE30\uBCF8\uAC12\uC73C\uB85C \uC0DD\uC131\uD569\uB2C8\uB2E4.").action(async t=>{let s=Date.now(),o=F(t);_.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let n=ns.safeParse(t);if(!n.success)throw n.error;let r=n.data,i=r.yes||r.default,c=i?K:await Se(),{start:m,stop:y}=_.spinner();m("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let C=await(async()=>{try{return(await fe({cwd:r.cwd,config:c})).relativePath}catch(h){throw y("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),h}})();y(`seed-design.json \uD30C\uC77C\uC774 ${a(C)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),_.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),_.log.info(a("seed-design add \uBA85\uB839\uC5B4\uB85C \uCD94\uAC00\uD560 \uC218 \uC788\uB294 \uBAA8\uB4E0 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.")),_.note(os(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
10
+ \uC124\uCE58\uD560 \uC758\uC874\uC131: ${a(Array.from(P).join(", ")||"\uC5C6\uC74C")}`),await $e({registryItemsToAdd:$,rootPath:h,cwd:m,baseUrl:p,config:y,onDiff:c.onDiff});let{installed:x,filtered:k}=await Ce({cwd:m,deps:Array.from(P)});x.size===0&&v.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),x.size&&(v.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(x).join(", "))}`),k.size&&v.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(k).join(", "))}`)),v.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let _=Date.now()-n,X=new Set($.map(l=>l.registryId)),S=d.some(l=>{let[b,...A]=l.split(":"),F=A.join(":");return f.find(V=>V.id===b)?.items.find(V=>V.id===F)?.deprecated});try{await U.track(c.cwd,{event:"add",properties:{items_count:g.length,registries:Array.from(X),has_deprecated:S,dependencies_count:P.size,duration_ms:_}})}catch(l){o&&console.error("[Telemetry] add tracking failed:",l)}}catch(r){L(r)&&(v.outro(a(r.message)),process.exit(0)),O(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:o}),process.exit(1)}})};import*as T from"@clack/prompts";import as from"path";import{z as ee}from"zod";var cs=ee.object({registryIds:ee.array(ee.string()).optional(),all:ee.boolean(),includeDeprecated:ee.boolean().optional(),cwd:ee.string(),baseUrl:ee.string().optional(),onDiff:ee.enum(["overwrite","backup"]).optional()}),et=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:N}).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 n=Date.now(),o=K(s);T.intro("seed-design add-all");try{let r=cs.safeParse({registryIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.cwd,m=i.baseUrl,p=await ye(c),y=as.resolve(c,p.path),{start:h,stop:w}=T.spinner();h("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let R=await(async()=>{try{let S=await Promise.all((await ne({baseUrl:m})).map(async({id:l})=>ae({baseUrl:m,registryId:l})));return w("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),S}catch(S){throw w("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),S}})(),f=await(async()=>{if(i.all){let l=R.map(b=>b.id);return T.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=R.map(b=>b.id);for(let b of i.registryIds)if(!l.includes(b))throw new I({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${b}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${l.join(", ")}`]});return T.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 S=await T.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:R.filter(({hideFromCLICatalog:l})=>!l).sort((l,b)=>b.items.length-l.items.length).map(l=>{let b=l.items[0]?.id,A=b?`${l.items.length}\uAC1C \uD56D\uBAA9 (${b} \uB4F1)`:`${l.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:l.id,value:l.id,hint:A}})});if(T.isCancel(S))throw new E;return T.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${a(S.join(", "))}`),S})(),d=R.filter(S=>f.includes(S.id)),g=d.flatMap(S=>S.items.filter(l=>l.deprecated?i.includeDeprecated:!0).map(l=>`${S.id}:${l.id}`)),$=d.reduce((S,l)=>S+l.items.filter(b=>b.deprecated).length,0);if(!i.includeDeprecated&&$>0&&T.log.info(`${$}\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.");T.log.message(`\uCD1D ${a(g.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:P,npmDependenciesToAdd:C}=we({selectedItemKeys:g,publicRegistries:R}),x=le({publicRegistries:R,itemKeys:P.flatMap(({registryId:S,items:l})=>l.map(b=>`${S}:${b.id}`)),projectPackageVersions:pe(i.cwd)});de({report:x,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 $e({registryItemsToAdd:P,rootPath:y,cwd:c,baseUrl:m,config:p,onDiff:i.onDiff});let{installed:k,filtered:_}=await Ce({cwd:c,deps:Array.from(C)});k.size===0&&T.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),k.size&&(T.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${a(Array.from(k).join(", "))}`),_.size&&T.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${a(Array.from(_).join(", "))}`)),T.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let X=Date.now()-n;try{await U.track(i.cwd,{event:"add-all",properties:{registries:f,items_count:g.length,include_deprecated:i.includeDeprecated||!1,dependencies_count:C.size,duration_ms:X}})}catch(S){o&&console.error("[Telemetry] add-all tracking failed:",S)}}catch(r){L(r)&&(T.outro(a(r.message)),process.exit(0)),O(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:o}),process.exit(1)}})};import*as M from"@clack/prompts";import tt from"path";import{z as H}from"zod";var ps=H.object({itemIds:H.array(H.string()).optional(),component:H.union([H.string(),H.array(H.string())]).optional(),all:H.boolean(),registry:H.string().optional(),cwd:H.string(),baseUrl:H.string().optional()});function ls({itemIds:e,component:t}){let s=r=>r.trim().replace(/\s+/g,"-"),n=(e??[]).map(s).filter(Boolean),o=(Array.isArray(t)?t:[t]).filter(r=>!!r).flatMap(r=>r.split(",")).map(s).filter(Boolean);return Array.from(new Set([...n,...o]))}function ds({publicRegistries:e,targetInputs:t,defaultRegistry:s}){let n=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}`)),o=new Set;for(let r of t){let i=r.includes(":")?r:s?`${s}:${r}`:(()=>{let c=n.filter(m=>m.endsWith(`:${r}`));if(!c.length)throw new I({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 I({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(!n.includes(i))throw new I({message:`${a(i)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});o.add(i)}return Array.from(o)}var st=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:N}).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 n=Date.now(),o=K(s);M.intro("seed-design compat");try{let r=ps.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,{start:c,stop:m}=M.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let p=await(async()=>{try{let d=await Promise.all((await ne({baseUrl:i.baseUrl})).map(async({id:g})=>ae({baseUrl:i.baseUrl,registryId:g})));return m("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),d}catch(d){throw m("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),d}})(),y=ls({itemIds:i.itemIds,component:i.component}),h=i.all?p.flatMap(g=>g.items.map($=>`${g.id}:${$.id}`)):y.length>0?ds({publicRegistries:p,targetInputs:y,defaultRegistry:i.registry}):ge(i.cwd),w=Array.isArray(h)?h:await(async()=>{let d=await h;if(!d)throw new I({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=tt.resolve(i.cwd,d.path),$=Qe({publicRegistries:p,rootPath:g});return $.length?$:(M.log.info(`${a(tt.relative(i.cwd,g)||d.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();w.length||(M.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let R=pe(i.cwd),f=le({publicRegistries:p,itemKeys:w,projectPackageVersions:R});if(M.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${a(f.checkedItemKeys.join(", "))}`),!f.issues.length){M.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()-n}})}catch(d){o&&console.error("[Telemetry] compat tracking failed:",d)}process.exit(0)}de({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."}),M.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."),M.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(d=>d.itemKey)).size,issue_count:f.issues.length,duration_ms:Date.now()-n}})}catch(d){o&&console.error("[Telemetry] compat tracking failed:",d)}process.exit(1)}catch(r){L(r)&&(M.outro(a(r.message)),process.exit(0)),O(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:o}),process.exit(1)}})};import*as j from"@clack/prompts";import{z as ve}from"zod";var ms="https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry",gs=ve.object({query:ve.string().optional(),baseUrl:ve.string().optional()});function rt(e,t){return`${ms}/${e}/${t}`}function fs(e,t){let s=`${t}${e.docUrl}`,n=`${t}/llms${e.docUrl}.txt`,o=[e.id,`- docs: ${s}`,`- llms.txt: ${n}`];if(e.snippetKey&&e.snippets&&e.snippets.length>0){let[r]=e.snippetKey.split(":");if(r==="ui"||r==="breeze")if(e.snippets.length===1)o.push(`- snippet: ${rt(r,e.snippets[0].path)}`);else{o.push("- snippet:");for(let i of e.snippets)o.push(` - ${i.label}: ${rt(r,i.path)}`)}}j.log.message(o.join(`
11
+ `))}function us(e,t){let s=e.length,n=t.length,o=Array.from({length:s+1},(r,i)=>Array.from({length:n+1},(c,m)=>i===0?m:m===0?i:0));for(let r=1;r<=s;r++)for(let i=1;i<=n;i++)o[r][i]=Math.min(o[r-1][i]+1,o[r][i-1]+1,o[r-1][i-1]+(e[r-1]!==t[i-1]?1:0));return o[s][n]}function te(e,t,s=3){let n=e.toLowerCase();return t.map(o=>({value:o,dist:us(n,o.toLowerCase())})).filter(({dist:o})=>o>0&&o<=s).sort((o,r)=>o.dist-r.dist).map(({value:o})=>o)}function hs(e,t){if(e.length===0)return;let s=[],n=t.map(i=>i.id),o=te(e[0],n);if(o.length===0){let i=t.flatMap(p=>p.sections.flatMap(y=>y.items.map(h=>`${p.id}/${y.id}/${h.id}`))),c=e.join("/"),m=te(c,i,5);m.length>0&&s.push(...m.slice(0,3))}else{let i=t.find(c=>c.id===o[0]);if(i&&e.length>=2){let c=i.sections.map(p=>p.id),m=te(e[1],c);if(m.length>0){let p=i.sections.find(y=>y.id===m[0]);if(p&&e.length>=3){let y=p.items.map(w=>w.id),h=te(e[2],y);for(let w of h.slice(0,3))s.push(`${i.id}/${p.id}/${w}`)}else for(let y of m.slice(0,3))s.push(`${i.id}/${y}`)}else{let p=i.sections.flatMap(h=>h.items.map(w=>({path:`${i.id}/${h.id}/${w.id}`,id:w.id}))),y=te(e[1],p.map(h=>h.id));for(let h of y.slice(0,3)){let w=p.find(R=>R.id===h);w&&s.push(w.path)}}}else for(let c of o.slice(0,3))s.push(c)}if(s.length===0)return;let r=["","\u{1F4A1} \uC774\uAC83\uC744 \uC758\uBBF8\uD588\uB098\uC694?"];for(let i of s)r.push(` - ${i}`);return r.join(`
12
+ `)}function ys(e){return e.split("/").map(t=>t.trim()).filter(Boolean)}function ws(e,t){let s=t.toLowerCase();return e.flatMap(n=>n.sections.flatMap(o=>o.items.filter(r=>r.id.toLowerCase().includes(s)||r.title.toLowerCase().includes(s)).map(r=>({item:r,categoryLabel:n.label,sectionLabel:o.label}))))}async function ue(e){let t=await j.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(j.isCancel(t))throw new E;return t}async function it(e){let t=await j.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(j.isCancel(t))throw new E;return t}async function bs(e){let t=await j.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((n,o)=>n+o.items.length,0)}\uAC1C \uD56D\uBAA9`}))});if(j.isCancel(t))throw new E;return t}var ot=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: ${N})`,{default:N}).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 n=Date.now(),o=K(s);j.intro("seed-design docs");try{let r=gs.safeParse({query:t,...s});if(!r.success)throw r.error;let{data:i}=r,c=i.baseUrl??N,{start:m,stop:p}=j.spinner();m("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let f=await Me({baseUrl:c});return p("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw p("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),{categories:h}=y,w;if(i.query){let f=ys(i.query),d=h.find(g=>g.id===f[0]);if(d&&f.length>=2){let g=d.sections.find($=>$.id===f[1]);if(g&&f.length>=3){let $=g.items.find(P=>P.id===f[2]);if($)w=$;else{let P=f[2].toLowerCase(),C=g.items.filter(x=>x.id.toLowerCase().includes(P)||x.title.toLowerCase().includes(P));if(C.length===0){let x=te(f[2],g.items.map(_=>_.id)),k=x.length>0?`
13
+
14
+ \u{1F4A1} \uC774\uAC83\uC744 \uC758\uBBF8\uD588\uB098\uC694?
15
+ ${x.slice(0,3).map(_=>` - ${d.id}/${g.id}/${_}`).join(`
16
+ `)}`:"";throw new I({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.${k}`,hint:`\`seed-design docs ${d.id}/${g.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`})}C.length===1?w=C[0]:w=await ue(C)}}else if(g)w=await ue(g.items);else{let $=f[1].toLowerCase(),P=d.sections.flatMap(C=>C.items.filter(x=>x.id.toLowerCase().includes($)||x.title.toLowerCase().includes($)).map(x=>({item:x,sectionLabel:C.label})));if(P.length===0){let C=d.sections.map(l=>l.id),x=te(f[1],C),k=d.sections.flatMap(l=>l.items.map(b=>({path:`${d.id}/${l.id}/${b.id}`,id:b.id}))),_=te(f[1],k.map(l=>l.id)),X=[...x.slice(0,2).map(l=>`${d.id}/${l}`),..._.slice(0,2).map(l=>k.find(b=>b.id===l)?.path).filter(l=>l!=null)],S=X.length>0?`
17
+
18
+ \u{1F4A1} \uC774\uAC83\uC744 \uC758\uBBF8\uD588\uB098\uC694?
19
+ ${X.map(l=>` - ${l}`).join(`
20
+ `)}`:"";throw new I({message:`${a(i.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.${S}`,hint:`\`seed-design docs ${d.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`})}if(P.length===1)w=P[0].item;else{let C=await j.select({message:`${a(f[1])}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:P.map(({item:x,sectionLabel:k})=>({label:`[${k}] ${x.title}`,value:x,hint:x.description}))});if(j.isCancel(C))throw new E;w=C}}}else if(d)if(d.sections.length===1)w=await ue(d.sections[0].items);else{let g=await it(d.sections);w=await ue(g.items)}else{let g=ws(h,i.query);if(g.length===0){let $=hs(f,h);throw new I({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(g.length===1)w=g[0].item;else{let $=await j.select({message:`${a(i.query)}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:g.map(({item:P,categoryLabel:C,sectionLabel:x})=>({label:`[${C} > ${x}] ${P.title}`,value:P,hint:P.description}))});if(j.isCancel($))throw new E;w=$}}}else{let f=await bs(h),d;f.sections.length===1?d=f.sections[0]:d=await it(f.sections),w=await ue(d.items)}fs(w,c),j.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let R=Date.now()-n;try{await U.track(process.cwd(),{event:"docs",properties:{query:i.query??null,item_id:w.id,has_snippet:!!(w.snippets&&w.snippets.length>0),duration_ms:R}})}catch(f){o&&console.error("[Telemetry] docs tracking failed:",f)}}catch(r){L(r)&&(j.outro(a(r.message)),process.exit(0)),O(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:o}),process.exit(1)}})};import*as z from"@clack/prompts";import{z as Ie}from"zod";import $s from"dedent";var Cs=Ie.object({cwd:Ie.string(),yes:Ie.boolean().optional(),default:Ie.boolean().optional()}),nt=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(),n=K(t);z.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let o=Cs.safeParse(t);if(!o.success)throw o.error;let r=o.data,i=r.yes||r.default,c=i?q:await Te(),{start:m,stop:p}=z.spinner();m("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let y=await(async()=>{try{return(await he({cwd:r.cwd,config:c})).relativePath}catch(w){throw p("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),w}})();p(`seed-design.json \uD30C\uC77C\uC774 ${a(y)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),z.log.info(a("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),z.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.")),z.note($s(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
12
21
 
13
22
  \uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
14
23
  \u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
15
24
  \u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
16
25
 
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();
26
+ \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),z.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let h=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:h}})}catch(w){n&&console.error("[Telemetry] init tracking failed:",w)}}catch(o){L(o)&&(z.outro(a(o.message)),process.exit(0)),O(o,{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:n}),process.exit(1)}})};import*as D from"@clack/prompts";import{coerce as Is,valid as xs}from"semver";import{z as me}from"zod";var ke="@seed-design/",Ps=me.object({packageName:me.string().optional(),cwd:me.string(),baseUrl:me.string(),raw:me.boolean(),all:me.boolean()});function ks(e){return e.startsWith(ke)?e:`${ke}${e}`}function Ss(e){return e.replace(ke,"")}function Rs(e){let t=Z(e),s={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},n={};for(let[o,r]of Object.entries(s))o.startsWith(ke)&&r&&(n[o]=r);return n}function Es(e){let t=e.trim();if(t.startsWith("workspace:")&&(t=t.slice(10).trim()),t.startsWith("npm:")){let n=t.lastIndexOf("@");n>4&&(t=t.slice(n+1))}if(xs(t))return t;let s=Is(t);return s?s.version:null}async function xe({targetPackage:e,currentVersionSpec:t,baseUrl:s}){let n=Es(t);if(!n)throw new I({message:`${e}\uC758 \uBC84\uC804\uC744 \uD30C\uC2F1\uD560 \uC218 \uC5C6\uC5B4\uC694: ${t}`,hint:"package.json\uC5D0\uC11C \uBC84\uC804 \uD615\uC2DD\uC744 \uD655\uC778\uD574\uC8FC\uC138\uC694."});let o=await Ve(e);if(n===o)return{package:e,currentVersion:n,latestVersion:o,upToDate:!0,changelog:null};let r=Ss(e),i=await Le({baseUrl:s,packageSlug:r,version:n});return{package:e,currentVersion:n,latestVersion:o,upToDate:!1,changelog:i}}function at(e){e.error?console.error(`## ${e.package}
27
+
28
+ Error: ${e.error}
29
+ `):e.upToDate?console.log(`${e.package}@${e.currentVersion} is already up to date.
30
+ `):(console.log(e.changelog),console.log(""))}function ct(e){e.error?D.log.error(`${a(e.package)}: ${e.error}`):e.upToDate?D.log.info(`${a(e.package)}: ${a(e.currentVersion)} \u2014 \uC774\uBBF8 \uCD5C\uC2E0 \uBC84\uC804\uC774\uC5D0\uC694.`):(D.log.info(`${a(e.package)}: ${a(e.currentVersion)} \u2192 ${a(e.latestVersion)}`),D.log.message(e.changelog??""),D.log.info(`\uC5C5\uADF8\uB808\uC774\uB4DC\uD558\uB824\uBA74: ${a(`bun add ${e.package}@${e.latestVersion}`)}`))}async function Pe(e,t,s){try{for(let n of t)await U.track(e,{event:"upgrade",properties:{package:n.package,current_version:n.currentVersion,latest_version:n.latestVersion,up_to_date:n.upToDate,duration_ms:Date.now()-s}})}catch{}}var pt=e=>{e.command("upgrade [package-name]","\uD328\uD0A4\uC9C0\uC758 \uD604\uC7AC \uBC84\uC804\uACFC \uCD5C\uC2E0 \uBC84\uC804 \uC0AC\uC774\uC758 \uBCC0\uACBD\uC0AC\uD56D\uC744 \uD655\uC778\uD569\uB2C8\uB2E4").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC\uC785\uB2C8\uB2E4.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","changelog\uB97C \uC870\uD68C\uD560 base URL\uC785\uB2C8\uB2E4.",{default:N}).option("--raw","UI \uC5C6\uC774 \uC21C\uC218 \uB9C8\uD06C\uB2E4\uC6B4\uB9CC \uCD9C\uB825\uD569\uB2C8\uB2E4. LLM \uD30C\uC774\uD504\uC5D0 \uC720\uC6A9\uD569\uB2C8\uB2E4.",{default:!1}).option("-a, --all","\uC124\uCE58\uB41C \uBAA8\uB4E0 @seed-design \uD328\uD0A4\uC9C0\uC758 \uBCC0\uACBD\uC0AC\uD56D\uC744 \uD655\uC778\uD569\uB2C8\uB2E4.",{default:!1}).example("seed-design upgrade").example("seed-design upgrade react").example("seed-design upgrade --all").example("seed-design upgrade --all --raw").action(async(t,s)=>{let n=Date.now(),o=K(s),r=Ps.safeParse({packageName:t,...s});r.success||(s.raw&&(console.error(r.error.message),process.exit(1)),D.intro("seed-design upgrade"),O(r.error,{defaultMessage:"\uC5C5\uADF8\uB808\uC774\uB4DC \uD655\uC778\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));let{data:i}=r,{raw:c,all:m}=i;c||D.intro("seed-design upgrade");try{let p=Rs(i.cwd),y=Object.keys(p);if(y.length===0)throw new I({message:"\uD504\uB85C\uC81D\uD2B8\uC5D0 \uC124\uCE58\uB41C @seed-design \uD328\uD0A4\uC9C0\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.",hint:"`bun add @seed-design/react`\uB85C \uD328\uD0A4\uC9C0\uB97C \uC124\uCE58\uD574\uBCF4\uC138\uC694."});if(i.packageName&&m)throw new I({message:"\uD328\uD0A4\uC9C0\uBA85\uACFC --all \uC635\uC158\uC744 \uB3D9\uC2DC\uC5D0 \uC0AC\uC6A9\uD560 \uC218 \uC5C6\uC5B4\uC694.",hint:"`seed-design upgrade --all` \uB610\uB294 `seed-design upgrade react` \uC911 \uD558\uB098\uB9CC \uC0AC\uC6A9\uD574\uC8FC\uC138\uC694."});if(m){if(c){let C=await Promise.all(y.map(k=>xe({targetPackage:k,currentVersionSpec:p[k],baseUrl:i.baseUrl}).catch(_=>({package:k,currentVersion:p[k],latestVersion:"unknown",upToDate:!1,changelog:null,error:_ instanceof Error?_.message:String(_)}))));for(let k of C)at(k);await Pe(i.cwd,C,n);let x=C.some(k=>"error"in k&&!!k.error);process.exit(x?1:0)}let{start:d,stop:g}=D.spinner();d("\uBAA8\uB4E0 \uD328\uD0A4\uC9C0\uC758 \uBCC0\uACBD\uC0AC\uD56D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let $=await Promise.all(y.map(C=>xe({targetPackage:C,currentVersionSpec:p[C],baseUrl:i.baseUrl}).catch(x=>({package:C,currentVersion:p[C],latestVersion:"unknown",upToDate:!1,changelog:null,error:x instanceof Error?x.message:String(x)}))));g("\uBCC0\uACBD\uC0AC\uD56D\uC744 \uAC00\uC838\uC654\uC5B4\uC694.");for(let C of $)ct(C);D.outro("\uC644\uB8CC\uD588\uC5B4\uC694."),await Pe(i.cwd,$,n);let P=$.some(C=>"error"in C&&!!C.error);process.exit(P?1:0)}let h;if(i.packageName){if(h=ks(i.packageName),!p[h])throw new I({message:`${a(h)}: \uD504\uB85C\uC81D\uD2B8\uC5D0 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC694.`,hint:`\uC124\uCE58\uB41C \uD328\uD0A4\uC9C0: ${y.map(d=>a(d)).join(", ")}`})}else{if(c)throw new I({message:"--raw \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uD328\uD0A4\uC9C0\uBA85 \uB610\uB294 --all \uC635\uC158\uC774 \uD544\uC694\uD574\uC694.",hint:"\uC608: `seed-design upgrade react --raw` \uB610\uB294 `seed-design upgrade --all --raw`"});if(y.length===1)h=y[0];else{let d=await D.select({message:"\uBCC0\uACBD\uC0AC\uD56D\uC744 \uD655\uC778\uD560 \uD328\uD0A4\uC9C0\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:y.map(g=>({label:g,value:g,hint:p[g]}))});if(D.isCancel(d))throw new E;h=d}}if(c){let d=await xe({targetPackage:h,currentVersionSpec:p[h],baseUrl:i.baseUrl});at(d),await Pe(i.cwd,[d],n),process.exit(0)}let{start:w,stop:R}=D.spinner();w("\uCD5C\uC2E0 \uBC84\uC804\uC744 \uD655\uC778\uD558\uACE0 \uC788\uC5B4\uC694...");let f;try{f=await xe({targetPackage:h,currentVersionSpec:p[h],baseUrl:i.baseUrl}),R("\uBCC0\uACBD\uC0AC\uD56D\uC744 \uAC00\uC838\uC654\uC5B4\uC694.")}catch(d){throw R("\uBCC0\uACBD\uC0AC\uD56D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),d}ct(f),D.outro("\uC644\uB8CC\uD588\uC5B4\uC694."),await Pe(i.cwd,[f],n)}catch(p){if(L(p)&&(c||D.outro(a(p.message)),process.exit(0)),c){let y=p instanceof Error?p.message:String(p);console.error(y),process.exit(1)}O(p,{defaultMessage:"\uC5C5\uADF8\uB808\uC774\uB4DC \uD655\uC778\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 vs}from"cac";var js="seed-design",W=vs(js);async function Ts(){let e=Z();W.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),Ze(W),et(W),st(W),ot(W),nt(W),pt(W),W.version(e.version||"1.0.0","-v, --version"),W.help(),W.parse()}Ts();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-design/cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,6 +49,112 @@ function printDocsResult(item: DocsItem, baseUrl: string) {
49
49
  p.log.message(lines.join("\n"));
50
50
  }
51
51
 
52
+ /**
53
+ * Compute the Levenshtein (edit) distance between two strings.
54
+ * Used to suggest similar valid paths when users make typos.
55
+ */
56
+ function levenshtein(a: string, b: string): number {
57
+ const m = a.length;
58
+ const n = b.length;
59
+ const dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>
60
+ Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),
61
+ );
62
+ for (let i = 1; i <= m; i++) {
63
+ for (let j = 1; j <= n; j++) {
64
+ dp[i][j] = Math.min(
65
+ dp[i - 1][j] + 1,
66
+ dp[i][j - 1] + 1,
67
+ dp[i - 1][j - 1] + (a[i - 1] !== b[j - 1] ? 1 : 0),
68
+ );
69
+ }
70
+ }
71
+ return dp[m][n];
72
+ }
73
+
74
+ /**
75
+ * Find candidates similar to `input` within `maxDistance` edits, sorted by distance.
76
+ */
77
+ function findSimilar(input: string, candidates: string[], maxDistance = 3): string[] {
78
+ const q = input.toLowerCase();
79
+ return candidates
80
+ .map((c) => ({ value: c, dist: levenshtein(q, c.toLowerCase()) }))
81
+ .filter(({ dist }) => dist > 0 && dist <= maxDistance)
82
+ .sort((a, b) => a.dist - b.dist)
83
+ .map(({ value }) => value);
84
+ }
85
+
86
+ /**
87
+ * Build a suggestion hint from a path query by fuzzy-matching each segment
88
+ * against the docs index hierarchy.
89
+ */
90
+ function buildSuggestionHint(segments: string[], categories: DocsCategory[]): string | undefined {
91
+ if (segments.length === 0) return undefined;
92
+
93
+ const suggestions: string[] = [];
94
+
95
+ // Try to fuzzy-match the first segment against category IDs
96
+ const categoryIds = categories.map((c) => c.id);
97
+ const similarCategories = findSimilar(segments[0], categoryIds);
98
+
99
+ if (similarCategories.length === 0) {
100
+ // No similar category — try to find similar full paths across everything
101
+ const allPaths = categories.flatMap((cat) =>
102
+ cat.sections.flatMap((sec) => sec.items.map((item) => `${cat.id}/${sec.id}/${item.id}`)),
103
+ );
104
+ const fullQuery = segments.join("/");
105
+ const similarPaths = findSimilar(fullQuery, allPaths, 5);
106
+ if (similarPaths.length > 0) {
107
+ suggestions.push(...similarPaths.slice(0, 3));
108
+ }
109
+ } else {
110
+ const bestCat = categories.find((c) => c.id === similarCategories[0]);
111
+ if (bestCat && segments.length >= 2) {
112
+ const sectionIds = bestCat.sections.map((s) => s.id);
113
+ const similarSections = findSimilar(segments[1], sectionIds);
114
+
115
+ if (similarSections.length > 0) {
116
+ const bestSec = bestCat.sections.find((s) => s.id === similarSections[0]);
117
+ if (bestSec && segments.length >= 3) {
118
+ const itemIds = bestSec.items.map((i) => i.id);
119
+ const similarItems = findSimilar(segments[2], itemIds);
120
+ for (const item of similarItems.slice(0, 3)) {
121
+ suggestions.push(`${bestCat.id}/${bestSec.id}/${item}`);
122
+ }
123
+ } else {
124
+ for (const sec of similarSections.slice(0, 3)) {
125
+ suggestions.push(`${bestCat.id}/${sec}`);
126
+ }
127
+ }
128
+ } else {
129
+ // Section not found, search items within category
130
+ const allItemIds = bestCat.sections.flatMap((s) =>
131
+ s.items.map((i) => ({ path: `${bestCat.id}/${s.id}/${i.id}`, id: i.id })),
132
+ );
133
+ const similarItems = findSimilar(
134
+ segments[1],
135
+ allItemIds.map((x) => x.id),
136
+ );
137
+ for (const itemId of similarItems.slice(0, 3)) {
138
+ const found = allItemIds.find((x) => x.id === itemId);
139
+ if (found) suggestions.push(found.path);
140
+ }
141
+ }
142
+ } else {
143
+ for (const cat of similarCategories.slice(0, 3)) {
144
+ suggestions.push(cat);
145
+ }
146
+ }
147
+ }
148
+
149
+ if (suggestions.length === 0) return undefined;
150
+
151
+ const lines = ["", "💡 이것을 의미했나요?"];
152
+ for (const s of suggestions) {
153
+ lines.push(` - ${s}`);
154
+ }
155
+ return lines.join("\n");
156
+ }
157
+
52
158
  /**
53
159
  * Parse a path-style query into segments.
54
160
  * e.g. "react/components/action-button" → ["react", "components", "action-button"]
@@ -183,8 +289,19 @@ export const docsCommand = (cli: CAC) => {
183
289
  (i) => i.id.toLowerCase().includes(q) || i.title.toLowerCase().includes(q),
184
290
  );
185
291
  if (matched.length === 0) {
292
+ const similarItems = findSimilar(
293
+ segments[2],
294
+ matchedSection.items.map((i) => i.id),
295
+ );
296
+ const suggestion =
297
+ similarItems.length > 0
298
+ ? `\n\n💡 이것을 의미했나요?\n${similarItems
299
+ .slice(0, 3)
300
+ .map((s) => ` - ${matchedCategory.id}/${matchedSection.id}/${s}`)
301
+ .join("\n")}`
302
+ : "";
186
303
  throw new CliError({
187
- message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
304
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.${suggestion}`,
188
305
  hint: `\`seed-design docs ${matchedCategory.id}/${matchedSection.id}\`로 목록을 확인해보세요.`,
189
306
  });
190
307
  }
@@ -209,8 +326,28 @@ export const docsCommand = (cli: CAC) => {
209
326
  );
210
327
 
211
328
  if (matched.length === 0) {
329
+ const sectionIds = matchedCategory.sections.map((s) => s.id);
330
+ const similarSections = findSimilar(segments[1], sectionIds);
331
+ const allItemIds = matchedCategory.sections.flatMap((s) =>
332
+ s.items.map((i) => ({ path: `${matchedCategory.id}/${s.id}/${i.id}`, id: i.id })),
333
+ );
334
+ const similarItems = findSimilar(
335
+ segments[1],
336
+ allItemIds.map((x) => x.id),
337
+ );
338
+ const suggestions: string[] = [
339
+ ...similarSections.slice(0, 2).map((s) => `${matchedCategory.id}/${s}`),
340
+ ...similarItems
341
+ .slice(0, 2)
342
+ .map((id) => allItemIds.find((x) => x.id === id)?.path)
343
+ .filter((p): p is string => p != null),
344
+ ];
345
+ const suggestion =
346
+ suggestions.length > 0
347
+ ? `\n\n💡 이것을 의미했나요?\n${suggestions.map((s) => ` - ${s}`).join("\n")}`
348
+ : "";
212
349
  throw new CliError({
213
- message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
350
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.${suggestion}`,
214
351
  hint: `\`seed-design docs ${matchedCategory.id}\`로 목록을 확인해보세요.`,
215
352
  });
216
353
  }
@@ -242,8 +379,9 @@ export const docsCommand = (cli: CAC) => {
242
379
  const matched = searchAllItems(categories, options.query);
243
380
 
244
381
  if (matched.length === 0) {
382
+ const suggestion = buildSuggestionHint(segments, categories);
245
383
  throw new CliError({
246
- message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
384
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.${suggestion ?? ""}`,
247
385
  hint: "`seed-design docs`로 전체 목록을 확인해보세요.",
248
386
  });
249
387
  }
@@ -0,0 +1,387 @@
1
+ import { getPackageInfo } from "@/src/utils/get-package-info";
2
+ import * as p from "@clack/prompts";
3
+ import { coerce, valid } from "semver";
4
+ import { z } from "zod";
5
+
6
+ import type { CAC } from "cac";
7
+ import { BASE_URL } from "../constants";
8
+ import { analytics } from "../utils/analytics";
9
+ import { highlight } from "../utils/color";
10
+ import {
11
+ CliCancelError,
12
+ CliError,
13
+ handleCliError,
14
+ isCliCancelError,
15
+ isVerboseMode,
16
+ } from "../utils/error";
17
+ import { fetchChangelog, fetchLatestVersion } from "../utils/fetch";
18
+
19
+ const SEED_SCOPE = "@seed-design/";
20
+
21
+ const upgradeOptionsSchema = z.object({
22
+ packageName: z.string().optional(),
23
+ cwd: z.string(),
24
+ baseUrl: z.string(),
25
+ raw: z.boolean(),
26
+ all: z.boolean(),
27
+ });
28
+
29
+ function toFullPackageName(input: string): string {
30
+ return input.startsWith(SEED_SCOPE) ? input : `${SEED_SCOPE}${input}`;
31
+ }
32
+
33
+ function toSlug(packageName: string): string {
34
+ return packageName.replace(SEED_SCOPE, "");
35
+ }
36
+
37
+ function findInstalledSeedPackages(cwd: string): Record<string, string> {
38
+ const packageInfo = getPackageInfo(cwd);
39
+ const allDeps = {
40
+ ...packageInfo.dependencies,
41
+ ...packageInfo.devDependencies,
42
+ ...packageInfo.peerDependencies,
43
+ ...packageInfo.optionalDependencies,
44
+ };
45
+
46
+ const seedPackages: Record<string, string> = {};
47
+ for (const [name, version] of Object.entries(allDeps)) {
48
+ if (name.startsWith(SEED_SCOPE) && version) {
49
+ seedPackages[name] = version;
50
+ }
51
+ }
52
+
53
+ return seedPackages;
54
+ }
55
+
56
+ function resolveExactVersion(versionSpec: string): string | null {
57
+ let normalized = versionSpec.trim();
58
+
59
+ if (normalized.startsWith("workspace:")) {
60
+ normalized = normalized.slice("workspace:".length).trim();
61
+ }
62
+
63
+ if (normalized.startsWith("npm:")) {
64
+ const lastAt = normalized.lastIndexOf("@");
65
+ if (lastAt > 4) {
66
+ normalized = normalized.slice(lastAt + 1);
67
+ }
68
+ }
69
+
70
+ if (valid(normalized)) return normalized;
71
+
72
+ const coerced = coerce(normalized);
73
+ if (coerced) return coerced.version;
74
+
75
+ return null;
76
+ }
77
+
78
+ interface UpgradeOneResult {
79
+ package: string;
80
+ currentVersion: string;
81
+ latestVersion: string;
82
+ upToDate: boolean;
83
+ changelog: string | null;
84
+ }
85
+
86
+ async function upgradeOne({
87
+ targetPackage,
88
+ currentVersionSpec,
89
+ baseUrl,
90
+ }: {
91
+ targetPackage: string;
92
+ currentVersionSpec: string;
93
+ baseUrl: string;
94
+ }): Promise<UpgradeOneResult> {
95
+ const currentVersion = resolveExactVersion(currentVersionSpec);
96
+
97
+ if (!currentVersion) {
98
+ throw new CliError({
99
+ message: `${targetPackage}의 버전을 파싱할 수 없어요: ${currentVersionSpec}`,
100
+ hint: "package.json에서 버전 형식을 확인해주세요.",
101
+ });
102
+ }
103
+
104
+ const latestVersion = await fetchLatestVersion(targetPackage);
105
+
106
+ if (currentVersion === latestVersion) {
107
+ return {
108
+ package: targetPackage,
109
+ currentVersion,
110
+ latestVersion,
111
+ upToDate: true,
112
+ changelog: null,
113
+ };
114
+ }
115
+
116
+ const slug = toSlug(targetPackage);
117
+ const changelog = await fetchChangelog({
118
+ baseUrl,
119
+ packageSlug: slug,
120
+ version: currentVersion,
121
+ });
122
+
123
+ return {
124
+ package: targetPackage,
125
+ currentVersion,
126
+ latestVersion,
127
+ upToDate: false,
128
+ changelog,
129
+ };
130
+ }
131
+
132
+ function printResultRaw(result: UpgradeOneResult & { error?: string }) {
133
+ if (result.error) {
134
+ console.error(`## ${result.package}\n\nError: ${result.error}\n`);
135
+ } else if (result.upToDate) {
136
+ console.log(`${result.package}@${result.currentVersion} is already up to date.\n`);
137
+ } else {
138
+ console.log(result.changelog);
139
+ console.log("");
140
+ }
141
+ }
142
+
143
+ function printResultInteractive(result: UpgradeOneResult & { error?: string }) {
144
+ if (result.error) {
145
+ p.log.error(`${highlight(result.package)}: ${result.error}`);
146
+ } else if (result.upToDate) {
147
+ p.log.info(
148
+ `${highlight(result.package)}: ${highlight(result.currentVersion)} — 이미 최신 버전이에요.`,
149
+ );
150
+ } else {
151
+ p.log.info(
152
+ `${highlight(result.package)}: ${highlight(result.currentVersion)} → ${highlight(result.latestVersion)}`,
153
+ );
154
+ p.log.message(result.changelog ?? "");
155
+ p.log.info(
156
+ `업그레이드하려면: ${highlight(`bun add ${result.package}@${result.latestVersion}`)}`,
157
+ );
158
+ }
159
+ }
160
+
161
+ async function trackResults(cwd: string, results: UpgradeOneResult[], startTime: number) {
162
+ try {
163
+ for (const result of results) {
164
+ await analytics.track(cwd, {
165
+ event: "upgrade",
166
+ properties: {
167
+ package: result.package,
168
+ current_version: result.currentVersion,
169
+ latest_version: result.latestVersion,
170
+ up_to_date: result.upToDate,
171
+ duration_ms: Date.now() - startTime,
172
+ },
173
+ });
174
+ }
175
+ } catch {}
176
+ }
177
+
178
+ export const upgradeCommand = (cli: CAC) => {
179
+ cli
180
+ .command(
181
+ "upgrade [package-name]",
182
+ "패키지의 현재 버전과 최신 버전 사이의 변경사항을 확인합니다",
183
+ )
184
+ .option("-c, --cwd <cwd>", "작업 디렉토리. 기본값은 현재 디렉토리입니다.", {
185
+ default: process.cwd(),
186
+ })
187
+ .option("-u, --baseUrl <baseUrl>", "changelog를 조회할 base URL입니다.", { default: BASE_URL })
188
+ .option("--raw", "UI 없이 순수 마크다운만 출력합니다. LLM 파이프에 유용합니다.", {
189
+ default: false,
190
+ })
191
+ .option("-a, --all", "설치된 모든 @seed-design 패키지의 변경사항을 확인합니다.", {
192
+ default: false,
193
+ })
194
+ .example("seed-design upgrade")
195
+ .example("seed-design upgrade react")
196
+ .example("seed-design upgrade --all")
197
+ .example("seed-design upgrade --all --raw")
198
+ .action(async (packageName, opts) => {
199
+ const startTime = Date.now();
200
+ const verbose = isVerboseMode(opts);
201
+ const parsed = upgradeOptionsSchema.safeParse({ packageName, ...opts });
202
+ if (!parsed.success) {
203
+ if (opts.raw) {
204
+ console.error(parsed.error.message);
205
+ process.exit(1);
206
+ }
207
+ p.intro("seed-design upgrade");
208
+ handleCliError(parsed.error, {
209
+ defaultMessage: "업그레이드 확인에 실패했어요.",
210
+ defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
211
+ verbose,
212
+ });
213
+ process.exit(1);
214
+ }
215
+
216
+ const { data: options } = parsed;
217
+ const { raw, all } = options;
218
+
219
+ if (!raw) p.intro("seed-design upgrade");
220
+
221
+ try {
222
+ const seedPackages = findInstalledSeedPackages(options.cwd);
223
+ const packageNames = Object.keys(seedPackages);
224
+
225
+ if (packageNames.length === 0) {
226
+ throw new CliError({
227
+ message: "프로젝트에 설치된 @seed-design 패키지를 찾을 수 없어요.",
228
+ hint: "`bun add @seed-design/react`로 패키지를 설치해보세요.",
229
+ });
230
+ }
231
+
232
+ if (options.packageName && all) {
233
+ throw new CliError({
234
+ message: "패키지명과 --all 옵션을 동시에 사용할 수 없어요.",
235
+ hint: "`seed-design upgrade --all` 또는 `seed-design upgrade react` 중 하나만 사용해주세요.",
236
+ });
237
+ }
238
+
239
+ // --all: iterate all packages
240
+ if (all) {
241
+ if (raw) {
242
+ const results = await Promise.all(
243
+ packageNames.map((name) =>
244
+ upgradeOne({
245
+ targetPackage: name,
246
+ currentVersionSpec: seedPackages[name],
247
+ baseUrl: options.baseUrl,
248
+ }).catch((error): UpgradeOneResult & { error: string } => ({
249
+ package: name,
250
+ currentVersion: seedPackages[name],
251
+ latestVersion: "unknown",
252
+ upToDate: false,
253
+ changelog: null,
254
+ error: error instanceof Error ? error.message : String(error),
255
+ })),
256
+ ),
257
+ );
258
+
259
+ for (const result of results) {
260
+ printResultRaw(result);
261
+ }
262
+
263
+ await trackResults(options.cwd, results, startTime);
264
+ const hasErrors = results.some((r) => "error" in r && Boolean(r.error));
265
+ process.exit(hasErrors ? 1 : 0);
266
+ }
267
+
268
+ // --all interactive
269
+ const { start, stop } = p.spinner();
270
+ start("모든 패키지의 변경사항을 가져오고 있어요...");
271
+ const results = await Promise.all(
272
+ packageNames.map((name) =>
273
+ upgradeOne({
274
+ targetPackage: name,
275
+ currentVersionSpec: seedPackages[name],
276
+ baseUrl: options.baseUrl,
277
+ }).catch((error): UpgradeOneResult & { error: string } => ({
278
+ package: name,
279
+ currentVersion: seedPackages[name],
280
+ latestVersion: "unknown",
281
+ upToDate: false,
282
+ changelog: null,
283
+ error: error instanceof Error ? error.message : String(error),
284
+ })),
285
+ ),
286
+ );
287
+ stop("변경사항을 가져왔어요.");
288
+
289
+ for (const result of results) {
290
+ printResultInteractive(result);
291
+ }
292
+
293
+ p.outro("완료했어요.");
294
+ await trackResults(options.cwd, results, startTime);
295
+ const hasErrors = results.some((r) => "error" in r && Boolean(r.error));
296
+ process.exit(hasErrors ? 1 : 0);
297
+ }
298
+
299
+ // resolve target package
300
+ let targetPackage: string;
301
+
302
+ if (options.packageName) {
303
+ targetPackage = toFullPackageName(options.packageName);
304
+
305
+ if (!seedPackages[targetPackage]) {
306
+ throw new CliError({
307
+ message: `${highlight(targetPackage)}: 프로젝트에 설치되어 있지 않아요.`,
308
+ hint: `설치된 패키지: ${packageNames.map((n) => highlight(n)).join(", ")}`,
309
+ });
310
+ }
311
+ } else {
312
+ // no package, no --all: interactive select
313
+ if (raw) {
314
+ throw new CliError({
315
+ message: "--raw 모드에서는 패키지명 또는 --all 옵션이 필요해요.",
316
+ hint: "예: `seed-design upgrade react --raw` 또는 `seed-design upgrade --all --raw`",
317
+ });
318
+ }
319
+
320
+ if (packageNames.length === 1) {
321
+ targetPackage = packageNames[0];
322
+ } else {
323
+ const selected = await p.select({
324
+ message: "변경사항을 확인할 패키지를 선택해주세요",
325
+ options: packageNames.map((name) => ({
326
+ label: name,
327
+ value: name,
328
+ hint: seedPackages[name],
329
+ })),
330
+ });
331
+ if (p.isCancel(selected)) throw new CliCancelError();
332
+ targetPackage = selected;
333
+ }
334
+ }
335
+
336
+ // single package
337
+ if (raw) {
338
+ const result = await upgradeOne({
339
+ targetPackage,
340
+ currentVersionSpec: seedPackages[targetPackage],
341
+ baseUrl: options.baseUrl,
342
+ });
343
+ printResultRaw(result);
344
+ await trackResults(options.cwd, [result], startTime);
345
+ process.exit(0);
346
+ }
347
+
348
+ // single package interactive
349
+ const { start, stop } = p.spinner();
350
+ start("최신 버전을 확인하고 있어요...");
351
+ let result: UpgradeOneResult;
352
+ try {
353
+ result = await upgradeOne({
354
+ targetPackage,
355
+ currentVersionSpec: seedPackages[targetPackage],
356
+ baseUrl: options.baseUrl,
357
+ });
358
+ stop("변경사항을 가져왔어요.");
359
+ } catch (error) {
360
+ stop("변경사항을 가져오지 못했어요.");
361
+ throw error;
362
+ }
363
+
364
+ printResultInteractive(result);
365
+ p.outro("완료했어요.");
366
+ await trackResults(options.cwd, [result], startTime);
367
+ } catch (error) {
368
+ if (isCliCancelError(error)) {
369
+ if (!raw) p.outro(highlight(error.message));
370
+ process.exit(0);
371
+ }
372
+
373
+ if (raw) {
374
+ const msg = error instanceof Error ? error.message : String(error);
375
+ console.error(msg);
376
+ process.exit(1);
377
+ }
378
+
379
+ handleCliError(error, {
380
+ defaultMessage: "업그레이드 확인에 실패했어요.",
381
+ defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
382
+ verbose,
383
+ });
384
+ process.exit(1);
385
+ }
386
+ });
387
+ };
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ import { addAllCommand } from "@/src/commands/add-all";
5
5
  import { compatCommand } from "@/src/commands/compat";
6
6
  import { docsCommand } from "@/src/commands/docs";
7
7
  import { initCommand } from "@/src/commands/init";
8
+ import { upgradeCommand } from "@/src/commands/upgrade";
8
9
  import { getPackageInfo } from "@/src/utils/get-package-info";
9
10
  import { cac } from "cac";
10
11
 
@@ -22,6 +23,7 @@ async function main() {
22
23
  compatCommand(CLI);
23
24
  docsCommand(CLI);
24
25
  initCommand(CLI);
26
+ upgradeCommand(CLI);
25
27
 
26
28
  CLI.version(packageInfo.version || "1.0.0", "-v, --version");
27
29
  CLI.help();
@@ -12,6 +12,26 @@ import {
12
12
  } from "@/src/schema";
13
13
  import { CliError } from "@/src/utils/error";
14
14
 
15
+ const FETCH_TIMEOUT_MS = 10_000;
16
+
17
+ async function fetchWithTimeout(url: string, timeoutMs = FETCH_TIMEOUT_MS): Promise<Response> {
18
+ const controller = new AbortController();
19
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
20
+ try {
21
+ return await fetch(url, { signal: controller.signal });
22
+ } catch (error) {
23
+ if (error instanceof Error && error.name === "AbortError") {
24
+ throw new CliError({
25
+ message: `요청 시간이 초과되었어요 (${timeoutMs}ms): ${url}`,
26
+ hint: "네트워크 상태를 확인하고 다시 시도해주세요.",
27
+ });
28
+ }
29
+ throw error;
30
+ } finally {
31
+ clearTimeout(timeout);
32
+ }
33
+ }
34
+
15
35
  export async function fetchDocsIndex({ baseUrl }: { baseUrl: string }): Promise<DocsIndex> {
16
36
  const response = await fetch(`${baseUrl}/__docs__/index.json`);
17
37
 
@@ -101,6 +121,46 @@ async function fetchRegistryItem({
101
121
  return parsedItem;
102
122
  }
103
123
 
124
+ export async function fetchLatestVersion(packageName: string): Promise<string> {
125
+ const response = await fetchWithTimeout(`https://registry.npmjs.org/${packageName}/latest`);
126
+
127
+ if (!response.ok) {
128
+ throw new CliError({
129
+ message: `${packageName}의 최신 버전을 가져오지 못했어요: ${response.status} ${response.statusText}`,
130
+ });
131
+ }
132
+
133
+ const data = await response.json();
134
+ if (!data || typeof data !== "object" || typeof data.version !== "string") {
135
+ throw new CliError({
136
+ message: `${packageName} 최신 버전 응답 형식이 올바르지 않아요.`,
137
+ });
138
+ }
139
+ return data.version;
140
+ }
141
+
142
+ export async function fetchChangelog({
143
+ baseUrl,
144
+ packageSlug,
145
+ version,
146
+ }: {
147
+ baseUrl: string;
148
+ packageSlug: string;
149
+ version: string;
150
+ }): Promise<string> {
151
+ const url = `${baseUrl}/llms/react/updates/changelog/${packageSlug}/${encodeURIComponent(version)}.txt`;
152
+ const response = await fetchWithTimeout(url);
153
+
154
+ if (!response.ok) {
155
+ throw new CliError({
156
+ message: `변경사항을 가져오지 못했어요: ${response.status} ${response.statusText}`,
157
+ hint: `${url} 에 접근할 수 있는지 확인해주세요.`,
158
+ });
159
+ }
160
+
161
+ return response.text();
162
+ }
163
+
104
164
  export async function fetchRegistryItems({
105
165
  baseUrl,
106
166
  registryId,