Communitygithub.com

mirac221/frame-judge

Skill de solo comando. Ejecuta este skill solo cuando el usuario lo invoque por nombre (/frame-judge, $frame-judge, @frame-judge o "use frame-judge"). Nunca lo cargues por tu cuenta para trabajos normales de UI, animación o video.

¿Qué es frame-judge?

Este skill establece un ciclo de retroalimentación visual riguroso para trabajo generado por IA, donde un crítico separado (un subagente fresco y ciego al código, sin acceso al código fuente del creador) evalúa cada salida renderizada contra la solicitud original del usuario. A diferencia de la autoevaluación, que sufre un sesgo de intención (el modelo "ve" el resultado que quiso crear, no el que realmente renderizó), este crítico solo recibe píxeles y las palabras textuales del usuario. El flujo de trabajo incluye pasos para bloquear la solicitud, renderizar y capturar (con soporte para páginas, animaciones y video mediante scripts de Node.js que usan Playwright), empaquetar los resultados visuales en un paquete de revisión sin código y ejecutar el crítico a través de una puerta de validación que automatiza las decisiones. Diseñado para plataformas como Claude Code, Codex y similares, detecta defectos como desbordamiento, fotogramas negros, problemas de sincronización de animaciones e inconsistencias de diseño, y exige correcciones basadas en evidencia antes de aprobar el trabajo, con un límite predeterminado de 3 rondas de críticas para evitar ciclos infinitos. El skill también incluye un modo experimental "unsloppy" que invierte los defectos típicos de la IA investigando cómo los modelos suelen fallar en tareas similares.

Compatible con✓Claude Code✓Codex CLI✓Cursor✓Antigravity
npx skills add https://github.com/mirac221/frame-judge/tree/HEAD

Preguntar en tu IA favorita

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

Documentación

¿Qué hace frame-judge?

No te toca calificar tu propio trabajo visual.

Lo construyes y lo renderizas. Luego un crítico independiente juzga lo que realmente salió en pantalla contra lo que el usuario pidió realmente. El crítico nunca ve tu código, tu razonamiento ni tu opinión del resultado. Hasta que pase el trabajo, o se alcance el límite de rondas, no lo des por terminado, pulido, suave o hermoso.

Por qué: el modelo que escribió el código lee su intención en la salida. "Ve" el ciclo de marcha que quiso escribir, no el que se renderiza. Un crítico que solo recibe píxeles más las palabras del usuario no puede hacer eso. Tiene que mirar.

<skill> a continuación significa la carpeta donde está este archivo (en Claude Code: ${CLAUDE_SKILL_DIR}). Los scripts son Node 18+ simples sin paso de instalación. Mantienen el estado en .frame-judge/ bajo tu directorio de trabajo.

El ciclo

PasoQuéQuién
0Bloquear la solicitud del usuario, textualtú
0bPreguntar "¿unsloppy?". Si es sí, un explorador investiga los valores predeterminados de IA que evitartú, el usuario, un explorador
1Construirtú
2Renderizar y capturar: capturas de pantalla, hojas de fotogramas, estelas de movimientoscripts
3Autocomprobación mecánica: se renderiza, nada en blanco, sin errores de ejecucióntú
4Empaquetar un paquete de revisión sin códigoscript
5Preguntar en qué modelo se ejecutará el crítico, si la plataforma lo permite (una vez)tú, luego el usuario
6El crítico revisa el paquetesubagente fresco
7La puerta valida la revisión y decidescript
8Responder a cada hallazgo de corrección obligatoria, luego volver al paso 2tú
9Reportar el veredicto del crítico, no tu opinióntú

Límite predeterminado: 3 rondas de críticas.

0. Bloquear la solicitud

node <skill>/scripts/judge.mjs init --brief-file request.txt --kind frontend,motion

Usa --brief "..." para texto en línea, o --brief-file - para leer desde stdin.

  • Textual. Guarda el mensaje del usuario tal como está escrito: errores tipográficos, mayúsculas, todo. Nunca parafrasees, resumas o "aclarezcas". El crítico juzga contra sus palabras, no contra tu lectura de ellas.
  • Aclaraciones posteriores del usuario van con judge.mjs brief --add "<sus palabras exactas>". Tus propias suposiciones nunca entran.
  • Imágenes de referencia que el usuario te dio: añade --ref mock.png (repetible) para que el crítico pueda comparar con ellas.
  • --kind elige las rúbricas: frontend para páginas e IU, motion para cualquier animación, video para clips y ediciones. Omítelo para que se detecte automáticamente desde las capturas.
  • --critic-model si el usuario ya nombró uno.

