Changelog → Video con Marca
Entrada: un changelog .md (temas + elementos, como el resumen semanal de HyperFrames).
Salida: un proyecto HyperFrames limpio y verificado en projects/active/weekly-changelog-<rango>/. Renderiza solo cuando se solicite.
Carga obligatoria e innegociable: motion-doctrine (+ cut-the-curve, oversized-cursor si aparece un cursor, seam-craft) y captions-overlay. Esta habilidad proporciona la cadena específica del changelog; la doctrina proporciona la ley de movimiento.
Directriz principal: visualizar, no enumerar
Cada tema se ilustra con un mock animado de la interfaz real o un análogo fiel que representa el cambio en la experiencia, nunca con viñetas de texto. Enruta cada tema/elemento a través de references/visualization-registry.md ANTES de escribir el guion; el registro decide entre ui-recreate / ui-analog / terminal / checklist. La lista de verificación de texto es el último recurso, reservado para elementos genuinamente no visuales (listas de correcciones de fiabilidad).
Cadena
0 · Inicializar el proyecto DESDE los activos de ESTA habilidad - innegociable
Haz esto antes de escribir cualquier composición HTML. Omitirlo siempre produce un video que se parece a un proyecto similar que construiste antes, NO a la marca de esta habilidad; esa es la forma más común de que esta habilidad se desvíe de la marca. Los activos, fuentes y andamio de la habilidad SON la habilidad; el prompt de SKILL.md es un enrutador.
mkdir -p project/assets/fonts
cp <SKILL_DIR>/assets/fonts/*.woff2 project/assets/fonts/
cp <SKILL_DIR>/assets/bgm.mp3 project/bgm.mp3
ffmpeg -y -stream_loop 15 -i <SKILL_DIR>/assets/bg-pattern.mp4 -t <TOTAL> \
-vf "scale=1080:1080,fps=30,eq=saturation=0.72,[email protected]:t=fill" \
-an -c:v libx264 -crf 20 -pix_fmt yuv420p project/assets/bg-pattern-<TOTAL>s.mp4
cp <SKILL_DIR>/examples/master-skeleton.html project/index.html
Luego lee references/build-spec.md de principio a fin (no lo hojees) - define los tokens de marca (TT Norms Pro + ABC Solar Display + TT Norms Mono, crema #f5f6f4, verde racionado #5ef17c, tarjetas de vidrio con bordes verdes, forma de píldora kicker/sec-chip, carril de subtítulos de 32px en top: 990) que cada escena hereda del andamio.
Solo ENTONCES comienza los pasos 1-6 a continuación. Los pasos 1-4 (analizar, enrutar, guion, VO) planifican lo que va al andamio; el paso 5 rellena los marcadores de posición (<RANGE>, <TOTAL>, <CUT_N>, <DUR_N>, cuerpos de escena) dentro de project/index.html ya copiado - NO reescribes el cromo, fuentes, paleta o capa de diseño del andamio.
Si te sorprendes usando cp en el index.html de un video anterior, o escribiendo tus propias declaraciones @font-face, o diseñando un fondo de sombreado WebGL en lugar de usar el bg-pattern MP4 codificado anterior: DETENTE. Elimina el index.html actual y reinicia desde el cp del andamio master-skeleton. Reconstruir el contenido de la escena sobre el andamio correcto es más barato que adaptar la marca a un andamio incorrecto.
1 · Análisis + corte editorial
- Extraer: rango de semana, estadísticas principales (lanzamientos, commits), temas, elementos.
- Presupuesto: 45-60s en total. Título ≤2s, outro ≤3.5s, 4 temas ≈ 9-12s cada uno.
- Por tema, mantén UNA visualización principal + como máximo 3 elementos hablados. Todo lo demás existe solo como el puntero de "resumen completo" en el outro. Cortar es el trabajo: un changelog con 30 elementos aún produce ≤14 compases hablados.
- Ordena los temas por historia: función destacada → superficie del producto → rendimiento → fiabilidad (el resumen generalmente ya se lee de esta manera).
2 · Enrutamiento de visualización
Para cada tema, elige la superficie de references/visualization-registry.md y escribe una línea: tema → superficie → las 2-4 acciones secuenciadas que realiza el mock, cada una vinculada a una frase del guion. Si ninguna superficie del registro se ajusta y no existe un análogo fiel, es una escena de lista de verificación; no inventes una interfaz falsa para algo que no podemos representar honestamente.
3 · Guion de dos capas (oral vs. visual)
Escribe el guion como líneas de token según references/script-voice.md: registro conversacional, cada término técnico lleva una forma fonética spoken de references/lexicon.json mientras que display mantiene la ortografía estándar. Los subtítulos muestran display; la VO lee spoken. Cualquier término que no esté en el léxico: DETENTE y pregunta al usuario cómo se pronuncia, luego agrégalo al léxico. Guarda como script-tokens.json en el proyecto.
4 · VO — Annie (HeyGen, fija)
# Solo texto de la capa oral; words JSON = marcas de tiempo de referencia del texto HABLADO
# Ruta nativa del repositorio: la habilidad changelog-video se ejecuta desde la raíz del repositorio hyperframes,
# por lo que usa directamente el ayudante TTS de hyperframes-media (sin paso de instalación `npx hyperframes
# skills`). Si has copiado la habilidad en otro repositorio, reemplaza con tu propia ruta al
# heygen-tts.mjs de media-use / hyperframes-media.
node skills/hyperframes-media/scripts/heygen-tts.mjs ./vo-spoken.txt \
-o voiceover.mp3 --words vo-words.json \
--voice 330290724a1b470fb63153f34d4c0183 # Annie — realista (no sustituir)
Requiere la CLI heygen ≥0.3.0 autenticada (heygen auth login --oauth).
Luego alinea las marcas de tiempo habladas con los tokens visuales:
node <SKILL_DIR>/scripts/align-captions.mjs \
--tokens script-tokens.json --words vo-words.json --out captions.json
captions.json es la entrada del carril de subtítulos (ortografía visual, sincronización hablada).
El alineador imprime advertencias MISMATCH: resuelve cada una antes de construir
(generalmente una ortografía del léxico que el TTS renderiza como múltiples palabras). El audio es el reloj: todos los tiempos de compás provienen de vo-words.json; una regeneración de VO reabre cada costura.
Las sincronizaciones de palabras son una puerta estricta. Antes de pasar al paso 5, verifica que vo-words.json no esté vacío y tenga un array words: [...] con start/end por palabra. Si está vacío (0 bytes) o falta el array (un modo de fallo conocido cuando el proveedor TTS devuelve audio pero no carga útil de marcas de tiempo), NO CONTINÚES sin ellas. Plan de contingencia: alineación forzada del audio producido contra el guion visual usando whisper local:
uvx --from openai-whisper whisper voiceover.mp3 \
--model base.en --language en --word_timestamps True \
--output_format json --output_dir .
# luego ejecuta align-captions.mjs con --words voiceover.json (misma forma)
Whisper malinterpreta las representaciones TTS ("gee-sap" → "gsap", "heyjen" → "hey Jen", etc.) — los subtítulos aún usan la ortografía VISUAL de script-tokens.json; whisper solo proporciona las marcas de tiempo. align-captions.mjs maneja la unión. Este plan de contingencia es la diferencia entre una compilación con subtítulos y una sin subtítulos en silencio.
5 · Construcción
Sigue references/build-spec.md exactamente: tokens de marca + fuentes (incluidas en <SKILL_DIR>/assets/), la codificación del fondo animado, andamio de escenas, cromo, carril de subtítulos, un momento de verde racionado por escena. Luego el orden de la doctrina: ledger.json (todas las costuras ordinarias cortadas a la izquierda) → sello de costura → compases internos en palabras de VO → verificación de puerta de costura.
Los subtítulos no son opcionales. El master-skeleton incluye una IIFE de carril de subtítulos que lee un array LINES — dejar ese array vacío es un error de envío, no una elección de estilo. Complétalo desde captions.json antes de pasar al paso 6:
// pegar en lugar de "const LINES = /* … */ []" en la IIFE del carril de subtítulos:
const LINES = /* contenido de captions.json */ [
{ id: 0, end: 2.74, w: [["This", 0.0], ["week,", 0.30], …] },
…
];
Si align-captions.mjs se omitió o LINES está [], la comprobación de fotogramas en el paso 6 fallará — no lo ocultes eliminando #cap-line del andamio.
6 · Puertas (todas en verde antes de presentar)
bun run --cwd packages/cli hyperframes check(o la CLIhyperframesinstalada desde la habilidadskills/hyperframes-cli/del repositorio local) — 0 errores (contraste: texto oscuro ≥ .66 de alfa). NO usesnpx hyperframes@latest; la CLI local del repositorio es la fuente de verdad para el contrato de composición que esta habilidad produce.seam-gate.mjs verify— 0 fallos.- Reinicia el servidor de vista previa (almacena en caché el paquete), verifica 3-4 compases mediante
__player.seeken la página de composición sin procesar. - NO renderices a menos que el usuario lo solicite. Después de un render solicitado, verifica los fotogramas del MP4 (
ffmpeg -ss <t> … -frames:v 1): subtítulos presentes, video de fondo no negro, sin fotogramas pequeños o congelados. - Puerta de presencia de subtítulos — fallo estricto. Muestra 3-4 fotogramas distribuidos en la ventana hablada de la VO (por ejemplo,
t=3,t=15,t=30,t=42para una VO de 48s) y confirma que el carril de subtítulos entop: 990renderiza texto visible en cada uno. Si algún fotograma en un intervalo hablado carece de subtítulos, la compilación se envía sin subtítulos: trátalo como una puerta roja y vuelve a verificar la población deLINESdel paso 5. Esto es exactamente lo que salió mal en la compilación v4 del 13-20 de julio.
Diseño del proyecto
projects/active/weekly-changelog-<rango>/
├── index.html # documento maestro único (escenas como diapositivas, costuras selladas)
├── ledger.json # libro mayor de vectores (entrada para el sello de costura)
├── script-tokens.json # guion de dos capas (fuente de verdad para VO + subtítulos)
├── vo-spoken.txt # generado: capa oral, una línea
├── voiceover.mp3 + vo-words.json + captions.json
├── bgm.mp3 # copia de <SKILL_DIR>/assets/bgm.mp3 (la pista base) a menos que el usuario proporcione una
└── assets/fonts/ + assets/bg-pattern-<dur>s.mp4
Anti-patrones
| No hagas | En su lugar |
|---|---|
| Diapositivas con viñetas para cambios de interfaz | Mock de la superficie interpretando el cambio |
| Interfaz falsa para elementos no representables | Escena honesta de lista de verificación |
| Texto "JSON"/"CLI" simple en el texto TTS | Formas habladas del léxico; la visual se mantiene estándar |
| Ortografías fonéticas en los subtítulos | Los subtítulos siempre renderizan la capa visual |
| Adivinar la pronunciación de un término desconocido | Preguntar, luego ampliar el léxico |
| Hablar cada elemento del changelog | ≤3 por tema; el enlace del resumen lleva el resto |
| Acentos verdes en todas partes | Un momento verde por escena (#5ef17c) |
| Comenzar desde el index.html de un video anterior | Paso 0 — copia examples/master-skeleton.html de esta habilidad a project/index.html, siempre |
@font-face / sombreador WebGL / BGM personalizados hechos a mano | Paso 0 — copia assets/ de esta habilidad textualmente; los activos de la habilidad SON la marca |
| Entregado sin invalidación de CloudFront | Ejecuta aws cloudfront create-invalidation en la distribución E2BSLVSZ7FG3U0 para la ruta exacta después de cualquier reemplazo en S3 — la CDN almacena en caché el archivo antiguo de lo contrario |
Enviar con el array LINES vacío en el andamio | El paso 4 debe producir un captions.json poblado; el paso 5 debe pegarlo en la IIFE; la puerta 5 del paso 6 debe confirmar subtítulos en los fotogramas renderizados. Un LINES vacío = envío sin subtítulos = rehacer la ejecución |
Sin vo-words.json → omitir subtítulos y enviar de todos modos | Recurrir a la alineación forzada de whisper en el audio producido; los subtítulos no son opcionales |