create-lexy 0.6.2 → 0.6.3

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.
Files changed (93) hide show
  1. package/README.md +7 -2
  2. package/assets/fonts/{OFL-NotoSans.txt → LICENSE-Geist.txt} +4 -5
  3. package/assets/fonts/geist-mono-variable-italic.woff2 +0 -0
  4. package/assets/fonts/geist-mono-variable.woff2 +0 -0
  5. package/assets/fonts/geist-sans-variable-italic.woff2 +0 -0
  6. package/assets/fonts/geist-sans-variable.woff2 +0 -0
  7. package/assets/r/accordion.json +3 -3
  8. package/assets/r/alert-dialog.json +3 -3
  9. package/assets/r/app-accordion.json +1 -1
  10. package/assets/r/app-dialog.json +3 -3
  11. package/assets/r/app-header-bar.json +2 -2
  12. package/assets/r/app-sidebar.json +2 -2
  13. package/assets/r/avatar.json +3 -3
  14. package/assets/r/badge.json +3 -3
  15. package/assets/r/brand-background.json +1 -1
  16. package/assets/r/breadcrumb.json +3 -3
  17. package/assets/r/button-group.json +3 -3
  18. package/assets/r/button.json +3 -3
  19. package/assets/r/calendar.json +2 -2
  20. package/assets/r/card.json +3 -3
  21. package/assets/r/chart.json +2 -2
  22. package/assets/r/checkbox.json +2 -2
  23. package/assets/r/combobox.json +3 -3
  24. package/assets/r/command.json +3 -3
  25. package/assets/r/confirmacion.json +1 -1
  26. package/assets/r/counter-badge.json +3 -3
  27. package/assets/r/crm-desk.json +1 -1
  28. package/assets/r/crm-detalle-caso.json +5 -5
  29. package/assets/r/date-picker.json +1 -1
  30. package/assets/r/dialog.json +3 -3
  31. package/assets/r/dropdown-menu.json +3 -3
  32. package/assets/r/empty.json +2 -2
  33. package/assets/r/feature-card.json +3 -3
  34. package/assets/r/form.json +3 -3
  35. package/assets/r/header-bar.json +2 -2
  36. package/assets/r/input.json +3 -3
  37. package/assets/r/intake-wizard.json +1 -1
  38. package/assets/r/label.json +3 -3
  39. package/assets/r/logo.json +2 -2
  40. package/assets/r/menubar.json +3 -3
  41. package/assets/r/navigation-menu.json +3 -3
  42. package/assets/r/pagination.json +2 -2
  43. package/assets/r/popover.json +3 -3
  44. package/assets/r/profile-card.json +3 -3
  45. package/assets/r/progress.json +2 -2
  46. package/assets/r/radio-group.json +2 -2
  47. package/assets/r/registry.json +47 -47
  48. package/assets/r/scroll-area.json +2 -2
  49. package/assets/r/searchbox.json +3 -3
  50. package/assets/r/select.json +3 -3
  51. package/assets/r/separator.json +2 -2
  52. package/assets/r/sheet.json +2 -2
  53. package/assets/r/sidebar.json +3 -3
  54. package/assets/r/skeleton.json +2 -2
  55. package/assets/r/slider.json +3 -3
  56. package/assets/r/snippet.json +3 -3
  57. package/assets/r/spinner.json +2 -2
  58. package/assets/r/status-dot.json +3 -3
  59. package/assets/r/switch.json +3 -3
  60. package/assets/r/table.json +3 -3
  61. package/assets/r/tabs.json +3 -3
  62. package/assets/r/tag.json +3 -3
  63. package/assets/r/textarea.json +3 -3
  64. package/assets/r/toaster.json +3 -3
  65. package/assets/r/tooltip.json +3 -3
  66. package/assets/r/tree.json +3 -3
  67. package/assets/registry-version +1 -1
  68. package/assets/theme/lexy-theme.css +562 -112
  69. package/dist/index.js +97 -91
  70. package/package.json +4 -2
  71. package/templates/.claude/skills/lexy-design/SKILL.md +189 -0
  72. package/templates/.claude/skills/lexy-dev/SKILL.md +168 -0
  73. package/templates/.claude/skills/lexy-mock-data/SKILL.md +50 -0
  74. package/templates/.github/copilot-instructions.md +50 -0
  75. package/templates/.mcp.json +8 -0
  76. package/templates/AGENTS.md +243 -0
  77. package/templates/CLAUDE.md +61 -0
  78. package/templates/ai/IMPLEMENTATION-PROTOCOL.md +148 -0
  79. package/templates/ai/PRODUCTION-CLEANUP.md +17 -0
  80. package/templates/ai/PROJECT-CONTEXT.md +65 -0
  81. package/templates/ai/README.md +19 -0
  82. package/templates/ai/TECHNICAL-USAGE.md +220 -0
  83. package/templates/ai/pautas/arquitectura-informacion-ux.md +243 -0
  84. package/templates/ai/pautas/buenas-practicas.md +236 -0
  85. package/templates/ai/pautas/calidad-industria.md +109 -0
  86. package/templates/ai/pautas/diseno-cliente.md +136 -0
  87. package/templates/ai/pautas/diseno-crm-lexy.md +109 -0
  88. package/templates/ai/pautas/patrones-de-codigo.md +234 -0
  89. package/templates/ai/pautas/recetas-layout.md +419 -0
  90. package/templates/ai/pautas/sistema-visual.md +197 -0
  91. package/templates/ai/pautas/ux-writing.md +214 -0
  92. package/templates/scripts/check-geometry.mjs +139 -0
  93. package/assets/fonts/noto-sans-latin.woff2 +0 -0
