Communitygithub.com

mikeozornin/skills

Úsalo cuando el usuario solicite un prototipo HTML interactivo, un mockup cliqueable o un recorrido de flujo de UI, estados de pantalla o una funcionalidad para revisores (diseñadores, gestores de producto, desarrolladores) - "prototipo", "mockup cliqueable", "muestra los estados de pantalla".

¿Qué es skills?

Esta skill permite construir prototipos HTML interactivos y cliqueables para explorar y decidir sobre flujos de UI, estados de pantalla o funcionalidades. Está diseñada para entornos colaborativos donde revisores (diseñadores, gestores de producto, desarrolladores) necesitan evaluar una decisión concreta, no solo ver una galería de pantallas. Soporta múltiples variantes de interfaz, anotaciones contextuales, un mapa de pantallas automático y comentarios de revisores integrados. Funciona con una plantilla autónoma (template.html) que incluye el shell (navegador, panel de notas, mapa de pantallas, comentarios y tokens de diseño Koobiq) y un sistema de montaje/desmontaje mediante scripts Node.js. El flujo de trabajo guía al usuario desde la definición del contexto y la pregunta clave hasta la construcción de escenarios, estados y datos realistas, asegurando que cada prototipo responda a una decisión específica y no contenga elementos superfluos.

Compatible con✓Claude Code✓Codex CLI✓Cursor✓Windsurf
npx skills add https://github.com/mikeozornin/skills/tree/HEAD/skills/mo-build-html-prototype

Preguntar en tu IA favorita

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

Documentación

Construir Prototipo HTML

Construye cada prototipo en assets/template.html (en el directorio de esta skill): un archivo HTML autónomo. La plantilla ya tiene el shell completo: encabezado, marco del navegador, conmutador de estado, panel de notas, mapa de pantalla, comentarios de revisores, tokens Koobiq con componentes k-* y el tiempo de ejecución. La interfaz del shell está en inglés o ruso, según el idioma del SO/navegador; el texto propio del prototipo es el que tú escribas. Solo escribes el bloque PROTOTYPE (JS) y la sección 5. PROTOTYPE STYLES (CSS). No rompas la plantilla: nunca reconstruyas, reestilices o describas el shell.

Diseño antes del código

Un prototipo es una herramienta para una decisión, no una galería de pantallas. Trabaja estos pasos antes de escribir prototype.js.

  1. Recopilar contexto. Quién es el usuario (rol, experiencia), qué tarea está realizando, qué la desencadena y cómo se ve "terminado" para ellos. Si el producto existe (repositorio, capturas de pantalla, Figma, docs, un prototipo anterior), toma su navegación, términos, entidades y datos de ahí y diseña solo el cambio. No inventes un producto alrededor de la funcionalidad.

  2. Nombrar la pregunta. Una frase, o varias solo para un prototipo grande: qué deben decidir los revisores, o qué es lo más dudoso en la interfaz (¿encontrarán los usuarios X?, ¿entenderán Y?, ¿Z se sostiene con datos reales?). Para cada pregunta, anota qué debe ver un revisor para responderla y qué estado o dato podría romper el diseño. Si la solicitud no nombra ninguna pregunta, toma la decisión más arriesgada como una y plantéasela al autor en el paso 4.

  3. Escribir el escenario en palabras del usuario, desde el desencadenante hasta el resultado: "el analista ve un pico → abre la regla → baja el umbral → ve cuántos incidentes habrá". Luego añade solo las ramas que necesita la pregunta: cancelación, error de validación, vacío o primer uso, y los casos difíciles donde surgen requisitos que nadie vio antes: sin permiso, un conflicto con otro objeto, un límite, muchos datos, una acción que el estado actual del objeto prohíbe. Los pasos se convierten en STEPS, las ramas en estados, y las condiciones transversales (rol, flag de funcionalidad, volumen de datos) en SWITCHES.

  4. Acordar con el autor antes de construir. En un mensaje corto, envía:

    • la pregunta;
    • el escenario con las ramas y los casos difíciles que planeas mostrar;
    • todo lo que has supuesto en lugar de tomar de la solicitud o del producto, como una lista numerada con una afirmación por elemento, para que el autor pueda responder por número: "2 — no, se necesita la aprobación de un gestor".

    Espera la respuesta. Omite este paso para pequeñas modificaciones de un prototipo existente. Si el autor pidió que no se le pregunte, construye basándote en tus suposiciones y enuméralas en la respuesta.

  5. Establecer la profundidad de cada celda paso × estado:

    • completo = en el camino de la pregunta: cliqueable, cada estado, datos de estrés;
    • plausible = contexto: estático pero realista;
    • fuera = nombrado en la respuesta como no cubierto.

    Usa solo los estados que la pregunta necesita: ideal, vacío o primer uso, parcial, error, sin permiso, aproximadamente 6 por paso como máximo. Añade carga solo cuando muestre algo específico (una operación larga, progreso, resultados parciales). Una carga fallida rara vez vale un estado, pero "no permitido en el estado de este objeto" normalmente sí. Nunca finjas un resultado que no esté diseñado.

  6. Diseñar cada pantalla primero en palabras: su propósito en una frase, la única acción principal y qué necesita ver el usuario para decidir aquí, ordenado por importancia. Luego constrúyela con patrones Koobiq estándar (tabla, formulario, panel lateral, modal, estado vacío). Pon novedad solo donde está la pregunta; todo lo demás se parece a las pantallas habituales del producto.

    • Cada acción tiene un resultado visible: qué pasó y dónde está el objeto ahora.
    • Una acción destructiva nombra el objeto y la consecuencia. Los botones suelen decir el verbo.
    • Un error dice cómo solucionarlo y mantiene la entrada.
    • Un nombre por cosa en todas las pantallas, migas de pan, toasts y la URL. El texto de la interfaz está en el idioma del usuario y sigue ux-write si está instalado.
  7. Escribir los datos antes que las vistas. Usa datos de dominio realistas que pongan a prueba el diseño: un nombre largo, un conteo 0 / 1 / muchos, un estado raro. Usa fechas y valores fijos (sin Date.now() / Math.random()) y sin lorem ipsum.

