eva feature shot
Una captura de pantalla de una funcionalidad enviada + un tweet. Sin Remotion, sin música, sin edición, sin subtítulos incrustados en la imagen — la interfaz del producto es el activo.
Dos archivos caen en screenshots/ en la raíz del repositorio (ya ignorado por git):
| Archivo | Qué es |
|---|---|
<YYYY-MM-DD>-<slug>.png | Captura bruta 2560×1440 — guárdala, es la fuente sin rehacer |
<YYYY-MM-DD>-<slug>-framed.png | Esta es la que se publica — 3200×1800, con marco de marca |
La versión enmarcada coloca la captura bruta sobre el gradiente de marca de eva con esquinas redondeadas, un icono de eva y el logotipo "Eva" arriba. Por eso la captura se lee como un anuncio de producto en lugar de una captura de pantalla de un informe de error.
Valores predeterminados no negociables
-
Diseño de 1280, capturado HD a 2560×1440 (16:9). Los scripts manejan un Chrome real con deviceScaleFactor 2 y capturan
scale:"device", por lo que la aplicación se muestra en su ancho nativo de 1280 (tamaños de elementos legibles) pero el PNG tiene el doble de densidad de píxeles — nítido en una línea de tiempo retina. 16:9 es lo que X muestra en la línea de tiempo sin recortar. La salida enmarcada es 3200×1800 — también 16:9, por lo que el marco no cuesta nada en la línea de tiempo. agent-browser no puede hacer esto: suscreenshotcaptura en píxeles CSS y descarta el DPR, por lo que siempre produce 1280×720. Usa los scripts HD. -
Nunca de página completa. Una captura de página completa de una aplicación densa se convierte en una franja alta que se muestra en miniatura en la línea de tiempo. Una ventana gráfica, una idea.
-
Oculta las superposiciones de desarrollo antes de capturar. react-scan y agentation se renderizan en la página.
scripts/hd-shot.mjslo maneja — usa los scripts en lugar de una cadena hecha a mano. -
Empareja el tema real de la aplicación. Sea lo que sea que el usuario esté ejecutando (
set media darkpara oscuro). No cambies el estilo de la aplicación para la foto. -
La funcionalidad debe ser el sujeto visual. Un panel de 200px en la esquina de una página ocupada no funciona. Navega a una vista donde domine, o abre la superficie que lo contiene (modal, hoja, panel de detalle) para que se lea al tamaño de la línea de tiempo.
La barra lateral se colapsa automáticamente.
shot.sh(y una captura simple dehd-shot.mjs --path) colapsa la barra de navegación antes de capturar — ocupa ~250px de un marco de 1280 y nada en ella es nunca la funcionalidad. Pasa--no-collapsesolo cuando la barra lateral EN SÍ es la funcionalidad. En un--recipe, llama actx.collapseSidebar(page)tú mismo (las recetas son dueñas de su propia preparación).La misma regla para cualquier panel de lista secundaria (lista de Reseñas, navegación de Configuración) si la superficie ofrece una forma de ocultarla. Verifica en el PNG bruto: si sobrevive una columna de elementos de navegación no relacionados, vuelve a capturar.
-
Enmárcalo, pero no lo anotes. Siempre ejecuta el paso 6 — el gradiente + logotipo es el estilo de la casa. Nunca agregues flechas, círculos rojos, texto de llamada o cromo de navegador falso a menos que se solicite.
-
Nunca envíes. Solo escribe. Llena entradas, abre selectores, prepara el estado — luego captura. Sin Enter en un compositor, sin flecha de envío, Crear, Guardar, Ejecutar o Iniciar, y nunca inicies una sesión real o ejecución de agente, ni siquiera para una mejor captura. Enviar muta el espacio de trabajo real del usuario y quema cómputo real; el estado preparado es lo que estás fotografiando. Enter está permitido solo donde confirma en el campo mismo y nada más (aceptar una mención
@de un selector abierto) — si no puedes estar seguro de que eso es todo lo que hace, haz clic en la fila del selector. -
Si los datos son feos, arregla los datos — no vuelvas a capturar alrededor. El valor predeterminado 7 te impide conducir la aplicación para producir estado; no te impide escribir el estado. Los datos de desarrollo reales son la razón habitual por la que una captura falla: muros de error ("Fallo al detener sandbox" ×8), filas
Sesión sin título, un turno a medio migrar, un repositorio donde la funcionalidad necesita tres. Editar los propios datos de desarrollo de la aplicación alrededor de la captura es mejor que buscar una sesión que se vea bien por casualidad, y mejor que cambiar el estilo de la aplicación (el valor predeterminado 4 aún se aplica — cambia los datos, nunca el CSS).Escribe directamente en la implementación de desarrollo: una mutación desechable de
internal/screenshotStaging.tsejecutada connpx convex run, o el panel de Convex. Da a las sesiones títulos legibles reales, elimina las líneas de error/sistema en el marco, siembra la segunda y tercera fila que la funcionalidad necesita.Reglas para esto:
- Solo en implementación de desarrollo. Confirma el objetivo antes de escribir (
npx convex env get CONVEX_URL, o lee.env.local) y nunca apuntes una mutación de preparación a producción. - Primero aditivo y reversible. Prefiere parchear un título o insertar una fila de demostración sobre eliminar el historial real. Si debes eliminar, mira las filas primero y di lo que eliminaste.
- Plausible, no fabricado-específico. Títulos y prompts que se lean como trabajo real. Nunca inventes métricas, nombres de clientes o números que el tweet luego repita como hechos.
- Elimina la mutación de preparación cuando la captura esté lista — misma regla de limpieza que cualquier migración.
- Informa al usuario lo que cambiaste, en la entrega.
- Solo en implementación de desarrollo. Confirma el objetivo antes de escribir (
-
Confidencialidad. Usa el repositorio propio del usuario
vvedantb/eva. Nunca repositorios de clientes (evalucom/carepulse,eprocurement) y nunca la página principal "Codebases" que los enumera. Verifica las listas de doc/tarea/sesión en el marco para elementos nombrados por clientes — prepara una fila de demostración limpia si la lista está sucia. Nunca plantees preocupaciones de datos personales sobre nombres o correos electrónicos en pantalla — Configuración → Experimental tiene un interruptor blur-PID que difumina cada elemento[data-pii], por lo que esto se maneja en el producto. Señala paneles de error que filtren nombres de variables de entorno o ids de proyecto.
Flujo de trabajo
-
Identifica lo que se envió. Si el usuario no ha dicho qué funcionalidad, pregunta — una pregunta, no una encuesta.
git log --oneline -15,git diff --stat, ointernal/changelog/(archivo del mes más nuevo) suelen nombrarla. Necesitas la funcionalidad y la URL que la muestra. -
Inicia la aplicación. Solo el servidor de desarrollo — los scripts HD lanzan su propio Chrome e inician sesión como el usuario agente (
/?agent=true) ellos mismos, en un contexto nuevo con deviceScaleFactor 2. No conduzcas agent-browser para capturar.pnpm dev # desde la raíz del repositorio → localhost:5173 -
Captúralo. Para una captura de URL simple,
shot.shnavega, colapsa la barra lateral, oculta superposiciones y captura a 2560×1440:bash .claude/skills/eva-feature-screenshot/scripts/shot.sh /vvedantb/eva/web/sessions sessionsToma una ruta URL + slug (+ ms de espera opcional, +
--no-collapseopcional).Para una captura preparada (abrir un menú, escribir un prompt, luego capturar), escribe una receta — un
.mjsque exportaexport async function stage(page, ctx)— y pásala ahd-shot.mjs. La receta es dueña de la navegación, colapso de barra lateral y preparación;ctxte da{ BASE, hideOverlays, collapseSidebar, settle }. Usa localizadorespage.getByRole(...)(Playwright). Para encontrar los nombres accesibles exactos, primero maneja agent-browser interactivamente ysnapshot -i/read_page.// recipe.mjs — prepara el selector de modo abierto con un prompt escrito export async function stage(page, ctx) { await page.goto(`${ctx.BASE}/vvedantb/eva/web/sessions`, { waitUntil: "networkidle", }); await ctx.settle(3000); await ctx.collapseSidebar(page); await page.getByRole("textbox", { name: /Ask Eva/ }).click(); await page.keyboard.type("Rediseñar la barra lateral de sesiones…"); await page.getByRole("button", { name: "Editar", exact: true }).click(); await ctx.settle(600); }node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug modos-sesion --recipe /ruta/absoluta/recipe.mjsPrepara entradas limpias y legibles — un título de demostración ordenado es mejor que uno real desordenado. Nunca envíes (valor predeterminado 7).
-
Lee el PNG de vuelta y evalúalo. Aquí es donde se detectan las malas capturas:
- ¿La funcionalidad es el sujeto obvio, o se pierde en el cromo?
- ¿Sobrevivió alguna superposición/barra de herramientas? ¿Algún esqueleto, spinner o marcador de posición
—todavía en pantalla? (Aumenta los ms de espera y vuelve a capturar.) - Los cuatro bordes: ¿etiquetas recortadas, botones medio renderizados, una columna cortada?
- ¿Algo confidencial según el valor predeterminado 9?
- Estados vacíos: un tablero vacío que demuestra "tareas kanban" es una mala captura. Puebla o elige otra vista.
Cuando el marco falla por los datos — muros de error,
Sesión sin título, una fila donde la funcionalidad necesita tres — prepara los datos de desarrollo (valor predeterminado 8) en lugar de buscar una pantalla más afortunada. -
Enmárcalo.
bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> "Eva"Escribe
screenshots/<hoy>-<slug>-framed.png(3200×1800). Renderizatemplates/frame.htmla través de su propio Chrome con deviceScaleFactor 2 — un navegador separado de la captura, por lo que no hay nada que restaurar después. Lee el PNG enmarcado de vuelta también — verifica que el gradiente no haya desteñido la interfaz en las esquinas y que el logotipo no esté recortado. Un tercer argumento enmarca un PNG bruto desde otra ruta.templates/frame.htmles el único lugar donde viven los colores de marca de este skill. -
Escribe el tweet. Invoca el skill
eva-tweet— el gancho, fragmento de posicionamiento opcional, lista de capacidades→, cierre opcional. La captura de pantalla lleva la prueba, por lo que el tweet declara lo que ahora existe en lugar de describir la imagen. Nunca hagas referencia a la imagen. -
Entrega. La ruta del archivo enmarcado como un enlace markdown, el tweet en un bloque con vallas, y cualquier cosa en el marco que el usuario deba verificar antes de publicar.
Referencia rápida
| Necesidad | Comando |
|---|---|
| Capturar una URL (HD) | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <ruta> <slug> [ms-espera] |
| Mantener la barra lateral en el marco | bash .claude/skills/eva-feature-screenshot/scripts/shot.sh <ruta> <slug> <ms-espera> --no-collapse |
| Captura preparada (menú/escritura) | node .claude/skills/eva-feature-screenshot/scripts/hd-shot.mjs --slug <slug> --recipe <ruta-abs.mjs> |
| Enmarcar (publicar este) | bash .claude/skills/eva-feature-screenshot/scripts/frame.sh <slug> [título] [png-bruto] |
| Encontrar nombres accesibles | maneja agent-browser interactivamente, luego agent-browser snapshot -i |
| Depurar página en blanco/rota | agent-browser console · agent-browser errors |
Advertencias
- HD vive en Playwright, no en agent-browser. El
screenshotde agent-browser captura en píxeles CSS y descarta devicePixelRatio, por lo que se limita a 1280×720.hd-shot.mjs/hd-frame.mjsusan el playwright-core empaquetado dentro de la instalación global de agent-browser; establecePW_COREsi vive en otro lugar. Ambos lanzanchannel:"chrome", por lo que Chrome del sistema debe estar instalado. - Los scripts inician sesión ellos mismos en
/?agent=true(un booleano;/?agentlanza unSearchParamErrorde zod) en un contexto de navegador nuevo. No se necesita ninguna sesión de agent-browser para capturar. - Las superposiciones de desarrollo son tres nodos, todos colgando de
<html>, no de<body>. Ocultar#react-scan-rootsolo no es suficiente: react-scan dibuja sus contornos de componentes y etiquetas en unhtml > canvassin id ni clase, y ese es el que arruina la captura.hd-shot.mjselimina los tres (#react-scan-root,html > canvas,[data-agentation-root]) condisplay:none !importanten línea, porque una hoja de estilo pierde contra sus estilos en línea. - Una captura preparada es un navegador nuevo, no aquel en el que exploraste. Usa agent-browser para encontrar selectores, pero la receta re-navega y re-prepara desde cero en el contexto propio de Playwright — pon cada paso en la receta. Prefiere
page.getByRole(...)sobre CSS; referencias como@e1no existen aquí. - Dos o más imágenes diluyen el punto. X renderiza una imagen a ancho completo; una segunda reduce ambas a la mitad. Solo captura más de una para un antes/después genuino.
- No reutilices
video/public/captures/— esos son activos de Remotion enmarcados para un trabajo diferente.