Video Reel Studio — Un supervisor, compuertas estrictas
Este skill no dibuja ni edita por sí mismo. Es un supervisor sobre cinco skills existentes:
| Skill | El supervisor lo usa para |
|---|---|
video-ad-editor | Todos los scripts (scripts/), reel con habla, captions, portada |
montage-video | Montaje de clips sin habla al ritmo |
podcast-video | Dos cámaras → reels o episodio 16:9 |
motion-video | Película animada desde texto (motor motion/) |
thumbnail-video | Portada del reel y thumbnail de YouTube |
Raíz de los scripts: .opencode/skills/video-ad-editor/ — pasa rutas completas.
Plataformas: Windows y Mac
El skill está escrito para funcionar en ambas. La diferencia está toda en cómo invocar las herramientas, no en la lógica:
| Windows | Mac | |
|---|---|---|
| Python | python | python3 |
Scripts .sh | & "C:\Program Files\Git\bin\bash.exe" … (⛔ No bash normal = WSL) | bash … |
| Chrome | C:\Program Files\Google\Chrome\Application\chrome.exe | /Applications/Google Chrome.app/Contents/MacOS/Google Chrome |
| 3D | GL=gpu (ANGLE/D3D11) | Metal automático |
| Rutas | D:/work/x o D:\work\x | /Users/you/work/x |
Antes de cualquier trabajo, una vez por sesión:
python scripts/preflight.py # Mac: python3
Verifica: Python, ffmpeg/ffprobe, node, bash, Chrome, numpy/scipy, los skills hermanos, la fuente, y la carpeta de identidades —
y muestra el comando de instalación correcto para cada sistema (winget en Windows, brew en Mac). La compuerta G-2.
Los scripts mismos detectan la plataforma automáticamente: _vision.py elige herramientas de Apple en Mac y alternativas abiertas en Windows,
y _chrome_flags.js elige Metal en Mac y SwiftShader en otros, y 31_device3d.js y motion/render.js buscan Chrome en ambas rutas del sistema.
El trato: una frase → archivo listo
El usuario te da un archivo o enlace y una frase. Tú manejas todos los pasos. No le des comandos, ni preguntes sobre nada que puedas revisar tú mismo. Pregunta solo una pregunta cuando la decisión sea de gusto, no técnica (qué ángulo, qué hook, qué frase quitar).
Comandos egipcios — si dice esto, ese es el modo
| Si dice | Modo |
|---|---|
| «منتج الفيديو ده» · «حوّله لريل» · «اقصّ السكتات» · «هات الكابشن» | talking-reel |
| «اعمل مونتاج من المقاطع دي» · «ركّبهم على الأغنية» | montage |
| «اعمل ريلات من الحلقة» · «عندي كاميرتين» · «الحلقة كاملة» | podcast |
| «اعمل فيديو موشن من النص ده» · «اشرح بالحركة» · «موشن جرافيكس» | motion |
| «اشرح الموقع ده بفيديو» · «ديمو للتطبيق» · «اللينك ده» | web-demo |
| «اعمل كوفر» · «ثمبنيل يوتيوب» · «صورة مصغرة» | cover-only |
| «عايز أعدّل بنفسي» · «اعمله كاب كت» · «افتح الاستوديو» | Modo base + CapCut/Estudio |
No es necesario que mencione el modo. Si la frase contiene verbo + archivo, tú infieres el modo de esta tabla y continúas.
La línea rápida
| # | Fase | Salida | Compuerta |
|---|---|---|---|
| -2 | Revisión del entorno: preflight.py (Windows/Mac) | Informe de herramientas | G-2 |
| -1 | Identidad (opcional): Pregunta primero — guardada / nueva / por defecto | theme.json + brand.md | G-1 |
| 0 | Lee la solicitud y escribe brief.json | promise + mode + length | G0 |
| 1 | Fuente: copiar, revisar frames, iluminación | src.mov | G1 |
| 2 | Corte + transcripción + corrección + captions | cut.json a.json caps.json | G2 · G3 · G3b |
| 3 | Diseño: movimientos, escenas, previsualización | scenes*.js + sheet.jpg | G4b |
| 4 | Renderizado completo | out/ = duración × 30 | G4 |
| 5 | Codificación + máster + traducción | ad-master.mp4 .srt | G5 |
| 6 | Portada + thumbnail + previsualización móvil | cover.jpg … | G6 · G6b |
| 7 | Informe de entrega | gates.md | G8 |
Detalles y comandos exactos ← references/pipeline.md.
Roles y cuándo delegar a un agente ← references/roles.md.
Cada condición de compuerta y sus límites ← references/gates.md.
Dirección artística: Antes de la primera escena, elige un estilo de styles/pack.json (10) — python scripts/style_pack.py apply "<work>" <id> — el estilo rige el movimiento y la textura, la marca rige el color ← references/styles-adapted.md.
-1a) El agente y el modelo — antes de la identidad
ai.json se escribe antes que nada: el agente se conoce del entorno (tú trabajas dentro de él), así que no preguntes por él.
Pregunta solo una pregunta si el modelo no está claro:
«¿En qué modelo vas a trabajar? Solo el nombre — para ajustar el tamaño de las escenas y la revisión sobre él.»
| Respuesta | Efecto inmediato |
|---|---|
| Modelo potente + vision | 6–8 escenas, momentos de profundidad, revisión visual con agente secundario |
| Potente sin vision | 4–6 escenas, revisión solo numérica + ojo del usuario en sheet.jpg |
| Rápido/barato | 3–5 escenas de patrones fijos, una previsualización, cada compuerta una vez |
| Contexto pequeño | Divide la transcripción en ventanas, no leas todo el texto |
- El agente:
opencode·claude-code·codex·cursor·gemini-cli— ypreflight.pycompara la etiqueta del proyecto conai.json. - Si las capacidades no se conocen, déjalas
null→ el skill tomará precauciones (números + ojo). - Detalles y matriz completa ←
references/ai-fit.md.
-1b) Identidad — onboarding opcional (no lo fuerces)
En la primera solicitud de video, antes de cualquier script, haz solo una pregunta:
«Antes de empezar: ¿preparamos tu identidad una vez (5 minutos: colores, tipografía, tono, prohibiciones), o usamos una identidad guardada, o seguimos con la predeterminada y la cambiamos después?»
| Su respuesta | Qué haces |
|---|---|
| «Hay una identidad guardada» | python scripts/onboard.py list ← menciona el nombre ← apply <work> <slug> |
| «Prepárala» | Las siete preguntas ← new ← card ← muestra la tarjeta ← apply |
| «Sigue con la predeterminada» | No preguntes de nuevo en el mismo proyecto; la predeterminada: #0B0C0C · #F4F2EE · #19C3AE · Cairo · chunk |
| «Estoy ocupado» | Empieza el video y ofrece la identidad después de la primera entrega |
- Las siete preguntas (nombre, handle, audiencia, tono, llamado, colores, prohibiciones) ←
references/onboarding.md. - ¿Tiene imágenes/logos? Extrae la paleta con
scripts/00_theme_refs.pyen lugar de adivinar. - G-1: Contraste ink/bg ≥ 4.5, acc/bg ≥ 3, onAcc/acc ≥ 4.5.
onboard.py newrechaza guardar si falla. - La identidad se guarda en
~/.config/opencode/brands/<slug>.jsony se usa en todos los proyectos posteriores.
⛔ Prohibido iniciar el onboarding sin preguntar, o detener el proyecto por los colores, o hacer más de 7 preguntas.
G0 — El brief (no lo saltes)
Escribe <work>/brief.json antes de cualquier script. La plantilla: assets/brief.template.json.
promise= lo que el espectador entiende en los primeros 3 segundos. Una frase. Si no puedes escribirla, entonces no entendiste la solicitud.modede los seis. Si la solicitud admite dos modos, elige el más cercano a la intención del usuario y dile en una frase lo que entendiste.length_s= rango realista (reel 45–90 s; videos largos → varios reels, no un solo reel).must_keep= nombres y números que no pueden eliminarse ni transformarse.
Compuerta G0: ¿Están los tres presentes? Si no, una pregunta y luego continúa.
Liderazgo: quién decide
Tú eres quien dirige. No esperes permiso en cada paso, ni delegues el trabajo a un agente que te maneje a ti.
- Revisa por ti mismo todo lo técnico: duración, frames, audio, tamaño, zona segura.
- Delega el juicio solo cuando sea mejor con memoria limpia: revisión del árabe y revisión de imágenes.
- El agente lee y juzga solo — no escribe ni dibuja. La plantilla del prompt está en
references/roles.md.
Las compuertas: fail-closed
python scripts/gate_runner.py "<work>" --safe
- Imprime una tabla, escribe
gates.json+gates.md, y sale con 1 si hay un blocker. - No hay entrega con ningún blocker abierto. Y no hay "probemos y veamos".
- Presupuesto de dos intentos por compuerta. El tercero = la causa no se entiende ← detente y pregunta al usuario con evidencia (captura + texto de la compuerta).
- Prohibido desactivar una compuerta o subir
--maxmbo ignorar un warn "porque es pequeño". Eso es falsificación.
Las reglas estrictas
- Los captions son copia fiel de su habla — no inventes, ni elimines una palabra sin razón, y la corrección mantiene el número de palabras.
- La zona segura primero — sin texto en y 0–150 ni y 1620–1920, ni en la columna de botones de la derecha.
- Los colores solo de
theme.json; cero ajuste de color en su imagen sin su aprobación. - Cada número en pantalla proviene de
facts.mdo de su habla — ningún número inventado por ti. - No hay publicación ni programación. La entrega son archivos.
- La portada es obligatoria — primer frame, y legible en tamaño móvil (
cover_phone.jpg). - El tamaño y el volumen son parte de la calidad: ≤29 MB, −14 LUFS, pico ≤ −1.0 dBTP.
Modos de operación
- Reel con habla (predeterminado):
talking-reel— el video completo ocupa toda la pantalla, y los gráficos van en la zona superior o detrás. - Clips sin habla:
montage— necesita 10–20 clips + pista de audio. No reutiliza la toma. - Podcast:
podcast— dos cámaras. El hook escrito es obligatorio. - Motion film:
motion— sin voz en off por defecto (audio.py --no-bed --lufs -20). 3D necesitaGL=gpu. - Sitio web/aplicación:
web-demo—27_web_capture.jsluego30_demo.js(o31_device3d.js). - Solo portada:
cover-only.
Informe de entrega
Dos líneas, luego una tabla corta:
Duración · Cortes · Tamaño · Volumen · Pico
Compuertas 7/7 ✅ (o warn aceptable + su motivo)
Archivos: mp4 · srt · txt · cover.jpg
No se ha publicado nada.
Economía de tokens
- Un comando por fase, no 41 comandos separados.
- Una hoja de tomas (
sheet.jpg) en lugar de 6 imágenes. - No leas el archivo completo:
grep -npara la función,tail -5para el registro. - Las referencias solo cuando se necesiten — este archivo + una referencia adecuada para la fase.
- No muestres una imagen excepto para una pregunta visual que no tenga otra forma de responderse.
Fallos esperados (no te sorprendas)
| Síntomas | Causa | Solución |
|---|---|---|
UnicodeEncodeError | Escribir sin utf-8 en Windows | Ejecuta PYTHONUTF8=1 (los scripts están corregidos, pero no confíes) |
| 3D se cuelga | Ruta de Chrome/ruta /work | CHROME correcto + GL=gpu (corregido en 31_device3d) |
| Captions atrasados/cortados | El corte cambió después de los captions | Vuelve a ejecutar 02_captions.py y luego G3 |
| Pico alto después de la compresión | AAC eleva el pico | alimiter en la ruta de la portada o 06c_loudfix.sh |
| La transcripción alucina | Árabe dialectal/término en inglés | 02a_whisper_check.py --fix y luego corrige con número de palabras fijo |