@neuraz/design-system-manager
v0.1.7
Published
Design System Studio local-first: gestiona, documenta y distribuye el Design System de tu proyecto (tokens DTCG, brand, assets, viewer) como archivos versionables — usable como harness por cualquier modelo/agente.
Maintainers
Readme
Neuraz Design System Manager
Nombre provisional. Paquete npm que se instala como dependencia de desarrollo dentro de un proyecto anfitrión y administra un Design System local, versionable y portable.
El Design System permanece como archivos en el repositorio anfitrión (fuente de verdad); el gestor no usa una base de datos interna. Funciona local-first, sin servicios cloud, y es independiente del framework del proyecto (WordPress, Astro, Next.js, etc.).
Visión de producto: este Core headless (los comandos documentados abajo) es el cimiento de tokens de Neuraz Design System Studio — un gestor, generador, documentador y distribuidor de Design Systems completos (Brand System, Foundations and Tokens, Component System, Patterns and Templates, Governance and Distribution), nunca solamente un token manager. Ver
docs/product/— modelo completo, modelo de Brand System, visión, guardrails y mapa de capacidades.
neuraz-ds init
Inicializa de forma segura el Design System del proyecto anfitrión: resuelve la raíz, valida la identidad (nombre/slug/versión), muestra un plan, pide confirmación y escribe de forma transaccional la estructura mínima.
Precondición
El proyecto anfitrión debe tener un package.json. init no crea package.json, no
ejecuta npm init, no instala dependencias, no modifica scripts, no publica en npm y
no crea commits de Git.
Uso
npm install -D @neuraz/design-system-manager
npx neuraz-ds init # interactivo: requiere terminal (TTY)
npx neuraz-ds init --name "Acme" --yes # no interactivo (agente/CI)
# Con fuentes de origen (032): registra sources.json en el mismo paso (add-only)
npx neuraz-ds init --name "Acme" --yes \
--source url:https://acme.com --source local:./brand-kitinit solicita: nombre, slug (autopropuesto desde el nombre, editable), descripción opcional y
versión (por defecto 0.1.0), muestra la raíz anfitriona y el plan, y pide confirmación.
--source <ref>(repetible, 032): registra fuentes de origen endesign-system/sources.jsondurante el init.inittambién parchea elpackage.jsondel host add-only (view/ds:validate/ds:inspect, sin pisar scripts existentes). Sin--source,initse comporta igual que antes (retrocompat). Ver la secciónneuraz-ds sources · fetch · brief.
Estructura generada
neuraz-ds.config.json
design-system/
├── design-system.json
└── tokens/
└── base.tokens.json- tokens sigue DTCG 2025.10. El color base de ejemplo usa el objeto sRGB conforme al
Color Module (
colorSpace/components/alpha/hex), y el color de marca es un alias ({color.base.blue-500}). Un string hexadecimal plano no es un valor de color válido. - En monorepos se usa el
package.jsonmás cercano e inicializa solo ese workspace; nunca escribe fuera de la raíz anfitriona.
neuraz-ds validate
Comando de solo lectura: responde ¿el Design System existente es válido?. Resuelve la raíz anfitriona, lee únicamente los documentos administrados y comprueba configuración, manifiesto, tokens DTCG 2025.10, aliases, ciclos, tipos, coherencia entre documentos y contención de rutas. Acumula todos los errores recuperables. No repara, no modifica archivos.
npx neuraz-ds validate # no interactivo; funciona en CI sin TTY
npx neuraz-ds validate --jsonMuestra raíz, estado, documentos comprobados, nº de errores/warnings, tokens y la lista de issues.
Con --json, stdout contiene exactamente un documento JSON v1 parseable, sin texto humano, y el
código de salida no cambia. Códigos principales: 0 válido · 3 inválido · 4 parcial · 5 no
localizado · 6 lectura/fs.
neuraz-ds inspect
Comando de solo lectura: responde ¿qué contiene y cómo está organizado?. Devuelve identidad,
archivos (presentes/ausentes), estadísticas de tokens (grupos, valores, aliases, byType,
profundidad), rutas de tokens y el resultado de validación. Conserva información recuperable
incluso en estados inválidos o parciales, marcando la confiabilidad. No infiere ni modifica nada.
npx neuraz-ds inspect # no interactivo; funciona en CI sin TTY
npx neuraz-ds inspect --jsonLa salida de terminal muestra hasta 200 rutas de tokens (cota de presentación); con más, indica
cuántas se omiten. Con --json, tokens.paths conserva todos los nodos (sin cota de 200).
Códigos principales: 0 · 3 · 4 · 5 · 6.
neuraz-ds foundations
Comando de solo lectura: proyecta los tokens DTCG existentes sobre las nueve categorías
foundation canónicas: color, spacing, typography, radius, border, shadow, opacity,
sizing y motion. No crea tokens, no aplica presets, no infiere niveles por nombre/ruta/tipo y no
modifica archivos.
npx neuraz-ds foundations
npx neuraz-ds foundations --jsonEl nivel foundation se declara en $extensions["ar.neuraz.design-system-manager"].foundation.level
con valor "primitive" o "semantic". Si falta metadata, el token queda unclassified; si la
metadata es inválida se emite foundation-level-invalid. La declaración propia del token gana sobre
la del grupo ancestro más cercano.
Ejemplo de grupo primitive:
{
"color": {
"$type": "color",
"$extensions": {
"ar.neuraz.design-system-manager": { "foundation": { "level": "primitive" } }
},
"base": {
"$value": { "colorSpace": "srgb", "components": [0, 0, 0], "alpha": 1, "hex": "#000000" }
}
}
}Un Design System recién creado por init queda intencionalmente partial: tiene dos tokens color
sin metadata foundation (unclassified), mientras las otras ocho categorías están absent.
Las categorías absent por sí solas no invalidan ni vuelven parcial el resultado. La validación
profunda sigue disponible solo para color; el resto de tipos DTCG reconocidos se inspeccionan de
forma superficial y pueden producir warnings heredados de inspect.
neuraz-ds presets
Aplica presets de tokens empaquetados con el gestor a tu Design System local. Un preset es un bloque de tokens DTCG curado, inmutable y versionado, distribuido dentro del paquete (no se descarga ni se lee desde tu repositorio); su propósito es sembrar foundations válidas sin que escribas el JSON a mano.
Diferencia clave con foundations:
- foundation (004) es una vista de solo lectura: clasifica los tokens que ya existen.
- preset (005) es una operación de escritura explícita y opt-in: añade tokens nuevos al
Design System.
initnunca aplica un preset automáticamente; el usuario elige el preset y ejecutaapplyde forma deliberada.
Preset disponible
| Campo | Valor |
|---|---|
| id | neutral-base |
| nombre | Neutral Base |
| versión | 1.0.0 |
| categorías | color, spacing |
| propósito | base neutral y portable: grises primitive, un rol de superficie semantic y una escala de espaciado primitive mínima. |
Es el único preset del catálogo en v1. El catálogo empaquetado permite incorporar más presets en versiones futuras; el README documenta únicamente lo que existe hoy.
Comandos
npx neuraz-ds presets list # lista el catálogo empaquetado
npx neuraz-ds presets inspect neutral-base # detalle del preset (categorías, tokens)
npx neuraz-ds presets plan neutral-base # PREVIEW: qué crearía/omitiría; nunca escribe
npx neuraz-ds presets apply neutral-base # aplica de forma segura (recalcula el plan y escribe)Cada subcomando acepta --json (local al subcomando, no global) para una salida estable y headless.
plan frente a apply
plan → recalcula el diff contra tu Design System → muestra el preview → NUNCA escribe.
apply → recalcula el plan → escribe SOLO si es seguro (sin conflictos bloqueantes).Ambos son deterministas y derivan del mismo motor de diff; plan es estrictamente de solo lectura.
Seguridad del merge
- add-only: solo crea tokens y grupos intermedios ausentes; no elimina ni sobrescribe contenido existente.
- conflictos bloqueantes: si un token del preset difiere del host en valor, tipo, nivel
foundation o alias, el plan se marca no escribible y
applyse detiene (exit4) sin tocar el archivo; loscreateseguros se conservan en el preview. - descripción distinta: si solo difiere
$description, no es un conflicto: la operación esskip(no bloqueante) y se preserva la descripción del host. - target fijo: siempre escribe
design-system/tokens/base.tokens.json; con contención de rutas (sin symlinks fuera de la raíz). - escritor atómico: escritura a un temporal +
renameatómico; nunca deja escrituras parciales. Ante fallo de escritura el archivo original queda intacto (exit6). - concurrencia optimista: detecta cambios del archivo entre lectura y escritura.
- idempotencia: aplicar dos veces el mismo preset es
unchanged(exit2); los bytes y elmtimedel archivo no cambian. - verificación posterior: tras escribir, se reanaliza el resultado; ante
verification-error(exit7) se retiene un backup. No hay rollback automático destructivo.
Opciones intencionalmente ausentes en v1
--force (no existe: los conflictos nunca se fuerzan)
--category (no existe: no hay filtrado por categoría)
--dry-run (no existe: `plan` ya es el preview de solo lectura)Tampoco están disponibles aquí: themes, dark mode, component tokens, presets externos/marketplace, Figma, importadores de URL/CSS, imágenes, IA, viewer, editor, asset manager ni MCP.
neuraz-ds build
Compila el Design System administrado a artefactos derivados y los publica como un conjunto completo (todo o nada) en un directorio de salida fijo:
design-system/build/
├── tokens.css # custom properties CSS (preserva aliases como var(--…))
├── tokens.resolved.json # tokens con aliases y tipos resueltos + metadata
├── tokens.ts # `export const tokens` (sin imports en runtime)
└── manifest.json # build manifest (fuente, hash, artifacts)npx neuraz-ds build # publica los tres formatos como un conjunto
npx neuraz-ds build --json # un único envelope JSON a stdout (formatVersion 1.0.0)- Fuente vs derivados: la única fuente de verdad es
design-system/tokens/base.tokens.json. Todo lo que vive endesign-system/build/es derivado y reproducible;buildnunca edita la fuente. - Directorio fijo: no hay
--output; el destino siempre esdesign-system/build/. - Determinismo: misma fuente → mismos bytes (orden canónico, sin timestamps ni rutas absolutas).
- Gradients: los tokens
$type: "gradient"(array DTCG de stops{color, position}) se emiten en CSS comolinear-gradient(180deg, …). El ángulo no forma parte del token DTCG: la convención canónica es top→bottom y la dirección final la decide el consumidor.border,transitionytypographycompuestos siguen sin representación CSS en v1 (bloquean el build). - Idempotencia: una segunda ejecución sin cambios resuelve
unchanged(exit 2) y no reescribe (se compara manifest, hashes, byte lengths, paths, ownership y presencia en disco, no solo el manifest). - Todo o nada: si un formato no es representable, el build completo se bloquea (
wrote:false, cero artefactos publicados). La publicación usa un writer transaccional con backup y recuperación explícita. - Contenido desconocido: los archivos/directorios desconocidos previos bajo
build/se preservan (copiados byte a byte); symlinks y nodos especiales bloquean conconflict.
neuraz-ds export <format>
Emite un formato a stdout, en modo estrictamente de solo lectura (no escribe, no toca build/):
npx neuraz-ds export css # bytes exactos de tokens.css
npx neuraz-ds export json # bytes exactos de tokens.resolved.json
npx neuraz-ds export typescript # bytes exactos de tokens.ts- Solo
css | json | typescript; cualquier otro valor es un error de uso. - No acepta
--json(el formato ya determina la salida) ni ningún otro flag. - Éxito → bytes exactos a stdout, stderr vacío; error esperado → stdout vacío, stderr con mensaje seguro.
Opciones intencionalmente ausentes en build/export
--output --input --formats --force --dry-run --cwd --clean --watch --minify
export --json (export nunca emite envelope; solo bytes del artifact)neuraz-ds asset
Administra assets locales (fonts, logos, SVG, icons, images) bajo design-system/assets/,
estrictamente separados de los tokens DTCG. El manifest design-system/assets/assets.json es la
autoridad de pertenencia (ownership).
npx neuraz-ds asset list [--json] # lista los assets administrados
npx neuraz-ds asset inspect <logicalPath> [--json] # metadata de un asset (MIME, tamaño, dimensiones, licencia, provenance)
npx neuraz-ds asset import plan <archivo…> [--json] [--kind <k>] # PREVIEW: qué crearía/duplicaría/bloquearía; nunca escribe
npx neuraz-ds asset import apply <archivo…> --license <id> [--kind <k>] # aplica de forma transaccional (todo o nada)
npx neuraz-ds asset remove <logicalPath> # elimina un asset administrado (transaccional, ownership-bound)- Separación tokens/assets: ninguna operación de assets lee o escribe
design-system/tokens/**, el host manifest nidesign-system/build/**; y viceversa. - plan es read-only: no escribe nada; el store y el manifest quedan byte-idénticos.
- Kind explícito: sin
--kind, el kind se deriva del MIME (font→font, SVG→svg, raster→image). Para que logos e iconos raster se clasifiquen como tales (y aparezcan en las secciones Brand/Icons del Viewer), pasa--kind logoo--kind icon; el destino lógico sigue al kind (logos/…,icons/…). - Sanitización de SVG: todo SVG se sanitiza (se eliminan scripts, handlers
on*, referencias externas,<foreignObject>, DOCTYPE/entidades) antes de escribirse; lo no saneable se bloquea. - Licencias: nunca se asumen;
applyregistra exactamente la licencia suministrada (--license). Un import sin licencia se marca con un avisolicense-required. - Deduplicación: contenido idéntico (mismo SHA-256) se detecta y no se almacena dos veces.
- Seguridad: nunca sigue symlinks; preserva contenido desconocido (no lo borra) o bloquea con
conflict; escrituras transaccionales con backup y recuperación explícita; idempotente (re-applysin cambios →unchanged). - JSON:
list/inspect/import planaceptan--json(AssetJsonEnvelopeV1,formatVersion 1.0.0);apply/removeson escrituras (salida humana). Fuera de alcance: Figma, scraping, IA, conversión de fuentes, optimización de imágenes, edición de SVG, CDN y cloud storage.
neuraz-ds token
Aplica mutaciones estructuradas y seguras sobre design-system/tokens/base.tokens.json —el único
archivo que estos comandos pueden escribir—, mediante un comando declarativo (TokenMutationCommandV1,
un array ordenado de operaciones: create/update/rename/move/remove de tokens y grupos, set/remove-alias)
o shorthands de una sola operación.
npx neuraz-ds token plan --file ./mutation.json # PREVIEW: nunca escribe (diff + candidato)
npx neuraz-ds token plan --file ./mutation.json --json # un único TokenMutationJsonEnvelopeV1 a stdout
npx neuraz-ds token apply --file ./mutation.json # aplica de forma transaccional (todo o nada)
# Shorthands (una sola operación; escriben directamente; sin --json, sin --force):
npx neuraz-ds token create color.brand.500 --type color --value '{"colorSpace":"srgb","components":[0.2,0.5,0.9],"alpha":1,"hex":"#3b82f6"}'
npx neuraz-ds token update color.brand.500 --value '"#111111"'
npx neuraz-ds token rename color.brand.500 primary
npx neuraz-ds token move color.brand.500 color.base
npx neuraz-ds token remove color.brand.500- Flujo obligatorio: comando → snapshot → analyze → validar comando → construir candidato → diff →
validar candidato → boundary de aprobación → apply transaccional → verificación posterior.
planejecuta todo hasta la validación del candidato, de solo lectura;applyre-deriva el plan, revisa concurrencia y solo entonces escribe. - Rename/move (política v1 — update-all-affected): renombrar o mover un token/grupo reescribe toda
referencia (
alias) afectada; nunca queda un alias roto. Una colisión de destino bloquea sin escribir. - Remove seguro por defecto:
removecon dependientes se bloquea (removal-with-dependents, lista los dependientes); no existe--force. Un grupo se elimina solo si está vacío. - Transaccional, single-file: temp → verificación → identity check (concurrencia) → backup → replace
(commit point) → verificación posterior; un cambio concurrente entre plan y apply produce
conflict; un fallo deja la fuente previa o la nueva, nunca un documento parcial; re-aplicar un no-op →unchanged. - Separación de superficies: las mutaciones de tokens nunca leen ni escriben
design-system/build/**,design-system/assets/**, el host manifest ni el asset manifest. - Preservación:
$extensionsde vendors ajenos y propiedades no gestionadas se conservan; solo se modifican los campos indicados por la operación. - JSON:
plan/applyaceptan--json(TokenMutationJsonEnvelopeV1,formatVersion 1.0.0, independiente de los envelopes devalidate/inspect/foundations/build/export/asset). - Headless:
planTokenMutation/applyTokenMutationson casos de uso puros (sin Commander/process/ TTY), reutilizados directamente por el Visual Token Editor (010, verneuraz-ds view) y disponibles para un futuro MCP server sin reescribir validación, aliases ni escritura. - Fuera de alcance: Figma, scraping, IA, MCP y Studio más allá del Editor ya implementado.
neuraz-ds view
Abre el Design System Viewer local: una vista exclusivamente de solo lectura (Overview, Colors,
Typography, Spacing, Radius, Borders, Shadows, Motion, Aliases, Foundations, Assets, Presets, Issues,
Build) sobre los casos de uso ya cerrados de 002–008. Cero escrituras, cero parseo directo, cero
acceso a filesystem desde la UI.
npx neuraz-ds view # arranca un servidor local (127.0.0.1, puerto efímero por defecto)
npx neuraz-ds view --port 4000 # puerto fijo
npx neuraz-ds view --json # imprime la sesión (ViewerJsonEnvelopeV1) y sale; sin servidor, sin navegador- Arquitectura: adapter
node:httppuro (src/infrastructure/viewer/http-server.ts) sirviendo una API JSON de solo lectura (GET /api/session,GET /api/section/:id) y un bundle estático vanilla TypeScript/DOM (src/infrastructure/viewer/ui/, compilado por el mismotscdel proyecto — sin framework, sin bundler, sin dependencia runtime nueva). El Core (src/application/viewer/**) nunca importanode:http, DOM, Commander ni ningún puerto de escritura — un guard de arquitectura dedicado (scripts/arch-guard.mjs) lo verifica. - Una sola carga por sesión/refresh: cada
GETreutiliza el snapshot único de006(que ya embebe el análisis de002y la proyección de foundations de004); ningún caso de uso reusado se invoca dos veces para la misma petición. - Estados soportados:
loading(solo en el cliente, antes de resolver)| ready | empty | invalid-design-system | not-found | read-error | partial— siempre proyectados desde un outcome ya devuelto por002/004/005/006/007, nunca inventados;partialconserva el contenido disponible (nunca una pantalla en blanco). - Aliases: alias inmediato, cadena completa, dependientes y una previsualización de impacto de
rename/move que reusa el plan read-only de
008(planTokenMutation) — nuncaapplyTokenMutation, nunca persiste el comando/plan sintético. - Assets: proyección 1:1 de
007(fonts, logos, SVG, icons, images: MIME, dimensiones, hash, licencia, provenance, ownership); sin copiar archivos, sin reimplementar sanitización/validación. - Accesibilidad: navegación completa por teclado, foco visible con contraste ≥3:1, landmarks
semánticos (
header/nav/main),prefers-reduced-motion, y ninguna información depende solo del color (los swatches siempre van acompañados de texto). - Offline: funciona sin red — el servidor solo escucha en
127.0.0.1; sin CDN, sin fuentes/scripts externos. - Fuera de alcance: edición de assets, autoría de presets, MCP server dedicado, Figma, scraping, IA.
Modo Editor (010-visual-token-editor)
El mismo servidor de view expone, además de la navegación de solo lectura, un Visual Token Editor
que permite editar tokens desde el navegador reutilizando exactamente planTokenMutation/
applyTokenMutation de 008 — nunca reimplementa validación, diff ni escritura.
npx neuraz-ds view # el botón "Enter edit mode" del Overview activa el Editor sobre la misma sesión- Flujo: draft (formularios de valor/metadata/alias/token/grupo) →
POST /api/editor/plan(mismoTokenMutationCommandV1/TokenMutationPlanV1/TokenMutationDiffV1de008) → diff visual read-only → aprobación explícita →POST /api/editor/apply(transaccional, víaapplyTokenMutation) → recarga de una sesión del Viewer nueva e independiente. Nunca aplica automáticamente. - Rutas (loopback,
POSTsolo bajo/api/editor/):GET /api/editor/session,POST /api/editor/refresh,POST /api/editor/plan,POST /api/editor/apply. SineditorApplyDeps(p. ej. en tests que no lo configuran),/api/editor/applyrespondeinternal-error— el modo read-only deviewnunca se rompe. - Estados de apply:
applied,unchanged,conflict,source-changed-concurrently,source-unavailable,write-error,verification-error,recovery-required— cada uno con mensaje explícito y, cuando aplica, backup/recovery visibles como texto (nunca solo codificado por color). - Cero escrituras antes de la aprobación explícita, en un plan bloqueado (
canApprove:false) o en cualquier ruta de solo lectura (session/refresh/plan);applyTokenMutation(008) es quien decide si escribe, nunca la UI ni el adapter HTTP. - Accesibilidad: teclado completo, foco visible, labels asociados, errores de control con
aria-describedby/aria-invalid, anuncios vía regiones vivas para preview/aprobación/conflicto/ apply/recovery, sin drag-and-drop obligatorio,prefers-reduced-motion, nunca solo color. - Fuera de alcance: edición de assets, autoría de presets, Figma, scraping, análisis de imágenes, IA, MCP, nube, autenticación, multi-theme, editor de componentes.
Comandos disponibles
| Comando | Descripción |
|---|---|
| neuraz-ds init | Inicializa el Design System local (interactivo, puede escribir). |
| neuraz-ds validate [--json] | Valida el Design System administrado sin modificar archivos. |
| neuraz-ds inspect [--json] | Inspecciona estructura, tokens y estado sin modificar archivos. |
| neuraz-ds foundations [--json] | Inspecciona categorías foundation y niveles sin modificar archivos. |
| neuraz-ds presets list [--json] | Lista el catálogo de presets empaquetado sin modificar archivos. |
| neuraz-ds presets inspect <id> [--json] | Detalla un preset sin modificar archivos. |
| neuraz-ds presets plan <id> [--json] | Previsualiza la aplicación sin modificar archivos. |
| neuraz-ds presets apply <id> [--json] | Aplica el preset de forma segura (add-only, atómica). |
| neuraz-ds build [--json] | Compila todos los formatos a design-system/build/ (conjunto, transaccional). |
| neuraz-ds export css\|json\|typescript | Emite un formato a stdout sin escribir (read-only). |
| neuraz-ds asset list [--json] | Lista los assets administrados sin modificar archivos. |
| neuraz-ds asset inspect <path> [--json] | Detalla un asset sin modificar archivos. |
| neuraz-ds asset import plan <archivo…> [--json] | Previsualiza la importación sin escribir. |
| neuraz-ds asset import apply <archivo…> --license <id> | Importa de forma transaccional (todo o nada). |
| neuraz-ds asset remove <path> | Elimina un asset administrado (transaccional, ownership-bound). |
| neuraz-ds token plan --file <cmd.json> [--json] | Previsualiza una mutación de tokens sin escribir. |
| neuraz-ds token apply --file <cmd.json> [--json] | Aplica una mutación de tokens (transaccional). |
| neuraz-ds token create <path> --type <t> --value <v> | Crea un token (shorthand; escribe). |
| neuraz-ds token update <path> --value <v> | Actualiza el valor de un token (shorthand; escribe). |
| neuraz-ds token rename <path> <newName> | Renombra un token y reescribe sus referencias (shorthand). |
| neuraz-ds token move <path> <newParent> | Mueve un token y reescribe sus referencias (shorthand). |
| neuraz-ds token remove <path> | Elimina un token; bloquea si tiene dependientes (shorthand). |
| neuraz-ds view [--port <n>] [--json] | Abre el Viewer local; el modo Editor solo escribe tras aprobación explícita. |
| neuraz-ds sources list [--json] | Lista las fuentes registradas en sources.json sin modificar archivos. |
| neuraz-ds sources add <ref…> | Registra una o más fuentes (url:/git:/local:/html-export:); escribe sources.json. |
| neuraz-ds sources remove <id> | Elimina una fuente por id de sources.json. |
| neuraz-ds fetch [--json] | Materializa material estático a capture/inputs/<id>/ tras el puerto RemoteMaterialSource (nunca ejecuta código de la fuente). |
| neuraz-ds brief [--json] | Analiza el material y emite brief.json + inbox/MANIFEST.md (checklist por-recurso con estado). |
| neuraz-ds generate --from-sources [--json] | Genera el DS desde la evidencia: foundations + aliases semánticos + component tokens + bloques + assets administrados + brand medible, todo con provenance; reemplaza los tokens demo; nunca pisa ediciones manuales (las reporta). |
| neuraz-ds verify-viewer [--json] | Verifica EN PROCESO que las secciones del Viewer (session/brand/assets/components/blocks/quality) se pueblan cuando hay evidencia sin modificar archivos. |
| neuraz-ds --help / <cmd> --help | Ayuda. |
| neuraz-ds --version | Versión del gestor. |
Códigos de salida (tabla común del binario)
| Código | Semántica |
|---:|---|
| 0 | Éxito válido / creado |
| 1 | Cancelación interactiva |
| 2 | Sin cambios (usado por init) |
| 3 | Entrada o Design System inválido |
| 4 | Estructura parcial o conflicto |
| 5 | Host o Design System no localizado |
| 6 | Error de lectura/filesystem |
| 7 | Verificación posterior de escritura |
| 70 | Error interno de frontera CLI (no contractual) |
validate, inspect y foundations no usan 1, 2 ni 7 en su flujo normal (operaciones de
solo lectura). presets list/inspect/plan también son de solo lectura; presets apply sí puede usar
2 (sin cambios / idempotente), 4 (conflicto bloqueante), 6 (error de escritura) y 7
(verificación posterior tras escribir). token plan es de solo lectura; token apply y los shorthands
usan la misma tabla: 2 (unchanged, idempotente), 3 (invalid-command/invalid-design-system), 4
(conflict: colisión, dependientes, grupo no vacío o cambio concurrente), 6 (read-error/write-error)
y 7 (verification-error, con backup retenido y recuperación explícita). view --json es de solo
lectura y usa el mismo vocabulario: 0 (ready/empty), 3 (invalid-design-system), 4 (partial),
5 (not-found), 6 (read-error); nunca usa 1, 2 ni 7 (no hay escritura ni cancelación
interactiva).
build usa 0 (built), 2 (unchanged), 3 (Design System inválido), 4 (valor no soportado o
conflicto), 5 (no inicializado), 6 (error de lectura/escritura) y 7 (verificación posterior a la
publicación). export es read-only y usa 0 (exported), 3, 4, 5 y 6.
asset list/inspect/import plan son de solo lectura (0; 3 store inválido, 4 no soportado/conflict,
5 no encontrado, 6 lectura). asset import apply/remove pueden usar 0 (applied/removed), 2
(unchanged / idempotente), 4 (conflicto), 6 (error de escritura) y 7 (verificación posterior).
sources list, fetch y brief devuelven 0 en su flujo normal: una fuente inaccesible durante
fetch no aborta a las demás ni cambia el código de salida (queda ok:false en el elemento
MaterializedInputV1 correspondiente). sources add usa 0 (al menos una registrada) o 4 (todas las
refs fallan validación). sources remove usa 0 (eliminada) o 5 (id no encontrado). Un --json
estable para agentes: sources list emite SourcesSetV1, fetch un MaterializedInputV1[] y brief
el GenerationBriefV1 completo (mismas claves y orden en cada corrida — determinismo, SC-004).
neuraz-ds sources · fetch · brief (032)
Ingesta de fuentes de origen y brief de generación asistida: registra de dónde viene la marca,
materializa su material estático de forma reproducible y emite una checklist que cualquier agente ejecuta
a la primera. El fetch por red es opt-in y va siempre tras el puerto RemoteMaterialSource: obtiene
material estático (HTML, CSS, fuentes, imágenes) y nunca ejecuta código de la fuente (ADR-0033 +
enmienda PATCH del Principio XIV). Los tipos de fuente son url:, git:, local: y html-export:.
# Registrar fuentes (también disponible al inicializar: `init --source url:… --source local:…`)
npx neuraz-ds sources add url:https://capstonewellness.com local:./brand-kit
npx neuraz-ds sources list --json # SourcesSetV1
npx neuraz-ds sources remove local-brand-kit
# Materializar material estático (reproducible byte a byte)
npx neuraz-ds fetch --json # → design-system/capture/inputs/<id>/ + MaterializedInputV1[]
# Emitir el brief que el agente ejecuta
npx neuraz-ds brief --json # → design-system/brief.json + design-system/inbox/MANIFEST.md- Reparto fijo (constitución): el gestor hace lo determinista (registrar, materializar, analizar,
emitir la checklist); el agente ejecuta lo no determinista (
npm i, descargas licenciadas, registrar bloques). Elbrief.jsonincluye por recursoaction+status(resolved|pending-manual|failed),truncations[]yrules[](p. ej. "nunca dejar un placeholder permanente"). - Cinco secciones siempre presentes en el brief:
fonts,icons,colors,componentTokenCandidates,layouts. Los componentes/bloques solo salen de evidencia trazable en el HTML/CSS materializado; nunca se inventan. - Fallback manual (
inbox/): un recurso no obtenible (p. ej. una fuente de foundry de pago) quedapending-manualcon undropTo(p. ej.design-system/inbox/fonts/) y aparece eninbox/MANIFEST.md. Al soltar el archivo y re-ejecutarbrief, el gestor detecta el aporte y reescribe la instrucción (action: "import-dropped") para que el agente lo registre con licencia explícita (neuraz-ds asset import apply <file> --license <id>); el gestor nunca fabrica una licencia. - Determinismo (SC-004): re-ejecutar
fetch+briefcon las mismas fuentes produce material,capture/inventory.jsonybrief.jsonbyte a byte idénticos. - Retrocompat (SC-007):
sources.json/brief.json/capture//inbox/no integran los archivos requeridos de un DS; un proyecto 001–031 sin ellos sigue clasificándose como completo yvalidate/inspectpermanecen verdes. - Layouts y feature 030: la porción de layouts reutiliza la captura de la feature 030 (aún no
implementada); mientras tanto el brief degrada
layoutsa vacío explícito.
neuraz-ds generate --from-sources (033)
Convierte la evidencia materializada+curada en artefactos REALES del DS (no solo candidatos):
npx neuraz-ds sources add local:./frontend # o html-export:/url:
npx neuraz-ds generate --from-sources --json # foundations + aliases semánticos, con provenance
npx neuraz-ds validate && npx neuraz-ds view- Foundations medidas del CSS (color/typography/spacing/radius/borders/shadows) en DTCG 2025.10,
con nombres canónicos por tono/luminosidad (
color.base.red-500) y provenance por token ($description+$extensions). Sin evidencia una categoría queda ausente: nunca se fabrica. - Aliases semánticos mínimos:
color.brand.primary/secondary,color.background.default/inverse,color.surface.default,color.text.primary/inverse,color.border.default,color.action.primary.background/text— cada uno alias de una foundation real. - Política de tokens demo: el
blue-500+ alias demo deinitse reemplazan cuando hay evidencia real; un token editado a mano nunca se pisa (queda y se reporta como conflicto). - Clasificación de respuesta URL (WAF/challenge/bot/vacío/redirect engañoso) con instrucción de fallback; una fuente sin HTML/CSS produce un diagnóstico accionable — nunca un DS vacío silencioso.
- Determinista e idempotente (misma fuente ⇒ mismos bytes). Exit codes:
0generated ·4fuentes bloqueadas/sin evidencia ·5sin fuentes registradas ·70error interno.--jsonemite{outcome, report}(reporte de calidad: fuentes, tokens creados, pendientes con ruta+razón, conflictos, ruido excluido, no-generado con razón). - Component tokens desde evidencia: los componentes detectados en la estructura HTML (button, navbar,
card, footer, form, …) se generan como
color.component.<name>.<part>— cada uno alias de un token semántico (nunca un hex directo) con metadata de capa (ar.neuraz.design-system) que el Viewer agrupa automáticamente.button/ctamapean acolor.action.primary.*(identidad, no superficie neutra). - Bloques renderizables:
design-system/blocks.jsoncon las composiciones reales detectadas (site-header, hero, content-grid, site-footer, …) en el contrato que el Viewer ya lee; un bloque editado a mano nunca se pisa (conflicto reportado). - Assets administrados + brand medible: los assets curados (logo/favicon/iconos/fuentes/imágenes) se
importan vía el Asset Manager (007) — la licencia queda
pending-manual(el gestor no la asume) — ybrand/visual-language.jsonse escribe con la parte MEDIBLE (paleta real, distribución de color por frecuencia, roles tipográficos, logo referenciado). Lo editorial (brand.json narrativo, voz/tono, guías) SIEMPRE quedapending-manualpara el agente: el gestor no fabrica contenido editorial. - html-export como fuente lógica: registrar un solo
.htmlexportado del navegador incorpora automáticamente su carpeta hermana (_files/_archivos/-Dateien/…); sin carpeta, la ausencia se declara con la ruta esperada.
neuraz-ds verify-viewer (033)
Verificación EN PROCESO del Viewer (misma fuente de estado que /api/session y /api/section/*, sin
servidor ni navegador): reporta cada sección (session/brand/assets/components/blocks/quality) como
populated, empty-no-evidence (estado esperado, no error) o error, con el porqué. Exit codes:
0 ok · 4 degraded (alguna sección en error) · 5 sin DS · 6 error de lectura · 70 interno.
npx neuraz-ds verify-viewer --json # ViewerVerificationV1 {version, sections[], ok, sessionState}Flujo de aceptación completo (SC-001):
npx neuraz-ds sources add <url:…|html-export:…|local:…>
npx neuraz-ds generate --from-sources --json
npx neuraz-ds validate --json && npx neuraz-ds build --json
npx neuraz-ds verify-viewer --json && npx neuraz-ds viewSalida JSON v1
validate --json, inspect --json y foundations --json son superficies estables para CI,
agentes, scripts y otros consumidores headless. init --json no existe, --json no es global y no
hay flags de formato como --compact, --pretty u --output.
build --json emite su propio envelope (BuildJsonEnvelopeV1, también formatVersion: "1.0.0") con
campos específicos del build (outcome, wrote, outputDirectory, artifacts, manifest,
verification, backupRelativePath, recoveryRequired, error). export no emite JSON: su salida
son los bytes exactos del artifact.
asset list/inspect/import plan --json emiten su propio envelope (AssetJsonEnvelopeV1, también
formatVersion: "1.0.0", con command asset-list|asset-inspect|asset-plan). asset import apply y
asset remove son escrituras: salida humana, sin envelope JSON.
El envelope público siempre incluye cuatro campos base:
{
"formatVersion": "1.0.0",
"command": "validate",
"outcome": "valid",
"result": {}
}formatVersionversiona el contrato JSON y es independiente depackage.version.commandes"validate","inspect"o"foundations".outcomepara estados esperados esvalid,complete-invalid,partial,not-foundoread-error;internal-errorexiste solo en la frontera CLI.resultcontiene el DTO del comando onullcuando no hay Design System administrado.erroraparece solo ennot-foundeinternal-error; ennot-foundesnullen v1 porque los casos de uso reutilizados no pueblanhostError.
Reglas de canales:
| Caso | stdout | stderr | exit |
|---|---|---|---:|
| outcome esperado con --json | exactamente un JSON con newline final | vacío | 0/3/4/5/6 |
| error interno CLI con --json | vacío | envelope JSON internal-error con newline final | 70 |
| error de uso Commander | política existente del parser | mensaje de uso/error | 3 |
La serialización usa 2 espacios y newline final, no emite ANSI/spinners/tablas, no contiene
undefined, preserva el orden de arrays del modelo, y no incluye stacks, errores crudos de librería,
contenidos de archivos ni el context interno de los issues. Los campos contractuales no disponibles
se serializan como null.
Resumen de DTOs:
validate --json:host,structuralState,valid, documentos comprobados/no comprobados,summary,errors,warningsylimits.inspect --json:host,structuralState,identity,schemaVersions,files,tokens,validationylimits;identityyschemaVersionsusan{value, trust}.foundations --json: contrato separado e independiente del JSON v1 de 003; incluyehost,structuralState, las nuevecategories,unresolved,summary,validationylimits. Conserva todos los tokens foundation, sin cota de 200.presets <sub> --json: contrato propio (formatVersion: "1.0.0"), aislado de los envelopes de 003 y 004.commandes"preset-list","preset-inspect","preset-plan"o"preset-apply";outcomecubresuccess/applied/unchanged/invalid-preset/conflict/not-found/read-error/write-error/verification-error(másinternal-erroren la frontera CLI). No emite rutas absolutas, stacks ni contenidos de archivo.
Arquitectura headless
La lógica de validación/inspección vive en un único productor compartido del que se derivan dos proyecciones; la CLI es solo un adapter opcional de presentación:
analyzeExistingDesignSystem (1 lectura + 1 parseo por documento, 1 recorrido del árbol)
├── ValidationReport (proyección de validez → validate)
├── DesignSystemInspection (proyección descriptiva → inspect)
└── FoundationsInspection (proyección foundation + pasada metadata O(nodes) → foundations)Los casos de uso validateDesignSystem, inspectDesignSystem e inspectFoundations son
headless (sin terminal): una futura TUI/Studio/MCP puede reutilizarlos sin reescribir el núcleo.
La salida JSON se deriva de resultados públicos mediante DTOs y mappers puros; no serializa objetos
de dominio en crudo ni ejecuta un segundo análisis.
Estado y límites de esta versión
Implementa init, validate, inspect, foundations y presets. Límites actuales (no son
defectos):
- un Design System por proyecto; tres documentos administrados; un archivo de tokens;
- tokens en JSON DTCG 2025.10; inspección profunda solo de
color; - los otros 12 tipos DTCG reconocidos se validan de forma superficial y producen un warning
(
dtcg-type-not-deeply-inspected), sin invalidar el Design System; foundationsclasifica solo foundation primitives/semantics;presetsofrece un preset empaquetado (neutral-base) con merge add-only sobre el archivo de tokens; sin--force/--category/--dry-run, sin delete, themes, dark mode, component tokens, presets externos/marketplace ni recomendador automático. Es la base para 006 (build/export), que no está disponible aquí;- sin reparación/edición/migración, sin TUI/viewer/MCP, sin Style Dictionary y sin múltiples themes ni múltiples archivos de tokens.
Roadmap (futuro, no disponible)
TUI opcional / viewer efímero
Style Dictionary
MCPDesarrollo
npm install
npm run typecheck # TypeScript estricto (ESM, NodeNext)
npm run lint # guard arquitectónico por capas
npm test # Vitest (unit + integración + CLI)
npm run build # compila a dist/Requiere Node.js >=22. Construido con Spec-Driven Development
(GitHub Spec Kit); especificaciones en
specs/001-ds-init/, specs/002-ds-validate-inspect/,
specs/003-json-output/, specs/004-foundations/
y specs/005-presets/, decisiones en docs/adr/
(0001–0021), principios en
.specify/memory/constitution.md.