Variantes, solo cuando la pregunta es "qué solución". Construye 2–3 (máximo 5) en VARIANTS en lugar de elegir por los revisores.

  • Se diferencian en estructura (diseño, jerarquía, acción principal), no en color o texto. Si dos borradores se parecen, rehaz uno con una prohibición explícita ("sin cuadrícula de tarjetas").
  • Las variantes pueden compartir datos, nunca diseño.
  • Dale a cada una un title y una idea de una línea en text.
  • El mejor feedback es "encabezado de B, lista de C".

Hecho cuando

Verifica el prototipo contra cada elemento antes de responder:

  • Cada ruta mostrada se ejecuta de principio a fin. Comienza donde el usuario se encuentra con el desencadenante, no en un inicio de sesión o un panel de control. Cada rama mostrada termina, de vuelta en el camino o en un resultado. Una transferencia a otro producto o sistema es un stub con un resultado visible (un toast, o un estado como "Tarea creada en Jira"), nunca una copia de la otra interfaz. Un control secundario puede no hacer nada (un elemento de menú puede simplemente close) siempre que ningún escenario comience desde él.
  • Lo que es debatible está marcado. Cada elemento cambiado o debatible tiene una nota. Cuando la pregunta es qué solución tomar, hay 2–3 variantes que difieren en estructura.
  • Nada extra. Cada estado, conmutador y nota ayuda a responder la pregunta o prueba una suposición sobre un requisito. Elimina el resto.