package/dist/index.js CHANGED
@@ -1,27 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{readFileSync as Po}from"fs";import tt from"path";import{fileURLToPath as jo}from"url";import{Command as Io}from"commander";import Co from"picocolors";import{spawn as ct}from"child_process";import Y from"fs/promises";import G from"path";import{confirm as dt,isCancel as pt,spinner as Te}from"@clack/prompts";import v from"picocolors";import te from"path";var ot=(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/'),at=[["components/base/",e=>e.paths.components],["views/",e=>e.paths.views],["hooks/",e=>e.paths.hooks],["lib/",e=>e.paths.lib]],T=(e,t)=>e.files.filter(o=>typeof o.content=="string").map(o=>{let a=at.find(([r])=>o.path.startsWith(r)),n=a?te.posix.join(a[1](t),o.path.slice(a[0].length)):te.posix.join(t.paths.components,te.posix.basename(o.path));return o.encoding==="base64"?{relPath:n,content:o.content,encoding:"base64"}:{relPath:n,content:ot(o.content,t)}});import we from"fs/promises";import nt from"path";var Se=e=>nt.join(e,".lexy"),_=async e=>{let t;try{t=await we.readFile(Se(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},ke=async(e,t)=>{await we.writeFile(Se(e),JSON.stringify(t,null,2)+`
3
- `)};import q from"fs/promises";import rt from"os";import R from"path";import{fileURLToPath as it}from"url";var Ee="@lexydesign/registry",F=`https://cdn.jsdelivr.net/npm/${Ee}`,st=8e3,J=R.resolve(R.dirname(it(import.meta.url)),"../assets"),lt=R.join(rt.homedir(),".cache","create-lexy","registry"),B=async e=>{let t=await fetch(e,{signal:AbortSignal.timeout(st)});if(!t.ok){let o=new Error(`HTTP ${t.status} al pedir ${e}`);throw o.status=t.status,o}return await t.json()},Pe=async e=>{try{return JSON.parse(await q.readFile(R.join(J,"r",e),"utf-8"))}catch{return null}},oe=async()=>{try{return(await q.readFile(R.join(J,"registry-version"),"utf-8")).trim()}catch{return"bundle"}},$=null,W=async()=>{if($)return $;try{$=(await B(`https://registry.npmjs.org/${Ee}/latest`)).version}catch{try{$=(await B(`${F}@latest/package.json`)).version}catch{$=await oe()}}return $},k=async(e,t)=>{let o=e.replace(/^@lexy\//,""),a=t??await W(),n=R.join(lt,a,`${o}.json`);try{return{item:JSON.parse(await q.readFile(n,"utf-8")),version:a,source:"cache"}}catch{}try{let r=await B(`${F}@${a}/r/${o}.json`);return await q.mkdir(R.dirname(n),{recursive:!0}),await q.writeFile(n,JSON.stringify(r)),{item:r,version:a,source:"cdn"}}catch(r){if(r.status===404)throw new Error(`El componente "${o}" no existe en el registry (versi\xF3n ${a}). Mira el cat\xE1logo con \`create-lexy view --list\`.`);let i=await Pe(`${o}.json`);if(i)return{item:i,version:await oe(),source:"bundle"};throw new Error(`No se pudo alcanzar el registry (\xBFsin red?) y "${o}" tampoco est\xE1 en el bundle local del CLI.`)}},je=async()=>{try{let e=await W();return{index:await B(`${F}@${e}/r/registry.json`),version:e,source:"cdn"}}catch{let e=await Pe("registry.json");if(e)return{index:e,version:await oe(),source:"bundle"};throw new Error("No se pudo alcanzar el registry ni leer el bundle local del CLI.")}},Ie=R.join(J,"theme/lexy-theme.css"),Ce=R.join(J,"fonts");var mt=(e,t)=>new Promise((o,a)=>{ct("pnpm",["add",...e],{cwd:t,stdio:"ignore",shell:!0}).on("close",r=>r===0?o():a(new Error(`pnpm add fall\xF3 con c\xF3digo ${r}`)))}),ut=async(e,t="utf-8")=>{try{return await Y.readFile(e,t)}catch{return null}},Re=async(e,t)=>{let o=process.cwd(),a=await _(o),n=Te();n.start("Resolviendo componentes en el registry...");let r=new Map,i=async p=>{let f=p.toLowerCase().replace(/^@lexy\//,"");if(r.has(f))return;let c=await k(f);r.set(f,c);for(let l of c.item.registryDependencies??[])await i(l)};try{for(let p of e)await i(p)}catch(p){throw n.stop(v.red("No se pudo resolver el pedido.")),p}let d=new Map;for(let[p,{item:f}]of r){let c=[];for(let l of T(f,a)){let g=await ut(G.join(o,l.relPath),l.encoding??"utf-8");c.push({...l,status:g===null?"new":g===l.content?"same":"differs"})}d.set(p,c)}let s=Array.from(d.values()).flat().filter(p=>p.status==="differs");if(n.stop(`Resueltos: ${Array.from(r.keys()).join(", ")}`),s.length>0&&!t.overwrite){let p=s.map(f=>` ${f.relPath}`).join(`
4
- `);if(process.stdout.isTTY&&process.stdin.isTTY){let f=await dt({message:`Estos archivos existen con cambios locales y ser\xE1n sobrescritos:
5
- ${p}
6
- \xBFContinuar?`});if(pt(f)||f!==!0){console.log(v.yellow("Operaci\xF3n cancelada \u2014 nada fue modificado.")),process.exitCode=1;return}}else{console.error(v.red(`Estos archivos existen con cambios locales:
7
- `)+p+v.dim(`
8
- Usa --overwrite para sobrescribirlos.`)),process.exitCode=1;return}}for(let[p,f]of d){let{item:c,version:l,source:g}=r.get(p);for(let x of f){if(x.status==="same")continue;let A=G.join(o,x.relPath);await Y.mkdir(G.dirname(A),{recursive:!0}),await Y.writeFile(A,x.content,x.encoding??"utf-8")}a.installed[c.name]=l;let P=e.map(x=>x.toLowerCase()).includes(p)?"":v.dim(" (dependencia)"),U=g==="bundle"?v.yellow(" [bundle local \u2014 sin red]"):"";console.log(v.green(`${v.bold(c.title??c.name)} instalado`)+P+v.cyan(` \u2192 ${a.paths.components}/`)+U);for(let x of f){let A=x.status==="same"?v.dim(" (sin cambios)"):"";console.log(v.dim(` ${x.relPath}${A}`))}}await ke(o,a);let u=new Set;for(let{item:p}of r.values())for(let f of p.dependencies??[])u.add(f);let m=JSON.parse(await Y.readFile(G.join(o,"package.json"),"utf-8")),y={...m.dependencies,...m.devDependencies},z=p=>{let f=p.lastIndexOf("@");return f>0?p.slice(0,f):p},M=Array.from(u).filter(p=>!y[z(p)]);if(M.length>0)if(t.install===!1)console.log(v.yellow(`Dependencias pendientes (inst\xE1lalas t\xFA): ${M.join(", ")}`));else{let p=Te();p.start(`Instalando dependencias: ${M.join(", ")}...`),await mt(M,o),p.stop("Dependencias instaladas.")}};import{spawn as po}from"child_process";import{note as mo,outro as uo,spinner as yo}from"@clack/prompts";import j from"picocolors";import{cancel as yt,intro as ft,isCancel as gt,select as _e,text as xt}from"@clack/prompts";import Oe from"picocolors";var ae=[{value:"screen",label:"Una pantalla o flujo corto",hint:"landing, formulario, demo \u2014 sin navegaci\xF3n entre secciones",architecture:"layer"},{value:"app",label:"Una app con secciones y navegaci\xF3n",hint:"dashboard, listados, detalle \u2014 varias vistas con router",architecture:"feature"}],Ne=e=>ae.find(t=>t.value===e).architecture;var ht=`
9
- ###### ######
10
- ##::+#### ####+::##
11
- #-..:+################+:..:#
12
- #+...=################=...+#
13
- #=-*##################*-=#
14
- ########################
15
- ==-:.:=*##########*=:.::==
16
- **#####*+--*####*--+*#####**
17
- ##########%@@#:-##=.#@@%##########
18
- #######*+*#%%*:-@@=.+%%#*+*#######
19
- #+:..........:*#:..........:=#
20
- ...........:====:...........
21
- ......................
22
- ..............
23
- `,ne=e=>{gt(e)&&(yt("Operaci\xF3n cancelada por el usuario."),process.exit(0))},Ae=async e=>{console.clear(),ft(`${Oe.cyan(ht)}
24
- ${Oe.bold(" Bienvenido al generador de proyectos Lexy")}`);let t=e;if(!t){let n=await xt({message:"\xBFCu\xE1l es el nombre de tu proyecto?",placeholder:"lexy-app",validate:r=>{if(!r||r.trim()==="")return"El nombre es obligatorio.";if(!/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(r))return"El nombre debe estar en min\xFAsculas, sin espacios ni caracteres especiales."}});ne(n),t=n}let o=await _e({message:"\xBFPara qui\xE9n es este proyecto?",options:[{label:"Clientes de Lexy",value:"cliente",hint:"Producto de cara al cliente final"},{label:"Equipo interno / CRM",value:"crm",hint:"Herramienta densa para el equipo Lexy"},{label:"Ambos o a\xFAn no lo s\xE9",value:"mixto",hint:"Se decide por pantalla m\xE1s adelante"}],initialValue:"mixto"});ne(o);let a=await _e({message:"\xBFC\xF3mo es lo que vas a construir?",options:ae.map(n=>({label:n.label,value:n.value,hint:n.hint})),initialValue:"app"});return ne(a),{projectName:t,architecture:Ne(a),world:o}};import b from"fs/promises";import w from"path";import{format as qt,resolveConfig as Vt}from"prettier";import Le from"fs/promises";import De from"path";var re="src/prototype/data-contract/prototype-data-contract.ts",vt="src/prototype/data-contract/data-contract-schema.ts",bt="scripts/check-data-contract.ts",wt=String.raw`import { z } from "zod";
2
+ import{readFileSync as pa}from"fs";import wt from"path";import{fileURLToPath as ma}from"url";import{Command as ua}from"commander";import St from"picocolors";import{spawn as jo}from"child_process";import re from"fs/promises";import ne from"path";import{confirm as Io,isCancel as To,spinner as nt}from"@clack/prompts";import P from"picocolors";import ye from"path";var kt=(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/'),Pt=[["components/base/",e=>e.paths.components],["views/",e=>e.paths.views],["hooks/",e=>e.paths.hooks],["lib/",e=>e.paths.lib]],O=(e,t)=>e.files.filter(o=>typeof o.content=="string").map(o=>{let a=Pt.find(([r])=>o.path.startsWith(r)),n=a?ye.posix.join(a[1](t),o.path.slice(a[0].length)):ye.posix.join(t.paths.components,ye.posix.basename(o.path));return o.encoding==="base64"?{relPath:n,content:o.content,encoding:"base64"}:{relPath:n,content:kt(o.content,t)}});import{execFileSync as Ze,spawnSync as ke}from"child_process";import{confirm as bo,isCancel as wo,spinner as So}from"@clack/prompts";import W from"picocolors";import S from"fs/promises";import k from"path";import{format as Qt,resolveConfig as Xt}from"prettier";import J from"fs/promises";import Et from"os";import A from"path";import{fileURLToPath as Ct}from"url";var Me="@lexydesign/registry",q=`https://cdn.jsdelivr.net/npm/${Me}`,jt=8e3,ee=A.resolve(A.dirname(Ct(import.meta.url)),"../assets"),It=A.join(Et.homedir(),".cache","create-lexy","registry"),Z=async e=>{let t=await fetch(e,{signal:AbortSignal.timeout(jt)});if(!t.ok){let o=new Error(`HTTP ${t.status} al pedir ${e}`);throw o.status=t.status,o}return await t.json()},$e=async e=>{try{return JSON.parse(await J.readFile(A.join(ee,"r",e),"utf-8"))}catch{return null}},fe=async()=>{try{return(await J.readFile(A.join(ee,"registry-version"),"utf-8")).trim()}catch{return"bundle"}},V=null,te=async()=>{if(V)return V;try{V=(await Z(`https://registry.npmjs.org/${Me}/latest`)).version}catch{try{V=(await Z(`${q}@latest/package.json`)).version}catch{V=await fe()}}return V},C=async(e,t)=>{let o=e.replace(/^@lexy\//,""),a=t??await te(),n=A.join(It,a,`${o}.json`);try{return{item:JSON.parse(await J.readFile(n,"utf-8")),version:a,source:"cache"}}catch{}try{let r=await Z(`${q}@${a}/r/${o}.json`);return await J.mkdir(A.dirname(n),{recursive:!0}),await J.writeFile(n,JSON.stringify(r)),{item:r,version:a,source:"cdn"}}catch(r){if(r.status===404)throw new Error(`El componente "${o}" no existe en el registry (versi\xF3n ${a}). Mira el cat\xE1logo con \`create-lexy view --list\`.`);let i=await $e(`${o}.json`);if(i)return{item:i,version:await fe(),source:"bundle"};throw new Error(`No se pudo alcanzar el registry (\xBFsin red?) y "${o}" tampoco est\xE1 en el bundle local del CLI.`)}},oe=async()=>{try{let e=await te();return{index:await Z(`${q}@${e}/r/registry.json`),version:e,source:"cdn"}}catch{let e=await $e("registry.json");if(e)return{index:e,version:await fe(),source:"bundle"};throw new Error("No se pudo alcanzar el registry ni leer el bundle local del CLI.")}},Fe=A.join(ee,"theme/lexy-theme.css"),Ve=A.join(ee,"fonts");import qe from"fs/promises";import Ue from"path";var ge="src/prototype/data-contract/prototype-data-contract.ts",Tt="src/prototype/data-contract/data-contract-schema.ts",Nt="scripts/check-data-contract.ts",Rt=String.raw`import { z } from "zod";
25
3
 
26
4
  const camelCaseIdSchema = z
27
5
  .string()
@@ -430,7 +408,7 @@ export function definePrototypeDataContract(
430
408
  ): PrototypeDataContract {
431
409
  return prototypeDataContractSchema.parse(contract);
432
410
  }
433
- `,St=String.raw`import { ZodError } from "zod";
411
+ `,_t=String.raw`import { ZodError } from "zod";
434
412
 
435
413
  import { prototypeDataContractSchema } from "../src/prototype/data-contract/data-contract-schema";
436
414
 
@@ -491,7 +469,7 @@ try {
491
469
  }
492
470
  process.exitCode = 1;
493
471
  }
494
- `,kt=e=>`import { definePrototypeDataContract } from "./data-contract-schema";
472
+ `,Ot=e=>`import { definePrototypeDataContract } from "./data-contract-schema";
495
473
 
496
474
  /**
497
475
  * Fuente de verdad de los datos usados por el prototipo.
@@ -509,8 +487,9 @@ export const prototypeDataContract = definePrototypeDataContract({
509
487
  relations: [],
510
488
  projections: {},
511
489
  });
512
- `,ze=async(e,t)=>{let o=async(a,n)=>{let r=De.join(e,a);await Le.mkdir(De.dirname(r),{recursive:!0}),await Le.writeFile(r,n)};await o(vt,wt),await o(re,kt(t)),await o(bt,St)};import Me from"fs/promises";import ie from"path";var se="src/prototype/designer-panel/designer-activity.ts",le="src/prototype/designer-panel/PrototypeDesignerPanel.tsx",Et=String.raw`export type DesignerActivityRecordInput = {
490
+ `,Ke=async(e,t)=>{let o=async(a,n)=>{let r=Ue.join(e,a);await qe.mkdir(Ue.dirname(r),{recursive:!0}),await qe.writeFile(r,n)};await o(Tt,Rt),await o(ge,Ot(t)),await o(Nt,_t)};import He from"fs/promises";import xe from"path";var he="src/prototype/designer-panel/designer-activity.ts",ve="src/prototype/designer-panel/PrototypeDesignerPanel.tsx",At=String.raw`export type DesignerActivityRecordInput = {
513
491
  kind: "load" | "event";
492
+ label?: string;
514
493
  technicalId?: string;
515
494
  triggerId?: string;
516
495
  input?: unknown;
@@ -520,6 +499,7 @@ export type DesignerActivityRecord = {
520
499
  id: string;
521
500
  occurredAt: string;
522
501
  kind: "load" | "event";
502
+ label: string;
523
503
  technicalId?: string;
524
504
  triggerId?: string;
525
505
  inputPreview?: string;
@@ -602,7 +582,7 @@ export const createDesignerActivityStore = (maxItems = 80): DesignerActivityStor
602
582
  id: tabId + "_" + sequence,
603
583
  occurredAt: new Date().toISOString(),
604
584
  kind: input.kind,
605
- label: input.technicalId ?? "evento",
585
+ label: input.label ?? input.technicalId ?? "evento",
606
586
  ...(input.technicalId ? { technicalId: input.technicalId } : {}),
607
587
  ...(input.triggerId ? { triggerId: input.triggerId } : {}),
608
588
  ...(preview(input.input) ? { inputPreview: preview(input.input) } : {}),
@@ -619,7 +599,7 @@ export const createDesignerActivityStore = (maxItems = 80): DesignerActivityStor
619
599
  };
620
600
 
621
601
  export const designerActivity = createDesignerActivityStore();
622
- `,Pt=`
602
+ `,Lt=`
623
603
  .lexy-dp {
624
604
  --dp-bg: #ffffff;
625
605
  --dp-fg: #0f172a;
@@ -640,8 +620,8 @@ export const designerActivity = createDesignerActivityStore();
640
620
  --dp-warning-fg: #ffffff;
641
621
  --dp-info: #0ea5e9;
642
622
  --dp-radius: 8px;
643
- --dp-mono: SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace;
644
- --dp-sans: "Inter", system-ui, -apple-system, sans-serif;
623
+ --dp-mono: "Geist Mono", SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace;
624
+ --dp-sans: "Geist Sans", system-ui, -apple-system, sans-serif;
645
625
  color: var(--dp-fg);
646
626
  font-family: var(--dp-sans);
647
627
  font-size: 13.5px;
@@ -1268,7 +1248,7 @@ export const designerActivity = createDesignerActivityStore();
1268
1248
  .lexy-dp-iconbtn:hover { opacity: 1; background: rgba(255, 255, 255, 0.1); color: #ffffff; }
1269
1249
  .lexy-dp-iconbtn svg { width: 15px; height: 15px; }
1270
1250
  .lexy-dp-sheet__body { flex: 1; min-height: 0; overflow-y: auto; background: var(--dp-bg); }
1271
- `,jt=()=>String.raw`import {
1251
+ `,Dt=()=>String.raw`import {
1272
1252
  Activity,
1273
1253
  ArrowUpRight,
1274
1254
  ChevronRight,
@@ -1294,7 +1274,7 @@ import { designerActivity } from "./designer-activity";
1294
1274
  // Panel autocontenido: trae su propio CSS scopeado (.lexy-dp) y no depende del
1295
1275
  // tema Tailwind del proyecto host ni de componentes del registry. Así se puede
1296
1276
  // previsualizar e iterar el diseño en cualquier entorno.
1297
- const PANEL_STYLES = ${JSON.stringify(Pt)};
1277
+ const PANEL_STYLES = ${JSON.stringify(Lt)};
1298
1278
 
1299
1279
  function PanelStyles() {
1300
1280
  return <style>{PANEL_STYLES}</style>;
@@ -2156,7 +2136,7 @@ export function PrototypeDesignerPanel() {
2156
2136
  </div>
2157
2137
  );
2158
2138
  }
2159
- `,$e=async(e,t)=>{let o=async(a,n)=>{await Me.mkdir(ie.dirname(ie.join(e,a)),{recursive:!0}),await Me.writeFile(ie.join(e,a),n)};await o(se,Et),await o(le,jt())};import Fe from"fs/promises";import qe from"path";var ce="src/prototype/mock-store/mock-store.ts",de="src/prototype/mock-store/fixtures.ts",It="src/prototype/ports/types.ts",Ct="src/prototype/ports/catalog.ts",Tt="src/prototype/ports/mock-read.ts",Rt="src/prototype/ports/mock-write.ts",Nt="src/prototype/ports/production.ts",pe="src/prototype/ports/index.ts",_t=String.raw`import { fixtures } from "./fixtures";
2139
+ `,Je=async(e,t)=>{let o=async(a,n)=>{await He.mkdir(xe.dirname(xe.join(e,a)),{recursive:!0}),await He.writeFile(xe.join(e,a),n)};await o(he,At),await o(ve,Dt())};import Be from"fs/promises";import We from"path";var be="src/prototype/mock-store/mock-store.ts",we="src/prototype/mock-store/fixtures.ts",zt="src/prototype/ports/types.ts",Mt="src/prototype/ports/catalog.ts",$t="src/prototype/ports/mock-read.ts",Ft="src/prototype/ports/mock-write.ts",Vt="src/prototype/ports/production.ts",Se="src/prototype/ports/index.ts",qt=String.raw`import { fixtures } from "./fixtures";
2160
2140
 
2161
2141
  export type JsonPrimitive = string | number | boolean | null;
2162
2142
  export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue };
@@ -2316,7 +2296,7 @@ export const findRecordById = (
2316
2296
  fieldId: string,
2317
2297
  id: JsonPrimitive,
2318
2298
  ) => records.find((record) => record[fieldId] === id);
2319
- `,Ot=String.raw`import type { MockEntityRecord } from "./mock-store";
2299
+ `,Ut=String.raw`import type { MockEntityRecord } from "./mock-store";
2320
2300
 
2321
2301
  export type Fixtures = {
2322
2302
  datasetVersion: number;
@@ -2332,7 +2312,7 @@ export const fixtures: Fixtures = {
2332
2312
  datasetVersion: 1,
2333
2313
  entities: {},
2334
2314
  };
2335
- `,At=String.raw`import { z } from "zod";
2315
+ `,Kt=String.raw`import { z } from "zod";
2336
2316
 
2337
2317
  /** Metadata de una carga de datos (GET): describe qué lee y qué la detona. */
2338
2318
  export const readMetaSchema = z
@@ -2385,7 +2365,7 @@ export interface LexyReadPort {
2385
2365
  export interface LexyWritePort {
2386
2366
  publish(eventId: string, payload: unknown, meta?: WriteMeta): Promise<EventReceipt>;
2387
2367
  }
2388
- `,Lt=String.raw`import type { EventReceipt, ReadMeta, WriteMeta } from "./types";
2368
+ `,Ht=String.raw`import type { EventReceipt, ReadMeta, WriteMeta } from "./types";
2389
2369
 
2390
2370
  export type CatalogEvent = {
2391
2371
  kind: "event";
@@ -2496,7 +2476,7 @@ const createCatalog = () => {
2496
2476
  };
2497
2477
 
2498
2478
  export const catalog = createCatalog();
2499
- `,Dt=String.raw`import { designerActivity } from "../designer-panel/designer-activity";
2479
+ `,Jt=String.raw`import { designerActivity } from "../designer-panel/designer-activity";
2500
2480
  import { type MockEntityRecord, mockStore } from "../mock-store/mock-store";
2501
2481
  import { catalog } from "./catalog";
2502
2482
  import { type LexyReadPort, type ReadMeta, readMetaSchema } from "./types";
@@ -2534,7 +2514,7 @@ export const mockRead: LexyReadPort = {
2534
2514
  return data as T;
2535
2515
  },
2536
2516
  };
2537
- `,zt=String.raw`import { designerActivity } from "../designer-panel/designer-activity";
2517
+ `,Bt=String.raw`import { designerActivity } from "../designer-panel/designer-activity";
2538
2518
  import { mockStore } from "../mock-store/mock-store";
2539
2519
  import { catalog } from "./catalog";
2540
2520
  import { type EventReceipt, type LexyWritePort, type WriteMeta, writeMetaSchema } from "./types";
@@ -2578,7 +2558,7 @@ export const mockWrite: LexyWritePort = {
2578
2558
  return receipt;
2579
2559
  },
2580
2560
  };
2581
- `,Mt=String.raw`import type { LexyReadPort, LexyWritePort } from "./types";
2561
+ `,Wt=String.raw`import type { LexyReadPort, LexyWritePort } from "./types";
2582
2562
 
2583
2563
  export const productionRead: LexyReadPort = {
2584
2564
  async load<T = unknown>(loadId: string): Promise<T> {
@@ -2595,7 +2575,7 @@ export const productionWrite: LexyWritePort = {
2595
2575
  );
2596
2576
  },
2597
2577
  };
2598
- `,$t=String.raw`import { mockRead } from "./mock-read";
2578
+ `,Gt=String.raw`import { mockRead } from "./mock-read";
2599
2579
  import { mockWrite } from "./mock-write";
2600
2580
  import { productionRead, productionWrite } from "./production";
2601
2581
  import type { LexyReadPort, LexyWritePort } from "./types";
@@ -2612,8 +2592,8 @@ export type {
2612
2592
  ReadMeta,
2613
2593
  WriteMeta,
2614
2594
  } from "./types";
2615
- `,Ft=[[ce,_t],[de,Ot],[It,At],[Ct,Lt],[Tt,Dt],[Rt,zt],[Nt,Mt],[pe,$t]],Ve=async e=>{for(let[t,o]of Ft){let a=qe.join(e,t);await Fe.mkdir(qe.dirname(a),{recursive:!0}),await Fe.writeFile(a,o)}};var Kt={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"]},Ut="10.33.3",Ht=e=>{let t=e.architecture==="feature"?{"react-router":"^7.9.0"}:{};return JSON.stringify({name:e.projectName,private:!0,version:"0.0.0",type:"module",packageManager:`pnpm@${Ut}`,scripts:{dev:"vite","check:data-contract":"tsx scripts/check-data-contract.ts","check:prototype":"pnpm check:data-contract","build:app":"tsc -b && vite build",build:"pnpm check:prototype && pnpm build:app",preview:"vite preview",lint:"eslint .",format:"prettier --write ."},dependencies:{clsx:"^2.1.1","lucide-react":"^0.460.0",react:"^19.2.6","react-dom":"^19.2.6",...t,"tailwind-merge":"^3.3.1",zod:"^4.1.0"},devDependencies:{"@babel/core":"^7.29.7","@eslint/js":"^10.0.1","@rolldown/plugin-babel":"^0.2.3","@tailwindcss/vite":"^4.3.0","@types/babel__core":"^7.20.5","@types/node":"^24.12.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.1","babel-plugin-react-compiler":"^1.0.0",eslint:"^10.4.1","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-simple-import-sort":"^13.0.0",globals:"^17.6.0",prettier:"^3.8.4",tailwindcss:"^4.3.0",terser:"^5.48.0",tsx:"^4.19.0",typescript:"~5.9.3","typescript-eslint":"^8.61.0",vite:"^8.0.12"}},null,2)+`
2616
- `},Bt=`import path from "node:path";
2595
+ `,Yt=[[be,qt],[we,Ut],[zt,Kt],[Mt,Ht],[$t,Jt],[Ft,Bt],[Vt,Wt],[Se,Gt]],Ge=async e=>{for(let[t,o]of Yt){let a=We.join(e,t);await Be.mkdir(We.dirname(a),{recursive:!0}),await Be.writeFile(a,o)}};var Zt={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"]},B="10.33.3",eo=e=>{let t=e.architecture==="feature"?{"react-router":"^7.9.0"}:{};return JSON.stringify({name:e.projectName,private:!0,version:"0.0.0",type:"module",packageManager:`pnpm@${B}`,scripts:{dev:"vite","check:data-contract":"tsx scripts/check-data-contract.ts","check:prototype":"pnpm check:data-contract","build:app":"tsc -b && vite build",build:"pnpm check:prototype && pnpm build:app",preview:"vite preview",lint:"eslint .",format:"prettier --write ."},dependencies:{clsx:"^2.1.1","lucide-react":"^0.460.0",react:"^19.2.6","react-dom":"^19.2.6",...t,"tailwind-merge":"^3.3.1",zod:"^4.1.0"},devDependencies:{"@babel/core":"^7.29.7","@eslint/js":"^10.0.1","@rolldown/plugin-babel":"^0.2.3","@tailwindcss/vite":"^4.3.0","@types/babel__core":"^7.20.5","@types/node":"^24.12.3","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.1","babel-plugin-react-compiler":"^1.0.0",eslint:"^10.4.1","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-simple-import-sort":"^13.0.0",globals:"^17.6.0",prettier:"^3.8.4",tailwindcss:"^4.3.0",terser:"^5.48.0",tsx:"^4.19.0",typescript:"~5.9.3","typescript-eslint":"^8.61.0",vite:"^8.0.12"}},null,2)+`
2596
+ `},to=`import path from "node:path";
2617
2597
 
2618
2598
  import babel from "@rolldown/plugin-babel";
2619
2599
  import tailwindcss from "@tailwindcss/vite";
@@ -2664,7 +2644,7 @@ export default defineConfig({
2664
2644
  },
2665
2645
  },
2666
2646
  });
