@seed-design/cli 1.3.2 → 1.3.4

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,30 +1,30 @@
1
1
  #!/usr/bin/env node
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:
2
+ import*as te from"@clack/prompts";import{cosmiconfig as dt}from"cosmiconfig";import{z as oe}from"zod";import*as Y from"@clack/prompts";import{ZodError as ct}from"zod";import at from"picocolors";var p=e=>at.cyan(e);var I=class extends Error{hint;details;constructor({message:t,hint:r,details:n=[],cause:o}){super(t,{cause:o}),this.name="CliError",this.hint=r,this.details=n}},_=class extends Error{constructor(t="\uC791\uC5C5\uC774 \uCDE8\uC18C\uB410\uC5B4\uC694."){super(t),this.name="CliCancelError"}};function N(e){return e instanceof _}function H(e){return!e||typeof e!="object"||!("verbose"in e)?!1:e.verbose===!0}function lt(e,t){if(e instanceof I)return{reason:e.message,hint:e.hint??t,details:e.details,stack:pt(e.cause??e)};if(e instanceof ct){let r=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:r,stack:e.stack}}if(e instanceof Error){let r=e,n=[];return(r.escapedCommand||r.command)&&n.push(`\uC2E4\uD589 \uBA85\uB839\uC5B4: ${r.escapedCommand??r.command}`),typeof r.exitCode=="number"&&n.push(`\uC885\uB8CC \uCF54\uB4DC: ${r.exitCode}`),r.stderr?.trim()?n.push(`stderr: ${r.stderr.trim()}`):r.stdout?.trim()&&n.push(`stdout: ${r.stdout.trim()}`),{reason:r.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 pt(e){if(e instanceof Error)return e.stack}function G(e,{defaultMessage:t,defaultHint:r,verbose:n=!1}){let o=lt(e,r);Y.log.error(t),Y.log.error(`\uC6D0\uC778: ${o.reason}`);for(let s of o.details)Y.log.info(s);o.hint&&Y.log.info(`\uD574\uACB0 \uD78C\uD2B8: ${o.hint}`),n&&o.stack&&(Y.log.message(p(`
3
+ [verbose] stack trace`)),Y.log.message(o.stack)),Y.outro(p("\uC791\uC5C5\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694."))}import*as Q from"@clack/prompts";import mt from"fs-extra";import Re from"path";var z={rsc:!1,tsx:!0,path:"./seed-design",telemetry:!0};async function Te(){return await Q.group({tsx:()=>Q.confirm({message:`${p("TypeScript")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:z.tsx}),rsc:()=>Q.confirm({message:`${p("React Server Components")}\uB97C \uC0AC\uC6A9\uC911\uC774\uC2E0\uAC00\uC694?`,initialValue:z.rsc}),path:()=>Q.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:z.path,defaultValue:z.path,placeholder:z.path}),telemetry:()=>Q.confirm({message:`\uAC1C\uC120\uC744 \uC704\uD574 ${p("\uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130")}\uB97C \uC218\uC9D1\uD560\uAE4C\uC694?`,initialValue:z.telemetry})},{onCancel:()=>{throw new _}})}async function ye({cwd:e,config:t}){let r=Re.resolve(e,"seed-design.json");return await mt.writeFile(r,`${JSON.stringify(t,null,2)}
4
+ `,"utf-8"),{relativePath:Re.relative(process.cwd(),r),targetPath:r}}var ve="seed-design",ft=dt(ve,{searchPlaces:[`${ve}.json`]}),_e=oe.object({$schema:oe.string().optional(),rsc:oe.coerce.boolean().default(!1),tsx:oe.coerce.boolean().default(!0),path:oe.string(),telemetry:oe.coerce.boolean().optional().default(!0)}).strict();async function he(e){let t=await de(e);if(t)return t;te.log.error("\uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8 \uACBD\uB85C\uC5D0 `seed-design.json` \uD30C\uC77C\uC774 \uC5C6\uC5B4\uC694.");let r=await te.confirm({message:"seed-design.json \uD30C\uC77C\uC744 \uC0DD\uC131\uD558\uC2DC\uACA0\uC5B4\uC694?"});if(te.isCancel(r)||!r)throw new _;try{return await ye({cwd:e,config:z}),te.log.message("seed-design.json \uD30C\uC77C\uC774 \uC0DD\uC131\uB410\uC5B4\uC694."),_e.parse(z)}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 de(e){let t=await ft.search(e);if(!t||t.isEmpty)return null;try{return _e.parse(t.config)}catch(r){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:r})}}function we({selectedItemKeys:e,publicRegistries:t}){let r=[],n=new Set;function o(s,i){let a=r.find(c=>c.registryId===s);if(!a?.items.some(c=>c.id===i.id)){if(a?a.items.push(i):r.push({registryId:s,items:[i]}),i.dependencies?.length)for(let c of i.dependencies)n.add(c);if(i.innerDependencies?.length)for(let c of i.innerDependencies)for(let d of c.itemIds){let y=t.find(w=>w.id===c.registryId)?.items.find(w=>w.id===d);if(!y)throw new Error(`Cannot find dependency item: ${c.registryId}:${d}`);o(c.registryId,y)}}}for(let s of e){let[i,...a]=s.split(":"),c=a.join(":");if(!i||!c)throw new Error(`Invalid snippet format: "${s}"`);let d=t.find(y=>y.id===i)?.items.find(y=>y.id===c);if(!d)throw new Error(`Cannot find snippet: "${s}"`);o(i,d)}return{registryItemsToAdd:r,npmDependenciesToAdd:n}}import*as ke from"@clack/prompts";import{z as m}from"zod";var Pe=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()}))}),Se=m.object({id:m.string(),hideFromCLICatalog:m.boolean().optional(),items:m.array(Pe.omit({snippets:!0}).extend({snippets:m.array(m.object({path:m.string(),dependencies:m.record(m.string(),m.string()).optional()}))}))}),je=m.array(m.object({id:m.string()})),gt=m.object({label:m.string(),path:m.string()}),ut=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(gt).optional()}),yt=m.object({id:m.string(),label:m.string(),items:m.array(ut)}),ht=m.object({id:m.string(),label:m.string(),sections:m.array(yt)}),De=m.object({categories:m.array(ht)});var wt=1e4;async function Ae(e,t=wt){let r=new AbortController,n=setTimeout(()=>r.abort(),t);try{return await fetch(e,{signal:r.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 Ee({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 r=await t.json(),{success:n,data:o,error:s}=De.safeParse(r);if(!n)throw new I({message:`\uBB38\uC11C \uBAA9\uB85D \uD30C\uC2F1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694: ${s?.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 r=await t.json(),{success:n,data:o,error:s}=je.safeParse(r);if(!n)throw new Error(`Failed to parse registries: ${s?.message}`);return o}async function ne({baseUrl:e,registryId:t}){let r=await fetch(`${e}/__registry__/${t}/index.json`);if(!r.ok)throw new Error(`Failed to fetch ${t} registry: ${r.status} ${r.statusText}`);let n=await r.json(),{success:o,data:s,error:i}=Se.safeParse(n);if(!o)throw new Error(`Failed to parse ${t} registry: ${i?.message}`);return s}async function bt({baseUrl:e,registryId:t,registryItemId:r}){let n=await fetch(`${e}/__registry__/${t}/${r}.json`);if(!n.ok)throw new Error(`Failed to fetch ${r}: ${n.status} ${n.statusText}`);let o=await n.json(),{success:s,data:i,error:a}=Pe.safeParse(o);if(!s)throw new Error(`Failed to parse ${r}: ${a?.message}`);return i}async function Oe({url:e}){let t=await Ae(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 Me({baseUrl:e,query:t}){let r=t.startsWith("/")?t.slice(1):t,n=[`${e}/llms/${r}.txt`,`${e}/llms/${r}/llms.txt`],o;for(let s of n){let i;try{i=await Ae(s)}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: ${r}`,hint:`\uB2E4\uC74C \uACBD\uB85C\uB97C \uC2DC\uB3C4\uD588\uC5B4\uC694:
5
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")}
6
+ `)}`});continue}throw new I({message:`llms.txt \uC694\uCCAD\uC774 \uC2E4\uD328\uD588\uC5B4\uC694: ${i.status} ${i.statusText}`,hint:`URL: ${s}`})}throw o??new I({message:`llms.txt\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694: ${r}`,hint:`\uB2E4\uC74C \uACBD\uB85C\uB97C \uC2DC\uB3C4\uD588\uC5B4\uC694:
7
+ ${n.map(s=>` - ${s}`).join(`
8
+ `)}`})}async function Le({baseUrl:e,registryId:t,registryItemIds:r}){return await Promise.all(r.map(async n=>{try{return await bt({baseUrl:e,registryId:t,registryItemId:n})}catch(o){let s=await fetch(`${e}/__registry__/${t}/index.json`);if(!s.ok)throw new Error(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694: ${s.status} ${s.statusText}`);let i=await s.json(),{success:a,data:c}=Se.safeParse(i);throw a?(ke.log.error(`${n} \uC2A4\uB2C8\uD3AB\uC774 ${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4\uC694.`),ke.log.info(`${t} \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC874\uC7AC\uD558\uB294 \uC2A4\uB2C8\uD3AB:
9
+ ${c.items.map(d=>d.id).join(`
10
+ `)}`),o):new Error(`Failed to parse registry index for ${t}`)}}))}import{promises as St}from"fs";import{tmpdir as kt}from"os";import Ke from"path";import{transformFromAstSync as Ct}from"@babel/core";import $t from"@babel/plugin-transform-typescript";import*as be from"recast";import{parse as It}from"@babel/parser";var xt={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"]},Fe=async({sourceFile:e,config:t})=>{let r=e.getFullText();if(t.tsx)return r;let n=be.parse(r,{parser:{parse:s=>It(s,xt)}}),o=Ct(n,r,{cloneInputAst:!1,code:!1,ast:!0,plugins:[$t],configFile:!1});if(!o||!o.ast)throw new Error("Failed to transform JSX");return be.print(o.ast).code};import{SyntaxKind as Pt}from"ts-morph";var Ue=async({sourceFile:e,config:t})=>{if(t.rsc)return e;let r=e.getFirstChildByKind(Pt.ExpressionStatement);if(!r)return e;let n=r.getExpression();if(!n)return e;let o=n.getText().trim();if(o!=='"use client"'&&o!=="'use client'")return e;let s=r.getText(),i=r.getFullText();if(s.trim()===i.trim())return e;let c=i.replace(s,"").replace(/^\s*\n/,"").replace(/\n\s*$/,"");return r.replaceWithText(c),e};import{Project as Et,ScriptKind as Rt}from"ts-morph";var Tt=[Ue],vt=new Et({compilerOptions:{}});async function _t(e){let t=await St.mkdtemp(Ke.join(kt(),"seed-design-"));return Ke.join(t,e)}async function Ne(e){let t=await _t(e.filename),r=vt.createSourceFile(t,e.raw,{scriptKind:Rt.TSX});for(let n of Tt)n({sourceFile:r,...e});return await Fe({sourceFile:r,...e})}import*as V from"@clack/prompts";import ae from"fs-extra";import J from"path";import{createPatch as jt}from"diff";import Dt from"@npmcli/disparity-colors";async function Ce({registryItemsToAdd:e,rootPath:t,cwd:r,baseUrl:n,config:o,onDiff:s}){let i=[];for(let{registryId:a,items:c}of e){let d=J.join(t,a);ae.ensureDirSync(d);let y=await Le({baseUrl:n,registryId:a,registryItemIds:c.map(w=>w.id)});for(let{id:w,snippets:C}of y){let E=await Promise.all(C.map(async h=>{let f=await Ne({filename:h.path,config:o,raw:h.content}),u=J.join(d,h.path);return o.tsx||(u=u.replace(/\.tsx$/,".jsx"),u=u.replace(/\.ts$/,".js")),{filePath:u,content:f,relativePath:J.relative(r,u),name:`${a}:${w}`}})),x=[];for(let h of E){let{filePath:f,content:u,relativePath:$}=h;if(await ae.ensureDir(J.dirname(f)),ae.existsSync(f)){let O=await ae.readFile(f,"utf-8");if(O===u){V.log.info(`${p($)}: \uC774\uBBF8 \uCD5C\uC2E0 \uC0C1\uD0DC\uC608\uC694.`);continue}let B=J.basename(f),P=J.extname(f),M=J.basename(f,P),L=Date.now(),W=`legacy-${M}-${L}${P}`,b=await(async()=>{if(s)return s;let l=jt($,O,u),g=Dt(l);return V.log.message(`
11
+ ${p($)}: \uD604\uC7AC \uD30C\uC77C\uACFC \uBC1B\uC73C\uB824\uB294 \uD30C\uC77C\uC758 \uB0B4\uC6A9\uC774 \uB2EC\uB77C\uC694.
12
+ `),V.log.message(g),V.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:`${B} \uB36E\uC5B4\uC4F0\uAE30`},{value:"backup",label:`\uAE30\uC874 \uD30C\uC77C \uB0B4\uC6A9\uC744 ${W}\uC73C\uB85C \uC62E\uAE30\uACE0 ${B} \uBC1B\uAE30`},{value:"skip",label:"\uC0C8 \uD30C\uC77C \uBC1B\uC9C0 \uC54A\uACE0 \uADF8\uB300\uB85C \uB450\uAE30"}]})})();if(V.isCancel(b)||b==="skip"){V.log.info(`${p($)}: \uD30C\uC77C\uC744 \uBC1B\uC9C0 \uC54A\uACE0 \uAC74\uB108\uB6F0\uC5C8\uC5B4\uC694.`);continue}if(b==="backup"){let l=J.dirname(f),g=J.join(l,W);await ae.rename(f,g),V.log.info(`${p($)}: \uAE30\uC874 \uD30C\uC77C\uC744 ${p(J.relative(r,g))}\uB85C \uC62E\uACBC\uC5B4\uC694.`)}}await ae.writeFile(f,u),x.push(h)}if(x.length>0){let h=x.map(({name:f,relativePath:u})=>({name:f,path:u}));i.push(...h),V.log.success(`${p(`${a}:${w}`)} \uAD00\uB828 \uC2A4\uB2C8\uD3AB \uB2E4\uC6B4\uB85C\uB4DC \uC644\uB8CC: ${p(h.map(f=>f.path).join(", "))}`)}}}}import*as T from"@clack/prompts";import sr from"path";import{z as se}from"zod";var F="https://seed-design.io";import*as Ve from"@clack/prompts";import{execa as Ut}from"execa";import{detect as At}from"@antfu/ni";async function ze(e){let t=await At({programmatic:!0,cwd:e});return t==="yarn@berry"?"yarn":t==="pnpm@6"?"pnpm":t==="bun"?"bun":t==="deno"?"deno":t??"npm"}import Ot from"findup-sync";import Mt from"fs-extra";var Lt="package.json";function Ft(e=process.cwd()){let t=Ot(Lt,{cwd:e});if(!t)throw new Error("No package.json file found in the project.");return t}function ce(e=process.cwd()){let t=Ft(e);return Mt.readJSONSync(t)}async function $e({cwd:e,deps:t,dev:r=!1}){let{start:n,stop:o}=Ve.spinner(),s=await ze(e),a={...ce(e).dependencies},c=new Set(t.filter(x=>!a[x])),d=new Set(t.filter(x=>a[x]));if(!c.size)return{installed:new Set,filtered:c};n("\uC758\uC874\uC131 \uC124\uCE58\uC911...");let C=[s==="npm"?"install":"add",r?"-D":null,...c].filter(x=>!!x),E=`${s} ${C.join(" ")}`;try{await Ut(s,C,{cwd:e})}catch(x){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: ${E}`],cause:x})}return o("\uC758\uC874\uC131 \uC124\uCE58\uAC00 \uC644\uB8CC\uB410\uC5B4\uC694."),{installed:c,filtered:d}}import{randomUUID as Kt}from"node:crypto";import*as Be from"@clack/prompts";var Nt="seed_cli";async function zt(e){if(process.env.DISABLE_TELEMETRY==="true"||process.env.SEED_DISABLE_TELEMETRY==="true")return!1;try{if((await de(e))?.telemetry===!1)return!1}catch{}return!0}function Vt(){return Kt()}var qt=Vt(),qe=!1;function He(e){return Object.fromEntries(Object.entries(e).filter(([,t])=>t!==void 0))}function Bt(e){return e instanceof Error&&e.name?e.name:typeof e=="object"&&e!==null?e.constructor?.name??"Object":typeof e}async function Ge(e,{event:t,properties:r={}}){if(!await zt(e))return;let o=`${Nt}.${t}`;qe||(Be.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)"),qe=!0);try{let s="https://us.i.posthog.com/capture",i={"Content-Type":"application/json"},a={api_key:"phc_seod8HhifElOP1R92KmvsQybrtUmkOTgZBsq0mfCelR",event:o,distinct_id:qt,properties:{...r,$process_person_profile:!1},timestamp:new Date().toISOString()},c=new AbortController,d=setTimeout(()=>c.abort(),5e3);try{await fetch(s,{method:"POST",headers:i,body:JSON.stringify(a),signal:c.signal})}finally{clearTimeout(d)}}catch{}}async function Je(e,{command:t,status:r,result:n,properties:o={}}){await Ge(e,{event:t,properties:He({status:r,result:n,...o})})}async function Ht(e,{command:t,error:r,result:n,properties:o={}}){await Je(e,{command:t,status:"failed",result:n,properties:He({error_type:Bt(r),...o})})}var R={track:Ge,trackCommandFailure:Ht,trackCommandOutcome:Je};import*as re from"@clack/prompts";import Gt from"fs-extra";import Jt from"path";import{intersects as Wt,satisfies as Yt,valid as Ye,validRange as Xe}from"semver";var fe=["@seed-design/react","@seed-design/css"],We="workspace:",Xt="npm:";function le(e){try{let t=ce(e),r={...t.dependencies,...t.devDependencies,...t.peerDependencies,...t.optionalDependencies},n={};for(let o of fe){let s=r[o];typeof s=="string"&&(n[o]=s)}return n}catch{return{}}}function pe({publicRegistries:e,itemKeys:t,projectPackageVersions:r}){let n=Array.from(new Set(t)),o=new Map(e.flatMap(i=>i.items.map(a=>[`${i.id}:${a.id}`,a]))),s=[];for(let i of n){let a=o.get(i);if(!a)continue;let c=Qt(a);for(let d of fe){let y=Array.from(c[d]??[]);if(!y.length)continue;let w=r[d];if(!w){s.push({itemKey:i,packageName:d,requiredRanges:y,type:"missing-package"});continue}let C=Zt(w);if(!C){s.push({itemKey:i,packageName:d,requiredRanges:y,installedVersionSpec:w,type:"invalid-version-spec"});continue}y.every(x=>er({currentVersionSpec:C,requiredRange:x}))||s.push({itemKey:i,packageName:d,requiredRanges:y,installedVersionSpec:w,type:"incompatible-version"})}}return{checkedItemKeys:n,projectPackageVersions:r,issues:s}}function me({report:e,title:t}){if(!e.issues.length)return;re.log.warn(t),re.log.info(`\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804: ${fe.map(n=>`${n}@${p(e.projectPackageVersions[n]??"\uBBF8\uC124\uCE58")}`).join(", ")}`);let r=new Map;for(let n of e.issues){let o=r.get(n.itemKey)??[];o.push(n),r.set(n.itemKey,o)}for(let[n,o]of r.entries()){re.log.warn(p(n));for(let s of o){let i=s.requiredRanges.join(" | ");if(s.type==="missing-package"){re.log.info(` - ${s.packageName}: \uD328\uD0A4\uC9C0\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC544\uC694. \uD544\uC694 \uBC94\uC704: ${i}`);continue}if(s.type==="invalid-version-spec"){re.log.info(` - ${s.packageName}: \uD604\uC7AC \uBC84\uC804 \uD615\uC2DD\uC744 \uD574\uC11D\uD558\uC9C0 \uBABB\uD588\uC5B4\uC694 (${s.installedVersionSpec}). \uD544\uC694 \uBC94\uC704: ${i}`);continue}re.log.info(` - ${s.packageName}: \uD604\uC7AC ${s.installedVersionSpec}, \uD544\uC694 \uBC94\uC704 ${i}`)}}}function Qe({publicRegistries:e,rootPath:t}){let r=[];for(let n of e)for(let o of n.items)o.snippets.some(i=>tr(i.path).some(a=>Gt.existsSync(Jt.join(t,n.id,a))))&&r.push(`${n.id}:${o.id}`);return r}function Qt(e){let t=Object.fromEntries(fe.map(r=>[r,new Set]));for(let r of e.snippets)for(let[n,o]of Object.entries(r.dependencies??{}))rr(n)&&t[n].add(o);return t}function Zt(e){let t=e.trim();if(t.startsWith(We)&&(t=t.slice(We.length).trim()),t.startsWith(Xt)){let r=t.split("@").at(-1);if(!r)return null;t=r}return!t||t==="*"?null:Ye(t)||Xe(t)?t:null}function er({currentVersionSpec:e,requiredRange:t}){let r=Xe(t);return r?Ye(e)?Yt(e,r,{includePrerelease:!0}):Wt(e,r,{includePrerelease:!0}):!1}function tr(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 rr(e){return fe.includes(e)}var or=se.object({itemIds:se.array(se.string()).optional(),all:se.boolean(),cwd:se.string(),baseUrl:se.string().default(F),onDiff:se.enum(["overwrite","backup"]).optional()}),Ze=e=>{e.command("add [...item-ids]","add items").option("-a, --all","[Deprecated] Add all items",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:F}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add ui:action-button").example("seed-design add ui:alert-dialog").action(async(t,r)=>{let n=Date.now(),o=H(r),s=typeof r?.cwd=="string"?r.cwd:process.cwd();T.intro("seed-design add");try{let i=or.safeParse({itemIds:t,...r});if(!i.success)throw i.error;let{data:{all:a,...c}}=i;if(a)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 d=c.cwd,y=c.baseUrl,w=await he(d),C=sr.resolve(d,w.path),{start:E,stop:x}=T.spinner();E("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let h=await(async()=>{try{let l=await Promise.all((await ie({baseUrl:y})).map(async({id:g})=>ne({baseUrl:y,registryId:g})));return x("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),l}catch(l){throw x("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),l}})(),f=await(async()=>{if(c.itemIds?.length)return c.itemIds;let l=await T.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:h.filter(({hideFromCLICatalog:g})=>!g).flatMap(({id:g,items:k})=>k.filter(({hideFromCLICatalog:A})=>!A).sort((A,D)=>A.id.localeCompare(D.id)).map(({id:A,description:D,deprecated:S})=>({label:`${S?"(deprecated) ":""}${p(g)}:${A}`,value:`${g}:${A}`,hint:D,deprecated:S,registryItemCount:k.length}))).sort((g,k)=>g.deprecated!==k.deprecated?g.deprecated?1:-1:k.registryItemCount-g.registryItemCount)});if(T.isCancel(l))throw new _;return l})();if(!f?.length)throw new _("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC120\uD0DD\uB418\uC9C0 \uC54A\uC558\uC5B4\uC694.");T.log.message(`\uC120\uD0DD\uB41C \uD56D\uBAA9: ${p(f.join(", "))}`);let u=[];for(let l of f){let[g,...k]=l.split(":"),A=k.join(":");if(!g||!A)throw new I({message:`${p(l)}: \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 D=h.find(S=>S.id===g)?.items.find(S=>S.id===A);if(!D)throw new I({message:`${p(l)}: \uD56D\uBAA9\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.`});if(D.deprecated){let S=await T.confirm({message:`${p(D.id)}: deprecated \uB418\uC5C8\uC5B4\uC694. \uCD94\uAC00\uD560\uAE4C\uC694?`,initialValue:!1});if(T.isCancel(S))throw new _;if(S===!1){T.log.info(`${p(D.id)}: \uCD94\uAC00\uD558\uC9C0 \uC54A\uC744\uAC8C\uC694.`);continue}}u.push(l)}let{registryItemsToAdd:$,npmDependenciesToAdd:O}=we({selectedItemKeys:u,publicRegistries:h}),B=pe({publicRegistries:h,itemKeys:$.flatMap(({registryId:l,items:g})=>g.map(k=>`${l}:${k.id}`)),projectPackageVersions:le(c.cwd)});me({report:B,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."}),T.log.info(`\uCD94\uAC00\uD560 \uD56D\uBAA9: ${p($.map(l=>l.items.map(g=>`${l.registryId}:${g.id}`).join(", ")).join(", ")||"\uC5C6\uC74C")}
13
13
 
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?`
14
+ \uC124\uCE58\uD560 \uC758\uC874\uC131: ${p(Array.from(O).join(", ")||"\uC5C6\uC74C")}`),await Ce({registryItemsToAdd:$,rootPath:C,cwd:d,baseUrl:y,config:w,onDiff:c.onDiff});let{installed:P,filtered:M}=await $e({cwd:d,deps:Array.from(O)});P.size===0&&T.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),P.size&&(T.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${p(Array.from(P).join(", "))}`),M.size&&T.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${p(Array.from(M).join(", "))}`)),T.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let L=Date.now()-n,W=new Set($.map(l=>l.registryId)),b=f.some(l=>{let[g,...k]=l.split(":"),A=k.join(":");return h.find(D=>D.id===g)?.items.find(D=>D.id===A)?.deprecated});try{await R.trackCommandOutcome(c.cwd,{command:"add",status:"completed",properties:{items_count:u.length,registries:Array.from(W),has_deprecated:b,dependencies_count:O.size,duration_ms:L}})}catch(l){o&&console.error("[Telemetry] add \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",l)}}catch(i){if(N(i)){try{await R.trackCommandOutcome(s,{command:"add",status:"cancelled",properties:{duration_ms:Date.now()-n}})}catch(a){o&&console.error("[Telemetry] add \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",a)}T.outro(p(i.message)),process.exit(0)}try{await R.trackCommandFailure(s,{command:"add",error:i,properties:{duration_ms:Date.now()-n}})}catch(a){o&&console.error("[Telemetry] add \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",a)}G(i,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:o}),process.exit(1)}})};import*as j from"@clack/prompts";import ir from"path";import{z as Z}from"zod";var nr=Z.object({registryIds:Z.array(Z.string()).optional(),all:Z.boolean(),includeDeprecated:Z.boolean().optional(),cwd:Z.string(),baseUrl:Z.string().default(F),onDiff:Z.enum(["overwrite","backup"]).optional()}),et=e=>{e.command("add-all [...registry-ids]","add all items from registries").option("-a, --all","Add all items from all registries",{default:!1}).option("--include-deprecated","Include deprecated items when used with `--all`",{default:!1}).option("-c, --cwd <cwd>","the working directory. defaults to the current directory.",{default:process.cwd()}).option("-u, --baseUrl <baseUrl>","the base url of the registry. defaults to the current directory.",{default:F}).option("--on-diff <mode>","Action when file differs: overwrite or backup").example("seed-design add-all ui --include-deprecated").example("seed-design add-all ui lib breeze").action(async(t,r)=>{let n=Date.now(),o=H(r),s=typeof r?.cwd=="string"?r.cwd:process.cwd();j.intro("seed-design add-all");try{let i=nr.safeParse({registryIds:t,...r});if(!i.success)throw i.error;let{data:a}=i,c=a.cwd,d=a.baseUrl,y=await he(c),w=ir.resolve(c,y.path),{start:C,stop:E}=j.spinner();C("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let x=await(async()=>{try{let b=await Promise.all((await ie({baseUrl:d})).map(async({id:l})=>ne({baseUrl:d,registryId:l})));return E("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),b}catch(b){throw E("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),b}})(),h=await(async()=>{if(a.all){let l=x.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(l.join(", "))}`),l}if(a.registryIds?.length){let l=x.map(g=>g.id);for(let g of a.registryIds)if(!l.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: ${l.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(a.registryIds.join(", "))}`),a.registryIds}let b=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:x.filter(({hideFromCLICatalog:l})=>!l).sort((l,g)=>g.items.length-l.items.length).map(l=>{let g=l.items[0]?.id,k=g?`${l.items.length}\uAC1C \uD56D\uBAA9 (${g} \uB4F1)`:`${l.items.length}\uAC1C \uD56D\uBAA9 (\uD56D\uBAA9 \uC5C6\uC74C)`;return{label:l.id,value:l.id,hint:k}})});if(j.isCancel(b))throw new _;return j.log.message(`\uC120\uD0DD\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4: ${p(b.join(", "))}`),b})(),f=x.filter(b=>h.includes(b.id)),u=f.flatMap(b=>b.items.filter(l=>l.deprecated?a.includeDeprecated:!0).map(l=>`${b.id}:${l.id}`)),$=f.reduce((b,l)=>b+l.items.filter(g=>g.deprecated).length,0);if(!a.includeDeprecated&&$>0&&j.log.info(`${$}\uAC1C\uC758 deprecated \uD56D\uBAA9\uC740 \uC81C\uC678\uB418\uC5C8\uC5B4\uC694. --include-deprecated \uC635\uC158\uC744 \uC0AC\uC6A9\uD558\uBA74 \uCD94\uAC00\uD560 \uC218 \uC788\uC5B4\uC694.`),!u.length)throw new _("\uCD94\uAC00\uD560 \uD56D\uBAA9\uC774 \uC5C6\uC5B4\uC694.");j.log.message(`\uCD1D ${p(u.length.toString())}\uAC1C\uC758 \uD56D\uBAA9\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4.`);let{registryItemsToAdd:O,npmDependenciesToAdd:B}=we({selectedItemKeys:u,publicRegistries:x}),P=pe({publicRegistries:x,itemKeys:O.flatMap(({registryId:b,items:l})=>l.map(g=>`${b}:${g.id}`)),projectPackageVersions:le(a.cwd)});me({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 Ce({registryItemsToAdd:O,rootPath:w,cwd:c,baseUrl:d,config:y,onDiff:a.onDiff});let{installed:M,filtered:L}=await $e({cwd:c,deps:Array.from(B)});M.size===0&&j.log.message("\uBAA8\uB4E0 \uC758\uC874\uC131\uC774 \uC774\uBBF8 \uC124\uCE58\uB418\uC5B4 \uC788\uC5B4\uC694."),M.size&&(j.log.message(`\uC758\uC874\uC131 \uC124\uCE58 \uC644\uB8CC: ${p(Array.from(M).join(", "))}`),L.size&&j.log.message(`\uC124\uCE58\uD558\uC9C0 \uC54A\uC740 \uC758\uC874\uC131 (\uC774\uBBF8 \uC124\uCE58\uB428): ${p(Array.from(L).join(", "))}`)),j.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let W=Date.now()-n;try{await R.trackCommandOutcome(a.cwd,{command:"add-all",status:"completed",properties:{registries:h,items_count:u.length,include_deprecated:a.includeDeprecated||!1,dependencies_count:B.size,duration_ms:W}})}catch(b){o&&console.error("[Telemetry] add-all \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",b)}}catch(i){if(N(i)){try{await R.trackCommandOutcome(s,{command:"add-all",status:"cancelled",properties:{duration_ms:Date.now()-n}})}catch(a){o&&console.error("[Telemetry] add-all \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",a)}j.outro(p(i.message)),process.exit(0)}try{await R.trackCommandFailure(s,{command:"add-all",error:i,properties:{duration_ms:Date.now()-n}})}catch(a){o&&console.error("[Telemetry] add-all \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",a)}G(i,{defaultMessage:"\uCD94\uAC00\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:o}),process.exit(1)}})};import*as U from"@clack/prompts";import tt from"path";import{z as q}from"zod";var ar=q.object({itemIds:q.array(q.string()).optional(),component:q.union([q.string(),q.array(q.string())]).optional(),all:q.boolean(),registry:q.string().optional(),cwd:q.string(),baseUrl:q.string().default(F)});function cr({itemIds:e,component:t}){let r=s=>s.trim().replace(/\s+/g,"-"),n=(e??[]).map(r).filter(Boolean),o=(Array.isArray(t)?t:[t]).filter(s=>!!s).flatMap(s=>s.split(",")).map(r).filter(Boolean);return Array.from(new Set([...n,...o]))}function lr({publicRegistries:e,targetInputs:t,defaultRegistry:r}){let n=e.filter(s=>typeof s.id=="string"&&Array.isArray(s.items)).flatMap(s=>s.items.filter(i=>typeof i.id=="string").map(i=>`${s.id}:${i.id}`)),o=new Set;for(let s of t){let i=s.includes(":")?s:r?`${r}:${s}`:(()=>{let a=n.filter(c=>c.endsWith(`:${s}`));if(!a.length)throw new I({message:`${p(s)}: \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(s)}: \uAC19\uC740 \uC774\uB984\uC758 \uD56D\uBAA9\uC774 \uC5EC\uB7EC \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC788\uC5B4\uC694.`,details:a.map(c=>`- ${c}`),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 rt=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:F}).example("seed-design compat").example("seed-design compat -c action-button").example("seed-design compat ui:action-button ui:alert-dialog").example("seed-design compat --all").action(async(t,r)=>{let n=Date.now(),o=H(r),s=typeof r?.cwd=="string"?r.cwd:process.cwd();U.intro("seed-design compat");try{let i=ar.safeParse({itemIds:t,...r});if(!i.success)throw i.error;let{data:a}=i,{start:c,stop:d}=U.spinner();c("Registry\uB97C \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");let y=await(async()=>{try{let f=await Promise.all((await ie({baseUrl:a.baseUrl})).map(async({id:u})=>ne({baseUrl:a.baseUrl,registryId:u})));return d("Registry\uB97C \uAC00\uC838\uC654\uC5B4\uC694."),f}catch(f){throw d("Registry\uB97C \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),f}})(),w=cr({itemIds:a.itemIds,component:a.component}),C=a.all?y.flatMap(u=>u.items.map($=>`${u.id}:${$.id}`)):w.length>0?lr({publicRegistries:y,targetInputs:w,defaultRegistry:a.registry}):de(a.cwd),E=Array.isArray(C)?C:await(async()=>{let f=await C;if(!f)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 u=tt.resolve(a.cwd,f.path),$=Qe({publicRegistries:y,rootPath:u});return $.length?$:(U.log.info(`${p(tt.relative(a.cwd,u)||f.path)}\uC5D0\uC11C \uC124\uCE58\uB41C \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC5B4\uC694.`),[])})();if(!E.length){try{await R.trackCommandOutcome(a.cwd,{command:"compat",status:"completed",result:"empty",properties:{duration_ms:Date.now()-n}})}catch(f){o&&console.error("[Telemetry] compat \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",f)}U.outro("\uAC80\uC0AC\uD560 \uC2A4\uB2C8\uD3AB\uC774 \uC5C6\uC5B4\uC694."),process.exit(0)}let x=le(a.cwd),h=pe({publicRegistries:y,itemKeys:E,projectPackageVersions:x});if(U.log.info(`\uAC80\uC0AC \uB300\uC0C1: ${p(h.checkedItemKeys.join(", "))}`),!h.issues.length){U.outro("\uBAA8\uB4E0 \uC2A4\uB2C8\uD3AB\uC774 \uD604\uC7AC @seed-design/react, @seed-design/css\uC640 \uD638\uD658\uB3FC\uC694.");try{await R.trackCommandOutcome(a.cwd,{command:"compat",status:"completed",result:"compatible",properties:{checked_items_count:h.checkedItemKeys.length,incompatible_items_count:0,duration_ms:Date.now()-n}})}catch(f){o&&console.error("[Telemetry] compat \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",f)}process.exit(0)}me({report:h,title:"\uD604\uC7AC \uD504\uB85C\uC81D\uD2B8 \uBC84\uC804\uACFC \uD638\uD658\uB418\uC9C0 \uC54A\uB294 \uC2A4\uB2C8\uD3AB\uC744 \uCC3E\uC558\uC5B4\uC694."}),U.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."),U.outro("\uD638\uD658\uC131 \uC774\uC288\uAC00 \uC788\uC5B4\uC694.");try{await R.trackCommandOutcome(a.cwd,{command:"compat",status:"completed",result:"incompatible",properties:{checked_items_count:h.checkedItemKeys.length,incompatible_items_count:new Set(h.issues.map(f=>f.itemKey)).size,issue_count:h.issues.length,duration_ms:Date.now()-n}})}catch(f){o&&console.error("[Telemetry] compat \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",f)}process.exit(1)}catch(i){if(N(i)){try{await R.trackCommandOutcome(s,{command:"compat",status:"cancelled",properties:{duration_ms:Date.now()-n}})}catch(a){o&&console.error("[Telemetry] compat \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",a)}U.outro(p(i.message)),process.exit(0)}try{await R.trackCommandFailure(s,{command:"compat",error:i,properties:{duration_ms:Date.now()-n}})}catch(a){o&&console.error("[Telemetry] compat \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",a)}G(i,{defaultMessage:"\uD638\uD658\uC131 \uAC80\uC0AC\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694.",defaultHint:"`--verbose` \uC635\uC158\uC73C\uB85C \uC0C1\uC138 \uC624\uB958\uB97C \uD655\uC778\uD574\uBCF4\uC138\uC694.",verbose:o}),process.exit(1)}})};import*as v from"@clack/prompts";import{z as Ie}from"zod";var pr="https://raw.githubusercontent.com/daangn/seed-design/refs/heads/dev/docs/registry",mr=Ie.object({query:Ie.string().optional(),baseUrl:Ie.string().optional(),raw:Ie.boolean()});function st(e,t){return`${pr}/${e}/${t}`}function dr(e,t){let r=`${t}${e.docUrl}`,n=`${t}/llms${e.docUrl}.txt`,o=[e.id,`- docs: ${r}`,`- llms.txt: ${n}`];if(e.snippetKey&&e.snippets&&e.snippets.length>0){let[s]=e.snippetKey.split(":");if(s==="ui"||s==="breeze")if(e.snippets.length===1)o.push(`- snippet: ${st(s,e.snippets[0].path)}`);else{o.push("- snippet:");for(let i of e.snippets)o.push(` - ${i.label}: ${st(s,i.path)}`)}}v.log.message(o.join(`
15
+ `))}function fr(e,t){let r=e.length,n=t.length,o=Array.from({length:r+1},(s,i)=>Array.from({length:n+1},(a,c)=>i===0?c:c===0?i:0));for(let s=1;s<=r;s++)for(let i=1;i<=n;i++)o[s][i]=Math.min(o[s-1][i]+1,o[s][i-1]+1,o[s-1][i-1]+(e[s-1]!==t[i-1]?1:0));return o[r][n]}function ee(e,t,r=3){let n=e.toLowerCase();return t.map(o=>({value:o,dist:fr(n,o.toLowerCase())})).filter(({dist:o})=>o>0&&o<=r).sort((o,s)=>o.dist-s.dist).map(({value:o})=>o)}function gr(e,t){if(e.length===0)return;let r=[],n=t.map(i=>i.id),o=ee(e[0],n);if(o.length===0){let i=t.flatMap(d=>d.sections.flatMap(y=>y.items.map(w=>`${d.id}/${y.id}/${w.id}`))),a=e.join("/"),c=ee(a,i,5);c.length>0&&r.push(...c.slice(0,3))}else{let i=t.find(a=>a.id===o[0]);if(i&&e.length>=2){let a=i.sections.map(d=>d.id),c=ee(e[1],a);if(c.length>0){let d=i.sections.find(y=>y.id===c[0]);if(d&&e.length>=3){let y=d.items.map(C=>C.id),w=ee(e[2],y);for(let C of w.slice(0,3))r.push(`${i.id}/${d.id}/${C}`)}else for(let y of c.slice(0,3))r.push(`${i.id}/${y}`)}else{let d=i.sections.flatMap(w=>w.items.map(C=>({path:`${i.id}/${w.id}/${C.id}`,id:C.id}))),y=ee(e[1],d.map(w=>w.id));for(let w of y.slice(0,3)){let C=d.find(E=>E.id===w);C&&r.push(C.path)}}}else for(let a of o.slice(0,3))r.push(a)}if(r.length===0)return;let s=["","\u{1F4A1} \uC774\uAC83\uC744 \uC758\uBBF8\uD588\uB098\uC694?"];for(let i of r)s.push(` - ${i}`);return s.join(`
16
+ `)}function ur(e){return e.split("/").map(t=>t.trim()).filter(Boolean)}function yr(e,t){let r=t.toLowerCase();return e.flatMap(n=>n.sections.flatMap(o=>o.items.filter(s=>s.id.toLowerCase().includes(r)||s.title.toLowerCase().includes(r)).map(s=>({item:s,categoryLabel:n.label,sectionLabel:o.label}))))}async function ge(e){let t=await v.select({message:"\uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(r=>({label:`${r.deprecated?"(deprecated) ":""}${r.title}`,value:r,hint:r.description}))});if(v.isCancel(t))throw new _;return t}async function ot(e){let t=await v.select({message:"\uC139\uC158\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(r=>({label:r.label,value:r,hint:`${r.items.length}\uAC1C \uD56D\uBAA9`}))});if(v.isCancel(t))throw new _;return t}async function hr(e){let t=await v.select({message:"\uCE74\uD14C\uACE0\uB9AC\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694",options:e.map(r=>({label:r.label,value:r,hint:`${r.sections.reduce((n,o)=>n+o.items.length,0)}\uAC1C \uD56D\uBAA9`}))});if(v.isCancel(t))throw new _;return t}var it=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: ${F})`,{default:F}).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,r)=>{let n=Date.now(),o=H(r),s=r.raw??!1,i=process.cwd();s||v.intro("seed-design docs");try{let a=mr.safeParse({query:t,...r});if(!a.success)throw a.error;let{data:c}=a,d=c.baseUrl??F;if(c.raw&&!c.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 y=await(async()=>{if(s)return await Ee({baseUrl:d});let{start:h,stop:f}=v.spinner();h("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uACE0 \uC788\uC5B4\uC694...");try{let u=await Ee({baseUrl:d});return f("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC654\uC5B4\uC694."),u}catch(u){throw f("\uBB38\uC11C \uBAA9\uB85D\uC744 \uAC00\uC838\uC624\uC9C0 \uBABB\uD588\uC5B4\uC694."),u}})(),{categories:w}=y,C,E=async()=>{if(c.query){let u=ur(c.query);if(s&&u.length>3)return;let $=w.find(P=>P.id===u[0]);if($&&u.length>=2){let P=$.sections.find(b=>b.id===u[1]);if(P&&u.length>=3){let b=P.items.find(k=>k.id===u[2]);if(b)return b;let l=u[2].toLowerCase(),g=P.items.filter(k=>k.id.toLowerCase().includes(l)||k.title.toLowerCase().includes(l));if(g.length===0){let k=ee(u[2],P.items.map(D=>D.id)),A=k.length>0?`
17
17
 
18
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?`
19
+ ${k.slice(0,3).map(D=>` - ${$.id}/${P.id}/${D}`).join(`
20
+ `)}`:"";throw new I({message:`${p(c.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.${A}`,hint:`\`seed-design docs ${$.id}/${P.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`})}return g.length===1?g[0]:await ge(g)}if(P)return await ge(P.items);let M=u[1].toLowerCase(),L=$.sections.flatMap(b=>b.items.filter(l=>l.id.toLowerCase().includes(M)||l.title.toLowerCase().includes(M)).map(l=>({item:l,sectionLabel:b.label})));if(L.length===0){let b=$.sections.map(S=>S.id),l=ee(u[1],b),g=$.sections.flatMap(S=>S.items.map(ue=>({path:`${$.id}/${S.id}/${ue.id}`,id:ue.id}))),k=ee(u[1],g.map(S=>S.id)),A=[...l.slice(0,2).map(S=>`${$.id}/${S}`),...k.slice(0,2).map(S=>g.find(ue=>ue.id===S)?.path).filter(S=>S!=null)],D=A.length>0?`
21
21
 
22
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.
23
+ ${A.map(S=>` - ${S}`).join(`
24
+ `)}`:"";throw new I({message:`${p(c.query)}: \uBB38\uC11C\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4\uC694.${D}`,hint:`\`seed-design docs ${$.id}\`\uB85C \uBAA9\uB85D\uC744 \uD655\uC778\uD574\uBCF4\uC138\uC694.`})}if(L.length===1)return L[0].item;let W=await v.select({message:`${p(u[1])}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:L.map(({item:b,sectionLabel:l})=>({label:`[${l}] ${b.title}`,value:b,hint:b.description}))});if(v.isCancel(W))throw new _;return W}if($){if($.sections.length===1)return await ge($.sections[0].items);let P=await ot($.sections);return await ge(P.items)}let O=yr(w,c.query);if(O.length===0){let P=gr(u,w);throw new I({message:`${p(c.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(O.length===1)return O[0].item;let B=await v.select({message:`${p(c.query)}\uC5D0 \uD574\uB2F9\uD558\uB294 \uD56D\uBAA9\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694`,options:O.map(({item:P,categoryLabel:M,sectionLabel:L})=>({label:`[${M} > ${L}] ${P.title}`,value:P,hint:P.description}))});if(v.isCancel(B))throw new _;return B}let h=await hr(w),f;return h.sections.length===1?f=h.sections[0]:f=await ot(h.sections),await ge(f.items)};if(s)try{C=await E()}catch(h){if(N(h))throw h}else C=await E();if(s){let h;if(C){let f=`${d}/llms${C.docUrl}.txt`;h=await Oe({url:f})}else h=await Me({baseUrl:d,query:c.query});console.log(h)}else dr(C,d),v.outro("\uC644\uB8CC\uD588\uC5B4\uC694.");let x=Date.now()-n;try{await R.trackCommandOutcome(i,{command:"docs",status:"completed",properties:{query:c.query??null,item_id:C?.id??c.query??null,has_snippet:!!(C?.snippets&&C.snippets.length>0),raw_mode:s,duration_ms:x}})}catch(h){o&&console.error("[Telemetry] docs \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",h)}}catch(a){if(N(a)){try{await R.trackCommandOutcome(i,{command:"docs",status:"cancelled",properties:{raw_mode:s,duration_ms:Date.now()-n}})}catch(c){o&&console.error("[Telemetry] docs \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",c)}s||v.outro(p(a.message)),process.exit(0)}try{await R.trackCommandFailure(i,{command:"docs",error:a,properties:{raw_mode:s,duration_ms:Date.now()-n}})}catch(c){o&&console.error("[Telemetry] docs \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",c)}if(s){let c=a instanceof Error?a.message:String(a);console.error(c),process.exit(1)}G(a,{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 K from"@clack/prompts";import{z as xe}from"zod";import wr from"dedent";var br=xe.object({cwd:xe.string(),yes:xe.boolean().optional(),default:xe.boolean().optional()}),nt=e=>{e.command("init","seed-design.json \uD30C\uC77C \uC0DD\uC131").option("-c, --cwd <cwd>","\uC791\uC5C5 \uB514\uB809\uD1A0\uB9AC. \uAE30\uBCF8\uAC12\uC740 \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC.",{default:process.cwd()}).option("-y, --yes","\uBAA8\uB4E0 \uC9C8\uBB38\uC5D0 \uB300\uD574 \uAE30\uBCF8\uAC12\uC73C\uB85C \uB2F5\uBCC0\uD569\uB2C8\uB2E4.").option("--default","Deprecated. --yes\uC640 \uB3D9\uC77C\uD558\uAC8C \uAE30\uBCF8\uAC12\uC73C\uB85C \uC0DD\uC131\uD569\uB2C8\uB2E4.").action(async t=>{let r=Date.now(),n=H(t),o=typeof t?.cwd=="string"?t.cwd:process.cwd();K.intro("seed-design.json \uD30C\uC77C \uC0DD\uC131");try{let s=br.safeParse(t);if(!s.success)throw s.error;let i=s.data,a=i.yes||i.default,c=a?z:await Te(),{start:d,stop:y}=K.spinner();d("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC911...");let w=await(async()=>{try{return(await ye({cwd:i.cwd,config:c})).relativePath}catch(E){throw y("seed-design.json \uD30C\uC77C \uC0DD\uC131\uC774 \uC911\uB2E8\uB410\uC5B4\uC694."),E}})();y(`seed-design.json \uD30C\uC77C\uC774 ${p(w)}\uC5D0 \uC0DD\uC131\uB410\uC5B4\uC694.`),K.log.info(p("seed-design add {component} \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD574\uBCF4\uC138\uC694!")),K.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.")),K.note(wr(`SEED Design CLI\uB294 \uAC1C\uC120\uC744 \uC704\uD574 \uC775\uBA85 \uC0AC\uC6A9 \uB370\uC774\uD130\uB97C \uC218\uC9D1\uD574\uC694.
25
25
 
26
26
  \uBE44\uD65C\uC131\uD654\uD558\uB824\uBA74:
27
27
  \u2022 seed-design.json\uC5D0\uC11C ${p('"telemetry": false')}\uB85C \uC124\uC815
28
28
  \u2022 ${p("DISABLE_TELEMETRY=true")} \uD658\uACBD \uBCC0\uC218 \uC124\uC815
29
29
 
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();
30
+ \uC790\uC138\uD55C \uB0B4\uC6A9: https://seed-design.com/react/getting-started/cli/configuration#telemetry`),"Telemetry \uC548\uB0B4"),K.outro("\uC791\uC5C5\uC774 \uC644\uB8CC\uB410\uC5B4\uC694.");let C=Date.now()-r;try{await R.trackCommandOutcome(i.cwd,{command:"init",status:"completed",properties:{tsx:c.tsx,rsc:c.rsc,telemetry:c.telemetry,yes_option:a,duration_ms:C}})}catch(E){n&&console.error("[Telemetry] init \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",E)}}catch(s){if(N(s)){try{await R.trackCommandOutcome(o,{command:"init",status:"cancelled",properties:{duration_ms:Date.now()-r}})}catch(i){n&&console.error("[Telemetry] init \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",i)}K.outro(p(s.message)),process.exit(0)}try{await R.trackCommandFailure(o,{command:"init",error:s,properties:{duration_ms:Date.now()-r}})}catch(i){n&&console.error("[Telemetry] init \uC774\uBCA4\uD2B8 \uC804\uC1A1\uC5D0 \uC2E4\uD328\uD588\uC5B4\uC694:",i)}G(s,{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 Cr}from"cac";var $r="seed-design",X=Cr($r);async function Ir(){let e=ce();X.option("--verbose","\uC624\uB958 \uC0C1\uC138 \uC815\uBCF4\uB97C \uCD9C\uB825\uD569\uB2C8\uB2E4."),Ze(X),et(X),rt(X),it(X),nt(X),X.version(e.version||"1.0.0","-v, --version"),X.help(),X.parse()}Ir();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seed-design/cli",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -45,11 +45,13 @@
45
45
  },
46
46
  "devDependencies": {
47
47
  "@types/babel__core": "^7.20.5",
48
+ "@types/findup-sync": "^4.0.5",
48
49
  "@types/fs-extra": "^11.0.4",
50
+ "@types/node": "^25.0.0",
49
51
  "dotenv": "^17.2.3",
50
52
  "esbuild": "^0.27.0",
51
53
  "type-fest": "^5.0.0",
52
- "typescript": "^5.9.2"
54
+ "typescript": "^6.0.0"
53
55
  },
54
56
  "publishConfig": {
55
57
  "access": "public"
@@ -29,7 +29,7 @@ const addAllOptionsSchema = z.object({
29
29
  all: z.boolean(),
30
30
  includeDeprecated: z.boolean().optional(),
31
31
  cwd: z.string(),
32
- baseUrl: z.string().optional(),
32
+ baseUrl: z.string().default(BASE_URL),
33
33
  onDiff: z.enum(["overwrite", "backup"]).optional(),
34
34
  });
35
35
 
@@ -56,6 +56,7 @@ export const addAllCommand = (cli: CAC) => {
56
56
  .action(async (registryIds, opts) => {
57
57
  const startTime = Date.now();
58
58
  const verbose = isVerboseMode(opts);
59
+ const trackCwd = typeof opts?.cwd === "string" ? opts.cwd : process.cwd();
59
60
  p.intro("seed-design add-all");
60
61
 
61
62
  try {
@@ -227,8 +228,9 @@ export const addAllCommand = (cli: CAC) => {
227
228
  // add-all 성공 이벤트 추적
228
229
  const duration = Date.now() - startTime;
229
230
  try {
230
- await analytics.track(options.cwd, {
231
- event: "add-all",
231
+ await analytics.trackCommandOutcome(options.cwd, {
232
+ command: "add-all",
233
+ status: "completed",
232
234
  properties: {
233
235
  registries: selectedRegistryIds,
234
236
  items_count: itemKeys.length,
@@ -239,15 +241,42 @@ export const addAllCommand = (cli: CAC) => {
239
241
  });
240
242
  } catch (telemetryError) {
241
243
  if (verbose) {
242
- console.error("[Telemetry] add-all tracking failed:", telemetryError);
244
+ console.error("[Telemetry] add-all 이벤트 전송에 실패했어요:", telemetryError);
243
245
  }
244
246
  }
245
247
  } catch (error) {
246
248
  if (isCliCancelError(error)) {
249
+ try {
250
+ await analytics.trackCommandOutcome(trackCwd, {
251
+ command: "add-all",
252
+ status: "cancelled",
253
+ properties: {
254
+ duration_ms: Date.now() - startTime,
255
+ },
256
+ });
257
+ } catch (telemetryError) {
258
+ if (verbose) {
259
+ console.error("[Telemetry] add-all 이벤트 전송에 실패했어요:", telemetryError);
260
+ }
261
+ }
247
262
  p.outro(highlight(error.message));
248
263
  process.exit(0);
249
264
  }
250
265
 
266
+ try {
267
+ await analytics.trackCommandFailure(trackCwd, {
268
+ command: "add-all",
269
+ error,
270
+ properties: {
271
+ duration_ms: Date.now() - startTime,
272
+ },
273
+ });
274
+ } catch (telemetryError) {
275
+ if (verbose) {
276
+ console.error("[Telemetry] add-all 이벤트 전송에 실패했어요:", telemetryError);
277
+ }
278
+ }
279
+
251
280
  handleCliError(error, {
252
281
  defaultMessage: "추가에 실패했어요.",
253
282
  defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
@@ -31,7 +31,7 @@ const addOptionsSchema = z.object({
31
31
  */
32
32
  all: z.boolean(),
33
33
  cwd: z.string(),
34
- baseUrl: z.string().optional(),
34
+ baseUrl: z.string().default(BASE_URL),
35
35
  onDiff: z.enum(["overwrite", "backup"]).optional(),
36
36
  });
37
37
 
@@ -55,6 +55,7 @@ export const addCommand = (cli: CAC) => {
55
55
  .action(async (itemIds, opts) => {
56
56
  const startTime = Date.now();
57
57
  const verbose = isVerboseMode(opts);
58
+ const trackCwd = typeof opts?.cwd === "string" ? opts.cwd : process.cwd();
58
59
  p.intro("seed-design add");
59
60
 
60
61
  try {
@@ -248,8 +249,9 @@ export const addCommand = (cli: CAC) => {
248
249
  });
249
250
 
250
251
  try {
251
- await analytics.track(options.cwd, {
252
- event: "add",
252
+ await analytics.trackCommandOutcome(options.cwd, {
253
+ command: "add",
254
+ status: "completed",
253
255
  properties: {
254
256
  items_count: filteredItemKeys.length,
255
257
  registries: Array.from(uniqueRegistries),
@@ -260,15 +262,42 @@ export const addCommand = (cli: CAC) => {
260
262
  });
261
263
  } catch (telemetryError) {
262
264
  if (verbose) {
263
- console.error("[Telemetry] add tracking failed:", telemetryError);
265
+ console.error("[Telemetry] add 이벤트 전송에 실패했어요:", telemetryError);
264
266
  }
265
267
  }
266
268
  } catch (error) {
267
269
  if (isCliCancelError(error)) {
270
+ try {
271
+ await analytics.trackCommandOutcome(trackCwd, {
272
+ command: "add",
273
+ status: "cancelled",
274
+ properties: {
275
+ duration_ms: Date.now() - startTime,
276
+ },
277
+ });
278
+ } catch (telemetryError) {
279
+ if (verbose) {
280
+ console.error("[Telemetry] add 이벤트 전송에 실패했어요:", telemetryError);
281
+ }
282
+ }
268
283
  p.outro(highlight(error.message));
269
284
  process.exit(0);
270
285
  }
271
286
 
287
+ try {
288
+ await analytics.trackCommandFailure(trackCwd, {
289
+ command: "add",
290
+ error,
291
+ properties: {
292
+ duration_ms: Date.now() - startTime,
293
+ },
294
+ });
295
+ } catch (telemetryError) {
296
+ if (verbose) {
297
+ console.error("[Telemetry] add 이벤트 전송에 실패했어요:", telemetryError);
298
+ }
299
+ }
300
+
272
301
  handleCliError(error, {
273
302
  defaultMessage: "추가에 실패했어요.",
274
303
  defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
@@ -22,7 +22,7 @@ const compatOptionsSchema = z.object({
22
22
  all: z.boolean(),
23
23
  registry: z.string().optional(),
24
24
  cwd: z.string(),
25
- baseUrl: z.string().optional(),
25
+ baseUrl: z.string().default(BASE_URL),
26
26
  });
27
27
 
28
28
  function parseTargetInputs({
@@ -123,6 +123,7 @@ export const compatCommand = (cli: CAC) => {
123
123
  .action(async (itemIds, opts) => {
124
124
  const startTime = Date.now();
125
125
  const verbose = isVerboseMode(opts);
126
+ const trackCwd = typeof opts?.cwd === "string" ? opts.cwd : process.cwd();
126
127
  p.intro("seed-design compat");
127
128
 
128
129
  try {
@@ -202,6 +203,20 @@ export const compatCommand = (cli: CAC) => {
202
203
  })();
203
204
 
204
205
  if (!resolvedTargetItemKeys.length) {
206
+ try {
207
+ await analytics.trackCommandOutcome(options.cwd, {
208
+ command: "compat",
209
+ status: "completed",
210
+ result: "empty",
211
+ properties: {
212
+ duration_ms: Date.now() - startTime,
213
+ },
214
+ });
215
+ } catch (telemetryError) {
216
+ if (verbose) {
217
+ console.error("[Telemetry] compat 이벤트 전송에 실패했어요:", telemetryError);
218
+ }
219
+ }
205
220
  p.outro("검사할 스니펫이 없어요.");
206
221
  process.exit(0);
207
222
  }
@@ -219,8 +234,10 @@ export const compatCommand = (cli: CAC) => {
219
234
  p.outro("모든 스니펫이 현재 @seed-design/react, @seed-design/css와 호환돼요.");
220
235
 
221
236
  try {
222
- await analytics.track(options.cwd, {
223
- event: "compat",
237
+ await analytics.trackCommandOutcome(options.cwd, {
238
+ command: "compat",
239
+ status: "completed",
240
+ result: "compatible",
224
241
  properties: {
225
242
  checked_items_count: compatibilityReport.checkedItemKeys.length,
226
243
  incompatible_items_count: 0,
@@ -229,7 +246,7 @@ export const compatCommand = (cli: CAC) => {
229
246
  });
230
247
  } catch (telemetryError) {
231
248
  if (verbose) {
232
- console.error("[Telemetry] compat tracking failed:", telemetryError);
249
+ console.error("[Telemetry] compat 이벤트 전송에 실패했어요:", telemetryError);
233
250
  }
234
251
  }
235
252
 
@@ -246,8 +263,10 @@ export const compatCommand = (cli: CAC) => {
246
263
  p.outro("호환성 이슈가 있어요.");
247
264
 
248
265
  try {
249
- await analytics.track(options.cwd, {
250
- event: "compat",
266
+ await analytics.trackCommandOutcome(options.cwd, {
267
+ command: "compat",
268
+ status: "completed",
269
+ result: "incompatible",
251
270
  properties: {
252
271
  checked_items_count: compatibilityReport.checkedItemKeys.length,
253
272
  incompatible_items_count: new Set(
@@ -259,17 +278,44 @@ export const compatCommand = (cli: CAC) => {
259
278
  });
260
279
  } catch (telemetryError) {
261
280
  if (verbose) {
262
- console.error("[Telemetry] compat tracking failed:", telemetryError);
281
+ console.error("[Telemetry] compat 이벤트 전송에 실패했어요:", telemetryError);
263
282
  }
264
283
  }
265
284
 
266
285
  process.exit(1);
267
286
  } catch (error) {
268
287
  if (isCliCancelError(error)) {
288
+ try {
289
+ await analytics.trackCommandOutcome(trackCwd, {
290
+ command: "compat",
291
+ status: "cancelled",
292
+ properties: {
293
+ duration_ms: Date.now() - startTime,
294
+ },
295
+ });
296
+ } catch (telemetryError) {
297
+ if (verbose) {
298
+ console.error("[Telemetry] compat 이벤트 전송에 실패했어요:", telemetryError);
299
+ }
300
+ }
269
301
  p.outro(highlight(error.message));
270
302
  process.exit(0);
271
303
  }
272
304
 
305
+ try {
306
+ await analytics.trackCommandFailure(trackCwd, {
307
+ command: "compat",
308
+ error,
309
+ properties: {
310
+ duration_ms: Date.now() - startTime,
311
+ },
312
+ });
313
+ } catch (telemetryError) {
314
+ if (verbose) {
315
+ console.error("[Telemetry] compat 이벤트 전송에 실패했어요:", telemetryError);
316
+ }
317
+ }
318
+
273
319
  handleCliError(error, {
274
320
  defaultMessage: "호환성 검사에 실패했어요.",
275
321
  defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
@@ -246,6 +246,7 @@ export const docsCommand = (cli: CAC) => {
246
246
  const startTime = Date.now();
247
247
  const verbose = isVerboseMode(opts);
248
248
  const raw = opts.raw ?? false;
249
+ const trackCwd = process.cwd();
249
250
 
250
251
  if (!raw) p.intro("seed-design docs");
251
252
 
@@ -465,26 +466,57 @@ export const docsCommand = (cli: CAC) => {
465
466
 
466
467
  const duration = Date.now() - startTime;
467
468
  try {
468
- await analytics.track(process.cwd(), {
469
- event: "docs",
469
+ await analytics.trackCommandOutcome(trackCwd, {
470
+ command: "docs",
471
+ status: "completed",
470
472
  properties: {
471
473
  query: options.query ?? null,
472
474
  item_id: selectedItem?.id ?? options.query ?? null,
473
475
  has_snippet: !!(selectedItem?.snippets && selectedItem.snippets.length > 0),
476
+ raw_mode: raw,
474
477
  duration_ms: duration,
475
478
  },
476
479
  });
477
480
  } catch (telemetryError) {
478
481
  if (verbose) {
479
- console.error("[Telemetry] docs tracking failed:", telemetryError);
482
+ console.error("[Telemetry] docs 이벤트 전송에 실패했어요:", telemetryError);
480
483
  }
481
484
  }
482
485
  } catch (error) {
483
486
  if (isCliCancelError(error)) {
487
+ try {
488
+ await analytics.trackCommandOutcome(trackCwd, {
489
+ command: "docs",
490
+ status: "cancelled",
491
+ properties: {
492
+ raw_mode: raw,
493
+ duration_ms: Date.now() - startTime,
494
+ },
495
+ });
496
+ } catch (telemetryError) {
497
+ if (verbose) {
498
+ console.error("[Telemetry] docs 이벤트 전송에 실패했어요:", telemetryError);
499
+ }
500
+ }
484
501
  if (!raw) p.outro(highlight(error.message));
485
502
  process.exit(0);
486
503
  }
487
504
 
505
+ try {
506
+ await analytics.trackCommandFailure(trackCwd, {
507
+ command: "docs",
508
+ error,
509
+ properties: {
510
+ raw_mode: raw,
511
+ duration_ms: Date.now() - startTime,
512
+ },
513
+ });
514
+ } catch (telemetryError) {
515
+ if (verbose) {
516
+ console.error("[Telemetry] docs 이벤트 전송에 실패했어요:", telemetryError);
517
+ }
518
+ }
519
+
488
520
  if (raw) {
489
521
  const msg = error instanceof Error ? error.message : String(error);
490
522
  console.error(msg);
@@ -27,6 +27,7 @@ export const initCommand = (cli: CAC) => {
27
27
  .action(async (opts) => {
28
28
  const startTime = Date.now();
29
29
  const verbose = isVerboseMode(opts);
30
+ const trackCwd = typeof opts?.cwd === "string" ? opts.cwd : process.cwd();
30
31
  p.intro("seed-design.json 파일 생성");
31
32
 
32
33
  try {
@@ -78,8 +79,9 @@ export const initCommand = (cli: CAC) => {
78
79
  // init 성공 이벤트 추적
79
80
  const duration = Date.now() - startTime;
80
81
  try {
81
- await analytics.track(options.cwd, {
82
- event: "init",
82
+ await analytics.trackCommandOutcome(options.cwd, {
83
+ command: "init",
84
+ status: "completed",
83
85
  properties: {
84
86
  tsx: config.tsx,
85
87
  rsc: config.rsc,
@@ -90,15 +92,42 @@ export const initCommand = (cli: CAC) => {
90
92
  });
91
93
  } catch (telemetryError) {
92
94
  if (verbose) {
93
- console.error("[Telemetry] init tracking failed:", telemetryError);
95
+ console.error("[Telemetry] init 이벤트 전송에 실패했어요:", telemetryError);
94
96
  }
95
97
  }
96
98
  } catch (error) {
97
99
  if (isCliCancelError(error)) {
100
+ try {
101
+ await analytics.trackCommandOutcome(trackCwd, {
102
+ command: "init",
103
+ status: "cancelled",
104
+ properties: {
105
+ duration_ms: Date.now() - startTime,
106
+ },
107
+ });
108
+ } catch (telemetryError) {
109
+ if (verbose) {
110
+ console.error("[Telemetry] init 이벤트 전송에 실패했어요:", telemetryError);
111
+ }
112
+ }
98
113
  p.outro(highlight(error.message));
99
114
  process.exit(0);
100
115
  }
101
116
 
117
+ try {
118
+ await analytics.trackCommandFailure(trackCwd, {
119
+ command: "init",
120
+ error,
121
+ properties: {
122
+ duration_ms: Date.now() - startTime,
123
+ },
124
+ });
125
+ } catch (telemetryError) {
126
+ if (verbose) {
127
+ console.error("[Telemetry] init 이벤트 전송에 실패했어요:", telemetryError);
128
+ }
129
+ }
130
+
102
131
  handleCliError(error, {
103
132
  defaultMessage: "seed-design.json 파일 생성에 실패했어요.",
104
133
  defaultHint: "`--verbose` 옵션으로 상세 오류를 확인해보세요.",
@@ -0,0 +1,95 @@
1
+ import { afterEach, beforeEach, describe, expect, it, mock, spyOn } from "bun:test";
2
+ import fs from "fs-extra";
3
+ import os from "os";
4
+ import path from "path";
5
+ import * as prompts from "@clack/prompts";
6
+ import { analytics } from "../utils/analytics";
7
+
8
+ describe("analytics command outcome tracking", () => {
9
+ const originalEnv = { ...process.env };
10
+ const tempDirs: string[] = [];
11
+
12
+ beforeEach(() => {
13
+ process.env.NODE_ENV = "prod";
14
+ process.env.POSTHOG_API_KEY = "test-api-key";
15
+ process.env.POSTHOG_HOST = "https://us.i.posthog.com";
16
+ delete process.env.DISABLE_TELEMETRY;
17
+ delete process.env.SEED_DISABLE_TELEMETRY;
18
+ });
19
+
20
+ afterEach(async () => {
21
+ process.env = { ...originalEnv };
22
+ mock.restore();
23
+
24
+ while (tempDirs.length > 0) {
25
+ const dir = tempDirs.pop();
26
+ if (dir) {
27
+ await fs.remove(dir);
28
+ }
29
+ }
30
+ });
31
+
32
+ async function createTempCwd() {
33
+ const cwd = await fs.mkdtemp(path.join(os.tmpdir(), "seed-cli-analytics-"));
34
+ tempDirs.push(cwd);
35
+ return cwd;
36
+ }
37
+
38
+ it("command outcome payload에 status를 포함해야 한다", async () => {
39
+ const cwd = await createTempCwd();
40
+ const fetchSpy = spyOn(globalThis, "fetch").mockResolvedValue(
41
+ new Response(null, { status: 200 }),
42
+ );
43
+ const infoSpy = spyOn(prompts.log, "info").mockImplementation(() => {});
44
+
45
+ await analytics.trackCommandOutcome(cwd, {
46
+ command: "add",
47
+ status: "completed",
48
+ properties: {
49
+ items_count: 2,
50
+ },
51
+ });
52
+
53
+ expect(fetchSpy).toHaveBeenCalledTimes(1);
54
+ expect(infoSpy).toHaveBeenCalled();
55
+
56
+ const [, request] = fetchSpy.mock.calls[0] ?? [];
57
+ const payload = JSON.parse(String(request?.body));
58
+
59
+ expect(payload.event).toBe("seed_cli.add");
60
+ expect(payload.properties).toMatchObject({
61
+ status: "completed",
62
+ items_count: 2,
63
+ $process_person_profile: false,
64
+ });
65
+ });
66
+
67
+ it("failed outcome payload에는 error_type만 포함하고 message는 포함하지 않아야 한다", async () => {
68
+ const cwd = await createTempCwd();
69
+ const fetchSpy = spyOn(globalThis, "fetch").mockResolvedValue(
70
+ new Response(null, { status: 200 }),
71
+ );
72
+ spyOn(prompts.log, "info").mockImplementation(() => {});
73
+
74
+ await analytics.trackCommandFailure(cwd, {
75
+ command: "docs",
76
+ error: new Error("sensitive details"),
77
+ properties: {
78
+ raw_mode: true,
79
+ },
80
+ });
81
+
82
+ expect(fetchSpy).toHaveBeenCalledTimes(1);
83
+
84
+ const [, request] = fetchSpy.mock.calls[0] ?? [];
85
+ const payload = JSON.parse(String(request?.body));
86
+
87
+ expect(payload.event).toBe("seed_cli.docs");
88
+ expect(payload.properties).toMatchObject({
89
+ status: "failed",
90
+ error_type: "Error",
91
+ raw_mode: true,
92
+ });
93
+ expect(payload.properties.error_message).toBeUndefined();
94
+ });
95
+ });
@@ -0,0 +1,195 @@
1
+ import { beforeEach, describe, expect, it, mock, spyOn } from "bun:test";
2
+ import type { CAC } from "cac";
3
+ import { cac } from "cac";
4
+ import { CliCancelError } from "../utils/error";
5
+ import { analytics } from "../utils/analytics";
6
+
7
+ const introMock = mock(() => {});
8
+ const outroMock = mock(() => {});
9
+ const infoMock = mock(() => {});
10
+ const messageMock = mock(() => {});
11
+ const errorMock = mock(() => {});
12
+ const noteMock = mock(() => {});
13
+ const spinnerStartMock = mock(() => {});
14
+ const spinnerStopMock = mock(() => {});
15
+ const promptInitConfigMock = mock(async () => ({
16
+ tsx: true,
17
+ rsc: false,
18
+ path: "./seed-design",
19
+ telemetry: true,
20
+ }));
21
+ const writeInitConfigFileMock = mock(async () => ({
22
+ relativePath: "seed-design.json",
23
+ }));
24
+
25
+ mock.module("@clack/prompts", () => ({
26
+ intro: introMock,
27
+ outro: outroMock,
28
+ note: noteMock,
29
+ log: {
30
+ info: infoMock,
31
+ message: messageMock,
32
+ error: errorMock,
33
+ },
34
+ spinner: () => ({
35
+ start: spinnerStartMock,
36
+ stop: spinnerStopMock,
37
+ }),
38
+ isCancel: () => false,
39
+ }));
40
+
41
+ mock.module("../utils/init-config", () => ({
42
+ DEFAULT_INIT_CONFIG: {
43
+ tsx: true,
44
+ rsc: false,
45
+ path: "./seed-design",
46
+ telemetry: true,
47
+ },
48
+ promptInitConfig: promptInitConfigMock,
49
+ writeInitConfigFile: writeInitConfigFileMock,
50
+ }));
51
+
52
+ const { addCommand } = await import("../commands/add");
53
+ const { initCommand } = await import("../commands/init");
54
+
55
+ function assertHasCommandAction<T extends { commandAction?: unknown }>(
56
+ command: T,
57
+ name: string,
58
+ ): asserts command is T & { commandAction: NonNullable<T["commandAction"]> } {
59
+ if (!command.commandAction) {
60
+ throw new Error(`Command has no action handler: ${name}`);
61
+ }
62
+ }
63
+
64
+ function getCommand(cli: CAC, name: string) {
65
+ const command = cli.commands.find((item) => item.name === name);
66
+
67
+ if (!command) {
68
+ throw new Error(`Command not found: ${name}`);
69
+ }
70
+
71
+ assertHasCommandAction(command, name);
72
+ return command;
73
+ }
74
+
75
+ describe("command telemetry", () => {
76
+ beforeEach(() => {
77
+ introMock.mockClear();
78
+ outroMock.mockClear();
79
+ infoMock.mockClear();
80
+ messageMock.mockClear();
81
+ errorMock.mockClear();
82
+ noteMock.mockClear();
83
+ spinnerStartMock.mockClear();
84
+ spinnerStopMock.mockClear();
85
+ promptInitConfigMock.mockClear();
86
+ writeInitConfigFileMock.mockClear();
87
+ });
88
+
89
+ it("init 성공 시 completed outcome을 전송해야 한다", async () => {
90
+ const trackCommandOutcomeSpy = spyOn(analytics, "trackCommandOutcome").mockImplementation(
91
+ async () => {},
92
+ );
93
+ const trackCommandFailureSpy = spyOn(analytics, "trackCommandFailure").mockImplementation(
94
+ async () => {},
95
+ );
96
+ const cli = cac("seed-design");
97
+ initCommand(cli);
98
+
99
+ await getCommand(cli, "init").commandAction({
100
+ cwd: "/tmp/seed-design",
101
+ yes: true,
102
+ default: false,
103
+ });
104
+
105
+ expect(writeInitConfigFileMock).toHaveBeenCalledTimes(1);
106
+ expect(trackCommandOutcomeSpy).toHaveBeenCalledWith(
107
+ "/tmp/seed-design",
108
+ expect.objectContaining({
109
+ command: "init",
110
+ status: "completed",
111
+ properties: expect.objectContaining({
112
+ yes_option: true,
113
+ telemetry: true,
114
+ }),
115
+ }),
116
+ );
117
+ expect(trackCommandFailureSpy).not.toHaveBeenCalled();
118
+
119
+ trackCommandOutcomeSpy.mockRestore();
120
+ trackCommandFailureSpy.mockRestore();
121
+ });
122
+
123
+ it("init 취소 시 cancelled outcome을 전송해야 한다", async () => {
124
+ const trackCommandOutcomeSpy = spyOn(analytics, "trackCommandOutcome").mockImplementation(
125
+ async () => {},
126
+ );
127
+ const trackCommandFailureSpy = spyOn(analytics, "trackCommandFailure").mockImplementation(
128
+ async () => {},
129
+ );
130
+ promptInitConfigMock.mockImplementationOnce(async () => {
131
+ throw new CliCancelError("작업이 취소됐어요.");
132
+ });
133
+
134
+ const exitSpy = spyOn(process, "exit").mockImplementation(((code?: number) => {
135
+ throw new Error(`EXIT:${code}`);
136
+ }) as never);
137
+
138
+ const cli = cac("seed-design");
139
+ initCommand(cli);
140
+
141
+ await expect(
142
+ getCommand(cli, "init").commandAction({
143
+ cwd: "/tmp/seed-design",
144
+ yes: false,
145
+ default: false,
146
+ }),
147
+ ).rejects.toThrow("EXIT:0");
148
+
149
+ expect(trackCommandOutcomeSpy).toHaveBeenCalledWith(
150
+ "/tmp/seed-design",
151
+ expect.objectContaining({
152
+ command: "init",
153
+ status: "cancelled",
154
+ }),
155
+ );
156
+ expect(trackCommandFailureSpy).not.toHaveBeenCalled();
157
+
158
+ exitSpy.mockRestore();
159
+ trackCommandOutcomeSpy.mockRestore();
160
+ trackCommandFailureSpy.mockRestore();
161
+ });
162
+
163
+ it("add 실패 시 failed outcome을 전송해야 한다", async () => {
164
+ const trackCommandFailureSpy = spyOn(analytics, "trackCommandFailure").mockImplementation(
165
+ async () => {},
166
+ );
167
+ const exitSpy = spyOn(process, "exit").mockImplementation(((code?: number) => {
168
+ throw new Error(`EXIT:${code}`);
169
+ }) as never);
170
+
171
+ const cli = cac("seed-design");
172
+ addCommand(cli);
173
+
174
+ await expect(
175
+ getCommand(cli, "add").commandAction([], {
176
+ all: true,
177
+ cwd: "/tmp/seed-design",
178
+ baseUrl: "https://seed-design.io",
179
+ }),
180
+ ).rejects.toThrow("EXIT:1");
181
+
182
+ expect(trackCommandFailureSpy).toHaveBeenCalledWith(
183
+ "/tmp/seed-design",
184
+ expect.objectContaining({
185
+ command: "add",
186
+ error: expect.objectContaining({
187
+ name: "CliError",
188
+ }),
189
+ }),
190
+ );
191
+
192
+ exitSpy.mockRestore();
193
+ trackCommandFailureSpy.mockRestore();
194
+ });
195
+ });
@@ -0,0 +1,11 @@
1
+ declare module "@babel/plugin-transform-typescript";
2
+
3
+ declare module "@npmcli/disparity-colors" {
4
+ /**
5
+ * Colorizes unified diff output with ANSI escape codes.
6
+ *
7
+ * @param str - A unified diff format string.
8
+ * @param opts.headerLength - Number of lines at the start of the diff to colorize as header.
9
+ */
10
+ export default function colorize(str: string, opts?: { headerLength?: number }): string;
11
+ }
@@ -3,12 +3,27 @@ import * as p from "@clack/prompts";
3
3
  import { getRawConfig } from "./get-config";
4
4
 
5
5
  const EVENT_PREFIX = "seed_cli";
6
+ const COMMAND_STATUSES = ["completed", "cancelled", "failed"] as const;
6
7
 
7
8
  interface TrackOptions {
8
9
  event: string;
9
10
  properties?: Record<string, unknown>;
10
11
  }
11
12
 
13
+ interface TrackCommandOutcomeOptions {
14
+ command: string;
15
+ status: (typeof COMMAND_STATUSES)[number];
16
+ result?: string;
17
+ properties?: Record<string, unknown>;
18
+ }
19
+
20
+ interface TrackCommandFailureOptions {
21
+ command: string;
22
+ error: unknown;
23
+ result?: string;
24
+ properties?: Record<string, unknown>;
25
+ }
26
+
12
27
  /**
13
28
  * 텔레메트리 활성화 여부를 확인합니다.
14
29
  * 우선순위:
@@ -48,6 +63,24 @@ const sessionId = generateSessionId();
48
63
  // 세션당 한 번만 메시지 표시
49
64
  let hasShownMessage = false;
50
65
 
66
+ function omitUndefined(properties: Record<string, unknown>): Record<string, unknown> {
67
+ return Object.fromEntries(
68
+ Object.entries(properties).filter(([, value]) => value !== undefined),
69
+ );
70
+ }
71
+
72
+ function getSafeErrorType(error: unknown): string {
73
+ if (error instanceof Error && error.name) {
74
+ return error.name;
75
+ }
76
+
77
+ if (typeof error === "object" && error !== null) {
78
+ return error.constructor?.name ?? "Object";
79
+ }
80
+
81
+ return typeof error;
82
+ }
83
+
51
84
  /**
52
85
  * PostHog에 이벤트를 전송합니다.
53
86
  */
@@ -76,7 +109,7 @@ async function track(cwd: string, { event, properties = {} }: TrackOptions): Pro
76
109
  // PostHog API 호출 (fire-and-forget)
77
110
  try {
78
111
  if (!process.env.POSTHOG_HOST || !process.env.POSTHOG_API_KEY) {
79
- console.warn("[Analytics] Missing POSTHOG_HOST or POSTHOG_API_KEY");
112
+ console.error("[Telemetry] POSTHOG_HOST 또는 POSTHOG_API_KEY가 없어서 이벤트를 전송하지 않아요.");
80
113
  return;
81
114
  }
82
115
 
@@ -113,6 +146,37 @@ async function track(cwd: string, { event, properties = {} }: TrackOptions): Pro
113
146
  }
114
147
  }
115
148
 
149
+ async function trackCommandOutcome(
150
+ cwd: string,
151
+ { command, status, result, properties = {} }: TrackCommandOutcomeOptions,
152
+ ): Promise<void> {
153
+ await track(cwd, {
154
+ event: command,
155
+ properties: omitUndefined({
156
+ status,
157
+ result,
158
+ ...properties,
159
+ }),
160
+ });
161
+ }
162
+
163
+ async function trackCommandFailure(
164
+ cwd: string,
165
+ { command, error, result, properties = {} }: TrackCommandFailureOptions,
166
+ ): Promise<void> {
167
+ await trackCommandOutcome(cwd, {
168
+ command,
169
+ status: "failed",
170
+ result,
171
+ properties: omitUndefined({
172
+ error_type: getSafeErrorType(error),
173
+ ...properties,
174
+ }),
175
+ });
176
+ }
177
+
116
178
  export const analytics = {
117
179
  track,
180
+ trackCommandFailure,
181
+ trackCommandOutcome,
118
182
  };
@@ -31,7 +31,7 @@ export async function installDependencies({ cwd, deps, dev = false }: InstallDep
31
31
 
32
32
  const isDev = dev ? "-D" : null;
33
33
  const addCommand = packageManager === "npm" ? "install" : "add";
34
- const command = [addCommand, isDev, ...depsToInstall].filter(Boolean);
34
+ const command = [addCommand, isDev, ...depsToInstall].filter((v): v is string => Boolean(v));
35
35
  const commandLabel = `${packageManager} ${command.join(" ")}`;
36
36
 
37
37
  try {
@@ -1,4 +1,4 @@
1
- import type { PublicRegistry, PublicRegistryItem } from "@/src/schema";
1
+ import type { PublicRegistry } from "@/src/schema";
2
2
 
3
3
  export function resolveDependencies({
4
4
  selectedItemKeys,
@@ -13,7 +13,7 @@ export function resolveDependencies({
13
13
  const registryItemsToAdd: { registryId: string; items: PublicRegistry["items"] }[] = [];
14
14
  const npmDependenciesToAdd = new Set<string>();
15
15
 
16
- function collectRegistryItemsToAdd(registryId: string, item: PublicRegistryItem) {
16
+ function collectRegistryItemsToAdd(registryId: string, item: PublicRegistry["items"][number]) {
17
17
  const registryFoundToAdd = registryItemsToAdd.find((r) => r.registryId === registryId);
18
18
 
19
19
  // if already added, skip