Construir

  1. Obtener las partes editables. Con SKILL_DIR = directorio de esta skill, A=$SKILL_DIR/scripts/assemble.mjs (ejecutar con node, sin dependencias), directorio de trabajo p.ej. /tmp/proto-<nombre>/:

    • prototipo nuevo: node $A --split $SKILL_DIR/assets/template.html /tmp/proto-<nombre>;
    • modificar uno existente: node $A --split <archivo>.html /tmp/proto-<nombre>. Reensamblar también actualiza su shell.

    Esto da prototype.js (bloque PROTOTYPE de demostración) y prototype.css (sección 5).

  2. Reescribir prototype.js, reemplazando todo el contenido de demostración: PROTO, STEPS, SWITCHES, S, NOTES, LINKS (normalmente []), datos, VIEWS, ACTIONS. El CSS personalizado va a prototype.css. Trabaja en pasadas:

    1. la ruta principal, cliqueable de principio a fin, en su estado ideal;
    2. los otros estados y ramas;
    3. notas;
    4. Verificar y Hecho cuando.

    No pulas una pantalla antes de que la ruta a través de ella funcione.

  3. Ensamblar: node $A <objetivo>.html /tmp/proto-<nombre>/prototype.js /tmp/proto-<nombre>/prototype.css. Comprueba la sintaxis y las declaraciones requeridas. Entrega solo el HTML.

  4. Vistas: un VIEWS[paso](S) por paso que devuelve una cadena HTML y ramifica en S.state / S.sw. Construye con clases k-*; consulta references/koobiq-cheatsheet.md.

    • Cada estado se renderiza completamente cuando se abre directamente. Una apertura directa (popover, enlace hash, miniatura del mapa, nota, ←/→, protoCheck) comienza desde el S inicial más el seed del estado, por ejemplo { id: 'confirm', title: 'Confirmación', seed: { name: 'Brute force: RDP' } }. Un goto() en flujo conserva lo que el usuario escribió. Las VIEWS solo leen S y datos constantes.
    • Superposiciones. Un modal o panel lateral se dibuja sobre la pantalla que cubre, dentro de la misma vista. Una superposición única (una confirmación) es un estado de ese paso (form/confirm). Una superposición con su propio subflujo (formulario → error → confirmar) puede ser su propio paso que dibuja la pantalla cubierta debajo. Para un modal sobre un panel, renderiza el modal después del panel: el último .k-overlay es el superior, y solo sus marcadores se muestran.
    • Desplazamiento. Una pantalla más alta que el marco del navegador se desplaza dentro de él, como una página. Un nuevo paso comienza en la parte superior; un nuevo estado o variante en el mismo paso mantiene el desplazamiento, para que los revisores los comparen en el mismo lugar. Un shell de aplicación (.app-body + .app-content) se desplaza dentro de .app-content, como antes.
    • Conecta los clics con data-act → ACTIONS. Cambia de pantalla solo mediante goto(paso, estado) / data-goto, para que el botón de estado, la barra de URL y el hash se mantengan sincronizados.
  5. Notas (3–7) van solo en los elementos sobre los que trata la pregunta: cambiados o debatibles.

    • Pon class="changed" data-anchor="note-N" en el elemento y ${marker(N)} dentro de él. Envuelve elementos vacíos o deshabilitados en <span class="k-anchor changed" data-anchor="note-N">.
    • El text de la nota dice qué cambió y por qué en 1–2 frases. Para una hipótesis, termínalo con "Comprobar: …".
    • try dice qué hacer clic para verlo.
  6. Mapa de pantalla se construye a partir de los estados y transiciones. Las transiciones provienen del marcado de cada estado: data-goto, y llamadas literales goto() / openState() en las ACTIONS que sus controles habilitados, elementos de menú y superposición superior llaman (los controles deshabilitados no dan flecha). Un estado calculado en la misma acción funciona si sus posibles ids aparecen allí como cadenas: goto('list', S.q ? 'empty' : 'data'). Una transición detrás de una función auxiliar, un temporizador o un evento que el usuario no hace clic va a LINKS: { from: 'report/building', to: 'report/ready', label: 'Informe listo' }.

  7. Verificar (ver Verificación). Corrige y reensambla hasta que protoCheck() esté limpio, luego verifica el prototipo contra Hecho cuando.

  8. Responder con la ruta del archivo, la tabla paso × estado, lo que deliberadamente no está cubierto y cualquier suposición hecha después del acuerdo. No describas el shell.

Comentarios del revisor

El usuario puede pegar el Markdown de "Copiar todo". Nombra el archivo en la línea Archivo:. Cada ## es una pantalla con su hash (#paso/estado?conmutadores); con variantes comienza con Variante B · Tarjetas → y el hash tiene variant=<id>. El shell lo escribe en el idioma de la interfaz del revisor, por lo que puede estar en ruso: Файл:, Вариант B. Cada ### es un elemento con su selector dentro de #vista, sus atributos data-* y el número de nota vinculado, seguido del comentario como cita.

Para aplicarlo, busca el elemento en VIEWS[paso] / ACTIONS de ese archivo (de esa variante), luego edita mediante --split y reensambla en el mismo archivo: los comentarios viven en el localStorage del navegador bajo la ruta del archivo.

