Communitygithub.com

yosegi-dev/yosegi

Ensamblado de pantallas impulsado por agente a partir de tus componentes Storybook existentes — CLI, servidor MCP y habilidad de agente. Sin interfaz gráfica.

¿Qué es yosegi?

Yosegi es una herramienta que permite a un agente de IA ensamblar propuestas de pantalla o maquetas de UI utilizando los componentes reales de un proyecto anfitrión, extraídos de su catálogo de Storybook o directamente de sus tipos TypeScript. En lugar de generar una interfaz gráfica o un entorno de renderizado propio, Yosegi produce un archivo Story (CSF) o un componente React plano que se puede revisar en el Storybook del proyecto anfitrión antes de implementar nada. Esto evita errores comunes al asumir nombres de props, opciones de enum o convenciones de composición que pueden haber sido personalizadas en el proyecto anfitrión. Soporta los ecosistemas React + TypeScript, se integra como CLI, servidor MCP y habilidad de agente (skill), y está diseñado para composición de pantallas, creación de prototipos y transcripción de mocks aprobados a código real, siempre manteniendo como fuente de verdad el registro de componentes del proyecto.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add yosegi-dev/yosegi

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Yosegi — construyendo pantallas a partir de los componentes del anfitrión

Versión: 2026-08-13. Un arnés de agente puede cargar una copia desactualizada de una habilidad sin indicarlo. Si esta fecha es más antigua que la del archivo skills/yosegi/SKILL.md en el repositorio, estás leyendo una copia obsoleta: vuelve a instalarla antes de continuar.

Yosegi convierte los componentes de un proyecto anfitrión en hechos con los que puedes construir una pantalla, y emite la pantalla como una Story (CSF) para su revisión antes de implementar nada. No tiene ni un entorno de renderizado ni una GUI propia; tú verificas el aspecto en el Storybook del anfitrión. En un anfitrión sin Storybook, el entregable se convierte en un archivo de componente React plano (--target component) — la rama del paso 1 a continuación indica cómo cambia el procedimiento.

Este documento es el procedimiento, y tú eres quien lo lleva a cabo. La CLI (y las herramientas MCP equivalentes) son los instrumentos a los que recurre.

Cuándo usarlo

  • Componer una propuesta de pantalla o maqueta de UI a partir de un sistema de diseño existente, en una forma revisable.
  • Obtener un primer borrador de una nueva pantalla visible en Storybook antes de implementarla.
  • Consultar qué componentes tiene un anfitrión y qué props realmente aceptan, antes de escribir cualquier UI.
  • Transcribir una Story de maqueta aprobada a una página real. Realiza los pasos 1 y 2, luego salta al paso 5.

No para: cambios de componentes puntuales.

Dónde está el valor

El trabajo del registro es específico: es la fuente de verdad para las props de un componente — los nombres reales de las props, las opciones reales de enum, cuáles son obligatorias, cuáles son slots versus children, la firma de llamada de una prop de función. Los componentes de un anfitrión no son la biblioteca de la que se bifurcaron. Sus enums de variantes se han renombrado, sus escalas de tamaño difieren entre hermanos, una prop de icono toma una referencia de componente en lugar de un elemento, una prop ReactNode es un slot con nombre en lugar de children, y tres componentes diferentes comparten un nombre de exportación. Nada de eso se puede deducir de la familiaridad con React o con la biblioteca upstream, y cada uno de esos es un defecto que enviarás si escribes la prop que esperas en lugar de la prop que dice el registro que existe. Para eso sirven las llamadas inspect de los pasos 1 y 2, y saltarlas es cómo una maqueta con apariencia plausible envía un defecto.