Esto crea .frame-judge/ (se ignora a sí mismo en git) con brief.md y ledger.json. El libro mayor sobrevive a la compactación del contexto. Si pierdes el rastro, ejecuta judge.mjs status.

0b. Preguntar sobre el modo unslop (antes de construir)

Pregunta al usuario una vez, en estas palabras:

¿Lo quieres sin chapuzas? (experimental: puede disminuir la calidad y gastará más tokens)

En Claude Code, pregunta con AskUserQuestion, en el mismo prompt que la pregunta del modelo crítico del paso 5. En otros lugares, pregunta en el chat. Omítelo si el usuario ya lo dijo.

  • No: continúa. Unslop está desactivado por defecto.
  • Sí:
    1. Ejecuta judge.mjs set unslop on, luego judge.mjs scout. Imprime un mensaje para un explorador de chapuzas: un subagente fresco con búsqueda web que descubre cómo los LLM suelen equivocarse en este tipo de solicitud.
    2. Envía ese mensaje al explorador y nada más. Las mismas reglas que para el crítico: agente fresco, sin bifurcación, sin añadidos. Usa el modelo del crítico si está configurado.
    3. Guarda su respuesta, luego ejecuta judge.mjs avoid --file <respuesta>. Eso rechaza listas sin fuentes reales.
  • No hay búsqueda web disponible: dile al usuario que unslop no puede ejecutarse aquí y continúa sin él.

La lista de evitar termina en .frame-judge/avoid.md, y se incluye en cada paquete de revisión, para que el crítico también verifique el trabajo contra ella.

"Experimental" porque alejarse de los valores predeterminados puede llevar a una construcción hacia elecciones extrañas, y el explorador cuesta una ejecución adicional de agente con búsquedas web.

1. Construir

Si unslop está activado, lee primero .frame-judge/avoid.md.

  • Diseña evitando cada patrón. No lo inviertas simplemente: el objetivo es un trabajo que se ajuste a la solicitud, no un trabajo que sea meramente diferente.
  • Cualquier cosa que el usuario haya pedido explícitamente prevalece sobre la lista.

Antes de construir, lee la sección de references/craft.md para tu medio, una vez por sesión. Cubre lo que los críticos señalan más: espaciado, tipo, marcas de plantilla de IA, easing, ciclos de marcha, ritmo de video.

Para cualquier cosa animada, haz que el tiempo sea una entrada explícita: una línea de tiempo que puedas buscar, o un hook window.frameJudgeSeek(ms). Eso hace que la captura sea precisa al fotograma, y convierte HTML en video gratis.

2. Renderizar y capturar

Páginas e IU (necesita Playwright; configuración en references/capture.md):

node <skill>/scripts/capture-page.mjs http://localhost:5173 --out .frame-judge/cap/page

Los valores predeterminados son escritorio 1440×900, tableta 768×1024 y móvil 390×844, capturados pantalla por pantalla. Opciones:

  • --actions states.json para estados hover, menú y error
  • --color-scheme dark
  • --reduced-motion
  • los archivos locales funcionan también como URLs

Animación en una página. Esto es preciso al fotograma (reloj falso más búsqueda de Web Animations) y codifica a MP4:

node <skill>/scripts/capture-page.mjs scene.html --out .frame-judge/cap/anim --animate 3000 --fps 30 --selector "#hero"

Cualquier video, incluyendo ese MP4:

node <skill>/scripts/video-frames.mjs .frame-judge/cap/anim/animation.mp4 --out .frame-judge/cap/anim-views --as motion

Lo que obtienes:

  • Rebanadas de viewport en lugar de una imagen gigante de página completa, que se reduciría a papilla.
  • Tomas de estado de tu archivo de acciones.
  • Una hoja de contactos con marca de tiempo.
  • Tiras de película: fotogramas muestreados a 12 fps por defecto, más tiras a velocidad completa alrededor de cualquier salto repentino o parada que el script detecte (--motion-fps source da cada fotograma en todas partes). Muestreado significa que un fallo de un fotograma puede caer entre losetas, por lo que existe la detección de eventos.
  • Estelas de movimiento: lo que debería permanecer quieto se mantiene nítido, y lo que se desliza se mancha.
  • Números objetivos: duración, fps, segmentos negros o congelados, desbordamiento horizontal, imágenes rotas.

Captura lo que el usuario experimentará: cada viewport que usaría, los estados que importan, toda la animación. El crítico no puede señalar lo que no le mostraste. Omitir las partes feas es exactamente el engaño que este skill existe para detener.

