Communitygithub.com

Sachin-pro-dev/PITCHFRAME-push-to-prod

Genera el plan de escenas de Remotion para un video de lanzamiento y lo renderiza a MP4, extendiendo los componentes de ritmo solo cuando el plan necesita algo que genuinamente no pueden expresar. Usado por Pitchframe para los pasos de generación de código y renderizado.

¿Qué es PITCHFRAME-push-to-prod?

Esta habilidad permite convertir un brief en un `plan.json` y renderizarlo a MP4 usando Remotion, siguiendo una gramática de video de lanzamiento predefinida. Está diseñada para mantener una alta calidad de salida sin necesidad de escribir animaciones personalizadas, ya que el proyecto de referencia ya implementa toda la lógica visual. La habilidad se enfoca exclusivamente en proporcionar datos estructurados (plan, paleta de colores, capturas de pantalla) y no en modificar componentes a menos que sea estrictamente necesario. Soporta cuatro tipos de ritmos (setup, hero, payoff, CTA) con un ritmo de interacción obligatorio que ocupa al menos el 30% de los fotogramas. Incluye pautas estrictas sobre cómo manejar colores (nunca en el plan ni en componentes, solo en `theme.ts` generado automáticamente), cómo verificar la aritmética de fotogramas antes de renderizar, y cómo solucionar fallos comunes de renderizado. Tras un renderizado exitoso, reporta la ruta del archivo y ofrece un enlace para editar el video mediante consultas en lenguaje natural.

Compatible con~Claude Code~Codex CLI✓Cursor
npx skills add https://github.com/Sachin-pro-dev/PITCHFRAME-push-to-prod/tree/HEAD/skills/pitchframe-remotion

Preguntar en tu IA favorita

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

Documentación

Generación de código y renderizado

Estás convirtiendo un brief en plan.json y renderizándolo. El proyecto de referencia ya implementa la gramática del video de lanzamiento; tú le proporcionas datos, no estás escribiendo un video desde cero.

El nivel de pulido del proyecto de referencia es el nivel de pulido de cada video que esta herramienta producirá. Por lo tanto, la opción predeterminada sólida es: escribe plan.json, no cambies nada más. Cada línea de animación personalizada que añadas a una ejecución es pulido que nunca llega al siguiente video, y una nueva forma de que el renderizado se rompa.

El mapa de archivos

