@seed-design/cli 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/index.mjs CHANGED
@@ -1,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 ee from"@clack/prompts";import{cosmiconfig as ct}from"cosmiconfig";import{z as re}from"zod";import*as J from"@clack/prompts";import{ZodError as it}from"zod";import rt from"picocolors";var p=e=>rt.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}},v=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function U(e){return e instanceof v}function q(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function ot(e,t){if(e instanceof I)return{reason:e.message,hint:e.hint??t,details:e.details,stack:nt(e.cause??e)};if(e instanceof it){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 nt(e){if(e instanceof Error)return e.stack}function B(e,{defaultMessage:t,defaultHint:s,verbose:n=!1}){let o=ot(e,s);J.log.error(t),J.log.error(`\uC6D0\uC778: ${o.reason}`);for(let r of o.details)J.log.info(r);o.hint&&J.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${o.hint}`),n&&o.stack&&(J.log.message(p(`
3
+ [verbose] stack trace`)),J.log.message(o.stack)),J.outro(p("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as X from"@clack/prompts";import at from"fs-extra";import Ee from"path";var K={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function ke(){return await X.group({tsx:()=>X.confirm({message:`${p("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.tsx}),rsc:()=>X.confirm({message:`${p("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:K.rsc}),path:()=>X.text({message:`${p("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:()=>X.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${p("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:K.telemetry})},{onCancel:()=>{throw new v}})}async function ue({cwd:e,config:t}){let s=Ee.resolve(e,"seed-design.json");return await at.writeFile(s,`${JSON.stringify(t,null,2)}
4
+ `,"utf-8"),{relativePath:Ee.relative(process.cwd(),s),targetPath:s}}var ve="seed-design",lt=ct(ve,{searchPlaces:[`${ve}.json`]}),je=re.object({$schema:re.string().optional(),rsc:re.coerce.boolean().default(!1),tsx:re.coerce.boolean().default(!0),path:re.string(),telemetry:re.coerce.boolean().optional().default(!0)}).strict();async function ye(e){let t=await me(e);if(t)return t;ee.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let s=await ee.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(ee.isCancel(s)||!s)throw new v;try{return await ue({cwd:e,config:K}),ee.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),je.parse(K)}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 me(e){let t=await lt.search(e);if(!t||t.isEmpty)return null;try{return je.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 he({selectedItemKeys:e,publicRegistries:t}){let s=[],n=new Set;function o(r,i){let a=s.find(l=>l.registryId===r);if(!a?.items.some(l=>l.id===i.id)){if(a?a.items.push(i):s.push({registryId:r,items:[i]}),i.dependencies?.length)for(let l of i.dependencies)n.add(l);if(i.innerDependencies?.length)for(let l of i.innerDependencies)for(let f of l.itemIds){let h=t.find(u=>u.id===l.registryId)?.items.find(u=>u.id===f);if(!h)throw new Error(`Cannot find dependency item: ${l.registryId}:${f}`);o(l.registryId,h)}}}for(let r of e){let[i,...a]=r.split(":"),l=a.join(":");if(!i||!l)throw new Error(`Invalid snippet format: "${r}"`);let f=t.find(h=>h.id===i)?.items.find(h=>h.id===l);if(!f)throw new Error(`Cannot find snippet: "${r}"`);o(i,f)}return{registryItemsToAdd:s,npmDependenciesToAdd:n}}import*as Se from"@clack/prompts";import{z as m}from"zod";var xe=m.object({id:m.string(),description:m.string().optional(),deprecated:m.boolean().optional(),hideFromCLICatalog:m.boolean().optional(),dependencies:m.array(m.string()).optional(),innerDependencies:m.array(m.object({registryId:m.string(),itemIds:m.array(m.string())})).optional(),snippets:m.array(m.object({path:m.string(),dependencies:m.record(m.string(),m.string()).optional(),content:m.string()}))}),Pe=m.object({id:m.string(),hideFromCLICatalog:m.boolean().optional(),items:m.array(xe.omit({snippets:!0}).extend({snippets:m.array(m.object({path:m.string(),dependencies:m.record(m.string(),m.string()).optional()}))}))}),Te=m.array(m.object({id:m.string()})),pt=m.object({label:m.string(),path:m.string()}),mt=m.object({id:m.string(),title:m.string(),description:m.string().optional(),docUrl:m.string(),deprecated:m.boolean().optional(),snippetKey:m.string().optional(),snippets:m.array(pt).optional()}),dt=m.object({id:m.string(),label:m.string(),items:m.array(mt)}),ft=m.object({id:m.string(),label:m.string(),sections:m.array(dt)}),Ae=m.object({categories:m.array(ft)});var gt=1e4;async function _e(e,t=gt){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 Re({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}=Ae.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 ie({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}=Te.safeParse(s);if(!n)throw new Error(`Failed to parse registries: ${r?.message}`);return o}async function oe({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}=Pe.safeParse(n);if(!o)throw new Error(`Failed to parse ${t} registry: ${i?.message}`);return r}async function ut({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:a}=xe.safeParse(o);if(!r)throw new Error(`Failed to parse ${s}: ${a?.message}`);return i}async function De({url:e}){let t=await _e(e);if(!t.ok)throw new I({message:`llms.txt\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${t.status} ${t.statusText}`,hint:`${e} \uC5D0 \uC811\uADFC\uD560 \uC218 \uC788\uB294\uC9C0 \uD655\uC778\uD574\uC8FC\uC138\uC694.`});return t.text()}async function Oe({baseUrl:e,query:t}){let s=t.startsWith("/")?t.slice(1):t,n=[`${e}/llms/${s}.txt`,`${e}/llms/${s}/llms.txt`],o;for(let r of n){let i;try{i=await _e(r)}catch(a){o=a;continue}if(i.ok)return i.text();if(i.status===404){o=new I({message:`llms.txt\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694: ${s}`,hint:`\uB2E4\uC74C \uACBD\uB85C\uB97C \uC2DC\uB3C4\uD588\uC5B4\uC694:
5
+ ${n.map(a=>` - ${a}`).join(`
6
+ `)}`});continue}throw new I({message:`llms.txt \uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC5B4\uC694: ${i.status} ${i.statusText}`,hint:`URL: ${r}`})}throw o??new I({message:`llms.txt\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694: ${s}`,hint:`\uB2E4\uC74C \uACBD\uB85C\uB97C \uC2DC\uB3C4\uD588\uC5B4\uC694:
7
+ ${n.map(r=>` - ${r}`).join(`
8
+ `)}`})}async function Me({baseUrl:e,registryId:t,registryItemIds:s}){return await Promise.all(s.map(async n=>{try{return await ut({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:a,data:l}=Pe.safeParse(i);throw a?(Se.log.error(`${n} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),Se.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
9
+ ${l.items.map(f=>f.id).join(`
10
+ `)}`),o):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as Ct}from"fs";import{tmpdir as It}from"os";import Ke from"path";import{transformFromAstSync as yt}from"@babel/core";import ht from"@babel/plugin-transform-typescript";import*as we from"recast";import{parse as wt}from"@babel/parser";var bt={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"]},Le=async({sourceFile:e,config:t})=>{let s=e.getFullText();if(t.tsx)return s;let n=we.parse(s,{parser:{parse:r=>wt(r,bt)}}),o=yt(n,s,{cloneInputAst:!1,code:!1,ast:!0,plugins:[ht],configFile:!1});if(!o||!o.ast)throw new Error("Failed to transform JSX");return we.print(o.ast).code};import{SyntaxKind as $t}from"ts-morph";var Ue=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let s=e.getFirstChildByKind($t.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 l=i.replace(r,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return s.replaceWithText(l),e};import{Project as xt,ScriptKind as Pt}from"ts-morph";var St=[Ue],Rt=new xt({compilerOptions:{}});async function Et(e){let t=await Ct.mkdtemp(Ke.join(It(),"seed-design-"));return Ke.join(t,e)}async function Fe(e){let t=await Et(e.filename),s=Rt.createSourceFile(t,e.raw,{scriptKind:Pt.TSX});for(let n of St)n({sourceFile:s,...e});return await Le({sourceFile:s,...e})}import*as F from"@clack/prompts";import ne from"fs-extra";import H from"path";import{createPatch as kt}from"diff";import vt from"@npmcli/disparity-colors";async function be({registryItemsToAdd:e,rootPath:t,cwd:s,baseUrl:n,config:o,onDiff:r}){let i=[];for(let{registryId:a,items:l}of e){let f=H.join(t,a);ne.ensureDirSync(f);let h=await Me({baseUrl:n,registryId:a,registryItemIds:l.map(u=>u.id)});for(let{id:u,snippets:C}of h){let k=await Promise.all(C.map(async w=>{let d=await Fe({filename:w.path,config:o,raw:w.content}),b=H.join(f,w.path);return o.tsx||(b=b.replace(/\.tsx$/,".jsx"),b=b.replace(/\.ts$/,".js")),{filePath:b,content:d,relativePath:H.relative(s,b),name:`${a}:${u}`}})),y=[];for(let w of k){let{filePath:d,content:b,relativePath:A}=w;if(await ne.ensureDir(H.dirname(d)),ne.existsSync(d)){let V=await ne.readFile(d,"utf-8");if(V===b){F.log.info(`${p(A)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let P=H.basename(d),D=H.extname(d),O=H.basename(d,D),Y=Date.now(),$=`legacy-${O}-${Y}${D}`,c=await(async()=>{if(r)return r;let g=kt(A,V,b),x=vt(g);return F.log.message(`
11
+ ${p(A)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
12
+ `),F.log.message(x),F.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 ${$}\uC73C\uB85C \uC62E\uAE30\uACE0 ${P} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(F.isCancel(c)||c==="skip"){F.log.info(`${p(A)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(c==="backup"){let g=H.dirname(d),x=H.join(g,$);await ne.rename(d,x),F.log.info(`${p(A)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${p(H.relative(s,x))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await ne.writeFile(d,b),y.push(w)}if(y.length>0){let w=y.map(({name:d,relativePath:b})=>({name:d,path:b}));i.push(...w),F.log.success(`${p(`${a}:${u}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${p(w.map(d=>d.path).join(", "))}`)}}}}import*as R from"@clack/prompts";import Qt from"path";import{z as se}from"zod";var G="https://seed-design.io";import*as ze from"@clack/prompts";import{execa as Ot}from"execa";import{detect as jt}from"@antfu/ni";async function Ne(e){let t=await jt({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import Tt from"findup-sync";import At from"fs-extra";var _t="package.json";function Dt(e=process.cwd()){let t=Tt(_t,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function ae(e=process.cwd()){let t=Dt(e);return At.readJSONSync(t)}async function $e({cwd:e,deps:t,dev:s=!1}){let{start:n,stop:o}=ze.spinner(),r=await Ne(e),a={...ae(e).dependencies},l=new Set(t.filter(y=>!a[y])),f=new Set(t.filter(y=>a[y]));if(!l.size)return{installed:new Set,filtered:l};n("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let C=[r==="npm"?"install":"add",s?"-D":null,...l].filter(Boolean),k=`${r} ${C.join(" ")}`;try{await Ot(r,C,{cwd:e})}catch(y){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: ${k}`],cause:y})}return o("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:l,filtered:f}}import{randomUUID as Mt}from"node:crypto";import*as qe from"@clack/prompts";var Lt="seed_cli";async function Ut(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await me(e))?.telemetry===!1)return!1}catch{}return!0}function Kt(){return Mt()}var Ft=Kt(),Ve=!1;async function Nt(e,{event:t,properties:s={}}){if(!await Ut(e))return;let o=`${Lt}.${t}`;Ve||(qe.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)"),Ve=!0);try{let r="https://us.i.posthog.com/capture",i={"Content-Type":"application/json"},a={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:o,distinct_id:Ft,properties:{...s,$process_person_profile:!1},timestamp:new Date().toISOString()},l=new AbortController,f=setTimeout(()=>l.abort(),5e3);try{await fetch(r,{method:"POST",headers:i,body:JSON.stringify(a),signal:l.signal})}finally{clearTimeout(f)}}catch{}}var N={track:Nt};import*as te from"@clack/prompts";import zt from"fs-extra";import Vt from"path";import{intersects as qt,satisfies as Bt,valid as He,validRange as Ge}from"semver";var de=["@seed-design/react","@seed-design/css"],Be="workspace:",Ht="npm:";function ce(e){try{let t=ae(e),s={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},n={};for(let o of de){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(a=>[`${i.id}:${a.id}`,a]))),r=[];for(let i of n){let a=o.get(i);if(!a)continue;let l=Gt(a);for(let f of de){let h=Array.from(l[f]??[]);if(!h.length)continue;let u=s[f];if(!u){r.push({itemKey:i,packageName:f,requiredRanges:h,type:"missing-package"});continue}let C=Jt(u);if(!C){r.push({itemKey:i,packageName:f,requiredRanges:h,installedVersionSpec:u,type:"invalid-version-spec"});continue}h.every(y=>Wt({currentVersionSpec:C,requiredRange:y}))||r.push({itemKey:i,packageName:f,requiredRanges:h,installedVersionSpec:u,type:"incompatible-version"})}}return{checkedItemKeys:n,projectPackageVersions:s,issues:r}}function pe({report:e,title:t}){if(!e.issues.length)return;te.log.warn(t),te.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${de.map(n=>`${n}@${p(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()){te.log.warn(p(n));for(let r of o){let i=r.requiredRanges.join(" | ");if(r.type==="missing-package"){te.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"){te.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}te.log.info(` - ${r.packageName}: \uD604\uC7AC ${r.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${i}`)}}}function Je({publicRegistries:e,rootPath:t}){let s=[];for(let n of e)for(let o of n.items)o.snippets.some(i=>Yt(i.path).some(a=>zt.existsSync(Vt.join(t,n.id,a))))&&s.push(`${n.id}:${o.id}`);return s}function Gt(e){let t=Object.fromEntries(de.map(s=>[s,new Set]));for(let s of e.snippets)for(let[n,o]of Object.entries(s.dependencies??{}))Xt(n)&&t[n].add(o);return t}function Jt(e){let t=e.trim();if(t.startsWith(Be)&&(t=t.slice(Be.length).trim()),t.startsWith(Ht)){let s=t.split("@").at(-1);if(!s)return null;t=s}return!t||t==="*"?null:He(t)||Ge(t)?t:null}function Wt({currentVersionSpec:e,requiredRange:t}){let s=Ge(t);return s?He(e)?Bt(e,s,{includePrerelease:!0}):qt(e,s,{includePrerelease:!0}):!1}function Yt(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 Xt(e){return de.includes(e)}var Zt=se.object({itemIds:se.array(se.string()).optional(),all:se.boolean(),cwd:se.string(),baseUrl:se.string().optional(),onDiff:se.enum(["overwrite","backup"]).optional()}),We=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:G}).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=q(s);R.intro("seed-design add");try{let r=Zt.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:{all:i,...a}}=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 l=a.cwd,f=a.baseUrl,h=await ye(l),u=Qt.resolve(l,h.path),{start:C,stop:k}=R.spinner();C("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let c=await Promise.all((await ie({baseUrl:f})).map(async({id:g})=>oe({baseUrl:f,registryId:g})));return k("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),c}catch(c){throw k("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),c}})(),w=await(async()=>{if(a.itemIds?.length)return a.itemIds;let c=await R.multiselect({message:"\uCD94\uAC00\uD560 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:y.filter(({hideFromCLICatalog:g})=>!g).flatMap(({id:g,items:x})=>x.filter(({hideFromCLICatalog:_})=>!_).sort((_,T)=>_.id.localeCompare(T.id)).map(({id:_,description:T,deprecated:S})=>({label:`${S?"(deprecated) ":""}${p(g)}:${_}`,value:`${g}:${_}`,hint:T,deprecated:S,registryItemCount:x.length}))).sort((g,x)=>g.deprecated!==x.deprecated?g.deprecated?1:-1:x.registryItemCount-g.registryItemCount)});if(R.isCancel(c))throw new v;return c})();if(!w?.length)throw new v("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");R.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${p(w.join(", "))}`);let d=[];for(let c of w){let[g,...x]=c.split(":"),_=x.join(":");if(!g||!_)throw new I({message:`${p(c)}: \uD56D\uBAA9 \uC774\uB984\uC774 \uC798\uBABB\uB418\uC5C8\uC5B4\uC694.`,hint:`${p("ui:action-button")}\uACFC \uAC19\uC740 \uD615\uC2DD\uC73C\uB85C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});let T=y.find(S=>S.id===g)?.items.find(S=>S.id===_);if(!T)throw new I({message:`${p(c)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(T.deprecated){let S=await R.confirm({message:`${p(T.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(R.isCancel(S))throw new v;if(S===!1){R.log.info(`${p(T.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}d.push(c)}let{registryItemsToAdd:b,npmDependenciesToAdd:A}=he({selectedItemKeys:d,publicRegistries:y}),V=le({publicRegistries:y,itemKeys:b.flatMap(({registryId:c,items:g})=>g.map(x=>`${c}:${x.id}`)),projectPackageVersions:ce(a.cwd)});pe({report:V,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uC744 \uC218 \uC788\uB294 \uC2A4\uB2C8\uD3AB\uC774 \uC788\uC5B4\uC694."}),R.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${p(b.map(c=>c.items.map(g=>`${c.registryId}:${g.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
9
13
 
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.
14
+ \uC124\uCE58\uD560 \uC758\uC874\uC131: ${p(Array.from(A).join(", ")||"\uC5C6\uC74C")}`),await be({registryItemsToAdd:b,rootPath:u,cwd:l,baseUrl:f,config:h,onDiff:a.onDiff});let{installed:P,filtered:D}=await $e({cwd:l,deps:Array.from(A)});P.size===0&&R.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),P.size&&(R.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${p(Array.from(P).join(", "))}`),D.size&&R.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${p(Array.from(D).join(", "))}`)),R.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let O=Date.now()-n,Y=new Set(b.map(c=>c.registryId)),$=w.some(c=>{let[g,...x]=c.split(":"),_=x.join(":");return y.find(T=>T.id===g)?.items.find(T=>T.id===_)?.deprecated});try{await N.track(a.cwd,{event:"add",properties:{items_count:d.length,registries:Array.from(Y),has_deprecated:$,dependencies_count:A.size,duration_ms:O}})}catch(c){o&&console.error("[Telemetry] add tracking failed:",c)}}catch(r){U(r)&&(R.outro(p(r.message)),process.exit(0)),B(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 j from"@clack/prompts";import es from"path";import{z as Q}from"zod";var ts=Q.object({registryIds:Q.array(Q.string()).optional(),all:Q.boolean(),includeDeprecated:Q.boolean().optional(),cwd:Q.string(),baseUrl:Q.string().optional(),onDiff:Q.enum(["overwrite","backup"]).optional()}),Ye=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:G}).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=q(s);j.intro("seed-design add-all");try{let r=ts.safeParse({registryIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,a=i.cwd,l=i.baseUrl,f=await ye(a),h=es.resolve(a,f.path),{start:u,stop:C}=j.spinner();u("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let k=await(async()=>{try{let $=await Promise.all((await ie({baseUrl:l})).map(async({id:c})=>oe({baseUrl:l,registryId:c})));return C("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),$}catch($){throw C("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),$}})(),y=await(async()=>{if(i.all){let c=k.map(g=>g.id);return j.log.message(`\uBAA8\uB4E0 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${p(c.join(", "))}`),c}if(i.registryIds?.length){let c=k.map(g=>g.id);for(let g of i.registryIds)if(!c.includes(g))throw new I({message:`\uB808\uC9C0\uC2A4\uD2B8\uB9AC '${g}'\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,details:[`\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uB808\uC9C0\uC2A4\uD2B8\uB9AC: ${c.join(", ")}`]});return j.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uBAA8\uB4E0 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${p(i.registryIds.join(", "))}`),i.registryIds}let $=await j.multiselect({message:"\uCD94\uAC00\uD560 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\uC2A4\uD398\uC774\uC2A4 \uBC14\uB85C \uC5EC\uB7EC \uAC1C \uC120\uD0DD \uAC00\uB2A5)",options:k.filter(({hideFromCLICatalog:c})=>!c).sort((c,g)=>g.items.length-c.items.length).map(c=>{let g=c.items[0]?.id,x=g?`${c.items.length}\uAC1C \uD56D\uBAA9 (${g} \uB4F1)`:`${c.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:c.id,value:c.id,hint:x}})});if(j.isCancel($))throw new v;return j.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${p($.join(", "))}`),$})(),w=k.filter($=>y.includes($.id)),d=w.flatMap($=>$.items.filter(c=>c.deprecated?i.includeDeprecated:!0).map(c=>`${$.id}:${c.id}`)),b=w.reduce(($,c)=>$+c.items.filter(g=>g.deprecated).length,0);if(!i.includeDeprecated&&b>0&&j.log.info(`${b}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),!d.length)throw new v("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");j.log.message(`\uCD1D ${p(d.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:A,npmDependenciesToAdd:V}=he({selectedItemKeys:d,publicRegistries:k}),P=le({publicRegistries:k,itemKeys:A.flatMap(({registryId:$,items:c})=>c.map(g=>`${$}:${g.id}`)),projectPackageVersions:ce(i.cwd)});pe({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 be({registryItemsToAdd:A,rootPath:h,cwd:a,baseUrl:l,config:f,onDiff:i.onDiff});let{installed:D,filtered:O}=await $e({cwd:a,deps:Array.from(V)});D.size===0&&j.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),D.size&&(j.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${p(Array.from(D).join(", "))}`),O.size&&j.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${p(Array.from(O).join(", "))}`)),j.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let Y=Date.now()-n;try{await N.track(i.cwd,{event:"add-all",properties:{registries:y,items_count:d.length,include_deprecated:i.includeDeprecated||!1,dependencies_count:V.size,duration_ms:Y}})}catch($){o&&console.error("[Telemetry] add-all tracking failed:",$)}}catch(r){U(r)&&(j.outro(p(r.message)),process.exit(0)),B(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 Xe from"path";import{z}from"zod";var ss=z.object({itemIds:z.array(z.string()).optional(),component:z.union([z.string(),z.array(z.string())]).optional(),all:z.boolean(),registry:z.string().optional(),cwd:z.string(),baseUrl:z.string().optional()});function rs({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 is({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 a=n.filter(l=>l.endsWith(`:${r}`));if(!a.length)throw new I({message:`${p(r)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`,hint:`${p("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});if(a.length>1)throw new I({message:`${p(r)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:a.map(l=>`- ${l}`),hint:`${p("ui:action-button")}\uCC98\uB7FC registry\uB97C \uD3EC\uD568\uD574\uC11C \uC785\uB825\uD574\uBCF4\uC138\uC694.`});return a[0]})();if(!n.includes(i))throw new I({message:`${p(i)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});o.add(i)}return Array.from(o)}var Qe=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:G}).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=q(s);M.intro("seed-design compat");try{let r=ss.safeParse({itemIds:t,...s});if(!r.success)throw r.error;let{data:i}=r,{start:a,stop:l}=M.spinner();a("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let f=await(async()=>{try{let w=await Promise.all((await ie({baseUrl:i.baseUrl})).map(async({id:d})=>oe({baseUrl:i.baseUrl,registryId:d})));return l("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),w}catch(w){throw l("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),w}})(),h=rs({itemIds:i.itemIds,component:i.component}),u=i.all?f.flatMap(d=>d.items.map(b=>`${d.id}:${b.id}`)):h.length>0?is({publicRegistries:f,targetInputs:h,defaultRegistry:i.registry}):me(i.cwd),C=Array.isArray(u)?u:await(async()=>{let w=await u;if(!w)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 d=Xe.resolve(i.cwd,w.path),b=Je({publicRegistries:f,rootPath:d});return b.length?b:(M.log.info(`${p(Xe.relative(i.cwd,d)||w.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();C.length||(M.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0));let k=ce(i.cwd),y=le({publicRegistries:f,itemKeys:C,projectPackageVersions:k});if(M.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${p(y.checkedItemKeys.join(", "))}`),!y.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 N.track(i.cwd,{event:"compat",properties:{checked_items_count:y.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-n}})}catch(w){o&&console.error("[Telemetry] compat tracking failed:",w)}process.exit(0)}pe({report:y,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),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 N.track(i.cwd,{event:"compat",properties:{checked_items_count:y.checkedItemKeys.length,incompatible_items_count:new Set(y.issues.map(w=>w.itemKey)).size,issue_count:y.issues.length,duration_ms:Date.now()-n}})}catch(w){o&&console.error("[Telemetry] compat tracking failed:",w)}process.exit(1)}catch(r){U(r)&&(M.outro(p(r.message)),process.exit(0)),B(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 E from"@clack/prompts";import{z as Ce}from"zod";var os="https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry",ns=Ce.object({query:Ce.string().optional(),baseUrl:Ce.string().optional(),raw:Ce.boolean()});function Ze(e,t){return`${os}/${e}/${t}`}function as(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: ${Ze(r,e.snippets[0].path)}`);else{o.push("- snippet:");for(let i of e.snippets)o.push(` - ${i.label}: ${Ze(r,i.path)}`)}}E.log.message(o.join(`
15
+ `))}function cs(e,t){let s=e.length,n=t.length,o=Array.from({length:s+1},(r,i)=>Array.from({length:n+1},(a,l)=>i===0?l:l===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 Z(e,t,s=3){let n=e.toLowerCase();return t.map(o=>({value:o,dist:cs(n,o.toLowerCase())})).filter(({dist:o})=>o>0&&o<=s).sort((o,r)=>o.dist-r.dist).map(({value:o})=>o)}function ls(e,t){if(e.length===0)return;let s=[],n=t.map(i=>i.id),o=Z(e[0],n);if(o.length===0){let i=t.flatMap(f=>f.sections.flatMap(h=>h.items.map(u=>`${f.id}/${h.id}/${u.id}`))),a=e.join("/"),l=Z(a,i,5);l.length>0&&s.push(...l.slice(0,3))}else{let i=t.find(a=>a.id===o[0]);if(i&&e.length>=2){let a=i.sections.map(f=>f.id),l=Z(e[1],a);if(l.length>0){let f=i.sections.find(h=>h.id===l[0]);if(f&&e.length>=3){let h=f.items.map(C=>C.id),u=Z(e[2],h);for(let C of u.slice(0,3))s.push(`${i.id}/${f.id}/${C}`)}else for(let h of l.slice(0,3))s.push(`${i.id}/${h}`)}else{let f=i.sections.flatMap(u=>u.items.map(C=>({path:`${i.id}/${u.id}/${C.id}`,id:C.id}))),h=Z(e[1],f.map(u=>u.id));for(let u of h.slice(0,3)){let C=f.find(k=>k.id===u);C&&s.push(C.path)}}}else for(let a of o.slice(0,3))s.push(a)}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(`
16
+ `)}function ps(e){return e.split("/").map(t=>t.trim()).filter(Boolean)}function ms(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 fe(e){let t=await E.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(E.isCancel(t))throw new v;return t}async function et(e){let t=await E.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(E.isCancel(t))throw new v;return t}async function ds(e){let t=await E.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(E.isCancel(t))throw new v;return t}var tt=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: ${G})`,{default:G}).option("--raw","llms.txt \uB0B4\uC6A9\uC744 \uC9C1\uC811 \uAC00\uC838\uC640 \uCD9C\uB825\uD569\uB2C8\uB2E4. LLM \uD30C\uC774\uD504\uC5D0 \uC720\uC6A9\uD569\uB2C8\uB2E4.",{default:!1}).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").example("seed-design docs react/updates/changelog --raw").action(async(t,s)=>{let n=Date.now(),o=q(s),r=s.raw??!1;r||E.intro("seed-design docs");try{let i=ns.safeParse({query:t,...s});if(!i.success)throw i.error;let{data:a}=i,l=a.baseUrl??G;if(a.raw&&!a.query)throw new I({message:"--raw \uBAA8\uB4DC\uC5D0\uC11C\uB294 \uCFFC\uB9AC\uAC00 \uD544\uC694\uD574\uC694.",hint:"\uC608: `seed-design docs react/updates/changelog --raw`"});let f=await(async()=>{if(r)return await Re({baseUrl:l});let{start:y,stop:w}=E.spinner();y("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");try{let d=await Re({baseUrl:l});return w("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC654\uC5B4\uC694."),d}catch(d){throw w("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),d}})(),{categories:h}=f,u,C=async()=>{if(a.query){let d=ps(a.query);if(r&&d.length>3)return;let b=h.find(P=>P.id===d[0]);if(b&&d.length>=2){let P=b.sections.find($=>$.id===d[1]);if(P&&d.length>=3){let $=P.items.find(x=>x.id===d[2]);if($)return $;let c=d[2].toLowerCase(),g=P.items.filter(x=>x.id.toLowerCase().includes(c)||x.title.toLowerCase().includes(c));if(g.length===0){let x=Z(d[2],P.items.map(T=>T.id)),_=x.length>0?`
17
+
18
+ \u{1F4A1} \uC774\uAC83\uC744 \uC758\uBBF8\uD588\uB098\uC694?
19
+ ${x.slice(0,3).map(T=>` - ${b.id}/${P.id}/${T}`).join(`
20
+ `)}`:"";throw new I({message:`${p(a.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.${_}`,hint:`\`seed-design docs ${b.id}/${P.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`})}return g.length===1?g[0]:await fe(g)}if(P)return await fe(P.items);let D=d[1].toLowerCase(),O=b.sections.flatMap($=>$.items.filter(c=>c.id.toLowerCase().includes(D)||c.title.toLowerCase().includes(D)).map(c=>({item:c,sectionLabel:$.label})));if(O.length===0){let $=b.sections.map(S=>S.id),c=Z(d[1],$),g=b.sections.flatMap(S=>S.items.map(ge=>({path:`${b.id}/${S.id}/${ge.id}`,id:ge.id}))),x=Z(d[1],g.map(S=>S.id)),_=[...c.slice(0,2).map(S=>`${b.id}/${S}`),...x.slice(0,2).map(S=>g.find(ge=>ge.id===S)?.path).filter(S=>S!=null)],T=_.length>0?`
21
+
22
+ \u{1F4A1} \uC774\uAC83\uC744 \uC758\uBBF8\uD588\uB098\uC694?
23
+ ${_.map(S=>` - ${S}`).join(`
24
+ `)}`:"";throw new I({message:`${p(a.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.${T}`,hint:`\`seed-design docs ${b.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`})}if(O.length===1)return O[0].item;let Y=await E.select({message:`${p(d[1])}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:O.map(({item:$,sectionLabel:c})=>({label:`[${c}] ${$.title}`,value:$,hint:$.description}))});if(E.isCancel(Y))throw new v;return Y}if(b){if(b.sections.length===1)return await fe(b.sections[0].items);let P=await et(b.sections);return await fe(P.items)}let A=ms(h,a.query);if(A.length===0){let P=ls(d,h);throw new I({message:`${p(a.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.${P??""}`,hint:"`seed-design docs`\uB85C \uC804\uCCB4 \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694."})}if(A.length===1)return A[0].item;let V=await E.select({message:`${p(a.query)}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:A.map(({item:P,categoryLabel:D,sectionLabel:O})=>({label:`[${D} > ${O}] ${P.title}`,value:P,hint:P.description}))});if(E.isCancel(V))throw new v;return V}let y=await ds(h),w;return y.sections.length===1?w=y.sections[0]:w=await et(y.sections),await fe(w.items)};if(r)try{u=await C()}catch(y){if(U(y))throw y}else u=await C();if(r){let y;if(u){let w=`${l}/llms${u.docUrl}.txt`;y=await De({url:w})}else y=await Oe({baseUrl:l,query:a.query});console.log(y)}else as(u,l),E.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let k=Date.now()-n;try{await N.track(process.cwd(),{event:"docs",properties:{query:a.query??null,item_id:u?.id??a.query??null,has_snippet:!!(u?.snippets&&u.snippets.length>0),duration_ms:k}})}catch(y){o&&console.error("[Telemetry] docs tracking failed:",y)}}catch(i){if(U(i)&&(r||E.outro(p(i.message)),process.exit(0)),r){let a=i instanceof Error?i.message:String(i);console.error(a),process.exit(1)}B(i,{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 L from"@clack/prompts";import{z as Ie}from"zod";import fs from"dedent";var gs=Ie.object({cwd:Ie.string(),yes:Ie.boolean().optional(),default:Ie.boolean().optional()}),st=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=q(t);L.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let o=gs.safeParse(t);if(!o.success)throw o.error;let r=o.data,i=r.yes||r.default,a=i?K:await ke(),{start:l,stop:f}=L.spinner();l("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let h=await(async()=>{try{return(await ue({cwd:r.cwd,config:a})).relativePath}catch(C){throw f("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),C}})();f(`seed-design.json \uD30C\uC77C\uC774 ${p(h)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),L.log.info(p("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),L.log.info(p("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.")),L.note(fs(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
12
25
 
13
26
  \uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
14
- \u2022 seed-design.json\uC5D0\uC11C ${a('"telemetry": false')}\uB85C \uC124\uC815
15
- \u2022 ${a("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
27
+ \u2022 seed-design.json\uC5D0\uC11C ${p('"telemetry": false')}\uB85C \uC124\uC815
28
+ \u2022 ${p("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
16
29
 
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();
30
+ \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),L.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let u=Date.now()-s;try{await N.track(r.cwd,{event:"init",properties:{tsx:a.tsx,rsc:a.rsc,telemetry:a.telemetry,yes_option:i,duration_ms:u}})}catch(C){n&&console.error("[Telemetry] init tracking failed:",C)}}catch(o){U(o)&&(L.outro(p(o.message)),process.exit(0)),B(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{cac as us}from"cac";var ys="seed-design",W=us(ys);async function hs(){let e=ae();W.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),We(W),Ye(W),Qe(W),tt(W),st(W),W.version(e.version||"1.0.0","-v, --version"),W.help(),W.parse()}hs();
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.2",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,4 +1,4 @@
1
- import { fetchDocsIndex } from "@/src/utils/fetch";
1
+ import { fetchDocsIndex, fetchLlmsTxt, tryFetchLlmsTxt } from "@/src/utils/fetch";
2
2
  import * as p from "@clack/prompts";
3
3
  import type { CAC } from "cac";
4
4
  import { z } from "zod";
@@ -20,6 +20,7 @@ const GITHUB_SNIPPET_BASE =
20
20
  const docsOptionsSchema = z.object({
21
21
  query: z.string().optional(),
22
22
  baseUrl: z.string().optional(),
23
+ raw: z.boolean(),
23
24
  });
24
25
 
25
26
  function buildSnippetUrl(registryId: string, snippetPath: string): string {
@@ -49,6 +50,112 @@ function printDocsResult(item: DocsItem, baseUrl: string) {
49
50
  p.log.message(lines.join("\n"));
50
51
  }
51
52
 
53
+ /**
54
+ * Compute the Levenshtein (edit) distance between two strings.
55
+ * Used to suggest similar valid paths when users make typos.
56
+ */
57
+ function levenshtein(a: string, b: string): number {
58
+ const m = a.length;
59
+ const n = b.length;
60
+ const dp: number[][] = Array.from({ length: m + 1 }, (_, i) =>
61
+ Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)),
62
+ );
63
+ for (let i = 1; i <= m; i++) {
64
+ for (let j = 1; j <= n; j++) {
65
+ dp[i][j] = Math.min(
66
+ dp[i - 1][j] + 1,
67
+ dp[i][j - 1] + 1,
68
+ dp[i - 1][j - 1] + (a[i - 1] !== b[j - 1] ? 1 : 0),
69
+ );
70
+ }
71
+ }
72
+ return dp[m][n];
73
+ }
74
+
75
+ /**
76
+ * Find candidates similar to `input` within `maxDistance` edits, sorted by distance.
77
+ */
78
+ function findSimilar(input: string, candidates: string[], maxDistance = 3): string[] {
79
+ const q = input.toLowerCase();
80
+ return candidates
81
+ .map((c) => ({ value: c, dist: levenshtein(q, c.toLowerCase()) }))
82
+ .filter(({ dist }) => dist > 0 && dist <= maxDistance)
83
+ .sort((a, b) => a.dist - b.dist)
84
+ .map(({ value }) => value);
85
+ }
86
+
87
+ /**
88
+ * Build a suggestion hint from a path query by fuzzy-matching each segment
89
+ * against the docs index hierarchy.
90
+ */
91
+ function buildSuggestionHint(segments: string[], categories: DocsCategory[]): string | undefined {
92
+ if (segments.length === 0) return undefined;
93
+
94
+ const suggestions: string[] = [];
95
+
96
+ // Try to fuzzy-match the first segment against category IDs
97
+ const categoryIds = categories.map((c) => c.id);
98
+ const similarCategories = findSimilar(segments[0], categoryIds);
99
+
100
+ if (similarCategories.length === 0) {
101
+ // No similar category — try to find similar full paths across everything
102
+ const allPaths = categories.flatMap((cat) =>
103
+ cat.sections.flatMap((sec) => sec.items.map((item) => `${cat.id}/${sec.id}/${item.id}`)),
104
+ );
105
+ const fullQuery = segments.join("/");
106
+ const similarPaths = findSimilar(fullQuery, allPaths, 5);
107
+ if (similarPaths.length > 0) {
108
+ suggestions.push(...similarPaths.slice(0, 3));
109
+ }
110
+ } else {
111
+ const bestCat = categories.find((c) => c.id === similarCategories[0]);
112
+ if (bestCat && segments.length >= 2) {
113
+ const sectionIds = bestCat.sections.map((s) => s.id);
114
+ const similarSections = findSimilar(segments[1], sectionIds);
115
+
116
+ if (similarSections.length > 0) {
117
+ const bestSec = bestCat.sections.find((s) => s.id === similarSections[0]);
118
+ if (bestSec && segments.length >= 3) {
119
+ const itemIds = bestSec.items.map((i) => i.id);
120
+ const similarItems = findSimilar(segments[2], itemIds);
121
+ for (const item of similarItems.slice(0, 3)) {
122
+ suggestions.push(`${bestCat.id}/${bestSec.id}/${item}`);
123
+ }
124
+ } else {
125
+ for (const sec of similarSections.slice(0, 3)) {
126
+ suggestions.push(`${bestCat.id}/${sec}`);
127
+ }
128
+ }
129
+ } else {
130
+ // Section not found, search items within category
131
+ const allItemIds = bestCat.sections.flatMap((s) =>
132
+ s.items.map((i) => ({ path: `${bestCat.id}/${s.id}/${i.id}`, id: i.id })),
133
+ );
134
+ const similarItems = findSimilar(
135
+ segments[1],
136
+ allItemIds.map((x) => x.id),
137
+ );
138
+ for (const itemId of similarItems.slice(0, 3)) {
139
+ const found = allItemIds.find((x) => x.id === itemId);
140
+ if (found) suggestions.push(found.path);
141
+ }
142
+ }
143
+ } else {
144
+ for (const cat of similarCategories.slice(0, 3)) {
145
+ suggestions.push(cat);
146
+ }
147
+ }
148
+ }
149
+
150
+ if (suggestions.length === 0) return undefined;
151
+
152
+ const lines = ["", "💡 이것을 의미했나요?"];
153
+ for (const s of suggestions) {
154
+ lines.push(` - ${s}`);
155
+ }
156
+ return lines.join("\n");
157
+ }
158
+
52
159
  /**
53
160
  * Parse a path-style query into segments.
54
161
  * e.g. "react/components/action-button" → ["react", "components", "action-button"]
@@ -126,15 +233,21 @@ export const docsCommand = (cli: CAC) => {
126
233
  .option("-u, --baseUrl <baseUrl>", `레지스트리의 기본 URL (기본값: ${BASE_URL})`, {
127
234
  default: BASE_URL,
128
235
  })
236
+ .option("--raw", "llms.txt 내용을 직접 가져와 출력합니다. LLM 파이프에 유용합니다.", {
237
+ default: false,
238
+ })
129
239
  .example("seed-design docs")
130
240
  .example("seed-design docs action-button")
131
241
  .example("seed-design docs react")
132
242
  .example("seed-design docs react/components")
133
243
  .example("seed-design docs react/components/action-button")
244
+ .example("seed-design docs react/updates/changelog --raw")
134
245
  .action(async (query, opts) => {
135
246
  const startTime = Date.now();
136
247
  const verbose = isVerboseMode(opts);
137
- p.intro("seed-design docs");
248
+ const raw = opts.raw ?? false;
249
+
250
+ if (!raw) p.intro("seed-design docs");
138
251
 
139
252
  try {
140
253
  const parsed = docsOptionsSchema.safeParse({ query, ...opts });
@@ -145,10 +258,19 @@ export const docsCommand = (cli: CAC) => {
145
258
  const { data: options } = parsed;
146
259
  const baseUrl = options.baseUrl ?? BASE_URL;
147
260
 
148
- const { start, stop } = p.spinner();
149
- start("문서 목록을 가져오고 있어요...");
261
+ if (options.raw && !options.query) {
262
+ throw new CliError({
263
+ message: "--raw 모드에서는 쿼리가 필요해요.",
264
+ hint: "예: `seed-design docs react/updates/changelog --raw`",
265
+ });
266
+ }
150
267
 
151
268
  const docsIndex = await (async () => {
269
+ if (raw) {
270
+ return await fetchDocsIndex({ baseUrl });
271
+ }
272
+ const { start, stop } = p.spinner();
273
+ start("문서 목록을 가져오고 있어요...");
152
274
  try {
153
275
  const index = await fetchDocsIndex({ baseUrl });
154
276
  stop("문서 목록을 가져왔어요.");
@@ -160,44 +282,62 @@ export const docsCommand = (cli: CAC) => {
160
282
  })();
161
283
 
162
284
  const { categories } = docsIndex;
163
- let selectedItem: DocsItem;
285
+ let selectedItem: DocsItem | undefined;
286
+
287
+ // In --raw mode, wrap index resolution in try-catch to allow fallback to direct URL
288
+ const resolveFromIndex = async (): Promise<DocsItem | undefined> => {
289
+ if (options.query) {
290
+ const segments = parseQueryPath(options.query);
164
291
 
165
- if (options.query) {
166
- const segments = parseQueryPath(options.query);
292
+ // Deep paths (more than category/section/item) can't be resolved from index
293
+ // e.g., react/updates/changelog/react/1.2.9 — skip to fallback in --raw mode
294
+ if (raw && segments.length > 3) {
295
+ return undefined;
296
+ }
167
297
 
168
- // Try to resolve as path: category / section / item
169
- const matchedCategory = categories.find((c) => c.id === segments[0]);
298
+ // Try to resolve as path: category / section / item
299
+ const matchedCategory = categories.find((c) => c.id === segments[0]);
170
300
 
171
- if (matchedCategory && segments.length >= 2) {
172
- const matchedSection = matchedCategory.sections.find((s) => s.id === segments[1]);
301
+ if (matchedCategory && segments.length >= 2) {
302
+ const matchedSection = matchedCategory.sections.find((s) => s.id === segments[1]);
173
303
 
174
- if (matchedSection && segments.length >= 3) {
175
- // Full path: category/section/item
176
- const matchedItem = matchedSection.items.find((i) => i.id === segments[2]);
177
- if (matchedItem) {
178
- selectedItem = matchedItem;
179
- } else {
304
+ if (matchedSection && segments.length >= 3) {
305
+ // Full path: category/section/item
306
+ const matchedItem = matchedSection.items.find((i) => i.id === segments[2]);
307
+ if (matchedItem) {
308
+ return matchedItem;
309
+ }
180
310
  // Item not found in section — search within the section
181
311
  const q = segments[2].toLowerCase();
182
312
  const matched = matchedSection.items.filter(
183
313
  (i) => i.id.toLowerCase().includes(q) || i.title.toLowerCase().includes(q),
184
314
  );
185
315
  if (matched.length === 0) {
316
+ const similarItems = findSimilar(
317
+ segments[2],
318
+ matchedSection.items.map((i) => i.id),
319
+ );
320
+ const suggestion =
321
+ similarItems.length > 0
322
+ ? `\n\n💡 이것을 의미했나요?\n${similarItems
323
+ .slice(0, 3)
324
+ .map((s) => ` - ${matchedCategory.id}/${matchedSection.id}/${s}`)
325
+ .join("\n")}`
326
+ : "";
186
327
  throw new CliError({
187
- message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
328
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.${suggestion}`,
188
329
  hint: `\`seed-design docs ${matchedCategory.id}/${matchedSection.id}\`로 목록을 확인해보세요.`,
189
330
  });
190
331
  }
191
332
  if (matched.length === 1) {
192
- selectedItem = matched[0];
193
- } else {
194
- selectedItem = await selectItem(matched);
333
+ return matched[0];
195
334
  }
335
+ return await selectItem(matched);
336
+ }
337
+ if (matchedSection) {
338
+ // category/section — select item within section
339
+ return await selectItem(matchedSection.items);
196
340
  }
197
- } else if (matchedSection) {
198
- // category/section — select item within section
199
- selectedItem = await selectItem(matchedSection.items);
200
- } else {
201
341
  // category/??? — search within category
202
342
  const q = segments[1].toLowerCase();
203
343
  const matched = matchedCategory.sections.flatMap((s) =>
@@ -209,61 +349,82 @@ export const docsCommand = (cli: CAC) => {
209
349
  );
210
350
 
211
351
  if (matched.length === 0) {
352
+ const sectionIds = matchedCategory.sections.map((s) => s.id);
353
+ const similarSections = findSimilar(segments[1], sectionIds);
354
+ const allItemIds = matchedCategory.sections.flatMap((s) =>
355
+ s.items.map((i) => ({
356
+ path: `${matchedCategory.id}/${s.id}/${i.id}`,
357
+ id: i.id,
358
+ })),
359
+ );
360
+ const similarItems = findSimilar(
361
+ segments[1],
362
+ allItemIds.map((x) => x.id),
363
+ );
364
+ const suggestions: string[] = [
365
+ ...similarSections.slice(0, 2).map((s) => `${matchedCategory.id}/${s}`),
366
+ ...similarItems
367
+ .slice(0, 2)
368
+ .map((id) => allItemIds.find((x) => x.id === id)?.path)
369
+ .filter((p): p is string => p != null),
370
+ ];
371
+ const suggestion =
372
+ suggestions.length > 0
373
+ ? `\n\n💡 이것을 의미했나요?\n${suggestions.map((s) => ` - ${s}`).join("\n")}`
374
+ : "";
212
375
  throw new CliError({
213
- message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
376
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.${suggestion}`,
214
377
  hint: `\`seed-design docs ${matchedCategory.id}\`로 목록을 확인해보세요.`,
215
378
  });
216
379
  }
217
380
  if (matched.length === 1) {
218
- selectedItem = matched[0].item;
219
- } else {
220
- const selected = await p.select({
221
- message: `${highlight(segments[1])}에 해당하는 항목을 선택해주세요`,
222
- options: matched.map(({ item, sectionLabel }) => ({
223
- label: `[${sectionLabel}] ${item.title}`,
224
- value: item,
225
- hint: item.description,
226
- })),
227
- });
228
- if (p.isCancel(selected)) throw new CliCancelError();
229
- selectedItem = selected;
381
+ return matched[0].item;
230
382
  }
383
+ const selected = await p.select({
384
+ message: `${highlight(segments[1])}에 해당하는 항목을 선택해주세요`,
385
+ options: matched.map(({ item, sectionLabel }) => ({
386
+ label: `[${sectionLabel}] ${item.title}`,
387
+ value: item,
388
+ hint: item.description,
389
+ })),
390
+ });
391
+ if (p.isCancel(selected)) throw new CliCancelError();
392
+ return selected;
231
393
  }
232
- } else if (matchedCategory) {
233
- // Single segment matching a category — drill into it
234
- if (matchedCategory.sections.length === 1) {
235
- selectedItem = await selectItem(matchedCategory.sections[0].items);
236
- } else {
394
+ if (matchedCategory) {
395
+ // Single segment matching a category — drill into it
396
+ if (matchedCategory.sections.length === 1) {
397
+ return await selectItem(matchedCategory.sections[0].items);
398
+ }
237
399
  const section = await selectSection(matchedCategory.sections);
238
- selectedItem = await selectItem(section.items);
400
+ return await selectItem(section.items);
239
401
  }
240
- } else {
241
402
  // No category match — global search
242
403
  const matched = searchAllItems(categories, options.query);
243
404
 
244
405
  if (matched.length === 0) {
406
+ const suggestion = buildSuggestionHint(segments, categories);
245
407
  throw new CliError({
246
- message: `${highlight(options.query)}: 문서를 찾을 수 없어요.`,
408
+ message: `${highlight(options.query)}: 문서를 찾을 수 없어요.${suggestion ?? ""}`,
247
409
  hint: "`seed-design docs`로 전체 목록을 확인해보세요.",
248
410
  });
249
411
  }
250
412
  if (matched.length === 1) {
251
- selectedItem = matched[0].item;
252
- } else {
253
- const selected = await p.select({
254
- message: `${highlight(options.query)}에 해당하는 항목을 선택해주세요`,
255
- options: matched.map(({ item, categoryLabel, sectionLabel }) => ({
256
- label: `[${categoryLabel} > ${sectionLabel}] ${item.title}`,
257
- value: item,
258
- hint: item.description,
259
- })),
260
- });
261
- if (p.isCancel(selected)) throw new CliCancelError();
262
- selectedItem = selected;
413
+ return matched[0].item;
263
414
  }
415
+ const selected = await p.select({
416
+ message: `${highlight(options.query)}에 해당하는 항목을 선택해주세요`,
417
+ options: matched.map(({ item, categoryLabel, sectionLabel }) => ({
418
+ label: `[${categoryLabel} > ${sectionLabel}] ${item.title}`,
419
+ value: item,
420
+ hint: item.description,
421
+ })),
422
+ });
423
+ if (p.isCancel(selected)) throw new CliCancelError();
424
+ return selected;
264
425
  }
265
- } else {
266
- // Full interactive flow: category → section → item
426
+
427
+ // No query — full interactive flow: category → section → item
267
428
  const category = await selectCategory(categories);
268
429
 
269
430
  let section: DocsSection;
@@ -273,11 +434,34 @@ export const docsCommand = (cli: CAC) => {
273
434
  section = await selectSection(category.sections);
274
435
  }
275
436
 
276
- selectedItem = await selectItem(section.items);
437
+ return await selectItem(section.items);
438
+ };
439
+
440
+ // In --raw mode, swallow index resolution errors and fall back to direct URL fetch
441
+ if (raw) {
442
+ try {
443
+ selectedItem = await resolveFromIndex();
444
+ } catch (error) {
445
+ if (isCliCancelError(error)) throw error;
446
+ // index miss in raw mode → will use fallback
447
+ }
448
+ } else {
449
+ selectedItem = await resolveFromIndex();
277
450
  }
278
451
 
279
- printDocsResult(selectedItem, baseUrl);
280
- p.outro("완료했어요.");
452
+ if (raw) {
453
+ let content: string;
454
+ if (selectedItem) {
455
+ const llmsUrl = `${baseUrl}/llms${selectedItem.docUrl}.txt`;
456
+ content = await fetchLlmsTxt({ url: llmsUrl });
457
+ } else {
458
+ content = await tryFetchLlmsTxt({ baseUrl, query: options.query! });
459
+ }
460
+ console.log(content);
461
+ } else {
462
+ printDocsResult(selectedItem!, baseUrl);
463
+ p.outro("완료했어요.");
464
+ }
281
465
 
282
466
  const duration = Date.now() - startTime;
283
467
  try {
@@ -285,8 +469,8 @@ export const docsCommand = (cli: CAC) => {
285
469
  event: "docs",
286
470
  properties: {
287
471
  query: options.query ?? null,
288
- item_id: selectedItem.id,
289
- has_snippet: !!(selectedItem.snippets && selectedItem.snippets.length > 0),
472
+ item_id: selectedItem?.id ?? options.query ?? null,
473
+ has_snippet: !!(selectedItem?.snippets && selectedItem.snippets.length > 0),
290
474
  duration_ms: duration,
291
475
  },
292
476
  });
@@ -297,10 +481,16 @@ export const docsCommand = (cli: CAC) => {
297
481
  }
298
482
  } catch (error) {
299
483
  if (isCliCancelError(error)) {
300
- p.outro(highlight(error.message));
484
+ if (!raw) p.outro(highlight(error.message));
301
485
  process.exit(0);
302
486
  }
303
487
 
488
+ if (raw) {
489
+ const msg = error instanceof Error ? error.message : String(error);
490
+ console.error(msg);
491
+ process.exit(1);
492
+ }
493
+
304
494
  handleCliError(error, {
305
495
  defaultMessage: "문서 조회에 실패했어요.",
306
496
  defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
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
+
8
9
  import { getPackageInfo } from "@/src/utils/get-package-info";
9
10
  import { cac } from "cac";
10
11
 
@@ -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,78 @@ async function fetchRegistryItem({
101
121
  return parsedItem;
102
122
  }
103
123
 
124
+ export async function fetchLlmsTxt({ url }: { url: string }): Promise<string> {
125
+ const response = await fetchWithTimeout(url);
126
+
127
+ if (!response.ok) {
128
+ throw new CliError({
129
+ message: `llms.txt를 가져오지 못했어요: ${response.status} ${response.statusText}`,
130
+ hint: `${url} 에 접근할 수 있는지 확인해주세요.`,
131
+ });
132
+ }
133
+
134
+ return response.text();
135
+ }
136
+
137
+ /**
138
+ * Try fetching llms.txt content with fallback URL patterns.
139
+ * 1. {baseUrl}/llms/{query}.txt
140
+ * 2. {baseUrl}/llms/{query}/llms.txt (for package changelog index)
141
+ */
142
+ export async function tryFetchLlmsTxt({
143
+ baseUrl,
144
+ query,
145
+ }: {
146
+ baseUrl: string;
147
+ query: string;
148
+ }): Promise<string> {
149
+ const normalizedQuery = query.startsWith("/") ? query.slice(1) : query;
150
+
151
+ const urls = [
152
+ `${baseUrl}/llms/${normalizedQuery}.txt`,
153
+ `${baseUrl}/llms/${normalizedQuery}/llms.txt`,
154
+ ];
155
+
156
+ let lastError: unknown;
157
+
158
+ for (const url of urls) {
159
+ let response: Response;
160
+ try {
161
+ response = await fetchWithTimeout(url);
162
+ } catch (error) {
163
+ lastError = error;
164
+ continue;
165
+ }
166
+
167
+ if (response.ok) {
168
+ return response.text();
169
+ }
170
+
171
+ // 404 → try next URL candidate
172
+ if (response.status === 404) {
173
+ lastError = new CliError({
174
+ message: `llms.txt를 찾을 수 없어요: ${normalizedQuery}`,
175
+ hint: `다음 경로를 시도했어요:\n${urls.map((u) => ` - ${u}`).join("\n")}`,
176
+ });
177
+ continue;
178
+ }
179
+
180
+ // Non-404 errors (5xx, 401, etc.) — propagate immediately
181
+ throw new CliError({
182
+ message: `llms.txt 요청이 실패했어요: ${response.status} ${response.statusText}`,
183
+ hint: `URL: ${url}`,
184
+ });
185
+ }
186
+
187
+ throw (
188
+ lastError ??
189
+ new CliError({
190
+ message: `llms.txt를 찾을 수 없어요: ${normalizedQuery}`,
191
+ hint: `다음 경로를 시도했어요:\n${urls.map((u) => ` - ${u}`).join("\n")}`,
192
+ })
193
+ );
194
+ }
195
+
104
196
  export async function fetchRegistryItems({
105
197
  baseUrl,
106
198
  registryId,