El registro no te da el esqueleto de la pantalla, el modismo de composición o el diseño — la llamada a un hook de biblioteca de cuadrícula que impulsa un DataGrid, un meta específico del anfitrión como { stickyHeader: true }, qué wrapper espera un componente a su alrededor. Eso proviene de las Stories propias del anfitrión y, en un anfitrión con un generador de páginas/rutas, de sus plantillas de Ejemplo (paso 2). Cuanto más rica sea la cobertura de plantillas y Stories del anfitrión, menor será la participación del registro en lo que realmente necesitabas para construir la pantalla — y eso no es una carencia. El registro y los ejemplos propios del anfitrión responden preguntas diferentes, y ambos son fundamentales para la pregunta que responden.

Referencias

Ábrelas cuando el paso siguiente te envíe a ellas, no de forma preventiva. En la ruta 3a (escribir la Story directamente), eso puede ser nunca: registry status y la salida de component inspect más el cuerpo de este archivo suelen ser lo suficientemente autodescriptivos para construir toda la pantalla. Sin embargo, una vez que necesites una, trabaja a partir de ella y no solo de la memoria de este archivo — su detalle no se repite aquí.

ArchivoLéelo
references/registry.mdCuando la salida de inspect tenga algo que no puedas interpretar — una línea shape: / signature: de una prop opaca, una prop no documentada, un especificador de importación que parezca incorrecto
references/cli.mdCuando un comando o flag no esté cubierto arriba, la CLI no se ejecute, o necesites los equivalentes MCP
references/screen-json.mdSolo si tomas la ruta Screen JSON (3b). El formato, y lo que no puede expresar
references/errors.mdEn el momento en que cualquier comando imprima un error o una advertencia. Cada código y su solución
references/implementation.mdPara la plantilla meta en el paso 3, y antes del paso 5

Paso 1. Construir el registro

Yosegi necesita un tsconfig.json legible del anfitrión (las props provienen de los tipos TypeScript, y eso solo es suficiente). Storybook es donde va la Story y donde confirmas cómo se renderiza, pero no es un requisito.

Si no puedes detectar Storybook — sin directorio de configuración .storybook/ (o equivalente), sin script storybook en el package.json del anfitrión, sin index.json para apuntar --index — el entregable es un archivo de componente React plano en lugar de una Story (screen generate --target component, references/cli.md). No elijas la ubicación de salida ni el método de revisión tú mismo: antes de construir nada, pregúntale al usuario (a) dónde debería ir el archivo del componente y (b) cómo quiere confirmar el resultado (renderizándolo en una ruta provisional de la aplicación anfitriona, por ejemplo). Yosegi no prescribe la superficie de revisión, y adivinar cualquiera de las dos respuestas viola la misma regla que adivinar una prop. Con esas respuestas, el procedimiento a continuación sigue siendo el mismo, con tres diferencias: registry build se ejecuta sin --index / --storybook-url (pierdes la curación, nada más); en la ruta 3a escribes el archivo del componente en la ubicación que nombró el usuario, y en la 3b pasas --target component --out <esa ubicación>.tsx; y las comprobaciones de Storybook del paso 4 se reemplazan por la verificación de tipos del anfitrión más el método de confirmación que nombró el usuario.

  1. ¿Puedes ejecutar la CLI? npx yosegi (o pnpm yosegi, yarn yosegi, bunx yosegi) sin argumentos imprime todos los comandos, una vez que @yosegi/yosegi ya sea una dependencia del anfitrión — instálalo primero si no lo es (references/cli.md). Node.js 20 o más reciente, anfitrión React + TypeScript. Si el comando falla, consulta "Si la CLI no se ejecuta" en references/cli.md; el movimiento más útil es leer <data-dir>/registry.json's builtWithCliPath si ya existe un registro de una sesión anterior.
  2. Fija un --data-dir ahora y pásalo a cada comando. Usa .yosegi bajo la raíz del paquete del anfitrión, que también es el valor predeterminado; los ejemplos a continuación aún lo escriben, porque el valor predeterminado sigue tu directorio de trabajo actual y un comando ejecutado desde otro lugar no encontrará lo que construiste.
  3. ¿Ya hay un registro y está actualizado? Ejecuta yosegi registry status --data-dir .yosegi primero — recalcula la versión del registro a partir de sus propias entradas registradas e informa source: current o source: stale con el comando de reconstrucción exacto, en lugar de que tú verifiques el encabezado de component list. "Registro no encontrado" significa que es la primera ejecución. Su mitad de índice de Storybook es de mejor esfuerzo y puede informar que el índice es inalcanzable mientras el veredicto de la fuente aún se mantiene — lee esa mitad como "no se pudo verificar", no como "obsoleto" o "actualizado", y no dejes que un servidor de desarrollo inalcanzable te impida confiar en un veredicto de fuente current. Reconstruye cada vez que status informe obsoleto, cada vez que se imprima REGISTRY_VERSION_MISMATCH, o cada vez que status informe source: unknown porque el registro es anterior a las entradas registradas (built: not recorded) — no hay nada que recalcular a partir de ahí, por lo que la antigüedad es la única señal que tienes. Reconstruye también cada vez que un comando advierta que el registro fue construido por una versión diferente de Yosegi a la que estás ejecutando: un Yosegi más antiguo no puede emitir campos que este sí puede (las firmas de llamada de una prop de función, por ejemplo), y ninguna otra señal muestra esa brecha — la cadena de versión, al ser un hash de contenido, permanece idéntica, por lo que un registro reconstruido a partir de un anfitrión sin cambios mantiene la misma. El registro es una instantánea, y una obsoleta es peor que ninguna.