3. Autocomprobación mecánica

Antes de gastar una ronda de críticas, verifica y corrige lo básico:

  • se renderiza
  • sin fotogramas en blanco o negros
  • nada en builder_only en cada capture.json (errores de consola, solicitudes fallidas)
  • la duración y el tamaño correctos
  • horizontal_overflow_px y broken_images son cero

Esa es toda la lista. No te corresponde decidir que se ve bien y saltarte el crítico.

4. Empaquetar

node <skill>/scripts/judge.mjs bundle .frame-judge/cap/page .frame-judge/cap/anim-views

Esto escribe .frame-judge/round-N/bundle/. Contiene solo archivos visuales (png, jpg, webp, gif, más video si pasas --include-video) y estos archivos de texto:

  • brief.md, con los bloques de código eliminados
  • las rúbricas
  • CRITIC.md, las instrucciones del crítico
  • manifest.json, con IDs de artefactos citables
  • prior.json, desde la ronda 2 en adelante: hallazgos abiertos sin tus afirmaciones de "corregido", para que el crítico verifique por sí mismo

El script no abrirá una nueva ronda mientras haya hallazgos de corrección obligatoria sin responder, o más allá del límite de rondas. Imprime el mensaje exacto para enviar al crítico.

Presupuesto de imágenes: apunta a 20 imágenes o menos por ronda. Claude endurece los límites por imagen después de 20 imágenes en una sola solicitud. Cada imagen cuesta aproximadamente ⌈w/28⌉×⌈h/28⌉ tokens; una toma de 1440×900 es alrededor de 1.7k. Las hojas de contactos y las tiras de película empaquetan de 12 a 16 fotogramas en una imagen, así que apóyate en ellas. --slices 3 recorta páginas largas.

5. Elegir el modelo del crítico (solo donde la plataforma lo soporte)

Pregunta solo si tu plataforma te permite elegir el modelo de un subagente, y solo una vez, antes de la ronda 1. Omítelo si el usuario ya nombró uno. Guarda la respuesta con judge.mjs set critic-model <alias> y reutilízala cada ronda.

Plataforma¿Preguntar?Cómo
Claude Code, apps ClaudeSíAskUserQuestion, en el mismo prompt que la pregunta de unslop: Sonnet (equilibrado, recomendado), Opus (ojo más agudo, más cuota), Haiku (más barato, pasa por alto problemas sutiles), Igual que yo
Codex app, Codex CLISíPregunta en el chat, luego pasa la elección cuando generes al crítico
AntigravityNoNo hay opción de modelo por generación. El crítico se ejecuta en la configuración de su archivo de agente; díselo al usuario.
Cualquier otra cosaNoA menos que soporte claramente modelos por subagente. Usa el predeterminado y dile al usuario qué modelo revisó el trabajo.

Cuando preguntes, sé directo sobre el compromiso. Un crítico más débil es más barato, pero alucina más defectos y pasa por alto los sutiles. La puerta atrapa la evidencia falsa; no puede atrapar el mal gusto.

Sintaxis exacta por plataforma: references/platforms.md.

6. Ejecutar el crítico

Usa un crítico fresco cada ronda, para que no tenga memoria más allá de prior.json y ningún interés en sus llamadas anteriores. Envíale el mensaje que bundle imprimió, y nada más:

Eres el crítico de fotogramas. Tu paquete es <ruta abs>. Lee <ruta abs>/CRITIC.md y síguelo exactamente. No abras nada fuera de esa carpeta. Responde solo con el JSON de revisión.

  • No añadas nada. Sin resumen de lo que construiste, sin "céntrate en el encabezado", sin "arreglé las piernas". Tu opinión es la única entrada que el crítico nunca debe recibir. Si el usuario quiere que se revise algo, ya está en la solicitud, en sus palabras.
  • Sin bifurcaciones. Nunca ejecutes al crítico como una bifurcación o cualquier otra cosa que herede contexto. Vería toda tu conversación, código incluido.
  • Prefiere el agente instalado. Usa frame-critic si existe, porque está limitado a leer archivos. Su nombre es frame-judge:frame-critic cuando el skill vino como un plugin de Claude Code, y frame_critic en Codex. De lo contrario, usa un subagente de propósito general con el mismo mensaje.
  • Claude Code: ejecuta el sandbox si puedes. Si el CLI de claude está en PATH, ejecuta node <skill>/scripts/critic-sandbox.mjs en lugar de generar un subagente. Ejecuta al crítico como un proceso sin cabeza separado en una copia privada del paquete. Ese proceso tiene solo la herramienta Read, más un hook que bloquea cualquier lectura fuera de la copia, y el script controla la revisión en sí mismo (omitir el paso 7). Este es el único camino donde la ceguera al código se aplica en lugar de solicitarse.
  • En cualquier otro lugar: usa el subagente en sesión, y la ceguera al código descansa en las instrucciones del crítico. En Claude Code, la auditoría de transcripción en el paso 7 aún atrapa a un crítico que haya mirado. En Codex, Antigravity y Cursor, nada lo verifica, así que dilo en tu informe.