Reglas del shell

  • Encabezado = solo título corto. Sin subtítulo, leyenda, descripción ni texto de "prototipo del flujo…" en ningún lugar sobre el marco.
  • Un control de estado: el popover "Paso · Estado". Sin steppers anterior/siguiente, controles segmentados por pantalla, pestañas sobre el marco o atajos de teclado personalizados (←/→, Esc y el selector de variantes con 1–9 están integrados).
  • Las notas solo viven en aside#notes, fuera de .browser. Dentro de .app solo hay marcadores numerados. Nunca pongas texto de nota en tooltips ::after, superposiciones o una columna de "modo revisión" dentro de la aplicación.
  • No edites RUNTIME, y no muevas ni reestilices el deck, escenario, navegador, notas, comentarios o mapa de pantalla. El comportamiento va en ACTIONS.
  • Koobiq por defecto: clases k-* y tokens --kbq-*. Sin colores hex/rgb, sin paleta inventada (p. ej. --bg, acentos morados) y sin estilo solo claro, porque el conmutador de tema debe funcionar. Para otro sistema de diseño, conserva el shell y reestiliza solo la aplicación.
  • Un archivo, sin JS externo.

API PROTOTYPE

QuéCómo
Título / Barra URLPROTO.title, PROTO.url(S)
Cuadrícula popoverSTEPS[{id,title,states[{id,title,seed?}]}], SWITCHES[{id,title,options}]
EstadoS.step, S.state, S.sw[id], S.menu (id de menú abierto), además de tus propios campos
Navegargoto(paso, estado, parche?) dentro del flujo (conserva S); marcado data-act="goto" data-goto="form/errors". openState(paso, estado) = apertura directa (S inicial + seed)
Accionesdata-act="nombre" → ACTIONS.nombre(el, e); re-renderiza a menos que devuelva false
Acciones integradasgoto; close (S.menu = null); menu + data-menu="id" (alternar); set + data-field + data-value (escribe en S, cierra menú). Un menú también se cierra con Esc, clic fuera y cualquier otra acción
Entradasdata-model="campo" escribe S.campo; data-live re-renderiza al introducir datos (el foco y el cursor se mantienen); data-live="act" primero llama a ACTIONS.act; data-scroll="clave" mantiene el desplazamiento
Focogoto('form', 'errors', { focus: 'name' }) enfoca [data-model="name"] una vez
Ayudantesicon('search'), marker(n, '--x:100%;--y:50%'), tip(html, text, 'k-float--right'), matches(S.q, ...campos), toast(title, {kind, text}), esc(str)
NotasNOTES[{id, step, state, title, text(html), try}]: step/state dicen dónde vive el ancla
Mapa de pantallaConstruido automáticamente; LINKS[{from: 'paso/estado', to: 'paso/estado', label}] añade transiciones que el escaneo no puede ver
VariantesVARIANTS[{id, title, text, STEPS?, NOTES?, VIEWS?, ACTIONS?, LINKS?, S?, url?}]. Las declaraciones globales son la variante A; una variante sobrescribe solo lo que difiere (S se fusiona con el S global). Cada una tiene su propio mapa de pantalla, notas y comentarios; SWITCHES y adelante/atrás son compartidos. Selector en el encabezado, teclas 1–9

Verificación

Sirve la carpeta en segundo plano (file:// a menudo está bloqueado) y abre la URL impresa más <archivo>.html en la herramienta del navegador. Recarga después de cada reensamblaje, porque un cambio solo de hash no recarga el archivo.

cd <dir> && node -e "const fs=require('fs'),T={'.html':'text/html; charset=utf-8','.js':'text/javascript','.css':'text/css','.svg':'image/svg+xml'};require('http').createServer((q,r)=>{const p='.'+decodeURIComponent(new URL(q.url,'http://x').pathname);fs.readFile(p,(e,d)=>{r.writeHead(e?404:200,{'Content-Type':T[require('path').extname(p)]||'application/octet-stream'});r.end(e?'Not found':d)})}).listen(0,'127.0.0.1',function(){console.log('http://127.0.0.1:'+this.address().port+'/')})"
  1. Ejecutar protoCheck() en la página (consola o herramienta de evaluación del navegador) con un ancho de ventana de 1440 o más. Debe devolver ok: true. Abre cada combinación paso × estado × conmutador en ambos temas e informa errores de renderizado, pantallas vacías, desbordamiento, marcadores o notas rotas, destinos desconocidos de data-act / data-goto / goto() / LINKS, colores codificados y restos de plantilla. Corrige cada advertencia (estados idénticos, conmutadores sin efecto, datos no deterministas, notas fuera de 3–7, un paso no conectado a otros) o explícala en la respuesta.
  2. Míralo en l

…

[truncated for translation]

Skills relacionados