yosegi registry build \
  --source "app/components/**/*.tsx" \
  --tsconfig <host>/tsconfig.json \
  --index http://localhost:6006/index.json \
  --storybook-url http://localhost:6006 \
  --report tmp/registry-report.json \
  --data-dir .yosegi

6006 arriba es el valor predeterminado de Storybook, utilizado solo porque esta es la primera compilación y nada te ha dicho otra cosa aún — no es necesariamente el puerto del anfitrión. Verifica el script de Storybook en el package.json del anfitrión (o pregunta) por el puerto en el que realmente se ejecuta antes de ejecutar esto. Cada reconstrucción después de esta primera tiene una mejor fuente que adivinar: el encabezado de component list imprime una línea rebuild: que lleva el --storybook-url exacto con el que se construyó el registro por última vez (references/cli.md).

Las flags y valores predeterminados están en references/cli.md. --index es la única parte con un requisito previo: una URL de servidor de desarrollo significa que el Storybook del anfitrión ya debe estar en ejecución. Sin él, pierdes las categorías derivadas de Stories y las marcas recommended, nada más.

Lee las estadísticas que imprime:

  • files: 0 → el glob no coincidió con nada. El comando aún tiene éxito y escribe un registro que contiene solo los tres primitivos sintéticos, así que no leas "Wrote 3 components" como éxito.
  • componentCandidates: 0 con files positivo, o withNodeSlots: 0 con un anyShapedProps alto → la compilación se degradó aunque tuvo éxito. El primero significa que el glob no cubrió ningún componente React; el segundo significa que @types/react no se resolvió, por lo que cada prop ReactNode se aplanó a json y no se detectaron slots. Una línea Warning: nombra la solución en ambos casos: resuélvela y reconstruye antes de continuar.
  • propsUnreadable alto en relación con extractedComponents → el tsconfig probablemente sea incorrecto. Resuélvelo ahora (references/cli.md, registry metadata); un componente en ese estado rechazará props perfectamente reales más adelante.

Paso 2. Consulta cada componente que planees usar

Si una plantilla de Ejemplo de un generador de páginas/rutas es la coincidencia más cercana a la pantalla que estás construyendo, léela primero, o junto con los comandos a continuación — decide el esqueleto y el modismo de composición, y luego el registro confirma las props exactas que la plantilla deja abiertas.

yosegi component list --category app/components/ui --data-dir .yosegi
yosegi component list --query card --data-dir .yosegi
yosegi component inspect "app/components/ui/button#Button" --data-dir .yosegi