2667
- `,Jt=`import js from "@eslint/js";
2647
+ `,oo=`import js from "@eslint/js";
2668
2648
  import jsxA11y from "eslint-plugin-jsx-a11y";
2669
2649
  import reactHooks from "eslint-plugin-react-hooks";
2670
2650
  import simpleImportSort from "eslint-plugin-simple-import-sort";
@@ -2693,14 +2673,14 @@ export default tseslint.config(
2693
2673
  },
2694
2674
  },
2695
2675
  );
2696
- `,Wt=`{
2676
+ `,ao=`{
2697
2677
  "printWidth": 100
2698
2678
  }
2699
- `,Gt=`pnpm-lock.yaml
2679
+ `,no=`pnpm-lock.yaml
2700
2680
  src/lexy-theme.css
2701
2681
  public/fonts/
2702
2682
  dist/
2703
- `,Yt=`name: CI
2683
+ `,ro=`name: CI
2704
2684
 
2705
2685
  on:
2706
2686
  push:
@@ -2723,7 +2703,7 @@ jobs:
2723
2703
  - run: pnpm check:data-contract
2724
2704
  - run: pnpm build:app
2725
2705
  - run: pnpm audit --audit-level high
2726
- `,Qt=`{
2706
+ `,io=`{
2727
2707
  "files": [],
2728
2708
  "references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }],
2729
2709
  "compilerOptions": {
@@ -2731,7 +2711,7 @@ jobs:
2731
2711
  "paths": { "@/*": ["./src/*"] }
2732
2712
  }
2733
2713
  }
2734
- `,Xt=`{
2714
+ `,so=`{
2735
2715
  "compilerOptions": {
2736
2716
  "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
2737
2717
  "target": "ES2022",
@@ -2755,7 +2735,7 @@ jobs:
2755
2735
  },
2756
2736
  "include": ["src"]
2757
2737
  }
2758
- `,Zt=`{
2738
+ `,lo=`{
2759
2739
  "compilerOptions": {
2760
2740
  "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
2761
2741
  "target": "ES2023",
@@ -2772,7 +2752,7 @@ jobs:
2772
2752
  },
2773
2753
  "include": ["vite.config.ts"]
2774
2754
  }
2775
- `,eo=e=>`<!doctype html>
2755
+ `,co=e=>`<!doctype html>
2776
2756
  <html lang="es">
2777
2757
  <head>
2778
2758
  <meta charset="UTF-8" />
@@ -2784,9 +2764,9 @@ jobs:
2784
2764
  <script type="module" src="/src/main.tsx"></script>
2785
2765
  </body>
2786
2766
  </html>
2787
- `,to=`@import "tailwindcss";
2767
+ `,po=`@import "tailwindcss";
2788
2768
  @import "./lexy-theme.css";
2789
- `,oo=e=>e.architecture==="feature"?`import "./index.css";
2769
+ `,mo=e=>e.architecture==="feature"?`import "./index.css";
2790
2770
 
2791
2771
  import { StrictMode } from "react";
2792
2772
  import { createRoot } from "react-dom/client";
@@ -2813,20 +2793,20 @@ createRoot(document.getElementById("root")!).render(
2813
2793
  <App />
2814
2794
  </StrictMode>,
2815
2795
  );
2816
- `,Ke=` <main className="flex min-h-screen items-center justify-center bg-background text-foreground">
2796
+ `,Ye=` <main className="flex min-h-screen items-center justify-center bg-background text-foreground">
2817
2797
  <div className="text-center">
2818
2798
  <h1 className="text-2xl font-semibold">Proyecto Lexy listo</h1>
2819
2799
  <p className="mt-2 text-sm text-muted-foreground">
2820
2800
  Trae tu primer componente: <code>npx create-lexy add button</code>
2821
2801
  </p>
2822
2802
  </div>
2823
- </main>`,ao=e=>e.architecture==="feature"?`import { Route, Routes } from "react-router";
2803
+ </main>`,uo=e=>e.architecture==="feature"?`import { Route, Routes } from "react-router";
2824
2804
 
2825
2805
  import { PrototypeDesignerPanel } from "../prototype/designer-panel/PrototypeDesignerPanel";
2826
2806
 
2827
2807
  const Home = () => {
2828
2808
  return (
2829
- ${Ke}
2809
+ ${Ye}
2830
2810
  );
2831
2811
  };
2832
2812
 
@@ -2849,22 +2829,22 @@ const showPrototypeDesignerPanel = import.meta.env.DEV;
2849
2829
  export const App = () => {
2850
2830
  return (
2851
2831
  <>
2852
- ${Ke}
2832
+ ${Ye}
2853
2833
  {showPrototypeDesignerPanel ? <PrototypeDesignerPanel /> : null}
2854
2834
  </>
2855
2835
  );
2856
2836
  };
2857
- `,no=`import { type ClassValue, clsx } from "clsx";
2837
+ `,yo=`import { type ClassValue, clsx } from "clsx";
2858
2838
  import { twMerge } from "tailwind-merge";
2859
2839
 
2860
2840
  export function cn(...inputs: ClassValue[]) {
2861
2841
  return twMerge(clsx(inputs));
2862
2842
  }
2863
- `,ro=`node_modules/
2843
+ `,fo=`node_modules/
2864
2844
  dist/
2865
2845
  *.log
2866
2846
  .env
2867
- `,io=e=>`# ${e.projectName}
2847
+ `,go=e=>`# ${e.projectName}
2868
2848
 
2869
2849
  Proyecto Lexy (React + Vite + TS + theme Lexy). Los componentes viven en tu proyecto: m\xEDralos con \`view\`, inst\xE1lalos con \`add\`, ed\xEDtalos con libertad.
2870
2850
 
@@ -2875,29 +2855,58 @@ npx create-lexy view button # ver un componente antes de instalarlo
2875
2855
  npx create-lexy add button # instalarlo (local y editable)
2876
2856
  npx create-lexy doctor # divergencia con el registry
2877
2857
  \`\`\`
2878
- `,so=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":`${F}@latest/r/{name}.json`}},null,2)+`
2879
- `},lo=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:F},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"},prototype:{dataContractVersion:"1",dataContractPath:re,runtimeVersion:"1",mockStorePath:ce,fixturesPath:de,portsPath:pe,designerPanelVersion:"1",designerPanelPath:le,designerActivityStorePath:se},installed:{}}},Ue=async(e,t)=>{let o=["package.json","src","index.html",".lexy"],a=[];for(let s of o)try{await b.access(w.join(t,s)),a.push(s)}catch{}if(a.length>0)throw new Error(`El directorio actual ya contiene archivos de un proyecto (${a.join(", ")}). Ejecuta el comando dentro de una carpeta vac\xEDa.`);for(let s of Kt[e.architecture])await b.mkdir(w.join(t,s),{recursive:!0});let n=(s,u)=>b.writeFile(w.join(t,s),u);await n("package.json",Ht(e)),await n("vite.config.ts",Bt),await n("tsconfig.json",Qt),await n("tsconfig.app.json",Xt),await n("tsconfig.node.json",Zt),await n("eslint.config.js",Jt),await n(".prettierrc",Wt),await n(".prettierignore",Gt),await b.mkdir(w.join(t,".github/workflows"),{recursive:!0}),await n(".github/workflows/ci.yml",Yt),await n("index.html",eo(e)),await n(".gitignore",ro),await n("README.md",io(e)),await n("src/index.css",to),await n("src/main.tsx",oo(e)),await ze(t,e.projectName),await Ve(t);let r=lo(e);await $e(t,r);let i=e.architecture==="feature"?"src/app":"src/views";await n(`${i}/App.tsx`,ao(e)),await n(".lexy",JSON.stringify(r,null,2)+`
2880
- `),await n("components.json",so(e)),await b.copyFile(Ie,w.join(t,"src/lexy-theme.css")),await b.mkdir(w.join(t,"public/fonts"),{recursive:!0}),await b.cp(Ce,w.join(t,"public/fonts"),{recursive:!0});let d=w.join(t,r.paths.lib,"utils");await b.mkdir(d,{recursive:!0}),await b.writeFile(w.join(d,"cn.ts"),no),await co(t)},co=async e=>{let t=[],o=async a=>{let n;try{n=await b.readdir(a,{withFileTypes:!0})}catch{return}for(let r of n){let i=w.join(a,r.name);r.isDirectory()?await o(i):/\.(ts|tsx)$/.test(r.name)&&t.push(i)}};await o(w.join(e,"src")),await o(w.join(e,"scripts"));for(let a of t){let n=await b.readFile(a,"utf-8"),r=await Vt(a)??{},i=await qt(n,{...r,filepath:a});i!==n&&await b.writeFile(a,i)}};var fo=["feature","layer"],go=["cliente","crm","mixto"],xo=e=>new Promise((t,o)=>{po("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}`)))}),He=async(e,t)=>{let o;!!(e&&t.type)?(fo.includes(t.type)||(console.error(j.red(`Error: la arquitectura "${t.type}" no es v\xE1lida. Usa "feature" o "layer".`)),process.exit(1)),t.world&&!go.includes(t.world)&&(console.error(j.red(`Error: el mundo "${t.world}" no es v\xE1lido. Usa "cliente", "crm" o "mixto".`)),process.exit(1)),t.world||console.warn(j.yellow('Aviso: sin --world; se asume "mixto". ')+j.dim("Pasa --world cliente|crm para fijar densidad y voz desde el inicio.")),o={projectName:e,architecture:t.type,world:t.world??"mixto"},console.log(j.blue("Modo automatizado detectado. Saltando interfaz interactiva..."))):o=await Ae(e),mo(`Nombre: ${o.projectName}
2858
+ `,xo=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":`${q}@latest/r/{name}.json`}},null,2)+`
2859
+ `},ho=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:q},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"},prototype:{dataContractVersion:"1",dataContractPath:ge,runtimeVersion:"1",mockStorePath:be,fixturesPath:we,portsPath:Se,designerPanelVersion:"1",designerPanelPath:ve,designerActivityStorePath:he},installed:{}}},Qe=async(e,t)=>{let o=["package.json","src","index.html",".lexy"],a=[];for(let s of o)try{await S.access(k.join(t,s)),a.push(s)}catch{}if(a.length>0)throw new Error(`El directorio actual ya contiene archivos de un proyecto (${a.join(", ")}). Ejecuta el comando dentro de una carpeta vac\xEDa.`);for(let s of Zt[e.architecture])await S.mkdir(k.join(t,s),{recursive:!0});let n=(s,m)=>S.writeFile(k.join(t,s),m);await n("package.json",eo(e)),await n("vite.config.ts",to),await n("tsconfig.json",io),await n("tsconfig.app.json",so),await n("tsconfig.node.json",lo),await n("eslint.config.js",oo),await n(".prettierrc",ao),await n(".prettierignore",no),await S.mkdir(k.join(t,".github/workflows"),{recursive:!0}),await n(".github/workflows/ci.yml",ro),await n("index.html",co(e)),await n(".gitignore",fo),await n("README.md",go(e)),await n("src/index.css",po),await n("src/main.tsx",mo(e)),await Ke(t,e.projectName),await Ge(t);let r=ho(e);await Je(t,r);let i=e.architecture==="feature"?"src/app":"src/views";await n(`${i}/App.tsx`,uo(e)),await n(".lexy",JSON.stringify(r,null,2)+`
2860
+ `),await n("components.json",xo(e)),await S.copyFile(Fe,k.join(t,"src/lexy-theme.css")),await S.mkdir(k.join(t,"public/fonts"),{recursive:!0}),await S.cp(Ve,k.join(t,"public/fonts"),{recursive:!0});let p=k.join(t,r.paths.lib,"utils");await S.mkdir(p,{recursive:!0}),await S.writeFile(k.join(p,"cn.ts"),yo),await vo(t)},vo=async e=>{let t=[],o=async a=>{let n;try{n=await S.readdir(a,{withFileTypes:!0})}catch{return}for(let r of n){let i=k.join(a,r.name);r.isDirectory()?await o(i):/\.(ts|tsx)$/.test(r.name)&&t.push(i)}};await o(k.join(e,"src")),await o(k.join(e,"scripts"));for(let a of t){let n=await S.readFile(a,"utf-8"),r=await Xt(a)??{},i=await Qt(n,{...r,filepath:a});i!==n&&await S.writeFile(a,i)}};var et=e=>{let t=Number(e.match(/(\d+)/)?.[1]??0),o=Number(process.versions.node.split(".")[0]);!t||o>=t||(console.error(W.red(`
2861
+ Node ${process.versions.node} es muy antiguo \u2014 create-lexy necesita Node ${e}.
2862
+ `)+W.dim(`Actualiza Node (https://nodejs.org) o usa un gestor de versiones (nvm, fnm) y vuelve a intentarlo.
2863
+ `)),process.exit(1))},Pe=()=>{try{return Ze("pnpm",["--version"],{stdio:"ignore"}),!0}catch{return!1}},ko=()=>{try{return Ze("corepack",["--version"],{stdio:"ignore"}),!0}catch{return!1}},Po=()=>{let e=ke("corepack",["enable"],{stdio:"ignore"}),t=ke("corepack",["prepare",`pnpm@${B}`,"--activate"],{stdio:"ignore"});return e.status===0&&t.status===0&&Pe()},Eo=()=>ke("npm",["install","-g",`pnpm@${B}`],{stdio:"ignore",shell:!0}).status===0&&Pe(),Xe=`\`corepack enable && corepack prepare pnpm@${B} --activate\` (o \`npm install -g pnpm\`)`,ae=async()=>{if(Pe())return;if(console.log(W.yellow("pnpm no est\xE1 instalado.")+W.dim(" create-lexy lo usa para instalar las dependencias del proyecto.")),!!(process.stdout.isTTY&&process.stdin.isTTY)){let a=await bo({message:"\xBFInstalar pnpm ahora?",initialValue:!0});if(wo(a)||!a)throw new Error(`pnpm es necesario. Inst\xE1lalo con ${Xe} y vuelve a intentarlo.`)}else console.log(W.dim("Modo no interactivo: intentando instalar pnpm autom\xE1ticamente..."));let t=So();t.start("Instalando pnpm...");let o=ko()?Po():Eo();if(t.stop(o?"pnpm instalado":"No se pudo instalar pnpm autom\xE1ticamente"),!o)throw new Error(`No se pudo instalar pnpm autom\xE1ticamente. Inst\xE1lalo con ${Xe} y vuelve a intentarlo.`)};import tt from"fs/promises";import Co from"path";var ot=e=>Co.join(e,".lexy"),z=async e=>{let t;try{t=await tt.readFile(ot(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},at=async(e,t)=>{await tt.writeFile(ot(e),JSON.stringify(t,null,2)+`
2864
+ `)};var No=(e,t)=>new Promise((o,a)=>{jo("pnpm",["add",...e],{cwd:t,stdio:"ignore",shell:!0}).on("close",r=>r===0?o():a(new Error(`pnpm add fall\xF3 con c\xF3digo ${r}`)))}),Ro=async(e,t="utf-8")=>{try{return await re.readFile(e,t)}catch{return null}},ie=async(e,t)=>{let o=process.cwd(),a=await z(o),n=nt();n.start("Resolviendo componentes en el registry...");let r=new Map,i=async d=>{let g=d.toLowerCase().replace(/^@lexy\//,"");if(r.has(g))return;let l=await C(g);r.set(g,l);for(let c of l.item.registryDependencies??[])await i(c)};try{for(let d of e)await i(d)}catch(d){throw n.stop(P.red("No se pudo resolver el pedido.")),d}let p=new Map;for(let[d,{item:g}]of r){let l=[];for(let c of O(g,a)){let f=await Ro(ne.join(o,c.relPath),c.encoding??"utf-8");l.push({...c,status:f===null?"new":f===c.content?"same":"differs"})}p.set(d,l)}let s=Array.from(p.values()).flat().filter(d=>d.status==="differs");if(n.stop(`Resueltos: ${Array.from(r.keys()).join(", ")}`),s.length>0&&!t.overwrite){let d=s.map(g=>` ${g.relPath}`).join(`
2865
+ `);if(process.stdout.isTTY&&process.stdin.isTTY){let g=await Io({message:`Estos archivos existen con cambios locales y ser\xE1n sobrescritos:
2866
+ ${d}
2867
+ \xBFContinuar?`});if(To(g)||g!==!0){console.log(P.yellow("Operaci\xF3n cancelada \u2014 nada fue modificado.")),process.exitCode=1;return}}else{console.error(P.red(`Estos archivos existen con cambios locales:
2868
+ `)+d+P.dim(`
2869
+ Usa --overwrite para sobrescribirlos.`)),process.exitCode=1;return}}for(let[d,g]of p){let{item:l,version:c,source:f}=r.get(d);for(let h of g){if(h.status==="same")continue;let _=ne.join(o,h.relPath);await re.mkdir(ne.dirname(_),{recursive:!0}),await re.writeFile(_,h.content,h.encoding??"utf-8")}a.installed[l.name]=c;let b=e.map(h=>h.toLowerCase()).includes(d)?"":P.dim(" (dependencia)"),K=f==="bundle"?P.yellow(" [bundle local \u2014 sin red]"):"";console.log(P.green(`${P.bold(l.title??l.name)} instalado`)+b+P.cyan(` \u2192 ${a.paths.components}/`)+K);for(let h of g){let _=h.status==="same"?P.dim(" (sin cambios)"):"";console.log(P.dim(` ${h.relPath}${_}`))}}await at(o,a);let m=new Set;for(let{item:d}of r.values())for(let g of d.dependencies??[])m.add(g);let u=JSON.parse(await re.readFile(ne.join(o,"package.json"),"utf-8")),y={...u.dependencies,...u.devDependencies},R=d=>{let g=d.lastIndexOf("@");return g>0?d.slice(0,g):d},v=Array.from(m).filter(d=>!y[R(d)]);if(v.length>0)if(t.install===!1)console.log(P.yellow(`Dependencias pendientes (inst\xE1lalas t\xFA): ${v.join(", ")}`));else{await ae();let d=nt();d.start(`Instalando dependencias: ${v.join(", ")}...`),await No(v,o),d.stop("Dependencias instaladas.")}};import{spawn as zo}from"child_process";import{note as Mo,outro as $o,spinner as Fo}from"@clack/prompts";import T from"picocolors";import{cancel as _o,intro as Oo,isCancel as Ao,select as it,text as Lo}from"@clack/prompts";import st from"picocolors";var Ee=[{value:"screen",label:"Una pantalla o flujo corto",hint:"landing, formulario, demo \u2014 sin navegaci\xF3n entre secciones",architecture:"layer"},{value:"app",label:"Una app con secciones y navegaci\xF3n",hint:"dashboard, listados, detalle \u2014 varias vistas con router",architecture:"feature"}],rt=e=>Ee.find(t=>t.value===e).architecture;var Do=`
2870
+ ###### ######
2871
+ ##::+#### ####+::##
2872
+ #-..:+################+:..:#
2873
+ #+...=################=...+#
2874
+ #=-*##################*-=#
2875
+ ########################
2876
+ ==-:.:=*##########*=:.::==
2877
+ **#####*+--*####*--+*#####**
2878
+ ##########%@@#:-##=.#@@%##########
2879
+ #######*+*#%%*:-@@=.+%%#*+*#######
2880
+ #+:..........:*#:..........:=#
2881
+ ...........:====:...........
2882
+ ......................
2883
+ ..............
2884
+ `,Ce=e=>{Ao(e)&&(_o("Operaci\xF3n cancelada por el usuario."),process.exit(0))},lt=async e=>{console.clear(),Oo(`${st.cyan(Do)}
2885
+ ${st.bold(" Bienvenido al generador de proyectos Lexy")}`);let t=e;if(!t){let n=await Lo({message:"\xBFCu\xE1l es el nombre de tu proyecto?",placeholder:"lexy-app",validate:r=>{if(!r||r.trim()==="")return"El nombre es obligatorio.";if(!/^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(r))return"El nombre debe estar en min\xFAsculas, sin espacios ni caracteres especiales."}});Ce(n),t=n}let o=await it({message:"\xBFPara qui\xE9n es este proyecto?",options:[{label:"Clientes de Lexy",value:"cliente",hint:"Producto de cara al cliente final"},{label:"Equipo interno / CRM",value:"crm",hint:"Herramienta densa para el equipo Lexy"},{label:"Ambos o a\xFAn no lo s\xE9",value:"mixto",hint:"Se decide por pantalla m\xE1s adelante"}],initialValue:"mixto"});Ce(o);let a=await it({message:"\xBFC\xF3mo es lo que vas a construir?",options:Ee.map(n=>({label:n.label,value:n.value,hint:n.hint})),initialValue:"app"});return Ce(a),{projectName:t,architecture:rt(a),world:o}};var Vo=["feature","layer"],qo=["cliente","crm","mixto"],Uo=e=>new Promise((t,o)=>{zo("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}`)))}),se=async(e,t)=>{let o;!!(e&&t.type)?(Vo.includes(t.type)||(console.error(T.red(`Error: la arquitectura "${t.type}" no es v\xE1lida. Usa "feature" o "layer".`)),process.exit(1)),t.world&&!qo.includes(t.world)&&(console.error(T.red(`Error: el mundo "${t.world}" no es v\xE1lido. Usa "cliente", "crm" o "mixto".`)),process.exit(1)),t.world||console.warn(T.yellow('Aviso: sin --world; se asume "mixto". ')+T.dim("Pasa --world cliente|crm para fijar densidad y voz desde el inicio.")),o={projectName:e,architecture:t.type,world:t.world??"mixto"},console.log(T.blue("Modo automatizado detectado. Saltando interfaz interactiva..."))):o=await lt(e),Mo(`Nombre: ${o.projectName}
2881
2886
  Arquitectura: ${o.architecture}
2882
- Mundo: ${o.world}`,"Configuraci\xF3n de Proyecto");let n=yo();n.start("Construyendo tu proyecto...");let r=process.cwd();try{await Ue(o,r)}catch(i){throw n.stop(j.red("No se pudo crear el proyecto.")),i}t.install!==!1&&(n.message("Instalando dependencias base..."),await xo(r)),n.stop("\xA1Proyecto construido con \xE9xito!"),uo(j.green(`Todo listo en el directorio actual
2887
+ Mundo: ${o.world}`,"Configuraci\xF3n de Proyecto"),t.install!==!1&&await ae();let n=Fo();n.start("Construyendo tu proyecto...");let r=process.cwd();try{await Qe(o,r)}catch(i){throw n.stop(T.red("No se pudo crear el proyecto.")),i}t.install!==!1&&(n.message("Instalando dependencias base..."),await Uo(r)),n.stop("\xA1Proyecto construido con \xE9xito!"),$o(T.green(`Todo listo en el directorio actual
2883
2888
 
2884
- `)+j.dim(`Siguientes pasos:
2885
- `)+j.cyan(` pnpm dev
2886
- `)+j.cyan(" npx create-lexy add button"))};import ho from"fs/promises";import vo from"path";import S from"picocolors";import me from"picocolors";var V=(e,t)=>{let o=e.split(`
2889
+ `)+T.dim(`Siguientes pasos:
2890
+ `)+T.cyan(` pnpm dev
2891
+ `)+T.cyan(" npx create-lexy add button"))};import Ko from"fs/promises";import Ho from"path";import E from"picocolors";import je from"picocolors";var G=(e,t)=>{let o=e.split(`
2887
2892
  `),a=t.split(`
2888
- `),n=o.length,r=a.length,i=Array.from({length:n+1},()=>new Array(r+1).fill(0));for(let m=n-1;m>=0;m--)for(let y=r-1;y>=0;y--)i[m][y]=o[m]===a[y]?i[m+1][y+1]+1:Math.max(i[m+1][y],i[m][y+1]);let d=[],s=0,u=0;for(;s<n&&u<r;)o[s]===a[u]?(d.push({type:"same",text:o[s]}),s++,u++):i[s+1][u]>=i[s][u+1]?d.push({type:"del",text:o[s++]}):d.push({type:"add",text:a[u++]});for(;s<n;)d.push({type:"del",text:o[s++]});for(;u<r;)d.push({type:"add",text:a[u++]});return d},Q=e=>e.some(t=>t.type!=="same"),Be=(e,t=3)=>{if(!Q(e))return null;let o=new Array(e.length).fill(!1);e.forEach((r,i)=>{if(r.type!=="same")for(let d=Math.max(0,i-t);d<=Math.min(e.length-1,i+t);d++)o[d]=!0});let a=[],n=!1;for(let r=0;r<e.length;r++){if(!o[r]){n||(a.push(me.dim(" \u22EF")),n=!0);continue}n=!1;let i=e[r];i.type==="same"?a.push(` ${i.text}`):i.type==="del"?a.push(me.red(`- ${i.text}`)):a.push(me.green(`+ ${i.text}`))}return a.join(`
2889
- `)};var Je=async e=>{let t=process.cwd(),o=await _(t),a=e.toLowerCase(),{item:n,version:r}=await k(a),i=o.installed[a];console.log(S.bold(`
2890
- ${n.title??a}`)+S.dim(` \xB7 instalado con registry@${i??"?"} \xB7 vigente registry@${r}
2891
- `));let d=!1;for(let s of T(n,o)){let u=await ho.readFile(vo.join(t,s.relPath),s.encoding??"utf-8").catch(()=>null);if(u===null){console.log(S.red(`\u2717 ${s.relPath} no existe localmente`)+S.dim(` \u2014 cr\xE9alo con \`create-lexy add ${a}\``)),d=!0;continue}if(s.encoding==="base64"){u===s.content?console.log(S.green(`\u2713 ${s.relPath}`)+S.dim(" sin diferencias")):(d=!0,console.log(S.yellow(`\xB1 ${s.relPath}`)+S.dim(" (binario difiere del registry)")));continue}let m=Be(V(u,s.content));m===null?console.log(S.green(`\u2713 ${s.relPath}`)+S.dim(" sin diferencias")):(d=!0,console.log(S.yellow(`\xB1 ${s.relPath}`)+S.dim(" (\u2212 local \xB7 + registry)")),console.log(m))}d&&(process.exitCode=1)};import O from"fs/promises";import h from"path";import I from"picocolors";var We=async e=>{let t=process.cwd(),o=0,a=c=>console.log(I.green(" \u2713 ")+c),n=c=>console.log(I.yellow(" \u2022 ")+c),r=(c,l)=>{o=1,console.log(I.red(" \u2717 ")+c),l&&console.log(I.dim(` \u2192 ${l}`))};console.log(I.bold(`
2893
+ `),n=o.length,r=a.length,i=Array.from({length:n+1},()=>new Array(r+1).fill(0));for(let u=n-1;u>=0;u--)for(let y=r-1;y>=0;y--)i[u][y]=o[u]===a[y]?i[u+1][y+1]+1:Math.max(i[u+1][y],i[u][y+1]);let p=[],s=0,m=0;for(;s<n&&m<r;)o[s]===a[m]?(p.push({type:"same",text:o[s]}),s++,m++):i[s+1][m]>=i[s][m+1]?p.push({type:"del",text:o[s++]}):p.push({type:"add",text:a[m++]});for(;s<n;)p.push({type:"del",text:o[s++]});for(;m<r;)p.push({type:"add",text:a[m++]});return p},le=e=>e.some(t=>t.type!=="same"),ct=(e,t=3)=>{if(!le(e))return null;let o=new Array(e.length).fill(!1);e.forEach((r,i)=>{if(r.type!=="same")for(let p=Math.max(0,i-t);p<=Math.min(e.length-1,i+t);p++)o[p]=!0});let a=[],n=!1;for(let r=0;r<e.length;r++){if(!o[r]){n||(a.push(je.dim(" \u22EF")),n=!0);continue}n=!1;let i=e[r];i.type==="same"?a.push(` ${i.text}`):i.type==="del"?a.push(je.red(`- ${i.text}`)):a.push(je.green(`+ ${i.text}`))}return a.join(`
2894
+ `)};var dt=async e=>{let t=process.cwd(),o=await z(t),a=e.toLowerCase(),{item:n,version:r}=await C(a),i=o.installed[a];console.log(E.bold(`
2895
+ ${n.title??a}`)+E.dim(` \xB7 instalado con registry@${i??"?"} \xB7 vigente registry@${r}
2896
+ `));let p=!1;for(let s of O(n,o)){let m=await Ko.readFile(Ho.join(t,s.relPath),s.encoding??"utf-8").catch(()=>null);if(m===null){console.log(E.red(`\u2717 ${s.relPath} no existe localmente`)+E.dim(` \u2014 cr\xE9alo con \`create-lexy add ${a}\``)),p=!0;continue}if(s.encoding==="base64"){m===s.content?console.log(E.green(`\u2713 ${s.relPath}`)+E.dim(" sin diferencias")):(p=!0,console.log(E.yellow(`\xB1 ${s.relPath}`)+E.dim(" (binario difiere del registry)")));continue}let u=ct(G(m,s.content));u===null?console.log(E.green(`\u2713 ${s.relPath}`)+E.dim(" sin diferencias")):(p=!0,console.log(E.yellow(`\xB1 ${s.relPath}`)+E.dim(" (\u2212 local \xB7 + registry)")),console.log(u))}p&&(process.exitCode=1)};import M from"fs/promises";import w from"path";import N from"picocolors";var ce=async e=>{let t=process.cwd(),o=0,a=l=>console.log(N.green(" \u2713 ")+l),n=l=>console.log(N.yellow(" \u2022 ")+l),r=(l,c)=>{o=1,console.log(N.red(" \u2717 ")+l),c&&console.log(N.dim(` \u2192 ${c}`))};console.log(N.bold(`
2892
2897
  Diagn\xF3stico del proyecto Lexy
2893
- `));let i;try{i=await _(t),a(`.lexy v\xE1lido (arquitectura ${i.architecture}${i.world?`, mundo ${i.world}`:""})`)}catch(c){return r(c.message),1}await O.access(h.join(t,"src/lexy-theme.css")).then(()=>!0,()=>!1)?a("theme presente (src/lexy-theme.css)"):r("falta src/lexy-theme.css","re-cr\xE9alo desde un proyecto nuevo o copia el theme del registry");let s=h.join(i.paths.lib,"utils/cn.ts");await O.access(h.join(t,s)).then(()=>!0,()=>!1)?a(`helper cn presente (${s})`):r(`falta el helper cn (${s})`);let m=await O.readFile(h.join(t,"package.json"),"utf-8").then(c=>JSON.parse(c)).catch(()=>null),y=async(c,l)=>{await O.access(h.join(t,c)).then(()=>!0,()=>!1)?a(`${l} presente (${c})`):r(`falta ${l} (${c})`)},z=(c,l)=>{if(!m){r("package.json no se pudo leer para validar scripts del prototipo");return}let g=m.scripts?.[c];if(!g){r(`falta el script ${c} en package.json`,l?`agrega \`${l}\``:void 0);return}if(l&&!g.includes(l)){r(`el script ${c} no ejecuta ${l}`);return}a(`script ${c} configurado`)};if(!i.prototype)n("prototipo funcional no habilitado \u2014 proyecto anterior al runtime de datos y ports");else{let c=i.prototype.dataContractPath;if(!c)n("contrato de datos no configurado \u2014 proyecto anterior a la Spec 1");else{await y(c,"contrato de datos");let l=h.join(h.dirname(c),"data-contract-schema.ts");await y(l,"schema del contrato"),await y("scripts/check-data-contract.ts","validador del contrato"),z("check:data-contract","tsx scripts/check-data-contract.ts")}i.prototype.runtimeVersion?(i.prototype.mockStorePath?(await y(i.prototype.mockStorePath,"mock-store del prototipo"),await y(h.join(h.dirname(i.prototype.mockStorePath),"fixtures.ts"),"fixtures del prototipo")):r("mockStorePath no est\xE1 configurado en .lexy"),i.prototype.portsPath?await y(i.prototype.portsPath,"ports del prototipo"):r("portsPath no est\xE1 configurado en .lexy")):n("runtime del prototipo no habilitado \u2014 proyecto anterior a la Spec 2"),i.prototype.designerPanelVersion?(i.prototype.designerPanelPath?await y(i.prototype.designerPanelPath,"panel de asistencia al Designer"):r("designerPanelPath no est\xE1 configurado en .lexy"),i.prototype.designerActivityStorePath?await y(i.prototype.designerActivityStorePath,"store de actividad del Designer"):r("designerActivityStorePath no est\xE1 configurado en .lexy")):n("panel de asistencia al Designer no habilitado \u2014 proyecto anterior a la Spec 4")}let M=h.join(t,"ai/lexy-ai-manifest.json"),p=await O.readFile(M,"utf-8").catch(()=>null);if(p===null)console.log(I.dim(" \xB7 capa de IA no instalada (npx @lexydesign/ai install) \u2014 opcional"));else try{let c=JSON.parse(p),l=c.files??[],g=[];for(let P of l)await O.access(h.join(t,P)).then(()=>!0,()=>!1)||g.push(P);g.length>0?r(`capa de IA ${c.aiVersion??"?"} incompleta \u2014 faltan ${g.length} archivo(s) (${g.slice(0,3).join(", ")}${g.length>3?", \u2026":""})`,"npx @lexydesign/ai install"):a(`capa de IA ${c.aiVersion??"?"} completa (${l.length} archivos)`)}catch{r("ai/lexy-ai-manifest.json no es JSON v\xE1lido","regenera con `npx @lexydesign/ai install`")}let f=Object.entries(i.installed);if(f.length===0)console.log(I.dim(`
2894
- Sin componentes instalados a\xFAn (create-lexy add <nombre>).`));else{let c=await W();console.log(I.bold(`
2895
- Componentes instalados (registry vigente: ${c})
2896
- `));for(let[l,g]of f){let P;try{P=await k(l)}catch(L){r(`${l}: ${L.message}`);continue}let U=T(P.item,i),x=[],A=!1;for(let L of U){let H=await O.readFile(h.join(t,L.relPath),"utf-8").catch(()=>null);H===null?x.push(L.relPath):Q(V(H,L.content))&&(A=!0)}if(x.length>0){r(`${l}: archivos faltantes (${x.join(", ")})`,`create-lexy add ${l}`);continue}if(!A){a(`${l} al d\xEDa (${P.version})`);continue}let ee=!0;if(g&&g!==P.version)try{let L=await k(l,g),H=T(L.item,i);ee=!1;for(let ve of H){let be=await O.readFile(h.join(t,ve.relPath),"utf-8").catch(()=>null);(be===null||Q(V(be,ve.content)))&&(ee=!0)}}catch{}ee?e.strict?r(`${l}: editado localmente (difiere del registry vigente)`,`create-lexy diff ${l}`):n(`${l}: editado localmente \u2014 divergencia deliberada (m\xEDrala con \`create-lexy diff ${l}\`)`):r(`${l}: desactualizado (instalado con ${g}, vigente ${P.version})`,`create-lexy diff ${l} \xB7 create-lexy add ${l} --overwrite`)}}return console.log(o===0?I.green(`
2898
+ `));let i;try{i=await z(t),a(`.lexy v\xE1lido (arquitectura ${i.architecture}${i.world?`, mundo ${i.world}`:""})`)}catch(l){return r(l.message),1}await M.access(w.join(t,"src/lexy-theme.css")).then(()=>!0,()=>!1)?a("theme presente (src/lexy-theme.css)"):r("falta src/lexy-theme.css","re-cr\xE9alo desde un proyecto nuevo o copia el theme del registry");let s=w.join(i.paths.lib,"utils/cn.ts");await M.access(w.join(t,s)).then(()=>!0,()=>!1)?a(`helper cn presente (${s})`):r(`falta el helper cn (${s})`);let u=await M.readFile(w.join(t,"package.json"),"utf-8").then(l=>JSON.parse(l)).catch(()=>null),y=async(l,c)=>{await M.access(w.join(t,l)).then(()=>!0,()=>!1)?a(`${c} presente (${l})`):r(`falta ${c} (${l})`)},R=(l,c)=>{if(!u){r("package.json no se pudo leer para validar scripts del prototipo");return}let f=u.scripts?.[l];if(!f){r(`falta el script ${l} en package.json`,c?`agrega \`${c}\``:void 0);return}if(c&&!f.includes(c)){r(`el script ${l} no ejecuta ${c}`);return}a(`script ${l} configurado`)};if(!i.prototype)n("prototipo funcional no habilitado \u2014 proyecto anterior al runtime de datos y ports");else{let l=i.prototype.dataContractPath;if(!l)n("contrato de datos no configurado \u2014 proyecto anterior a la Spec 1");else{await y(l,"contrato de datos");let c=w.join(w.dirname(l),"data-contract-schema.ts");await y(c,"schema del contrato"),await y("scripts/check-data-contract.ts","validador del contrato"),R("check:data-contract","tsx scripts/check-data-contract.ts")}i.prototype.runtimeVersion?(i.prototype.mockStorePath?(await y(i.prototype.mockStorePath,"mock-store del prototipo"),await y(w.join(w.dirname(i.prototype.mockStorePath),"fixtures.ts"),"fixtures del prototipo")):r("mockStorePath no est\xE1 configurado en .lexy"),i.prototype.portsPath?await y(i.prototype.portsPath,"ports del prototipo"):r("portsPath no est\xE1 configurado en .lexy")):n("runtime del prototipo no habilitado \u2014 proyecto anterior a la Spec 2"),i.prototype.designerPanelVersion?(i.prototype.designerPanelPath?await y(i.prototype.designerPanelPath,"panel de asistencia al Designer"):r("designerPanelPath no est\xE1 configurado en .lexy"),i.prototype.designerActivityStorePath?await y(i.prototype.designerActivityStorePath,"store de actividad del Designer"):r("designerActivityStorePath no est\xE1 configurado en .lexy")):n("panel de asistencia al Designer no habilitado \u2014 proyecto anterior a la Spec 4")}let v=w.join(t,"ai/lexy-ai-manifest.json"),d=await M.readFile(v,"utf-8").catch(()=>null);if(d===null)console.log(N.dim(" \xB7 capa de IA no instalada (npx create-lexy install-ai) \u2014 opcional"));else try{let l=JSON.parse(d),c=l.files??[],f=[];for(let b of c)await M.access(w.join(t,b)).then(()=>!0,()=>!1)||f.push(b);f.length>0?r(`capa de IA ${l.aiVersion??"?"} incompleta \u2014 faltan ${f.length} archivo(s) (${f.slice(0,3).join(", ")}${f.length>3?", \u2026":""})`,"npx create-lexy install-ai"):a(`capa de IA ${l.aiVersion??"?"} completa (${c.length} archivos)`)}catch{r("ai/lexy-ai-manifest.json no es JSON v\xE1lido","regenera con `npx create-lexy install-ai`")}let g=Object.entries(i.installed);if(g.length===0)console.log(N.dim(`
2899
+ Sin componentes instalados a\xFAn (create-lexy add <nombre>).`));else{let l=await te();console.log(N.bold(`
2900
+ Componentes instalados (registry vigente: ${l})
2901
+ `));for(let[c,f]of g){let b;try{b=await C(c)}catch($){r(`${c}: ${$.message}`);continue}let K=O(b.item,i),h=[],_=!1;for(let $ of K){let X=await M.readFile(w.join(t,$.relPath),"utf-8").catch(()=>null);X===null?h.push($.relPath):le(G(X,$.content))&&(_=!0)}if(h.length>0){r(`${c}: archivos faltantes (${h.join(", ")})`,`create-lexy add ${c}`);continue}if(!_){a(`${c} al d\xEDa (${b.version})`);continue}let H=!0;if(f&&f!==b.version)try{let $=await C(c,f),X=O($.item,i);H=!1;for(let De of X){let ze=await M.readFile(w.join(t,De.relPath),"utf-8").catch(()=>null);(ze===null||le(G(ze,De.content)))&&(H=!0)}}catch{}H?e.strict?r(`${c}: editado localmente (difiere del registry vigente)`,`create-lexy diff ${c}`):n(`${c}: editado localmente \u2014 divergencia deliberada (m\xEDrala con \`create-lexy diff ${c}\`)`):r(`${c}: desactualizado (instalado con ${f}, vigente ${b.version})`,`create-lexy diff ${c} \xB7 create-lexy add ${c} --overwrite`)}}return console.log(o===0?N.green(`
2897
2902
  Todo en orden.
2898
- `):I.red(`
2903
+ `):N.red(`
2899
2904
  Hay problemas que atender (exit 1).
2900
- `)),o};import ue from"fs/promises";import Ge from"path";import{note as bo,outro as wo}from"@clack/prompts";import ye from"picocolors";var X="LEXY-KICKOFF.md",So=`# Kickoff de proyecto Lexy \u2014 protocolo de entrevista
2905
+ `)),o};import L from"fs/promises";import j from"path";import U from"picocolors";import pt from"path";import{fileURLToPath as Jo}from"url";var Ie=pt.resolve(pt.dirname(Jo(import.meta.url)),"../templates");var Te="ai/lexy-ai-manifest.json",Bo=new Set(["ai/PROJECT-CONTEXT.md"]),Ne=async e=>{try{return JSON.parse(await L.readFile(e,"utf-8"))}catch{return null}},mt=async(e,t=e)=>{let o=[];for(let a of await L.readdir(e,{withFileTypes:!0})){let n=j.join(e,a.name);a.isDirectory()?o.push(...await mt(n,t)):o.push(j.relative(t,n))}return o},Y=async(e,t)=>{let o=process.cwd(),a=await Ne(j.join(o,".lexy"));a||console.log(U.yellow("Aviso: no hay .lexy en este directorio \u2014 se asumen rutas de arquitectura layer.")+U.dim(" (en proyectos create-lexy este archivo existe siempre)"));let n=a?.architecture??"layer",r=n==="feature",i=a?.paths?.components??(r?"src/shared/components/base":"src/components/base"),p=a?.componentImportPattern??(r?"@/shared/components/base/{Component}":"@/components/base/{Component}"),s=!!a?.prototype,m=!!(a?.prototype?.dataContractVersion&&a.prototype.dataContractPath),u=!!(a?.prototype?.runtimeVersion&&a.prototype.mockStorePath&&a.prototype.portsPath),y=!!(a?.prototype?.designerPanelVersion&&a.prototype.designerPanelPath&&a.prototype.designerActivityStorePath),R=(await mt(Ie)).sort(),v=[],d=[];for(let f of R){let b=j.join(o,f);if(await L.access(b).then(()=>!0,()=>!1)&&Bo.has(f)&&!e.force){d.push(f);continue}await L.mkdir(j.dirname(b),{recursive:!0});let h=await L.readFile(j.join(Ie,f),"utf-8");if(f==="ai/PROJECT-CONTEXT.md"){let _=await Ne(j.join(o,"package.json")),H={cliente:"cliente (persona en un momento dif\xEDcil)",crm:"CRM / equipo interno Lexy",mixto:"mixto \u2014 a\xFAn sin definir, pregunta al dise\xF1ador"};h=h.replaceAll("{{PROJECT_NAME}}",_?.name??j.basename(o)).replaceAll("{{WORLD}}",H[a?.world??"mixto"]??"mixto \u2014 a\xFAn sin definir").replaceAll("{{GENERATED_AT}}",new Date().toISOString().slice(0,10))}await L.writeFile(b,h),v.push(f)}let g=j.join(o,"package.json"),l=await Ne(g);l&&(l.scripts??={},l.scripts["lint:geometry"]||(l.scripts["lint:geometry"]="node scripts/check-geometry.mjs",await L.writeFile(g,JSON.stringify(l,null,2)+`
2906
+ `),v.push("package.json (script lint:geometry)")));let c={$comment:"Generado por create-lexy install-ai \u2014 no editar a mano; regenerar con `npx create-lexy install-ai`.",aiVersion:t,generatedAt:new Date().toISOString(),model:"registry-only: los componentes viven en este proyecto. Descubre con viewList, mira con view, instala con add, edita localmente con libertad; diff/doctor mantienen la divergencia visible.",registry:{package:a?.registry?.package??"@lexydesign/registry",cdn:a?.registry?.cdn??"https://cdn.jsdelivr.net/npm/@lexydesign/registry",catalogUrl:`${a?.registry?.cdn??"https://cdn.jsdelivr.net/npm/@lexydesign/registry"}@latest/r/registry.json`},commands:{viewList:"npx create-lexy view --list",view:"npx create-lexy view {component}",add:"npx create-lexy add {component}",diff:"npx create-lexy diff {component}",doctor:"npx create-lexy doctor"},architecture:n,componentImportPattern:p,componentsPath:i,docPattern:`${i}/{Component}.md`,prototype:s?{enabled:!0,dataContractVersion:m?a.prototype.dataContractVersion:null,dataContractPath:m?a.prototype.dataContractPath:null,runtimeEnabled:u,runtimeVersion:u?a.prototype.runtimeVersion:null,mockStorePath:u?a.prototype.mockStorePath:null,fixturesPath:u?a.prototype.fixturesPath:null,portsPath:u?a.prototype.portsPath:null,designerPanelEnabled:y,designerPanelVersion:y?a.prototype.designerPanelVersion:null,designerPanelPath:y?a.prototype.designerPanelPath:null,designerActivityStorePath:y?a.prototype.designerActivityStorePath:null,checkDataContractCommand:m?"pnpm check:data-contract":null,checkPrototypeCommand:m?"pnpm check:prototype":null,checkCommand:m?"pnpm check:data-contract":null}:{enabled:!1,dataContractVersion:null,dataContractPath:null,runtimeEnabled:!1,runtimeVersion:null,mockStorePath:null,fixturesPath:null,portsPath:null,designerPanelEnabled:!1,designerPanelVersion:null,designerPanelPath:null,designerActivityStorePath:null,checkDataContractCommand:null,checkPrototypeCommand:null,checkCommand:null},designGuidance:{"elecci\xF3n de mundo (cliente vs CRM)":"ai/pautas/diseno-cliente.md \xB7 ai/pautas/diseno-crm-lexy.md","jerarqu\xEDa y progressive disclosure":"ai/pautas/arquitectura-informacion-ux.md","densidad, espaciado, tokens, tipograf\xEDa":"ai/pautas/sistema-visual.md","elecci\xF3n de componentes y estados obligatorios":"ai/pautas/buenas-practicas.md","composiciones can\xF3nicas":"ai/pautas/recetas-layout.md","voz, tono y microcopy":"ai/pautas/ux-writing.md","vara de calidad / pase anti-gen\xE9rico":"ai/pautas/calidad-industria.md"},files:[...R,Te].sort()};await L.mkdir(j.join(o,"ai"),{recursive:!0}),await L.writeFile(j.join(o,Te),JSON.stringify(c,null,2)+`
2907
+ `),console.log(U.green(`
2908
+ \u2713 Capa de IA instalada (${n})`)),console.log(U.dim(` ${v.length} archivo(s) escritos, manifest generado \u2192 ${Te}`));for(let f of d)console.log(U.yellow(` \u2022 ${f} ya exist\xEDa \u2014 se conserv\xF3 (es el brief vivo; --force lo pisa)`));console.log(U.dim(`
2909
+ Entry points: AGENTS.md \xB7 CLAUDE.md \xB7 .claude/skills/ \xB7 .github/copilot-instructions.md`))};import Re from"fs/promises";import ut from"path";import{note as Wo,outro as Go}from"@clack/prompts";import _e from"picocolors";var de="LEXY-KICKOFF.md",Yo=`# Kickoff de proyecto Lexy \u2014 protocolo de entrevista
2901
2910
 
2902
2911
  > **Para el agente (Claude Code):** este archivo es tu guion. La persona que
2903
2912
  > tienes enfrente es **dise\xF1adora, no programadora**: no le preguntes por
@@ -2953,12 +2962,12 @@ En **esta misma carpeta vac\xEDa**, corre:
2953
2962
 
2954
2963
  \`\`\`bash
2955
2964
  npx create-lexy create <nombre> --type <layer|feature> --world <cliente|crm|mixto>
2956
- npx @lexydesign/ai install
2965
+ npx create-lexy install-ai
2957
2966
  \`\`\`
2958
2967
 
2959
2968
  ## 4. Volcar la entrevista en el brief vivo
2960
2969
 
2961
- 1. Abre \`ai/PROJECT-CONTEXT.md\` (lo cre\xF3 \`@lexydesign/ai install\`) y
2970
+ 1. Abre \`ai/PROJECT-CONTEXT.md\` (lo cre\xF3 \`create-lexy install-ai\`) y
2962
2971
  compl\xE9talo con lo que recopilaste: **qu\xE9 se construye**, **para qui\xE9n**,
2963
2972
  **pantallas y flujos clave**, un resumen de **datos principales**,
2964
2973
  **referencias** y **decisiones/restricciones** ya tomadas.
@@ -2984,19 +2993,16 @@ producci\xF3n; el panel registra cargas y publicaciones para inspecci\xF3n.
2984
2993
 
2985
2994
  ## 5. Cerrar
2986
2995
 
2987
- Borra este archivo (\`${X}\`): su trabajo termin\xF3. Conf\xEDrmale a la
2996
+ Borra este archivo (\`${de}\`): su trabajo termin\xF3. Conf\xEDrmale a la
2988
2997
  persona que su proyecto est\xE1 listo y prop\xF3n el primer paso concreto
2989
2998
  (p. ej. "\xBFDise\xF1amos la pantalla de inicio?").
2990
- `,Ye=async e=>{let t=process.cwd();for(let n of["package.json",".lexy"])if(await ue.access(Ge.join(t,n)).then(()=>!0,()=>!1))throw new Error(`El directorio actual ya contiene un proyecto (${n}). \`kickoff\` es para empezar de cero en una carpeta vac\xEDa.`);let o=Ge.join(t,X);if(await ue.access(o).then(()=>!0,()=>!1)&&!e.force)throw new Error(`${X} ya existe. Usa --force para regenerarlo.`);await ue.writeFile(o,So),bo(`Se cre\xF3 ${ye.cyan(X)} en esta carpeta.
2991
-
2992
- Abre la carpeta con Claude Code y di: `+ye.bold("\xABay\xFAdame a arrancar mi proyecto Lexy\xBB")+`.
2993
- El agente te entrevistar\xE1 y montar\xE1 el proyecto por ti.`,"Kickoff listo"),wo(ye.green("Sin flags, sin prompts t\xE9cnicos \u2014 solo conversa con el agente."))};import fe from"fs/promises";import Z from"path";import C from"picocolors";var xe="@lexydesign/kit",Qe=`https://cdn.jsdelivr.net/npm/${xe}`,Xe=8e3,ge=async e=>{let t=await fetch(e,{signal:AbortSignal.timeout(Xe)});if(!t.ok){let o=new Error(`HTTP ${t.status} al pedir ${e}`);throw o.status=t.status,o}return Buffer.from(await t.arrayBuffer())},ko=async()=>{try{let t=await fetch(`https://registry.npmjs.org/${xe}/latest`,{signal:AbortSignal.timeout(Xe)});if(t.ok)return(await t.json()).version}catch{}return JSON.parse((await ge(`${Qe}@latest/package.json`)).toString("utf-8")).version},Ze=async e=>{let t=process.cwd(),o=Z.resolve(t,e.dir??"lexy-kit"),a=Z.relative(t,o)||".";if(await fe.access(o).then(()=>!0).catch(()=>!1)&&!e.force)throw new Error(`Ya existe ${C.bold(a)}. Usa ${C.cyan("--force")} para sobrescribir o ${C.cyan("--dir <ruta>")} para otra carpeta.`);let r=await ko();console.log(C.dim(`
2994
- Trayendo ${xe}@${r} \u2192 ${a}/
2995
- `));let i=`${Qe}@${r}/kit`,d=JSON.parse((await ge(`${i}/manifest.json`)).toString("utf-8")),s=["index.html","kit.css","kit.js","manifest.json","README.md","AGENTS.md","llms.txt","llms-full.txt","fonts/noto-sans-latin.woff2","fonts/OFL-NotoSans.txt",...d.guides?.pautas??[],...d.components.map(m=>m.file),...d.blocks.map(m=>m.file)],u=0;for(let m of s)try{let y=await ge(`${i}/${m}`),z=Z.join(o,m);await fe.mkdir(Z.dirname(z),{recursive:!0}),await fe.writeFile(z,y),u+=1}catch(y){console.warn(C.yellow(`\u26A0 no se pudo traer ${m}`)+C.dim(` (${y.message})`))}console.log(C.green("\u2713 Kit listo")+C.dim(` \u2014 ${u} archivo(s), ${d.components.length} componente(s) + ${d.blocks.length} block(s)
2996
- `)),console.log(` Abre ${C.bold(`${a}/index.html`)} en el navegador.`),console.log(C.dim(` El cat\xE1logo m\xE1quina-legible est\xE1 en ${a}/manifest.json.
2997
- `))};import Eo from"fs/promises";import he from"path";import E from"picocolors";var K=e=>console.log(E.bold(E.cyan(`
2999
+ `,pe=async e=>{let t=process.cwd();for(let n of["package.json",".lexy"])if(await Re.access(ut.join(t,n)).then(()=>!0,()=>!1))throw new Error(`El directorio actual ya contiene un proyecto (${n}). \`kickoff\` es para empezar de cero en una carpeta vac\xEDa.`);let o=ut.join(t,de);if(await Re.access(o).then(()=>!0,()=>!1)&&!e.force)throw new Error(`${de} ya existe. Usa --force para regenerarlo.`);await Re.writeFile(o,Yo),Wo(`Se cre\xF3 ${_e.cyan(de)} en esta carpeta.
3000
+
3001
+ Abre la carpeta con Claude Code y di: `+_e.bold("\xABay\xFAdame a arrancar mi proyecto Lexy\xBB")+`.
3002
+ El agente te entrevistar\xE1 y montar\xE1 el proyecto por ti.`,"Kickoff listo"),Go(_e.green("Sin flags, sin prompts t\xE9cnicos \u2014 solo conversa con el agente."))};import Qo from"fs/promises";import Oe from"path";import I from"picocolors";var Q=e=>console.log(I.bold(I.cyan(`
2998
3003
  \u2500\u2500 ${e} \u2500\u2500
2999
- `))),et=async(e,t)=>{if(t.list||!e){let{index:i,version:d,source:s}=await je();K(`Cat\xE1logo Lexy \xB7 @lexydesign/registry@${d}${s==="bundle"?" (bundle local)":""}`);for(let u of i.items)console.log(` ${E.bold(u.name.padEnd(20))} ${E.dim(u.description??"")}`);console.log(E.dim(`
3000
- ${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),s=d.installed[o];if(!s){console.error(E.red(`"${o}" no figura como instalado en .lexy. Inst\xE1lalo con \`create-lexy add ${o}\`.`)),process.exitCode=1;return}let{item:u}=await k(o,s).catch(()=>k(o));K(`${u.title??o} \xB7 copia local (instalado con registry@${s})`);for(let m of T(u,d)){let y=await Eo.readFile(he.join(i,m.relPath),"utf-8").catch(()=>null);K(y===null?`${m.relPath} (FALTANTE)`:m.relPath),y!==null&&console.log(y)}return}let{item:a,version:n,source:r}=await k(o);K(`${a.title??a.name} \xB7 @lexydesign/registry@${n}${r==="bundle"?" (bundle local)":""}`),a.description&&console.log(a.description+`
3001
- `),console.log(E.dim("tipo: ")+a.type),console.log(E.dim("deps npm: ")+((a.dependencies??[]).join(", ")||"\u2014")),console.log(E.dim("deps registry: ")+((a.registryDependencies??[]).join(", ")||"\u2014")),console.log(E.dim("archivos: ")+a.files.map(i=>he.posix.basename(i.path)).join(", ")),console.log(E.dim("instalar: ")+`create-lexy add ${a.name}`);for(let i of a.files)typeof i.content=="string"&&(K(he.posix.basename(i.path)),console.log(i.content))};var To=tt.dirname(jo(import.meta.url)),Ro=JSON.parse(Po(tt.join(To,"../package.json"),"utf-8")),N=new Io,D=e=>async()=>{try{await e()}catch(t){console.error(Co.red(`
3002
- 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(Ro.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)=>D(()=>He(e,t))());N.command("kickoff").description("Deja un .md de entrevista para que el agente conduzca el arranque de un dise\xF1ador (carpeta vac\xEDa)").option("--force","Regenerar el .md de kickoff si ya existe").action(e=>D(()=>Ye(e))());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)=>D(()=>Re(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)=>D(()=>et(e,t))());N.command("kit").description("Trae el kit HTML/low-fi (mismos componentes y blocks en HTML plano) a una carpeta").option("--dir <path>","Carpeta destino (por defecto: lexy-kit)").option("--force","Sobrescribir la carpeta si ya existe").action(e=>D(()=>Ze(e))());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=>D(()=>Je(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=>D(async()=>{process.exitCode=await We(e)})());N.parse(process.argv);
3004
+ `))),yt=async(e,t)=>{if(t.list||!e){let{index:i,version:p,source:s}=await oe();Q(`Cat\xE1logo Lexy \xB7 @lexydesign/registry@${p}${s==="bundle"?" (bundle local)":""}`);for(let m of i.items)console.log(` ${I.bold(m.name.padEnd(20))} ${I.dim(m.description??"")}`);console.log(I.dim(`
3005
+ ${i.items.length} componente(s). Instala con: create-lexy add <nombre>`));return}let o=e.toLowerCase();if(t.installed){let i=process.cwd(),p=await z(i),s=p.installed[o];if(!s){console.error(I.red(`"${o}" no figura como instalado en .lexy. Inst\xE1lalo con \`create-lexy add ${o}\`.`)),process.exitCode=1;return}let{item:m}=await C(o,s).catch(()=>C(o));Q(`${m.title??o} \xB7 copia local (instalado con registry@${s})`);for(let u of O(m,p)){let y=await Qo.readFile(Oe.join(i,u.relPath),"utf-8").catch(()=>null);Q(y===null?`${u.relPath} (FALTANTE)`:u.relPath),y!==null&&console.log(y)}return}let{item:a,version:n,source:r}=await C(o);Q(`${a.title??a.name} \xB7 @lexydesign/registry@${n}${r==="bundle"?" (bundle local)":""}`),a.description&&console.log(a.description+`
3006
+ `),console.log(I.dim("tipo: ")+a.type),console.log(I.dim("deps npm: ")+((a.dependencies??[]).join(", ")||"\u2014")),console.log(I.dim("deps registry: ")+((a.registryDependencies??[]).join(", ")||"\u2014")),console.log(I.dim("archivos: ")+a.files.map(i=>Oe.posix.basename(i.path)).join(", ")),console.log(I.dim("instalar: ")+`create-lexy add ${a.name}`);for(let i of a.files)typeof i.content=="string"&&(Q(Oe.posix.basename(i.path)),console.log(i.content))};import{existsSync as Xo}from"fs";import Zo from"fs/promises";import{basename as ea,join as vt}from"path";import{confirm as ta,isCancel as Le,multiselect as oa,note as ft,outro as gt,select as xt}from"@clack/prompts";import x from"picocolors";function Ae(e){return aa(e).length}function me(e,t){let o=t-Ae(e);return o>0?e+" ".repeat(o):e}function aa(e){return e.replace(/\[[0-9;]*m/g,"")}function na(e,t){let o=process.env.HOME??process.env.USERPROFILE,a=e;return o&&(a===o||a.startsWith(o+"/"))&&(a="~"+a.slice(o.length)),a.length<=t?a:"\u2026"+a.slice(a.length-(t-1))}var ht=["\u2588 \u2588\u2580\u2580 \u2588 \u2588 \u2588 \u2588 \u2588\u2580\u2580 \u2588 \u2588","\u2588 \u2588\u2580\u2580 \u2588 \u2588 \u2588 \u2588 \u2588","\u2588\u2584\u2584 \u2588\u2584\u2584 \u2588 \u2588 \u2588 \u2588\u2584\u2584 \u2588\u2584\u2584 \u2588"],ra=[x.cyan,x.blue,x.blue];function ia(e){let t=ht.map((v,d)=>x.bold(ra[d](v))),o=Ae(ht[0]),a=[x.dim("Lexy Design System"),`${x.dim("versi\xF3n")} ${x.bold(x.cyan(`v${e}`))}`,x.cyan(na(process.cwd(),38))],n=Math.max(...a.map(Ae)),r=2,i=5,p=r+o+i+n+r,s="\u2500".repeat(p),m=(v,d)=>{let g=" ".repeat(r)+me(v,o)+" ".repeat(i)+me(d,n)+" ".repeat(r);return x.dim("\u2502")+g+x.dim("\u2502")},u=Math.floor(i/2),y=()=>{let v=" ".repeat(r)+me(t[1],o)+" ".repeat(u)+x.dim("\u2502")+" ".repeat(i-u-1)+me(a[1],n)+" ".repeat(r);return x.dim("\u2502")+v+x.dim("\u2502")},R=x.dim("\u2502")+" ".repeat(p)+x.dim("\u2502");console.log(""),console.log(x.dim(`\u256D${s}\u256E`)),console.log(R),console.log(m(t[0],a[0])),console.log(y()),console.log(m(t[2],a[2])),console.log(R),console.log(x.dim(`\u2570${s}\u256F`)),console.log("")}function sa(){return Xo(vt(process.cwd(),".lexy"))}async function la(){try{let e=JSON.parse(await Zo.readFile(vt(process.cwd(),"package.json"),"utf-8"));if(e.name)return e.name}catch{}return ea(process.cwd())}async function bt({version:e}){console.clear(),ia(e);let t=sa();ft(t?`${x.dim("Proyecto:")} ${x.bold(await la())}`:x.dim("No hay un proyecto Lexy en esta carpeta todav\xEDa."),t?"Proyecto existente":"Carpeta vac\xEDa");let o=t?await xt({message:"\xBFQu\xE9 quieres hacer?",options:[{value:"add",label:"Agregar componente",hint:"instala un componente del registry en tu proyecto"},{value:"doctor",label:"Revisar salud del proyecto",hint:"detecta drift, versiones desactualizadas y problemas"},{value:"install-ai",label:"Instalar / actualizar IA",hint:"pautas, skills y entry points para agentes"}]}):await xt({message:"\xBFQu\xE9 quieres hacer?",options:[{value:"create",label:"Crear un proyecto ahora",hint:"responde t\xFA nombre, mundo y forma del producto"},{value:"kickoff",label:"Dejar que un agente me ayude",hint:"genera LEXY-KICKOFF.md para que Claude Code te entreviste"},{value:"help",label:"Ayuda / Documentaci\xF3n",hint:"comandos disponibles"}]});if(Le(o)){gt(x.dim("Operaci\xF3n cancelada."));return}switch(o){case"create":await se(void 0,{}),await da(e);return;case"kickoff":await pe({});return;case"help":ft(x.dim("Ejecuta ")+x.cyan("create-lexy --help")+x.dim(" para ver todos los comandos y flags."),"Ayuda");break;case"add":await ca();break;case"doctor":process.exitCode=await ce({});break;case"install-ai":await Y({},e);break}gt(x.green("\xA1Hasta luego!"))}async function ca(){let{index:e}=await oe(),t=await oa({message:"\xBFQu\xE9 componentes quieres instalar?",options:e.items.map(o=>({value:o.name,label:o.title??o.name,hint:o.description})),required:!0});Le(t)||await ie(t,{})}async function da(e){let t=await ta({message:"\xBFInstalar tambi\xE9n la capa de IA ahora?",initialValue:!0});Le(t)||!t||await Y({},e)}var ya=wt.dirname(ma(import.meta.url)),ue=JSON.parse(pa(wt.join(ya,"../package.json"),"utf-8"));et(ue.engines?.node??">=20");var D=new ua,F=e=>async()=>{try{await e()}catch(t){console.error(St.red(`
3007
+ Error: `)+t.message),process.exit(1)}};D.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(ue.version);D.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)=>F(()=>se(e,t))());D.command("kickoff").description("Deja un .md de entrevista para que el agente conduzca el arranque de un dise\xF1ador (carpeta vac\xEDa)").option("--force","Regenerar el .md de kickoff si ya existe").action(e=>F(()=>pe(e))());D.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)=>F(()=>ie(e,t))());D.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)=>F(()=>yt(e,t))());D.command("diff").description("Copia local vs versi\xF3n vigente del registry (exit 1 si hay diferencias)").argument("<component>","Nombre en el registry").action(e=>F(()=>dt(e))());D.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=>F(async()=>{process.exitCode=await ce(e)})());D.command("install-ai").description("Instala o actualiza la capa de IA (pautas, skills, entry points para agentes) \u2014 idempotente").option("--force","Sobrescribir tambi\xE9n ai/PROJECT-CONTEXT.md (el brief vivo)").action(e=>F(()=>Y(e,ue.version))());process.argv.length<=2&&process.stdout.isTTY?bt({version:ue.version}).catch(e=>{console.error(St.red(`
3008
+ Error: `)+e.message),process.exit(1)}):D.parse(process.argv);