create-lexy 0.3.0 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@
9
9
  "class-variance-authority"
10
10
  ],
11
11
  "registryDependencies": [
12
- "button"
12
+ "@lexy/button"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -6,7 +6,7 @@
6
6
  "description": "Acordeón de aplicación **data-driven**. Describe los items como datos (`items`)",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
- "accordion"
9
+ "@lexy/accordion"
10
10
  ],
11
11
  "files": [
12
12
  {
@@ -6,8 +6,8 @@
6
6
  "description": "Diálogo de aplicación al estilo **Material 3**. Estructura canónica sin dividers: El componente vive en tu proyecto: instálalo con `create-lexy add app-dialog` y edítalo con libertad.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
- "button",
10
- "dialog"
9
+ "@lexy/button",
10
+ "@lexy/dialog"
11
11
  ],
12
12
  "files": [
13
13
  {
@@ -8,9 +8,9 @@
8
8
  "class-variance-authority"
9
9
  ],
10
10
  "registryDependencies": [
11
- "button",
12
- "header-bar",
13
- "logo"
11
+ "@lexy/button",
12
+ "@lexy/header-bar",
13
+ "@lexy/logo"
14
14
  ],
15
15
  "files": [
16
16
  {
@@ -8,8 +8,8 @@
8
8
  "lucide-react"
9
9
  ],
10
10
  "registryDependencies": [
11
- "avatar",
12
- "sidebar"
11
+ "@lexy/avatar",
12
+ "@lexy/sidebar"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -9,7 +9,7 @@
9
9
  "class-variance-authority"
10
10
  ],
11
11
  "registryDependencies": [
12
- "separator"
12
+ "@lexy/separator"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -9,7 +9,7 @@
9
9
  "react-day-picker@^9.8.0"
10
10
  ],
11
11
  "registryDependencies": [
12
- "button"
12
+ "@lexy/button"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -6,9 +6,9 @@
6
6
  "description": "Campo de entrada con lista desplegable filtrable. Para búsqueda + selección. El componente vive en tu proyecto: instálalo con `create-lexy add combobox` y edítalo con libertad.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
- "button",
10
- "command",
11
- "popover"
9
+ "@lexy/button",
10
+ "@lexy/command",
11
+ "@lexy/popover"
12
12
  ],
13
13
  "files": [
14
14
  {
@@ -8,7 +8,7 @@
8
8
  "lucide-react"
9
9
  ],
10
10
  "registryDependencies": [
11
- "button"
11
+ "@lexy/button"
12
12
  ],
13
13
  "files": [
14
14
  {
@@ -8,9 +8,9 @@
8
8
  "lucide-react"
9
9
  ],
10
10
  "registryDependencies": [
11
- "app-sidebar",
12
- "logo",
13
- "sidebar"
11
+ "@lexy/app-sidebar",
12
+ "@lexy/logo",
13
+ "@lexy/sidebar"
14
14
  ],
15
15
  "files": [
16
16
  {
@@ -8,11 +8,11 @@
8
8
  "lucide-react"
9
9
  ],
10
10
  "registryDependencies": [
11
- "button",
12
- "input",
13
- "pagination",
14
- "status-dot",
15
- "table"
11
+ "@lexy/button",
12
+ "@lexy/input",
13
+ "@lexy/pagination",
14
+ "@lexy/status-dot",
15
+ "@lexy/table"
16
16
  ],
17
17
  "files": [
18
18
  {
@@ -6,10 +6,10 @@
6
6
  "description": "Detalle master-detail para **CRM**: contexto del caso a la izquierda (panel fijo de 288px), trabajo al centro en tabs, acción primaria a la mano. La información que se consulta junta vive junta. Instálalo con `create-lexy add crm-detalle-caso` — trae `Tabs`, `Tag`, `Separator` y `Button`. La vista queda en tu proyecto (`views/CasoDetalle.tsx`): edítala con libertad.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
- "button",
10
- "separator",
11
- "tabs",
12
- "tag"
9
+ "@lexy/button",
10
+ "@lexy/separator",
11
+ "@lexy/tabs",
12
+ "@lexy/tag"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -9,9 +9,9 @@
9
9
  "react-day-picker@^9.8.0"
10
10
  ],
11
11
  "registryDependencies": [
12
- "button",
13
- "calendar",
14
- "popover"
12
+ "@lexy/button",
13
+ "@lexy/calendar",
14
+ "@lexy/popover"
15
15
  ],
16
16
  "files": [
17
17
  {
@@ -11,7 +11,7 @@
11
11
  "@hookform/resolvers@^5.2.0"
12
12
  ],
13
13
  "registryDependencies": [
14
- "label"
14
+ "@lexy/label"
15
15
  ],
16
16
  "files": [
17
17
  {
@@ -8,7 +8,7 @@
8
8
  "class-variance-authority"
9
9
  ],
10
10
  "registryDependencies": [
11
- "logo"
11
+ "@lexy/logo"
12
12
  ],
13
13
  "files": [
14
14
  {
@@ -6,10 +6,10 @@
6
6
  "description": "Paso de wizard de intake para **mundo cliente**: un paso enfocado, columna angosta (`max-w-xl`), indicador de avance arriba y CTA al final. Instálalo con `create-lexy add intake-wizard` — trae consigo `Progress`, `Input`, `Label` y `Button`. La vista queda en tu proyecto (`views/IntakeDatosPersonales.tsx`): edítala con libertad.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
- "button",
10
- "input",
11
- "label",
12
- "progress"
9
+ "@lexy/button",
10
+ "@lexy/input",
11
+ "@lexy/label",
12
+ "@lexy/progress"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -6,10 +6,10 @@
6
6
  "description": "Pantalla de acceso: una sola tarea, foco único, ayuda contextual breve. Instálalo con `create-lexy add login` — trae `Card`, `Input`, `Label` y `Button`. La vista queda en tu proyecto (`views/Login.tsx`): edítala con libertad.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
- "button",
10
- "card",
11
- "input",
12
- "label"
9
+ "@lexy/button",
10
+ "@lexy/card",
11
+ "@lexy/input",
12
+ "@lexy/label"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -9,7 +9,7 @@
9
9
  "lucide-react"
10
10
  ],
11
11
  "registryDependencies": [
12
- "button"
12
+ "@lexy/button"
13
13
  ],
14
14
  "files": [
15
15
  {
@@ -6,8 +6,8 @@
6
6
  "description": "Tarjeta de perfil. Para mostrar información de usuario. El componente vive en tu proyecto: instálalo con `create-lexy add profile-card` y edítalo con libertad.",
7
7
  "dependencies": [],
8
8
  "registryDependencies": [
9
- "avatar",
10
- "button"
9
+ "@lexy/avatar",
10
+ "@lexy/button"
11
11
  ],
12
12
  "files": [
13
13
  {
@@ -35,7 +35,7 @@
35
35
  "class-variance-authority"
36
36
  ],
37
37
  "registryDependencies": [
38
- "button"
38
+ "@lexy/button"
39
39
  ],
40
40
  "files": [
41
41
  {
@@ -57,7 +57,7 @@
57
57
  "description": "Acordeón de aplicación **data-driven**. Describe los items como datos (`items`)",
58
58
  "dependencies": [],
59
59
  "registryDependencies": [
60
- "accordion"
60
+ "@lexy/accordion"
61
61
  ],
62
62
  "files": [
63
63
  {
@@ -79,8 +79,8 @@
79
79
  "description": "Diálogo de aplicación al estilo **Material 3**. Estructura canónica sin dividers: El componente vive en tu proyecto: instálalo con `create-lexy add app-dialog` y edítalo con libertad.",
80
80
  "dependencies": [],
81
81
  "registryDependencies": [
82
- "button",
83
- "dialog"
82
+ "@lexy/button",
83
+ "@lexy/dialog"
84
84
  ],
85
85
  "files": [
86
86
  {
@@ -104,9 +104,9 @@
104
104
  "class-variance-authority"
105
105
  ],
106
106
  "registryDependencies": [
107
- "button",
108
- "header-bar",
109
- "logo"
107
+ "@lexy/button",
108
+ "@lexy/header-bar",
109
+ "@lexy/logo"
110
110
  ],
111
111
  "files": [
112
112
  {
@@ -130,8 +130,8 @@
130
130
  "lucide-react"
131
131
  ],
132
132
  "registryDependencies": [
133
- "avatar",
134
- "sidebar"
133
+ "@lexy/avatar",
134
+ "@lexy/sidebar"
135
135
  ],
136
136
  "files": [
137
137
  {
@@ -245,7 +245,7 @@
245
245
  "class-variance-authority"
246
246
  ],
247
247
  "registryDependencies": [
248
- "separator"
248
+ "@lexy/separator"
249
249
  ],
250
250
  "files": [
251
251
  {
@@ -270,7 +270,7 @@
270
270
  "react-day-picker@^9.8.0"
271
271
  ],
272
272
  "registryDependencies": [
273
- "button"
273
+ "@lexy/button"
274
274
  ],
275
275
  "files": [
276
276
  {
@@ -358,9 +358,9 @@
358
358
  "description": "Campo de entrada con lista desplegable filtrable. Para búsqueda + selección. El componente vive en tu proyecto: instálalo con `create-lexy add combobox` y edítalo con libertad.",
359
359
  "dependencies": [],
360
360
  "registryDependencies": [
361
- "button",
362
- "command",
363
- "popover"
361
+ "@lexy/button",
362
+ "@lexy/command",
363
+ "@lexy/popover"
364
364
  ],
365
365
  "files": [
366
366
  {
@@ -429,9 +429,9 @@
429
429
  "react-day-picker@^9.8.0"
430
430
  ],
431
431
  "registryDependencies": [
432
- "button",
433
- "calendar",
434
- "popover"
432
+ "@lexy/button",
433
+ "@lexy/calendar",
434
+ "@lexy/popover"
435
435
  ],
436
436
  "files": [
437
437
  {
@@ -544,7 +544,7 @@
544
544
  "@hookform/resolvers@^5.2.0"
545
545
  ],
546
546
  "registryDependencies": [
547
- "label"
547
+ "@lexy/label"
548
548
  ],
549
549
  "files": [
550
550
  {
@@ -568,7 +568,7 @@
568
568
  "class-variance-authority"
569
569
  ],
570
570
  "registryDependencies": [
571
- "logo"
571
+ "@lexy/logo"
572
572
  ],
573
573
  "files": [
574
574
  {
@@ -791,7 +791,7 @@
791
791
  "lucide-react"
792
792
  ],
793
793
  "registryDependencies": [
794
- "button"
794
+ "@lexy/button"
795
795
  ],
796
796
  "files": [
797
797
  {
@@ -835,8 +835,8 @@
835
835
  "description": "Tarjeta de perfil. Para mostrar información de usuario. El componente vive en tu proyecto: instálalo con `create-lexy add profile-card` y edítalo con libertad.",
836
836
  "dependencies": [],
837
837
  "registryDependencies": [
838
- "avatar",
839
- "button"
838
+ "@lexy/avatar",
839
+ "@lexy/button"
840
840
  ],
841
841
  "files": [
842
842
  {
@@ -1015,12 +1015,12 @@
1015
1015
  "lucide-react"
1016
1016
  ],
1017
1017
  "registryDependencies": [
1018
- "button",
1019
- "input",
1020
- "separator",
1021
- "sheet",
1022
- "skeleton",
1023
- "tooltip"
1018
+ "@lexy/button",
1019
+ "@lexy/input",
1020
+ "@lexy/separator",
1021
+ "@lexy/sheet",
1022
+ "@lexy/skeleton",
1023
+ "@lexy/tooltip"
1024
1024
  ],
1025
1025
  "files": [
1026
1026
  {
@@ -1327,7 +1327,7 @@
1327
1327
  "lucide-react"
1328
1328
  ],
1329
1329
  "registryDependencies": [
1330
- "button"
1330
+ "@lexy/button"
1331
1331
  ],
1332
1332
  "files": [
1333
1333
  {
@@ -1351,9 +1351,9 @@
1351
1351
  "lucide-react"
1352
1352
  ],
1353
1353
  "registryDependencies": [
1354
- "app-sidebar",
1355
- "logo",
1356
- "sidebar"
1354
+ "@lexy/app-sidebar",
1355
+ "@lexy/logo",
1356
+ "@lexy/sidebar"
1357
1357
  ],
1358
1358
  "files": [
1359
1359
  {
@@ -1377,11 +1377,11 @@
1377
1377
  "lucide-react"
1378
1378
  ],
1379
1379
  "registryDependencies": [
1380
- "button",
1381
- "input",
1382
- "pagination",
1383
- "status-dot",
1384
- "table"
1380
+ "@lexy/button",
1381
+ "@lexy/input",
1382
+ "@lexy/pagination",
1383
+ "@lexy/status-dot",
1384
+ "@lexy/table"
1385
1385
  ],
1386
1386
  "files": [
1387
1387
  {
@@ -1403,10 +1403,10 @@
1403
1403
  "description": "Detalle master-detail para **CRM**: contexto del caso a la izquierda (panel fijo de 288px), trabajo al centro en tabs, acción primaria a la mano. La información que se consulta junta vive junta. Instálalo con `create-lexy add crm-detalle-caso` — trae `Tabs`, `Tag`, `Separator` y `Button`. La vista queda en tu proyecto (`views/CasoDetalle.tsx`): edítala con libertad.",
1404
1404
  "dependencies": [],
1405
1405
  "registryDependencies": [
1406
- "button",
1407
- "separator",
1408
- "tabs",
1409
- "tag"
1406
+ "@lexy/button",
1407
+ "@lexy/separator",
1408
+ "@lexy/tabs",
1409
+ "@lexy/tag"
1410
1410
  ],
1411
1411
  "files": [
1412
1412
  {
@@ -1428,10 +1428,10 @@
1428
1428
  "description": "Paso de wizard de intake para **mundo cliente**: un paso enfocado, columna angosta (`max-w-xl`), indicador de avance arriba y CTA al final. Instálalo con `create-lexy add intake-wizard` — trae consigo `Progress`, `Input`, `Label` y `Button`. La vista queda en tu proyecto (`views/IntakeDatosPersonales.tsx`): edítala con libertad.",
1429
1429
  "dependencies": [],
1430
1430
  "registryDependencies": [
1431
- "button",
1432
- "input",
1433
- "label",
1434
- "progress"
1431
+ "@lexy/button",
1432
+ "@lexy/input",
1433
+ "@lexy/label",
1434
+ "@lexy/progress"
1435
1435
  ],
1436
1436
  "files": [
1437
1437
  {
@@ -1453,10 +1453,10 @@
1453
1453
  "description": "Pantalla de acceso: una sola tarea, foco único, ayuda contextual breve. Instálalo con `create-lexy add login` — trae `Card`, `Input`, `Label` y `Button`. La vista queda en tu proyecto (`views/Login.tsx`): edítala con libertad.",
1454
1454
  "dependencies": [],
1455
1455
  "registryDependencies": [
1456
- "button",
1457
- "card",
1458
- "input",
1459
- "label"
1456
+ "@lexy/button",
1457
+ "@lexy/card",
1458
+ "@lexy/input",
1459
+ "@lexy/label"
1460
1460
  ],
1461
1461
  "files": [
1462
1462
  {
@@ -10,12 +10,12 @@
10
10
  "lucide-react"
11
11
  ],
12
12
  "registryDependencies": [
13
- "button",
14
- "input",
15
- "separator",
16
- "sheet",
17
- "skeleton",
18
- "tooltip"
13
+ "@lexy/button",
14
+ "@lexy/input",
15
+ "@lexy/separator",
16
+ "@lexy/sheet",
17
+ "@lexy/skeleton",
18
+ "@lexy/tooltip"
19
19
  ],
20
20
  "files": [
21
21
  {
package/dist/index.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import{readFileSync as dt}from"fs";import be from"path";import{fileURLToPath as mt}from"url";import{Command as pt}from"commander";import ft from"picocolors";import{spawn as Fe}from"child_process";import W from"fs/promises";import G from"path";import{confirm as Te,isCancel as Se,spinner as de}from"@clack/prompts";import h from"picocolors";import X from"path";var je=(e,t)=>t.architecture!=="feature"?e:e.replace(/from ["']@\/lib\/utils\/cn["']/g,'from "@/shared/lib/utils/cn"').replace(/from ["']@\/components\/base\//g,'from "@/shared/components/base/'),$e=[["components/base/",e=>e.paths.components],["views/",e=>e.paths.views],["hooks/",e=>e.paths.hooks],["lib/",e=>e.paths.lib]],$=(e,t)=>e.files.filter(o=>typeof o.content=="string").map(o=>{let r=$e.find(([s])=>o.path.startsWith(s));return{relPath:r?X.posix.join(r[1](t),o.path.slice(r[0].length)):X.posix.join(t.paths.components,X.posix.basename(o.path)),content:je(o.content,t)}});import oe from"fs/promises";import Pe from"path";var re=e=>Pe.join(e,".lexy"),I=async e=>{let t;try{t=await oe.readFile(re(e),"utf-8")}catch{throw new Error("No se encontr\xF3 el archivo .lexy. \xBFEst\xE1s en la ra\xEDz de un proyecto Lexy? (cr\xE9alo con `npx create-lexy create`)")}let o=JSON.parse(t);if(!o.paths?.components)throw new Error("El .lexy no tiene paths.components \u2014 archivo corrupto o de una versi\xF3n incompatible.");return o.installed??={},o},ne=async(e,t)=>{await oe.writeFile(re(e),JSON.stringify(t,null,2)+`
3
- `)};import R from"fs/promises";import Ce from"os";import P from"path";import{fileURLToPath as Ie}from"url";var se="@lexydesign/registry",O=`https://cdn.jsdelivr.net/npm/${se}`,Ee=8e3,H=P.resolve(P.dirname(Ie(import.meta.url)),"../assets"),Le=P.join(Ce.homedir(),".cache","create-lexy","registry"),U=async e=>{let t=await fetch(e,{signal:AbortSignal.timeout(Ee)});if(!t.ok){let o=new Error(`HTTP ${t.status} al pedir ${e}`);throw o.status=t.status,o}return await t.json()},ie=async e=>{try{return JSON.parse(await R.readFile(P.join(H,"r",e),"utf-8"))}catch{return null}},Y=async()=>{try{return(await R.readFile(P.join(H,"registry-version"),"utf-8")).trim()}catch{return"bundle"}},k=null,q=async()=>{if(k)return k;try{k=(await U(`https://registry.npmjs.org/${se}/latest`)).version}catch{try{k=(await U(`${O}@latest/package.json`)).version}catch{k=await Y()}}return k},x=async(e,t)=>{let o=t??await q(),r=P.join(Le,o,`${e}.json`);try{return{item:JSON.parse(await R.readFile(r,"utf-8")),version:o,source:"cache"}}catch{}try{let n=await U(`${O}@${o}/r/${e}.json`);return await R.mkdir(P.dirname(r),{recursive:!0}),await R.writeFile(r,JSON.stringify(n)),{item:n,version:o,source:"cdn"}}catch(n){if(n.status===404)throw new Error(`El componente "${e}" no existe en el registry (versi\xF3n ${o}). Mira el cat\xE1logo con \`create-lexy view --list\`.`);let s=await ie(`${e}.json`);if(s)return{item:s,version:await Y(),source:"bundle"};throw new Error(`No se pudo alcanzar el registry (\xBFsin red?) y "${e}" tampoco est\xE1 en el bundle local del CLI.`)}},ae=async()=>{try{let e=await q();return{index:await U(`${O}@${e}/r/registry.json`),version:e,source:"cdn"}}catch{let e=await ie("registry.json");if(e)return{index:e,version:await Y(),source:"bundle"};throw new Error("No se pudo alcanzar el registry ni leer el bundle local del CLI.")}},ce=P.join(H,"theme/lexy-theme.css"),le=P.join(H,"fonts");var Ne=(e,t)=>new Promise((o,r)=>{Fe("pnpm",["add",...e],{cwd:t,stdio:"ignore",shell:!0}).on("close",s=>s===0?o():r(new Error(`pnpm add fall\xF3 con c\xF3digo ${s}`)))}),ke=async e=>{try{return await W.readFile(e,"utf-8")}catch{return null}},me=async(e,t)=>{let o=process.cwd(),r=await I(o),n=de();n.start("Resolviendo componentes en el registry...");let s=new Map,i=async a=>{let l=a.toLowerCase();if(s.has(l))return;let u=await x(l);s.set(l,u);for(let v of u.item.registryDependencies??[])await i(v)};try{for(let a of e)await i(a)}catch(a){throw n.stop(h.red("No se pudo resolver el pedido.")),a}let d=new Map;for(let[a,{item:l}]of s){let u=[];for(let v of $(l,r)){let C=await ke(G.join(o,v.relPath));u.push({...v,status:C===null?"new":C===v.content?"same":"differs"})}d.set(a,u)}let c=Array.from(d.values()).flat().filter(a=>a.status==="differs");if(n.stop(`Resueltos: ${Array.from(s.keys()).join(", ")}`),c.length>0&&!t.overwrite){let a=c.map(l=>` ${l.relPath}`).join(`
2
+ import{readFileSync as dt}from"fs";import be from"path";import{fileURLToPath as mt}from"url";import{Command as pt}from"commander";import ft from"picocolors";import{spawn as Fe}from"child_process";import W from"fs/promises";import G from"path";import{confirm as Te,isCancel as Se,spinner as de}from"@clack/prompts";import h from"picocolors";import X from"path";var je=(e,t)=>t.architecture!=="feature"?e:e.replace(/from ["']@\/lib\/utils\/cn["']/g,'from "@/shared/lib/utils/cn"').replace(/from ["']@\/components\/base\//g,'from "@/shared/components/base/'),$e=[["components/base/",e=>e.paths.components],["views/",e=>e.paths.views],["hooks/",e=>e.paths.hooks],["lib/",e=>e.paths.lib]],$=(e,t)=>e.files.filter(o=>typeof o.content=="string").map(o=>{let r=$e.find(([n])=>o.path.startsWith(n));return{relPath:r?X.posix.join(r[1](t),o.path.slice(r[0].length)):X.posix.join(t.paths.components,X.posix.basename(o.path)),content:je(o.content,t)}});import oe from"fs/promises";import Pe from"path";var re=e=>Pe.join(e,".lexy"),I=async e=>{let t;try{t=await oe.readFile(re(e),"utf-8")}catch{throw new Error("No se encontr\xF3 el archivo .lexy. \xBFEst\xE1s en la ra\xEDz de un proyecto Lexy? (cr\xE9alo con `npx create-lexy create`)")}let o=JSON.parse(t);if(!o.paths?.components)throw new Error("El .lexy no tiene paths.components \u2014 archivo corrupto o de una versi\xF3n incompatible.");return o.installed??={},o},ne=async(e,t)=>{await oe.writeFile(re(e),JSON.stringify(t,null,2)+`
3
+ `)};import R from"fs/promises";import Ce from"os";import P from"path";import{fileURLToPath as Ie}from"url";var se="@lexydesign/registry",k=`https://cdn.jsdelivr.net/npm/${se}`,Ee=8e3,H=P.resolve(P.dirname(Ie(import.meta.url)),"../assets"),Le=P.join(Ce.homedir(),".cache","create-lexy","registry"),U=async e=>{let t=await fetch(e,{signal:AbortSignal.timeout(Ee)});if(!t.ok){let o=new Error(`HTTP ${t.status} al pedir ${e}`);throw o.status=t.status,o}return await t.json()},ie=async e=>{try{return JSON.parse(await R.readFile(P.join(H,"r",e),"utf-8"))}catch{return null}},Y=async()=>{try{return(await R.readFile(P.join(H,"registry-version"),"utf-8")).trim()}catch{return"bundle"}},O=null,q=async()=>{if(O)return O;try{O=(await U(`https://registry.npmjs.org/${se}/latest`)).version}catch{try{O=(await U(`${k}@latest/package.json`)).version}catch{O=await Y()}}return O},x=async(e,t)=>{let o=e.replace(/^@lexy\//,""),r=t??await q(),s=P.join(Le,r,`${o}.json`);try{return{item:JSON.parse(await R.readFile(s,"utf-8")),version:r,source:"cache"}}catch{}try{let n=await U(`${k}@${r}/r/${o}.json`);return await R.mkdir(P.dirname(s),{recursive:!0}),await R.writeFile(s,JSON.stringify(n)),{item:n,version:r,source:"cdn"}}catch(n){if(n.status===404)throw new Error(`El componente "${o}" no existe en el registry (versi\xF3n ${r}). Mira el cat\xE1logo con \`create-lexy view --list\`.`);let i=await ie(`${o}.json`);if(i)return{item:i,version:await Y(),source:"bundle"};throw new Error(`No se pudo alcanzar el registry (\xBFsin red?) y "${o}" tampoco est\xE1 en el bundle local del CLI.`)}},ae=async()=>{try{let e=await q();return{index:await U(`${k}@${e}/r/registry.json`),version:e,source:"cdn"}}catch{let e=await ie("registry.json");if(e)return{index:e,version:await Y(),source:"bundle"};throw new Error("No se pudo alcanzar el registry ni leer el bundle local del CLI.")}},ce=P.join(H,"theme/lexy-theme.css"),le=P.join(H,"fonts");var Ne=(e,t)=>new Promise((o,r)=>{Fe("pnpm",["add",...e],{cwd:t,stdio:"ignore",shell:!0}).on("close",n=>n===0?o():r(new Error(`pnpm add fall\xF3 con c\xF3digo ${n}`)))}),Oe=async e=>{try{return await W.readFile(e,"utf-8")}catch{return null}},me=async(e,t)=>{let o=process.cwd(),r=await I(o),s=de();s.start("Resolviendo componentes en el registry...");let n=new Map,i=async a=>{let l=a.toLowerCase().replace(/^@lexy\//,"");if(n.has(l))return;let u=await x(l);n.set(l,u);for(let v of u.item.registryDependencies??[])await i(v)};try{for(let a of e)await i(a)}catch(a){throw s.stop(h.red("No se pudo resolver el pedido.")),a}let d=new Map;for(let[a,{item:l}]of n){let u=[];for(let v of $(l,r)){let C=await Oe(G.join(o,v.relPath));u.push({...v,status:C===null?"new":C===v.content?"same":"differs"})}d.set(a,u)}let c=Array.from(d.values()).flat().filter(a=>a.status==="differs");if(s.stop(`Resueltos: ${Array.from(n.keys()).join(", ")}`),c.length>0&&!t.overwrite){let a=c.map(l=>` ${l.relPath}`).join(`
4
4
  `);if(process.stdout.isTTY&&process.stdin.isTTY){let l=await Te({message:`Estos archivos existen con cambios locales y ser\xE1n sobrescritos:
5
5
  ${a}
6
6
  \xBFContinuar?`});if(Se(l)||l!==!0){console.log(h.yellow("Operaci\xF3n cancelada \u2014 nada fue modificado.")),process.exitCode=1;return}}else{console.error(h.red(`Estos archivos existen con cambios locales:
7
7
  `)+a+h.dim(`
8
- Usa --overwrite para sobrescribirlos.`)),process.exitCode=1;return}}for(let[a,l]of d){let{item:u,version:v,source:C}=s.get(a);for(let y of l){if(y.status==="same")continue;let j=G.join(o,y.relPath);await W.mkdir(G.dirname(j),{recursive:!0}),await W.writeFile(j,y.content)}r.installed[u.name]=v;let J=e.map(y=>y.toLowerCase()).includes(a)?"":h.dim(" (dependencia)"),D=C==="bundle"?h.yellow(" [bundle local \u2014 sin red]"):"";console.log(h.green(`${h.bold(u.title??u.name)} instalado`)+J+h.cyan(` \u2192 ${r.paths.components}/`)+D);for(let y of l){let j=y.status==="same"?h.dim(" (sin cambios)"):"";console.log(h.dim(` ${y.relPath}${j}`))}}await ne(o,r);let m=new Set;for(let{item:a}of s.values())for(let l of a.dependencies??[])m.add(l);let p=JSON.parse(await W.readFile(G.join(o,"package.json"),"utf-8")),g={...p.dependencies,...p.devDependencies},z=a=>{let l=a.lastIndexOf("@");return l>0?a.slice(0,l):a},f=Array.from(m).filter(a=>!g[z(a)]);if(f.length>0)if(t.install===!1)console.log(h.yellow(`Dependencias pendientes (inst\xE1lalas t\xFA): ${f.join(", ")}`));else{let a=de();a.start(`Instalando dependencias: ${f.join(", ")}...`),await Ne(f,o),a.stop("Dependencias instaladas.")}};import{spawn as et}from"child_process";import{note as tt,outro as ot,spinner as rt}from"@clack/prompts";import F from"picocolors";import{cancel as Oe,intro as Ae,isCancel as De,select as pe,text as Re}from"@clack/prompts";import fe from"picocolors";var Me=`
8
+ Usa --overwrite para sobrescribirlos.`)),process.exitCode=1;return}}for(let[a,l]of d){let{item:u,version:v,source:C}=n.get(a);for(let y of l){if(y.status==="same")continue;let j=G.join(o,y.relPath);await W.mkdir(G.dirname(j),{recursive:!0}),await W.writeFile(j,y.content)}r.installed[u.name]=v;let J=e.map(y=>y.toLowerCase()).includes(a)?"":h.dim(" (dependencia)"),D=C==="bundle"?h.yellow(" [bundle local \u2014 sin red]"):"";console.log(h.green(`${h.bold(u.title??u.name)} instalado`)+J+h.cyan(` \u2192 ${r.paths.components}/`)+D);for(let y of l){let j=y.status==="same"?h.dim(" (sin cambios)"):"";console.log(h.dim(` ${y.relPath}${j}`))}}await ne(o,r);let m=new Set;for(let{item:a}of n.values())for(let l of a.dependencies??[])m.add(l);let p=JSON.parse(await W.readFile(G.join(o,"package.json"),"utf-8")),g={...p.dependencies,...p.devDependencies},z=a=>{let l=a.lastIndexOf("@");return l>0?a.slice(0,l):a},f=Array.from(m).filter(a=>!g[z(a)]);if(f.length>0)if(t.install===!1)console.log(h.yellow(`Dependencias pendientes (inst\xE1lalas t\xFA): ${f.join(", ")}`));else{let a=de();a.start(`Instalando dependencias: ${f.join(", ")}...`),await Ne(f,o),a.stop("Dependencias instaladas.")}};import{spawn as et}from"child_process";import{note as tt,outro as ot,spinner as rt}from"@clack/prompts";import F from"picocolors";import{cancel as ke,intro as Ae,isCancel as De,select as pe,text as Re}from"@clack/prompts";import fe from"picocolors";var Me=`
9
9
  ###### ######
10
10
  ##::+#### ####+::##
11
11
  #-..:+################+:..:#
@@ -20,8 +20,8 @@ Usa --overwrite para sobrescribirlos.`)),process.exitCode=1;return}}for(let[a,l]
20
20
  ...........:====:...........
21
21
  ......................
22
22
  ..............
23
- `,K=e=>{De(e)&&(Oe("Operaci\xF3n cancelada por el usuario."),process.exit(0))},ue=async e=>{console.clear(),Ae(`${fe.cyan(Me)}
24
- ${fe.bold(" Bienvenido al generador de proyectos Lexy")}`);let t=e;if(!t){let n=await Re({message:"\xBFCu\xE1l es el nombre de tu proyecto?",placeholder:"lexy-app",validate:s=>{if(!s||s.trim()==="")return"El nombre es obligatorio.";if(!/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(s))return"El nombre debe estar en min\xFAsculas, sin espacios ni caracteres especiales."}});K(n),t=n}let o=await pe({message:"\xBFPara qu\xE9 mundo es este proyecto?",options:[{label:"Cliente",value:"cliente",hint:"Producto de cara al cliente final"},{label:"CRM / equipo interno",value:"crm",hint:"Herramienta densa para el equipo Lexy"},{label:"Mixto",value:"mixto",hint:"Ambos o a\xFAn sin definir"}],initialValue:"mixto"});K(o);let r=await pe({message:"\xBFQu\xE9 tipo de arquitectura utilizar\xE1 este proyecto?",options:[{label:"Por Feature",value:"feature",hint:"Recomendado para apps escalables"},{label:"Por Capas",value:"layer",hint:"Cl\xE1sica"}],initialValue:"feature"});return K(r),{projectName:t,architecture:r,world:o}};import E from"fs/promises";import L from"path";var Ve={feature:["src/app","src/features","src/shared/assets","src/shared/components/base","src/shared/hooks","src/shared/services","src/shared/lib","src/shared/types"],layer:["src/assets","src/components/base","src/hooks","src/services","src/lib","src/types","src/views","src/stores"]},_e=e=>JSON.stringify({name:e.projectName,private:!0,version:"0.0.0",type:"module",scripts:{dev:"vite",build:"tsc -b && vite build",preview:"vite preview"},dependencies:{clsx:"^2.1.1",react:"^19.2.6","react-dom":"^19.2.6","tailwind-merge":"^3.3.1"},devDependencies:{"@tailwindcss/vite":"^4.3.0","@types/node":"^24.12.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.1",tailwindcss:"^4.3.0",typescript:"~5.9.3",vite:"^8.0.12"}},null,2)+`
23
+ `,K=e=>{De(e)&&(ke("Operaci\xF3n cancelada por el usuario."),process.exit(0))},ue=async e=>{console.clear(),Ae(`${fe.cyan(Me)}
24
+ ${fe.bold(" Bienvenido al generador de proyectos Lexy")}`);let t=e;if(!t){let s=await Re({message:"\xBFCu\xE1l es el nombre de tu proyecto?",placeholder:"lexy-app",validate:n=>{if(!n||n.trim()==="")return"El nombre es obligatorio.";if(!/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(n))return"El nombre debe estar en min\xFAsculas, sin espacios ni caracteres especiales."}});K(s),t=s}let o=await pe({message:"\xBFPara qu\xE9 mundo es este proyecto?",options:[{label:"Cliente",value:"cliente",hint:"Producto de cara al cliente final"},{label:"CRM / equipo interno",value:"crm",hint:"Herramienta densa para el equipo Lexy"},{label:"Mixto",value:"mixto",hint:"Ambos o a\xFAn sin definir"}],initialValue:"mixto"});K(o);let r=await pe({message:"\xBFQu\xE9 tipo de arquitectura utilizar\xE1 este proyecto?",options:[{label:"Por Feature",value:"feature",hint:"Recomendado para apps escalables"},{label:"Por Capas",value:"layer",hint:"Cl\xE1sica"}],initialValue:"feature"});return K(r),{projectName:t,architecture:r,world:o}};import E from"fs/promises";import L from"path";var Ve={feature:["src/app","src/features","src/shared/assets","src/shared/components/base","src/shared/hooks","src/shared/services","src/shared/lib","src/shared/types"],layer:["src/assets","src/components/base","src/hooks","src/services","src/lib","src/types","src/views","src/stores"]},_e=e=>JSON.stringify({name:e.projectName,private:!0,version:"0.0.0",type:"module",scripts:{dev:"vite",build:"tsc -b && vite build",preview:"vite preview"},dependencies:{clsx:"^2.1.1",react:"^19.2.6","react-dom":"^19.2.6","tailwind-merge":"^3.3.1"},devDependencies:{"@tailwindcss/vite":"^4.3.0","@types/node":"^24.12.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.1",tailwindcss:"^4.3.0",typescript:"~5.9.3",vite:"^8.0.12"}},null,2)+`
25
25
  `,ze=`import path from "node:path";
26
26
  import { defineConfig } from "vite";
27
27
  import react from "@vitejs/plugin-react";
@@ -40,7 +40,11 @@ export default defineConfig({
40
40
  "references": [
41
41
  { "path": "./tsconfig.app.json" },
42
42
  { "path": "./tsconfig.node.json" }
43
- ]
43
+ ],
44
+ "compilerOptions": {
45
+ "baseUrl": ".",
46
+ "paths": { "@/*": ["./src/*"] }
47
+ }
44
48
  }
45
49
  `,Ue=`{
46
50
  "compilerOptions": {
@@ -139,31 +143,31 @@ npx create-lexy view button # ver un componente antes de instalarlo
139
143
  npx create-lexy add button # instalarlo (local y editable)
140
144
  npx create-lexy doctor # divergencia con el registry
141
145
  \`\`\`
142
- `,Qe=e=>{let o=e.architecture==="feature"?"@/shared":"@";return JSON.stringify({$schema:"https://ui.shadcn.com/schema.json",style:"new-york",rsc:!1,tsx:!0,tailwind:{config:"",css:"src/index.css",baseColor:"neutral",cssVariables:!0},aliases:{components:`${o}/components`,ui:`${o}/components/base`,utils:`${o}/lib/utils/cn`,lib:`${o}/lib`,hooks:`${o}/hooks`},registries:{"@lexy":`${O}@latest/r/{name}.json`}},null,2)+`
143
- `},Ze=e=>{let t=e.architecture==="feature";return{version:"2.0.0",generatedAt:new Date().toISOString(),architecture:e.architecture,world:e.world,registry:{package:"@lexydesign/registry",cdn:O},componentImportPattern:t?"@/shared/components/base/{Component}":"@/components/base/{Component}",paths:{components:t?"src/shared/components/base":"src/components/base",hooks:t?"src/shared/hooks":"src/hooks",services:t?"src/shared/services":"src/services",lib:t?"src/shared/lib":"src/lib",views:t?"src/features":"src/views"},installed:{}}},ge=async(e,t)=>{let o=["package.json","src","index.html",".lexy"],r=[];for(let c of o)try{await E.access(L.join(t,c)),r.push(c)}catch{}if(r.length>0)throw new Error(`El directorio actual ya contiene archivos de un proyecto (${r.join(", ")}). Ejecuta el comando dentro de una carpeta vac\xEDa.`);for(let c of Ve[e.architecture])await E.mkdir(L.join(t,c),{recursive:!0});let n=(c,m)=>E.writeFile(L.join(t,c),m);await n("package.json",_e(e)),await n("vite.config.ts",ze),await n("tsconfig.json",Je),await n("tsconfig.app.json",Ue),await n("tsconfig.node.json",He),await n("index.html",qe(e)),await n(".gitignore",Ye),await n("README.md",Ke(e)),await n("src/index.css",Ge),await n("src/main.tsx",We(e));let s=e.architecture==="feature"?"src/app":"src/views";await n(`${s}/App.tsx`,Be);let i=Ze(e);await n(".lexy",JSON.stringify(i,null,2)+`
144
- `),await n("components.json",Qe(e)),await E.copyFile(ce,L.join(t,"src/lexy-theme.css")),await E.mkdir(L.join(t,"public/fonts"),{recursive:!0}),await E.cp(le,L.join(t,"public/fonts"),{recursive:!0});let d=L.join(t,i.paths.lib,"utils");await E.mkdir(d,{recursive:!0}),await E.writeFile(L.join(d,"cn.ts"),Xe)};var nt=["feature","layer"],st=["cliente","crm","mixto"],it=e=>new Promise((t,o)=>{et("pnpm",["install"],{cwd:e,stdio:"ignore",shell:!0}).on("close",n=>n===0?t():o(new Error(`pnpm install fall\xF3 con c\xF3digo ${n}`)))}),ye=async(e,t)=>{let o;!!(e&&t.type)?(nt.includes(t.type)||(console.error(F.red(`Error: la arquitectura "${t.type}" no es v\xE1lida. Usa "feature" o "layer".`)),process.exit(1)),t.world&&!st.includes(t.world)&&(console.error(F.red(`Error: el mundo "${t.world}" no es v\xE1lido. Usa "cliente", "crm" o "mixto".`)),process.exit(1)),o={projectName:e,architecture:t.type,world:t.world??"mixto"},console.log(F.blue("Modo automatizado detectado. Saltando interfaz interactiva..."))):o=await ue(e),tt(`Nombre: ${o.projectName}
146
+ `,Qe=e=>{let o=e.architecture==="feature"?"@/shared":"@";return JSON.stringify({$schema:"https://ui.shadcn.com/schema.json",style:"new-york",rsc:!1,tsx:!0,tailwind:{config:"",css:"src/index.css",baseColor:"neutral",cssVariables:!0},aliases:{components:`${o}/components`,ui:`${o}/components/base`,utils:`${o}/lib/utils/cn`,lib:`${o}/lib`,hooks:`${o}/hooks`},registries:{"@lexy":`${k}@latest/r/{name}.json`}},null,2)+`
147
+ `},Ze=e=>{let t=e.architecture==="feature";return{version:"2.0.0",generatedAt:new Date().toISOString(),architecture:e.architecture,world:e.world,registry:{package:"@lexydesign/registry",cdn:k},componentImportPattern:t?"@/shared/components/base/{Component}":"@/components/base/{Component}",paths:{components:t?"src/shared/components/base":"src/components/base",hooks:t?"src/shared/hooks":"src/hooks",services:t?"src/shared/services":"src/services",lib:t?"src/shared/lib":"src/lib",views:t?"src/features":"src/views"},installed:{}}},ge=async(e,t)=>{let o=["package.json","src","index.html",".lexy"],r=[];for(let c of o)try{await E.access(L.join(t,c)),r.push(c)}catch{}if(r.length>0)throw new Error(`El directorio actual ya contiene archivos de un proyecto (${r.join(", ")}). Ejecuta el comando dentro de una carpeta vac\xEDa.`);for(let c of Ve[e.architecture])await E.mkdir(L.join(t,c),{recursive:!0});let s=(c,m)=>E.writeFile(L.join(t,c),m);await s("package.json",_e(e)),await s("vite.config.ts",ze),await s("tsconfig.json",Je),await s("tsconfig.app.json",Ue),await s("tsconfig.node.json",He),await s("index.html",qe(e)),await s(".gitignore",Ye),await s("README.md",Ke(e)),await s("src/index.css",Ge),await s("src/main.tsx",We(e));let n=e.architecture==="feature"?"src/app":"src/views";await s(`${n}/App.tsx`,Be);let i=Ze(e);await s(".lexy",JSON.stringify(i,null,2)+`
148
+ `),await s("components.json",Qe(e)),await E.copyFile(ce,L.join(t,"src/lexy-theme.css")),await E.mkdir(L.join(t,"public/fonts"),{recursive:!0}),await E.cp(le,L.join(t,"public/fonts"),{recursive:!0});let d=L.join(t,i.paths.lib,"utils");await E.mkdir(d,{recursive:!0}),await E.writeFile(L.join(d,"cn.ts"),Xe)};var nt=["feature","layer"],st=["cliente","crm","mixto"],it=e=>new Promise((t,o)=>{et("pnpm",["install"],{cwd:e,stdio:"ignore",shell:!0}).on("close",s=>s===0?t():o(new Error(`pnpm install fall\xF3 con c\xF3digo ${s}`)))}),ye=async(e,t)=>{let o;!!(e&&t.type)?(nt.includes(t.type)||(console.error(F.red(`Error: la arquitectura "${t.type}" no es v\xE1lida. Usa "feature" o "layer".`)),process.exit(1)),t.world&&!st.includes(t.world)&&(console.error(F.red(`Error: el mundo "${t.world}" no es v\xE1lido. Usa "cliente", "crm" o "mixto".`)),process.exit(1)),o={projectName:e,architecture:t.type,world:t.world??"mixto"},console.log(F.blue("Modo automatizado detectado. Saltando interfaz interactiva..."))):o=await ue(e),tt(`Nombre: ${o.projectName}
145
149
  Arquitectura: ${o.architecture}
146
- Mundo: ${o.world}`,"Configuraci\xF3n de Proyecto");let n=rt();n.start("Construyendo tu proyecto...");let s=process.cwd();try{await ge(o,s)}catch(i){throw n.stop(F.red("No se pudo crear el proyecto.")),i}t.install!==!1&&(n.message("Instalando dependencias base..."),await it(s)),n.stop("\xA1Proyecto construido con \xE9xito!"),ot(F.green(`Todo listo en el directorio actual
150
+ Mundo: ${o.world}`,"Configuraci\xF3n de Proyecto");let s=rt();s.start("Construyendo tu proyecto...");let n=process.cwd();try{await ge(o,n)}catch(i){throw s.stop(F.red("No se pudo crear el proyecto.")),i}t.install!==!1&&(s.message("Instalando dependencias base..."),await it(n)),s.stop("\xA1Proyecto construido con \xE9xito!"),ot(F.green(`Todo listo en el directorio actual
147
151
 
148
152
  `)+F.dim(`Siguientes pasos:
149
153
  `)+F.cyan(` pnpm dev
150
154
  `)+F.cyan(" npx create-lexy add button"))};import at from"fs/promises";import ct from"path";import T from"picocolors";import Q from"picocolors";var M=(e,t)=>{let o=e.split(`
151
155
  `),r=t.split(`
152
- `),n=o.length,s=r.length,i=Array.from({length:n+1},()=>new Array(s+1).fill(0));for(let p=n-1;p>=0;p--)for(let g=s-1;g>=0;g--)i[p][g]=o[p]===r[g]?i[p+1][g+1]+1:Math.max(i[p+1][g],i[p][g+1]);let d=[],c=0,m=0;for(;c<n&&m<s;)o[c]===r[m]?(d.push({type:"same",text:o[c]}),c++,m++):i[c+1][m]>=i[c][m+1]?d.push({type:"del",text:o[c++]}):d.push({type:"add",text:r[m++]});for(;c<n;)d.push({type:"del",text:o[c++]});for(;m<s;)d.push({type:"add",text:r[m++]});return d},B=e=>e.some(t=>t.type!=="same"),he=(e,t=3)=>{if(!B(e))return null;let o=new Array(e.length).fill(!1);e.forEach((s,i)=>{if(s.type!=="same")for(let d=Math.max(0,i-t);d<=Math.min(e.length-1,i+t);d++)o[d]=!0});let r=[],n=!1;for(let s=0;s<e.length;s++){if(!o[s]){n||(r.push(Q.dim(" \u22EF")),n=!0);continue}n=!1;let i=e[s];i.type==="same"?r.push(` ${i.text}`):i.type==="del"?r.push(Q.red(`- ${i.text}`)):r.push(Q.green(`+ ${i.text}`))}return r.join(`
153
- `)};var xe=async e=>{let t=process.cwd(),o=await I(t),r=e.toLowerCase(),{item:n,version:s}=await x(r),i=o.installed[r];console.log(T.bold(`
154
- ${n.title??r}`)+T.dim(` \xB7 instalado con registry@${i??"?"} \xB7 vigente registry@${s}
155
- `));let d=!1;for(let c of $(n,o)){let m=await at.readFile(ct.join(t,c.relPath),"utf-8").catch(()=>null);if(m===null){console.log(T.red(`\u2717 ${c.relPath} no existe localmente`)+T.dim(` \u2014 cr\xE9alo con \`create-lexy add ${r}\``)),d=!0;continue}let p=he(M(m,c.content));p===null?console.log(T.green(`\u2713 ${c.relPath}`)+T.dim(" sin diferencias")):(d=!0,console.log(T.yellow(`\xB1 ${c.relPath}`)+T.dim(" (\u2212 local \xB7 + registry)")),console.log(p))}d&&(process.exitCode=1)};import A from"fs/promises";import S from"path";import b from"picocolors";var we=async e=>{let t=process.cwd(),o=0,r=f=>console.log(b.green(" \u2713 ")+f),n=f=>console.log(b.yellow(" \u2022 ")+f),s=(f,a)=>{o=1,console.log(b.red(" \u2717 ")+f),a&&console.log(b.dim(` \u2192 ${a}`))};console.log(b.bold(`
156
+ `),s=o.length,n=r.length,i=Array.from({length:s+1},()=>new Array(n+1).fill(0));for(let p=s-1;p>=0;p--)for(let g=n-1;g>=0;g--)i[p][g]=o[p]===r[g]?i[p+1][g+1]+1:Math.max(i[p+1][g],i[p][g+1]);let d=[],c=0,m=0;for(;c<s&&m<n;)o[c]===r[m]?(d.push({type:"same",text:o[c]}),c++,m++):i[c+1][m]>=i[c][m+1]?d.push({type:"del",text:o[c++]}):d.push({type:"add",text:r[m++]});for(;c<s;)d.push({type:"del",text:o[c++]});for(;m<n;)d.push({type:"add",text:r[m++]});return d},B=e=>e.some(t=>t.type!=="same"),he=(e,t=3)=>{if(!B(e))return null;let o=new Array(e.length).fill(!1);e.forEach((n,i)=>{if(n.type!=="same")for(let d=Math.max(0,i-t);d<=Math.min(e.length-1,i+t);d++)o[d]=!0});let r=[],s=!1;for(let n=0;n<e.length;n++){if(!o[n]){s||(r.push(Q.dim(" \u22EF")),s=!0);continue}s=!1;let i=e[n];i.type==="same"?r.push(` ${i.text}`):i.type==="del"?r.push(Q.red(`- ${i.text}`)):r.push(Q.green(`+ ${i.text}`))}return r.join(`
157
+ `)};var xe=async e=>{let t=process.cwd(),o=await I(t),r=e.toLowerCase(),{item:s,version:n}=await x(r),i=o.installed[r];console.log(T.bold(`
158
+ ${s.title??r}`)+T.dim(` \xB7 instalado con registry@${i??"?"} \xB7 vigente registry@${n}
159
+ `));let d=!1;for(let c of $(s,o)){let m=await at.readFile(ct.join(t,c.relPath),"utf-8").catch(()=>null);if(m===null){console.log(T.red(`\u2717 ${c.relPath} no existe localmente`)+T.dim(` \u2014 cr\xE9alo con \`create-lexy add ${r}\``)),d=!0;continue}let p=he(M(m,c.content));p===null?console.log(T.green(`\u2713 ${c.relPath}`)+T.dim(" sin diferencias")):(d=!0,console.log(T.yellow(`\xB1 ${c.relPath}`)+T.dim(" (\u2212 local \xB7 + registry)")),console.log(p))}d&&(process.exitCode=1)};import A from"fs/promises";import S from"path";import b from"picocolors";var we=async e=>{let t=process.cwd(),o=0,r=f=>console.log(b.green(" \u2713 ")+f),s=f=>console.log(b.yellow(" \u2022 ")+f),n=(f,a)=>{o=1,console.log(b.red(" \u2717 ")+f),a&&console.log(b.dim(` \u2192 ${a}`))};console.log(b.bold(`
156
160
  Diagn\xF3stico del proyecto Lexy
157
- `));let i;try{i=await I(t),r(`.lexy v\xE1lido (arquitectura ${i.architecture}${i.world?`, mundo ${i.world}`:""})`)}catch(f){return s(f.message),1}await A.access(S.join(t,"src/lexy-theme.css")).then(()=>!0,()=>!1)?r("theme presente (src/lexy-theme.css)"):s("falta src/lexy-theme.css","re-cr\xE9alo desde un proyecto nuevo o copia el theme del registry");let c=S.join(i.paths.lib,"utils/cn.ts");await A.access(S.join(t,c)).then(()=>!0,()=>!1)?r(`helper cn presente (${c})`):s(`falta el helper cn (${c})`);let p=S.join(t,"ai/lexy-ai-manifest.json"),g=await A.readFile(p,"utf-8").catch(()=>null);if(g===null)console.log(b.dim(" \xB7 capa de IA no instalada (npx @lexydesign/ai install) \u2014 opcional"));else try{let f=JSON.parse(g),a=f.files??[],l=[];for(let u of a)await A.access(S.join(t,u)).then(()=>!0,()=>!1)||l.push(u);l.length>0?s(`capa de IA ${f.aiVersion??"?"} incompleta \u2014 faltan ${l.length} archivo(s) (${l.slice(0,3).join(", ")}${l.length>3?", \u2026":""})`,"npx @lexydesign/ai install"):r(`capa de IA ${f.aiVersion??"?"} completa (${a.length} archivos)`)}catch{s("ai/lexy-ai-manifest.json no es JSON v\xE1lido","regenera con `npx @lexydesign/ai install`")}let z=Object.entries(i.installed);if(z.length===0)console.log(b.dim(`
161
+ `));let i;try{i=await I(t),r(`.lexy v\xE1lido (arquitectura ${i.architecture}${i.world?`, mundo ${i.world}`:""})`)}catch(f){return n(f.message),1}await A.access(S.join(t,"src/lexy-theme.css")).then(()=>!0,()=>!1)?r("theme presente (src/lexy-theme.css)"):n("falta src/lexy-theme.css","re-cr\xE9alo desde un proyecto nuevo o copia el theme del registry");let c=S.join(i.paths.lib,"utils/cn.ts");await A.access(S.join(t,c)).then(()=>!0,()=>!1)?r(`helper cn presente (${c})`):n(`falta el helper cn (${c})`);let p=S.join(t,"ai/lexy-ai-manifest.json"),g=await A.readFile(p,"utf-8").catch(()=>null);if(g===null)console.log(b.dim(" \xB7 capa de IA no instalada (npx @lexydesign/ai install) \u2014 opcional"));else try{let f=JSON.parse(g),a=f.files??[],l=[];for(let u of a)await A.access(S.join(t,u)).then(()=>!0,()=>!1)||l.push(u);l.length>0?n(`capa de IA ${f.aiVersion??"?"} incompleta \u2014 faltan ${l.length} archivo(s) (${l.slice(0,3).join(", ")}${l.length>3?", \u2026":""})`,"npx @lexydesign/ai install"):r(`capa de IA ${f.aiVersion??"?"} completa (${a.length} archivos)`)}catch{n("ai/lexy-ai-manifest.json no es JSON v\xE1lido","regenera con `npx @lexydesign/ai install`")}let z=Object.entries(i.installed);if(z.length===0)console.log(b.dim(`
158
162
  Sin componentes instalados a\xFAn (create-lexy add <nombre>).`));else{let f=await q();console.log(b.bold(`
159
163
  Componentes instalados (registry vigente: ${f})
160
- `));for(let[a,l]of z){let u;try{u=await x(a)}catch(y){s(`${a}: ${y.message}`);continue}let v=$(u.item,i),C=[],J=!1;for(let y of v){let j=await A.readFile(S.join(t,y.relPath),"utf-8").catch(()=>null);j===null?C.push(y.relPath):B(M(j,y.content))&&(J=!0)}if(C.length>0){s(`${a}: archivos faltantes (${C.join(", ")})`,`create-lexy add ${a}`);continue}if(!J){r(`${a} al d\xEDa (${u.version})`);continue}let D=!0;if(l&&l!==u.version)try{let y=await x(a,l),j=$(y.item,i);D=!1;for(let ee of j){let te=await A.readFile(S.join(t,ee.relPath),"utf-8").catch(()=>null);(te===null||B(M(te,ee.content)))&&(D=!0)}}catch{}D?e.strict?s(`${a}: editado localmente (difiere del registry vigente)`,`create-lexy diff ${a}`):n(`${a}: editado localmente \u2014 divergencia deliberada (m\xEDrala con \`create-lexy diff ${a}\`)`):s(`${a}: desactualizado (instalado con ${l}, vigente ${u.version})`,`create-lexy diff ${a} \xB7 create-lexy add ${a} --overwrite`)}}return console.log(o===0?b.green(`
164
+ `));for(let[a,l]of z){let u;try{u=await x(a)}catch(y){n(`${a}: ${y.message}`);continue}let v=$(u.item,i),C=[],J=!1;for(let y of v){let j=await A.readFile(S.join(t,y.relPath),"utf-8").catch(()=>null);j===null?C.push(y.relPath):B(M(j,y.content))&&(J=!0)}if(C.length>0){n(`${a}: archivos faltantes (${C.join(", ")})`,`create-lexy add ${a}`);continue}if(!J){r(`${a} al d\xEDa (${u.version})`);continue}let D=!0;if(l&&l!==u.version)try{let y=await x(a,l),j=$(y.item,i);D=!1;for(let ee of j){let te=await A.readFile(S.join(t,ee.relPath),"utf-8").catch(()=>null);(te===null||B(M(te,ee.content)))&&(D=!0)}}catch{}D?e.strict?n(`${a}: editado localmente (difiere del registry vigente)`,`create-lexy diff ${a}`):s(`${a}: editado localmente \u2014 divergencia deliberada (m\xEDrala con \`create-lexy diff ${a}\`)`):n(`${a}: desactualizado (instalado con ${l}, vigente ${u.version})`,`create-lexy diff ${a} \xB7 create-lexy add ${a} --overwrite`)}}return console.log(o===0?b.green(`
161
165
  Todo en orden.
162
166
  `):b.red(`
163
167
  Hay problemas que atender (exit 1).
164
168
  `)),o};import lt from"fs/promises";import Z from"path";import w from"picocolors";var V=e=>console.log(w.bold(w.cyan(`
165
169
  \u2500\u2500 ${e} \u2500\u2500
166
170
  `))),ve=async(e,t)=>{if(t.list||!e){let{index:i,version:d,source:c}=await ae();V(`Cat\xE1logo Lexy \xB7 @lexydesign/registry@${d}${c==="bundle"?" (bundle local)":""}`);for(let m of i.items)console.log(` ${w.bold(m.name.padEnd(20))} ${w.dim(m.description??"")}`);console.log(w.dim(`
167
- ${i.items.length} componente(s). Instala con: create-lexy add <nombre>`));return}let o=e.toLowerCase();if(t.installed){let i=process.cwd(),d=await I(i),c=d.installed[o];if(!c){console.error(w.red(`"${o}" no figura como instalado en .lexy. Inst\xE1lalo con \`create-lexy add ${o}\`.`)),process.exitCode=1;return}let{item:m}=await x(o,c).catch(()=>x(o));V(`${m.title??o} \xB7 copia local (instalado con registry@${c})`);for(let p of $(m,d)){let g=await lt.readFile(Z.join(i,p.relPath),"utf-8").catch(()=>null);V(g===null?`${p.relPath} (FALTANTE)`:p.relPath),g!==null&&console.log(g)}return}let{item:r,version:n,source:s}=await x(o);V(`${r.title??r.name} \xB7 @lexydesign/registry@${n}${s==="bundle"?" (bundle local)":""}`),r.description&&console.log(r.description+`
171
+ ${i.items.length} componente(s). Instala con: create-lexy add <nombre>`));return}let o=e.toLowerCase();if(t.installed){let i=process.cwd(),d=await I(i),c=d.installed[o];if(!c){console.error(w.red(`"${o}" no figura como instalado en .lexy. Inst\xE1lalo con \`create-lexy add ${o}\`.`)),process.exitCode=1;return}let{item:m}=await x(o,c).catch(()=>x(o));V(`${m.title??o} \xB7 copia local (instalado con registry@${c})`);for(let p of $(m,d)){let g=await lt.readFile(Z.join(i,p.relPath),"utf-8").catch(()=>null);V(g===null?`${p.relPath} (FALTANTE)`:p.relPath),g!==null&&console.log(g)}return}let{item:r,version:s,source:n}=await x(o);V(`${r.title??r.name} \xB7 @lexydesign/registry@${s}${n==="bundle"?" (bundle local)":""}`),r.description&&console.log(r.description+`
168
172
  `),console.log(w.dim("tipo: ")+r.type),console.log(w.dim("deps npm: ")+((r.dependencies??[]).join(", ")||"\u2014")),console.log(w.dim("deps registry: ")+((r.registryDependencies??[]).join(", ")||"\u2014")),console.log(w.dim("archivos: ")+r.files.map(i=>Z.posix.basename(i.path)).join(", ")),console.log(w.dim("instalar: ")+`create-lexy add ${r.name}`);for(let i of r.files)typeof i.content=="string"&&(V(Z.posix.basename(i.path)),console.log(i.content))};var ut=be.dirname(mt(import.meta.url)),gt=JSON.parse(dt(be.join(ut,"../package.json"),"utf-8")),N=new pt,_=e=>async()=>{try{await e()}catch(t){console.error(ft.red(`
169
173
  Error: `)+t.message),process.exit(1)}};N.name("create-lexy").description("CLI del Lexy Design System: crea proyectos y trae componentes a demanda.\nLos componentes viven en tu proyecto \u2014 m\xEDralos con `view`, inst\xE1lalos con `add`, ed\xEDtalos con libertad.").version(gt.version);N.command("create",{isDefault:!0}).alias("init").description("Crea un proyecto Lexy vac\xEDo (React + Vite + TS + theme); los componentes llegan con `add`").argument("[project-name]","Nombre del proyecto").option("-t, --type <architecture>","Arquitectura (feature o layer) \u2014 activa el modo no interactivo").option("-w, --world <world>","Mundo de dise\xF1o (cliente, crm o mixto)").option("--no-install","No correr pnpm install al final").action((e,t)=>_(()=>ye(e,t))());N.command("add").description("Instala componentes del registry en tu proyecto (local y editable), con sus dependencias").argument("<components...>","Nombres en el registry (ej: button card)").option("--overwrite","Sobrescribir copias locales con cambios sin preguntar").option("--no-install","No instalar dependencias npm").action((e,t)=>_(()=>me(e,t))());N.command("view").description("Muestra c\xF3digo + doc + metadata de un componente antes de instalarlo").argument("[component]","Nombre en el registry (sin nombre: lista el cat\xE1logo)").option("--installed","Mostrar la copia local instalada en vez de la del registry").option("--list","Listar el cat\xE1logo completo").action((e,t)=>_(()=>ve(e,t))());N.command("diff").description("Copia local vs versi\xF3n vigente del registry (exit 1 si hay diferencias)").argument("<component>","Nombre en el registry").action(e=>_(()=>xe(e))());N.command("doctor").description("Drift de todo lo instalado contra el registry (solo lectura; exit 1 con problemas)").option("--strict","Las ediciones locales tambi\xE9n hacen fallar").action(e=>_(async()=>{process.exitCode=await we(e)})());N.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-lexy",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "CLI del Lexy Design System — crea proyectos y trae componentes a demanda desde el registry",
5
5
  "type": "module",
6
6
  "bin": {