pitchframe/
├── plan.json               ← el plan de escenas. Este es el video.
├── palette.json            ← colores extraídos. Datos, nunca prosa.
├── public/assets/*.png     ← capturas de pantalla.
├── scripts/
│   ├── extract-palette.mjs ← tailwind → vars CSS → URL en vivo
│   ├── apply-palette.mjs   ← escribe src/theme.ts desde palette.json
│   └── capture.mjs         ← servidor de desarrollo + captura con Playwright
├── src/
│   ├── Root.tsx            ← registra la composición LaunchVideo
│   ├── LaunchVideo.tsx     ← mapea ritmos a Sequences. Controla el cross-dissolve.
│   ├── theme.ts            ← GENERADO. Cada color se resuelve aquí.
│   ├── lib/
│   │   ├── types.ts        ← el contrato del plan
│   │   └── motion.ts       ← easing, fundidos, pulso de clic, deriva sostenida
│   ├── components/         ← Background, Cursor, FocusOverlay, Zoom, Panel, …
│   └── scenes/
│       ├── TypographyBeat.tsx
│       ├── InteractionBeat.tsx   ← el momento heroico
│       ├── UIBeat.tsx
│       └── CTABeat.tsx
└── output.mp4

Escribiendo el plan

Carga pitchframe-launch-video para la estructura y el esquema. La versión corta:

  • Cuatro partes — setup, hero, payoff, CTA. En ese orden. Siempre.
  • Exactamente un ritmo de interaction, y recibe al menos el 30% de los fotogramas.
  • La duración proviene de thesis_weight en el brief, no de un valor predeterminado.
  • Copia video_thesis y hero_moment en el plan para que la pasada de crítica pueda verificar el video contra la afirmación.

Haz la aritmética correcta antes de renderizar

Un renderizado fallido cuesta dos minutos; un plan cuyos ritmos se desvían cuesta un rerenderizado más el tiempo para darse cuenta. Verifica a mano, cada vez:

  • Ritmos contiguos — cada frames[0] es igual al frames[1] anterior.
  • El primer ritmo comienza en 0; el último ritmo termina exactamente en total_frames.
  • total_frames === duration_seconds * fps.
  • Ningún ritmo de tipografía por debajo de 45 fotogramas.
  • Ritmo de interacción ≥ 30% de total_frames.

Razona sobre las coordenadas, no las adivines

target_element.coordinates y zoom_target son porcentajes de la captura de pantalla. Son afirmaciones sobre dónde están los píxeles interesantes, y un punto focal desplazado un 10% del centro centra la toma heroica en un cromo vacío.

Abre la captura de pantalla, encuentra el elemento, convierte a porcentajes y verifica el resultado contra lo que se supone que debe mostrar el ritmo. Cuando la consecuencia de una acción ocurre en otro lugar que no sea el objetivo —el destino de un arrastre, un campo que se actualiza en otro lugar—, apunta zoom_target a la consecuencia, no a lo que tocó el cursor.

Colores: nunca en el plan, nunca en un componente

theme.ts es generado por apply-palette.mjs desde palette.json. Es el único lugar donde se escribe un color.

node pitchframe/scripts/extract-palette.mjs      # → palette.json
node pitchframe/scripts/apply-palette.mjs        # → src/theme.ts

Reglas que se derivan de eso:

  • Nunca pongas un color en plan.json. El plan dice qué palabra está acentuada; el tema dice cuál es el acento.
  • Nunca pongas un color literal en un componente. Si necesitas un tono que el tema no expone, añade un token derivado al generador para que cada video futuro también lo obtenga.
  • Nunca edites theme.ts manualmente. Se sobrescribe en la siguiente generación.

Si los videos de dos productos se ven coloreados de manera idéntica, theme.ts no fue regenerado. Eso es lo primero que hay que verificar, antes de tocar cualquier otra cosa.

El renderizado

cd pitchframe && npx remotion render LaunchVideo output.mp4

Tres verificaciones primero, que cuestan un segundo y ahorran un renderizado fallido de dos minutos:

  1. plan.json se analiza; la aritmética anterior se cumple.
  2. Cada captura de pantalla nombrada en el plan existe en public/assets/. Un ritmo de interacción necesita tanto before_screenshot como after_screenshot.
  3. node_modules existe en pitchframe/. Si no, ejecuta npm install allí primero.

Espera de 20 a 60 segundos para un video de 20 segundos.

Cuando el renderizado falla

Lee el error real antes de cambiar nada.

SíntomaCausaSolución
Cannot find module '../plan.json'Andamio incompletoVuelve a ejecutar npx pitchframe install
Cannot find name 'ACCENT' etc.theme.ts no generadoEjecuta apply-palette.mjs
Tiempo de espera de renderizado de fuentes agotadoSin conexión, o una fuente no está en Google FontsEstablece fonts.sans a Inter en palette.json y regenera
Error de decodificación de imagenCaptura de pantalla corrupta o parcialVuelve a capturar esa toma
Discrepancia en la duración de la composicióntotal_frames no coincide con los ritmosCorrige la aritmética
OOM / fallo de ChromeCapturas de pantalla enormesReduce la escala de cualquier cosa de más de ~4000px de ancho; --concurrency=2

Nunca respondas a un fallo de renderizado reescribiendo la composición. Corrige los datos.

Si el renderizado falla dos veces, detente y conserva la evidencia. Deja plan.json, palette.json y los assets en su lugar y di qué archivo revisar. Un renderizado fallido con un plan inspeccionable es recuperable; uno que ha sido "arreglado" por una reescritura no lo es.

Cuando tienes que tocar los componentes

Solo cuando un plan necesita algo que los componentes de ritmo genuinamente no pueden expresar. Tres reglas si llegas ahí:

  1. Añade, nunca reescribas. Un nuevo movimiento de cámara es una entrada en SHOTS en lib/camera.ts, no un componente reestructurado — y tiene que estar listado en pitchframe-motion-language o nada lo elegirá nunca.
  2. Usa lib/motion.ts y lib/camera.ts. EASE, EASE_OUT, clickPulse, heldDrift, entranceBlur son el género. El easing hecho a mano es cómo un ritmo termina pareciendo que vino de un video diferente. Los resortes, rebotes y curvas elásticas están prohibidos. Hay exactamente un sistema de cámara. No añadas perspective o una transformación 3D fuera de Stage.tsx; este repo tuvo dos una vez, se desviaron y las tomas dejaron de parecer filmadas por la misma persona.
  3. Mantenlo basado en datos. Cualquier cosa que añadas debe poder alcanzarse desde un campo en plan.json. Si la única forma de activarlo es editando el componente, es algo único y no pertenece a la referencia.

Siempre está mal aquí: un color literal; el nombre del producto o texto copiado directamente en un componente; una nueva composición de nivel superior; cambiar el contrato de 1920×1080 / 30fps; importar una biblioteca de animación.

Añadir un tipo de ritmo es casi siempre la respuesta incorrecta. El esquema tiene cuatro porque un video de lanzamiento necesita cuatro. Un nuevo tipo de ritmo suele ser un ritmo de característica disfrazado, y en el momento en que el esquema puede expresar una lista de características, los planes comienzan a contener una.

Después de un renderizado exitoso

Informa la ruta y la opción de edición:

Listo. Video disponible en ./pitchframe/output.mp4

Para editar, solo pregunta:
  "mantén el momento heroico más tiempo"
  "amplía el campo que cambió en su lugar"

La edición es manejada por pitchframe-editing, no por volver a ejecutar el pipeline.

Skills relacionados