El registro puede llegar a varios cientos de entradas, así que reduce con --category / --query, orienta con el resumen, luego inspect cada componente que vayas a escribir. inspect es autoritativo y tu conocimiento del framework no lo es. Lee references/registry.md para saber cómo interpretar lo que te da — las opciones de enum, las líneas shape: y signature: bajo una prop opaca, el especificador de importación que el anfitrión realmente escribe, y qué significa una prop no documentada.

Prefiere los componentes marcados como recommended; tienen una Story propia.

Luego recopila las convenciones del anfitrión. La Story aterriza en el repositorio del anfitrión y se revisa como código del anfitrión; saltarse esto produce una UI que funciona y aún así es devuelta.

  • Encuentra el contrato de datos, si ya existe uno — una definición de OpenAPI/JSON Schema, un esquema GraphQL, tipos TypeScript escritos a mano para la respuesta de la API, cualquier forma que use la capa de datos del anfitrión. Léelo antes de inventar datos simulados. Decide más que las props de los componentes: qué campos son obligatorios versus anulables y qué significa nulo para un campo dado (un límite nulo puede significar "ilimitado", no "desconocido"), qué campos son mutuamente excluyentes y — igual de útil — qué no está ahí (ningún campo de ordenación o búsqueda en el contrato significa que la pantalla tampoco debería inventar uno). Esto es lo que convierte el mock de una propuesta de apariencia en algo que refleja la forma real de los datos. Dónde vive varía según el anfitrión (openapi/schemas/, un archivo .graphql, un types.ts generado); encuentra el que exista para este dominio y síguelo en lugar de una suposición plausible.
  • Busca en el directorio de rutas/páginas del anfitrión (app/routes/, o donde sea que sirva páginas) una pantalla existente en el mismo dominio. En un producto maduro a menudo existe una, y encontrarla puede redefinir la tarea por completo — por ejemplo, una ruta existente bookings.calendar._index podría convertir "hacer una pantalla de reservas" en "proponer una lista transversal contra el flujo de reservas existente". Esto determina si el mock que te pidieron es incluso lo correcto para construir, así que hazlo antes del punto de control a continuación y deja que dé forma a las preguntas que hagas allí.
  • Ejecuta git status y mira el directorio de salida antes de construir nada. Un intento anterior, sin confirmar, de la misma pantalla ya puede estar en el árbol de trabajo — común después de un reinicio de contexto y una solicitud reemitida. Concilia con él en lugar de crear un duplicado a su lado. Para rehacer un archivo que ya existe — un generador del anfitrión se niega cuando la ruta de destino existe, o un intento anterior necesita ser reemplazado — muévelo a un lado (renómbralo) en lugar de eliminarlo; la eliminación puede no estar disponible para ti, y un cambio de nombre despeja la ruta de todos modos.
  • Verifica si el anfitrión tiene un generador para nuevas páginas o pantallas — un generador plop/hygen, un script estilo bun add-route, a menudo documentado en el AGENTS.md del anfitrión o en un script de package.json. En un anfitrión con uno, escribir un nuevo archivo de pantalla desde cero es incorrecto: el generador clona la plantilla sancionada y aplica las convenciones de archivo y nomenclatura, así que ejecútalo en lugar de crear el archivo tú mismo. Esto también resuelve la elección del paso 3 entre una Story de árbol en línea y un módulo de página más una Story wrapper delgada — un anfitrión con un generador como este casi siempre quiere lo último.
  • Lee AGENTS.md / CLAUDE.md en cada nivel desde la raíz del repositorio hasta el directorio de salida, y sigue cualquier documento al que apunten.
  • Lee una o dos Stories existentes cerca de la ubicación de salida. Los ejemplos compuestos que combinan varios componentes son los que vale la pena imitar para el esqueleto de la página, el espaciado y la selección de componentes. Para el modismo de composición — cómo se ensambla realmente un componente, no solo qué props toma: la llamada al hook de biblioteca de cuadrícula que impulsa un DataGrid, un meta específico del anfitrión como { stickyHeader: true }, el wrapper que un componente espera a su alrededor — una Story existente es la fuente de verdad, y el registro no lo es.

...

Skills relacionados