Guarda la respuesta, sin modificaciones, en .frame-judge/round-N/review.json.

7. Puerta

node <skill>/scripts/judge.mjs gate --review .frame-judge/round-N/review.json --reviewer subagent --transcript auto

En Claude Code, --transcript auto encuentra la transcripción del subagente crítico, para que la puerta cuente las imágenes que realmente abrió (no las que afirma) e invalide la revisión si tocó algo fuera del paquete. En otros lugares, omite la bandera; la cobertura entonces es autoinformada, y el informe lo dice. (critic-sandbox.mjs pasa su propia transcripción automáticamente.)

La puerta decide, no el estado de ánimo del crítico y no tú. Ella:

  • Rechaza hallazgos que citan IDs de artefactos que no existen o que el crítico nunca abrió, hallazgos sin evidencia, citas de la solicitud que no están en la solicitud, y valores incorrectos de gravedad o confianza.
  • Verifica la cobertura: una aprobación solo cuenta si el crítico abrió cada imagen, verificado desde su transcripción donde exista, de lo contrario desde su propia lista opened.
  • Verifica el aislamiento: con una transcripción, cualquier lectura fuera del paquete invalida la revisión (RERUN_CRITIC).
  • Ordena el resto:
    • corrección obligatoria: bloqueante o mayor, confianza 0.6 o superior
    • verificar: bloqueante o mayor por debajo de 0.6. Recapturar más de cerca; no corregir a ciegas.
    • pulir: menor
    • ignorado: nimiedades
  • Verifica que CRITIC.md y las rúbricas no fueron editadas, para que nadie haya suavizado al juez.
  • Actualiza el libro mayor e imprime una decisión:
DecisiónSignificadoTú
PASSNo queda corrección obligatoria, nada de la solicitud faltaReportar (paso 9)
SELF_PASSLo mismo, pero de un fallback de autoevaluaciónReportar, y decir que no fue independiente
REVISEExisten elementos de corrección obligatoriaPaso 8, luego una nueva ronda
RETHINKEl crítico dice que el enfoque es incorrecto desde la raízDecírselo al usuario antes de reconstruir
STOP_MAX_ROUNDSLímite alcanzado, aún fallandoReportar lo que está abierto, preguntar si continuar
STOP_PLATEAUEsta ronda no resolvió nadaDejar de dar vueltas. Reportar, preguntar
RERUN_CRITICRevisión inutilizable (sin JSON, evidencia mayormente falsa), una aprobación de un crítico que se saltó imágenes, o un crítico que leyó fuera de su paqueteEjecutar un crítico fresco en el mismo paquete
STOP_CRITIC_UNRELIABLESegunda revisión inutilizableSugerir un modelo de crítico más fuerte o un fallback

8. Revisar

Trabaja a través de los elementos de corrección obligatoria por ID, bloqueantes primero. Responde a cada uno antes de la siguiente ronda:

node <skill>/scripts/judge.mjs respond R1-F2 fixed "contact foot planted for 4 frames"
node <skill>/scripts/judge.mjs respond R1-F4 disputed "gutters are equal on both sides" --evidence crop.png
node <skill>/scripts/judge.mjs respond R1-F6 wont-fix "user asked for this gradient" --quote "purple to blue gradient"
  • disputed necesita evidencia visual, como un recorte o fotogramas adicionales. Va al siguiente paquete y el próximo crítico decide sobre ello. "El CSS dice 16px" no es evidencia; los píxeles lo son.
  • wont-fix necesita una cita textual de la solicitud que la corrección violaría.
  • Corrige causas, no capturas. Nunca cambies la captura para esquivar un hallazgo: nada de recortar el pie de página roto, eliminar el viewport móvil o recortar el clip.
  • Elementos de verificar y solicitudes del crítico: captura ese punto más de cerca (una acción con clip, una ventana --motion más densa) para que el próximo crítico pueda confirmarlos o eliminarlos.
  • No retrocedas en lo que el crítico enumeró en keep.

Skills relacionados