@esquadrao/cli 0.0.0-stage → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +366 -2
- package/assets/fonts/Anton-Regular.ttf +0 -0
- package/assets/fonts/BebasNeue-Regular.ttf +0 -0
- package/assets/fonts/OFL.txt +93 -0
- package/assets/fonts/Poppins-Bold.ttf +0 -0
- package/assets/fonts/README.md +13 -0
- package/bin/cli.js +126 -0
- package/package.json +58 -4
- package/scripts/ast_slice.js +73 -0
- package/scripts/cutout.py +197 -0
- package/scripts/dag_validator.js +78 -0
- package/scripts/lint.js +43 -0
- package/scripts/merkle_verify.js +83 -0
- package/scripts/wcag_check.js +77 -0
- package/skill-audit/SKILL.md +42 -0
- package/skill-audit/references/merkle-ledger-spec.md +27 -0
- package/skill-audit/references/receipt-ed25519-verification.md +17 -0
- package/skill-audit/references/time-travel-replay.md +10 -0
- package/skill-code-reviewer/SKILL.md +40 -0
- package/skill-context/SKILL.md +44 -0
- package/skill-context/references/ast-virtualization.md +10 -0
- package/skill-context/references/openapi-contract-synthesis.md +10 -0
- package/skill-engineering-manager/SKILL.md +40 -0
- package/skill-media-producer/SKILL.md +328 -0
- package/skill-media-producer/references/caption-templates.md +194 -0
- package/skill-media-producer/references/composicoes-especiais.md +99 -0
- package/skill-media-producer/references/configuracao-inicial.md +239 -0
- package/skill-media-producer/references/corte-podcast-3-niveis.md +179 -0
- package/skill-media-producer/references/llm-agent-guide.md +231 -0
- package/skill-orchestrate/SKILL.md +49 -0
- package/skill-orchestrate/references/mission-lifecycle.md +36 -0
- package/skill-orchestrate/references/swarm-coordination.md +33 -0
- package/skill-pipeline/SKILL.md +42 -0
- package/skill-pipeline/references/auto-healing-patterns.md +17 -0
- package/skill-pipeline/references/dag-decomposition-rules.md +18 -0
- package/skill-pipeline/references/topological-waves.md +16 -0
- package/skill-product-manager/SKILL.md +40 -0
- package/skill-qa-engineer/SKILL.md +40 -0
- package/skill-review/SKILL.md +46 -0
- package/skill-review/references/anti-slop-patterns.md +17 -0
- package/skill-review/references/dual-blind-adjudication.md +15 -0
- package/skill-review/references/voice-calibration.md +10 -0
- package/skill-security-engineer/SKILL.md +40 -0
- package/skill-software-architect/SKILL.md +40 -0
- package/skill-software-engineer/SKILL.md +40 -0
- package/skill-sre-engineer/SKILL.md +40 -0
- package/skill-system-analyst/SKILL.md +40 -0
- package/skill-tech-lead/SKILL.md +40 -0
- package/skill-technical-writer/SKILL.md +40 -0
- package/skill-ui/SKILL.md +45 -0
- package/skill-ui/references/design-tokens-spec.md +19 -0
- package/skill-ui/references/visual-tdd-methodology.md +10 -0
- package/skill-ui/references/wcag-target-sizes.md +9 -0
- package/src/captionTemplates.js +285 -0
- package/src/commands/onboard.js +618 -0
- package/src/commands/role.js +119 -0
- package/src/commands/setup.js +174 -0
- package/src/commands/studio.js +1822 -0
- package/src/roles/authority.js +129 -0
- package/src/roles/codeReviewer.js +65 -0
- package/src/roles/engineeringManager.js +53 -0
- package/src/roles/index.js +80 -0
- package/src/roles/mediaProducer.js +223 -0
- package/src/roles/productManager.js +50 -0
- package/src/roles/qaEngineer.js +54 -0
- package/src/roles/securityEngineer.js +53 -0
- package/src/roles/softwareArchitect.js +58 -0
- package/src/roles/softwareEngineer.js +76 -0
- package/src/roles/sreEngineer.js +60 -0
- package/src/roles/systemAnalyst.js +45 -0
- package/src/roles/techLead.js +46 -0
- package/src/roles/technicalWriter.js +46 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Catálogo de Templates de Legenda
|
|
2
|
+
|
|
3
|
+
> **Status:** implementado no CLI **1.5.0**. Use `--caption-template <id>` em `studio auto-clip`/`studio render` ou `captions[].template` no EditPlan. Os estilos `impact`, `word` e `full` continuam disponíveis como legado via `--caption-style`.
|
|
4
|
+
|
|
5
|
+
Este documento é a fonte canônica para fonte, cor, contorno, sombra, posição e animação das legendas. Ele descreve os nove estilos usados no grid de demonstração e serve de base para a implementação no `@esquadrao/cli`.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Princípios
|
|
10
|
+
|
|
11
|
+
1. **Sem fundo sólido:** nenhum template usa caixa, tarja ou retângulo colorido atrás do texto. A legibilidade vem de preenchimento, contorno e sombra.
|
|
12
|
+
2. **Duas linhas curtas:** o texto é dividido em `LEGENDA DO` / `SEU JEITO`; tamanho e quebra são calculados para caber em 90% da largura segura.
|
|
13
|
+
3. **Contraste alto:** preenchimento claro com contorno escuro, ou preenchimento escuro com contorno claro; contorno mínimo de 5 px na referência 640×360.
|
|
14
|
+
4. **Área segura:** margem mínima de 5% em cada borda. Nenhum texto encosta na borda da célula.
|
|
15
|
+
5. **Escala relativa:** todos os valores são proporcionais à largura do canvas. A referência é **640×360**; o fator é `k = largura / 640`.
|
|
16
|
+
6. **Sem áudio no grid:** o catálogo é visual; o grid de demonstração é renderizado com `-an`.
|
|
17
|
+
7. **Fontes licenciadas:** Anton, Poppins e Bebas Neue são OFL (Google Fonts); Liberation Sans e DejaVu Sans Mono são fontes de sistema. O CLI deve empacotar as OFL ou aplicar fallback documentado.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Escala e coordenadas
|
|
22
|
+
|
|
23
|
+
Referência de projeto: célula **640×360** (16:9). Para outro canvas, multiplique tamanhos por `k = largura / 640` e calcule `y` pela porcentagem da altura.
|
|
24
|
+
|
|
25
|
+
| Token | Referência 640×360 | Fórmula | Equivalente 1080×1920 |
|
|
26
|
+
| :--- | ---: | :--- | ---: |
|
|
27
|
+
| `font_size` base | 64 px | `64 * k` | 108 px |
|
|
28
|
+
| `stroke` base | 7 px | `7 * k` | 12 px |
|
|
29
|
+
| `shadow` base | 4 px | `4 * k` | 7 px |
|
|
30
|
+
| linha 1 (`y1`) | 100 px (27,8%) | `0.2778 * altura` | 533 px |
|
|
31
|
+
| linha 2 (`y2`) | 170 px | `y1 + lineGap * font_size` | 651 px (heavy-white) |
|
|
32
|
+
| lower third (`y`) | 276 px (76,7%) | `0.7667 * altura` | 1472 px |
|
|
33
|
+
|
|
34
|
+
O motor deve arredondar para inteiro e garantir `stroke >= 2` e `font_size >= 12` em qualquer canvas. O `lineGap` é específico por template (1,0× a 1,4× o `font_size`) e mantém o bloco compacto em 9:16, em vez de abrir um vão proporcional à altura.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## 3. Catálogo
|
|
39
|
+
|
|
40
|
+
| # | ID | Nome | Fonte | Preenchimento | Contorno | Sombra | Posição (640×360) | Uso |
|
|
41
|
+
| ---: | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
|
42
|
+
| 1 | `mrbeast-yellow` | MrBeast Yellow | Anton | `#FFE600` | `#000000` 7 px | 4 px, 4 px | 100 / 170 | Alto impacto, retenção |
|
|
43
|
+
| 2 | `tiktok-white` | TikTok White | Poppins Bold | `#FFFFFF` | `#000000` 8 px | 3 px, 3 px | 105 / 175 | Padrão social, legível |
|
|
44
|
+
| 3 | `gold-stroke` | Gold Stroke | Anton | `#FFF6D6` | `#FFC400` 5 px | 3 px, 3 px | 100 / 170 | Premium, luxo |
|
|
45
|
+
| 4 | `green-stroke` | Green Stroke | Bebas Neue | `#FFFFFF` | `#00E676` 6 px | 3 px, 3 px | 108 / 176 | Karaokê, energia |
|
|
46
|
+
| 5 | `neon-glitch` | Neon Glitch | Anton | `#FFFFFF` + offsets `#00E5FF` / `#FF00E5` | `#000000` 3 px no núcleo | halo 0 px, 70% | 100 / 170 | Gaming, tech |
|
|
47
|
+
| 6 | `minimal-lower-third` | Minimal Lower Third | Liberation Sans Bold | `#FFFFFF` | `#000000` 3 px | 2 px, 2 px | 276 (linha única) | Corporativo, clean |
|
|
48
|
+
| 7 | `red-stroke` | Red Stroke | Poppins Bold | `#FFFFFF` | `#E11D2E` 6 px | 3 px, 3 px | 105 / 175 | Alerta, ênfase |
|
|
49
|
+
| 8 | `heavy-white` | Heavy White | Poppins Bold | `#FFFFFF` | `#000000` 8 px | 4 px, 4 px | 105 / 178 | Máxima leitura |
|
|
50
|
+
| 9 | `mono-clean` | Mono Clean | DejaVu Sans Mono Bold | `#FFFFFF` | `#000000` 9 px | 4 px, 4 px | 112 / 178 | Técnico, typewriter |
|
|
51
|
+
|
|
52
|
+
> **Sem fundo:** nenhum dos nove usa `box=1` ou `drawbox` atrás do texto. A linha horizontal do template 6 é um elemento gráfico, não um fundo.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 4. Especificação por template
|
|
57
|
+
|
|
58
|
+
### 4.1. `mrbeast-yellow`
|
|
59
|
+
|
|
60
|
+
- **Fonte:** Anton Regular, 64 px (`k * 64`).
|
|
61
|
+
- **Texto:** `LEGENDA DO` / `SEU JEITO`, caixa alta, centralizado.
|
|
62
|
+
- **Preenchimento:** `#FFE600`.
|
|
63
|
+
- **Contorno:** `#000000`, 7 px.
|
|
64
|
+
- **Sombra:** `#000000` a 80%, deslocamento 4×4.
|
|
65
|
+
- **Animação:** fade-in de 400 ms (`alpha='if(lt(t,0.4),t/0.4,1)'`).
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
drawtext=fontfile='Anton-Regular.ttf':text='LEGENDA DO':fontsize=64:fontcolor=#FFE600:borderw=7:bordercolor=black:shadowx=4:shadowy=4:shadowcolor=black@0.8:x=(w-text_w)/2:y=100:alpha='if(lt(t,0.4),t/0.4,1)'
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 4.2. `tiktok-white`
|
|
72
|
+
|
|
73
|
+
- **Fonte:** Poppins Bold, 54 px.
|
|
74
|
+
- **Preenchimento:** `#FFFFFF`.
|
|
75
|
+
- **Contorno:** `#000000`, 8 px.
|
|
76
|
+
- **Sombra:** `#000000` a 70%, 3×3.
|
|
77
|
+
- **Uso:** estilo padrão de TikTok/Reels; máxima compatibilidade.
|
|
78
|
+
|
|
79
|
+
### 4.3. `gold-stroke`
|
|
80
|
+
|
|
81
|
+
- **Fonte:** Anton Regular, 64 px.
|
|
82
|
+
- **Preenchimento:** `#FFF6D6` (creme).
|
|
83
|
+
- **Contorno:** `#FFC400` (dourado), 5 px.
|
|
84
|
+
- **Sombra:** preta a 85%, 3×3.
|
|
85
|
+
- **Uso:** imobiliário, luxo, viagens.
|
|
86
|
+
|
|
87
|
+
### 4.4. `green-stroke`
|
|
88
|
+
|
|
89
|
+
- **Fonte:** Bebas Neue, 70 px.
|
|
90
|
+
- **Preenchimento:** `#FFFFFF`.
|
|
91
|
+
- **Contorno:** `#00E676`, 6 px.
|
|
92
|
+
- **Sombra:** preta a 85%, 3×3.
|
|
93
|
+
- **Uso:** karaokê, música, fitness.
|
|
94
|
+
|
|
95
|
+
### 4.5. `neon-glitch`
|
|
96
|
+
|
|
97
|
+
- **Fonte:** Anton Regular, 62 px.
|
|
98
|
+
- **Núcleo:** `#FFFFFF`, contorno preto 3 px.
|
|
99
|
+
- **Camada ciano:** `#00E5FF`, deslocada −4 px em X e +2 px em Y.
|
|
100
|
+
- **Camada magenta:** `#FF00E5`, deslocada +4 px em X e −2 px em Y.
|
|
101
|
+
- **Halo preto no núcleo:** sombra de 0 px a 70% para separar do fundo.
|
|
102
|
+
- **Uso:** gaming, tecnologia, edição.
|
|
103
|
+
|
|
104
|
+
### 4.6. `minimal-lower-third`
|
|
105
|
+
|
|
106
|
+
- **Fonte:** Liberation Sans Bold, 40 px.
|
|
107
|
+
- **Texto:** uma linha, `LEGENDA DO SEU JEITO`.
|
|
108
|
+
- **Preenchimento:** `#FFFFFF`.
|
|
109
|
+
- **Contorno:** `#000000` a 90%, 3 px.
|
|
110
|
+
- **Sombra:** preta a 90%, 2×2.
|
|
111
|
+
- **Elemento gráfico:** linha horizontal branca de 2 px, 500 px de largura, 24 px acima do texto.
|
|
112
|
+
- **Uso:** corporativo, documentário, notícias.
|
|
113
|
+
|
|
114
|
+
### 4.7. `red-stroke`
|
|
115
|
+
|
|
116
|
+
- **Fonte:** Poppins Bold, 54 px.
|
|
117
|
+
- **Preenchimento:** `#FFFFFF`.
|
|
118
|
+
- **Contorno:** `#E11D2E`, 6 px.
|
|
119
|
+
- **Sombra:** preta a 85%, 3×3.
|
|
120
|
+
- **Uso:** alerta, erro, urgência.
|
|
121
|
+
|
|
122
|
+
### 4.8. `heavy-white`
|
|
123
|
+
|
|
124
|
+
- **Fonte:** Poppins Bold, 60 px.
|
|
125
|
+
- **Preenchimento:** `#FFFFFF`.
|
|
126
|
+
- **Contorno:** `#000000`, 8 px.
|
|
127
|
+
- **Sombra:** preta a 90%, 4×4.
|
|
128
|
+
- **Uso:** máxima legibilidade; é o template corrigido da posição inferior central.
|
|
129
|
+
|
|
130
|
+
### 4.9. `mono-clean`
|
|
131
|
+
|
|
132
|
+
- **Fonte:** DejaVu Sans Mono Bold, 48 px.
|
|
133
|
+
- **Preenchimento:** `#FFFFFF`.
|
|
134
|
+
- **Contorno:** `#000000`, 9 px.
|
|
135
|
+
- **Sombra:** preta a 85%, 4×4.
|
|
136
|
+
- **Uso:** técnico, tutorial, terminal.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 5. Contrato CLI implementado (1.5.0)
|
|
141
|
+
|
|
142
|
+
O motor nativo deve aceitar:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
esquadrao studio auto-clip <video> --caption-template heavy-white
|
|
146
|
+
esquadrao studio render <plan.json> --caption-template mrbeast-yellow
|
|
147
|
+
esquadrao studio caption-templates --json
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
No `EditPlan`, o campo planejado é:
|
|
151
|
+
|
|
152
|
+
```json
|
|
153
|
+
{
|
|
154
|
+
"captions": [
|
|
155
|
+
{
|
|
156
|
+
"text": "LEGENDA DO SEU JEITO",
|
|
157
|
+
"timeline_start_ms": 0,
|
|
158
|
+
"duration_ms": 3000,
|
|
159
|
+
"template": "heavy-white"
|
|
160
|
+
}
|
|
161
|
+
]
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Regras de contrato:
|
|
166
|
+
- `template` é opcional; ausente usa `impact` (compatibilidade).
|
|
167
|
+
- `template` inválido falha com código 1 e lista os IDs disponíveis.
|
|
168
|
+
- `caption-templates --json` devolve `{ version, reference_canvas, templates: [...] }`.
|
|
169
|
+
- O renderizador não deve introduzir fundo sólido em nenhum template do catálogo.
|
|
170
|
+
- Fontes ausentes usam fallback explícito e registram aviso, nunca falham em silêncio.
|
|
171
|
+
|
|
172
|
+
**Estado:** implementado no CLI 1.5.0. `--caption-template` e `captions[].template` são validados contra os nove IDs; ID inválido encerra com código 1 e lista os disponíveis.
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
## 6. Regras para agentes de IA
|
|
177
|
+
|
|
178
|
+
1. Use `--caption-template <id>` para escolher um dos nove presets; `caption-templates --json` lista os IDs.
|
|
179
|
+
2. `--caption-style impact|word|full` continua válido como legado quando nenhum template é informado.
|
|
180
|
+
3. ID inválido deve ser tratado como erro, nunca ignorado.
|
|
181
|
+
4. Nunca aplique `drawbox`/`box=1` atrás do texto ao recriar estes templates.
|
|
182
|
+
5. Preserve a área segura de 5% e o contorno mínimo.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 7. Checklist de QA do catálogo
|
|
187
|
+
|
|
188
|
+
- [ ] Texto completo e sem corte em 640×360 e 1080×1920.
|
|
189
|
+
- [ ] Contraste >= 4.5:1 entre preenchimento e contorno/fundo imediato.
|
|
190
|
+
- [ ] Nenhum fundo sólido atrás das letras.
|
|
191
|
+
- [ ] Fonte e fallback resolvidos no ambiente.
|
|
192
|
+
- [ ] Fade-in de 400 ms sem flicker.
|
|
193
|
+
- [ ] Nenhuma faixa de áudio no grid de demonstração.
|
|
194
|
+
- [ ] Nove IDs únicos, nove estilos visualmente distintos.
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Composições especiais: split permanente e recorte de pessoa
|
|
2
|
+
|
|
3
|
+
Status: **implementado no CLI 1.6.0**. O split permanente está operacional; o recorte de pessoa é experimental e depende de Python.
|
|
4
|
+
|
|
5
|
+
## 1. Split permanente (orador no topo + pack na base)
|
|
6
|
+
|
|
7
|
+
### Comando
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
esquadrao studio auto-clip entrada.mp4 \
|
|
11
|
+
--no-captions \
|
|
12
|
+
--broll pack.mp4 \
|
|
13
|
+
--layout split_bottom \
|
|
14
|
+
--overlay-duration full
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Regras:
|
|
18
|
+
|
|
19
|
+
- `--layout` aceita `fullscreen`, `pip` e `split_bottom`. `split_top` continua pendente (CLI-06).
|
|
20
|
+
- `--overlay-duration inserts` (padrão) distribui B-rolls de 2–4 s; `full` usa o primeiro `--broll` durante toda a linha do tempo.
|
|
21
|
+
- O pack é silenciado e repetido em loop; se for mais longo que o clipe, é cortado.
|
|
22
|
+
- O áudio do orador é preservado; o pack não entra no mix.
|
|
23
|
+
- `split_bottom` preenche a metade inferior com `scale` + `crop` (sem tarjas).
|
|
24
|
+
- O plano gerado fica em `packages/autoclip-plan.json` e pode ser reproduzido com `studio render`.
|
|
25
|
+
|
|
26
|
+
Limites:
|
|
27
|
+
|
|
28
|
+
- Apenas o primeiro `--broll` é usado no modo `full`; os demais são ignorados com aviso.
|
|
29
|
+
- O pack não é escolhido automaticamente por tema; a seleção é editorial.
|
|
30
|
+
- `split_top` não está implementado.
|
|
31
|
+
|
|
32
|
+
Critérios de aceite:
|
|
33
|
+
|
|
34
|
+
- [x] `auto-clip --broll ... --layout split_bottom --overlay-duration full` gera 1080×1920 com duas metades.
|
|
35
|
+
- [x] O pack cobre a metade inferior durante todo o clipe, em loop.
|
|
36
|
+
- [x] Áudio original preservado; pack silenciado.
|
|
37
|
+
- [x] `--help` documenta `--layout` e `--overlay-duration`.
|
|
38
|
+
- [x] Teste de render em `tests/autoclip.test.js` verifica plano, loop e QA.
|
|
39
|
+
- [ ] `split_top` (CLI-06).
|
|
40
|
+
|
|
41
|
+
## 2. Recorte de pessoa com troca de fundo (cutout)
|
|
42
|
+
|
|
43
|
+
### Comando
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
esquadrao studio cutout entrada.mp4 \
|
|
47
|
+
--background pack.mp4 \
|
|
48
|
+
--python python3 \
|
|
49
|
+
--fps 15
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Pré-requisitos no interpretador Python escolhido:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python3 -m pip install "rembg[cpu]" onnxruntime opencv-python-headless numpy
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Regras:
|
|
59
|
+
|
|
60
|
+
- Saída 1080×1920 (9:16) nesta versão; `--format 16:9` é rejeitado.
|
|
61
|
+
- `--fps` aceita 1–30; padrão 15.
|
|
62
|
+
- O pack é silenciado, repetido/cortado para a duração.
|
|
63
|
+
- Áudio original preservado; se a entrada não tiver áudio, o script adiciona uma faixa silenciosa para o QA.
|
|
64
|
+
- O motor é `rembg` com `u2net_human_seg`.
|
|
65
|
+
- A máscara do `u2net` é refinada com GrabCut e tem a borda suavizada; isso remove o halo escuro do fundo original.
|
|
66
|
+
- Conversão obrigatória RGB→BGR antes da composição. Sem isso, vermelho e azul trocam e a pele fica azul.
|
|
67
|
+
- O script fica em `scripts/cutout.py` e é chamado pelo comando Node.
|
|
68
|
+
|
|
69
|
+
Custo e limites:
|
|
70
|
+
|
|
71
|
+
- ~18–20 min de CPU para 60 s em 15 fps (1080×1920), sem GPU.
|
|
72
|
+
- Halo residual possível em cabelo/fone em frames difíceis; não há matting temporal.
|
|
73
|
+
- Sem cache de máscaras e sem aceleração GPU nesta versão.
|
|
74
|
+
- Modelo `u2net_human_seg` (~176 MB) é baixado pelo `rembg` na primeira execução; não é empacotado no npm.
|
|
75
|
+
- Sem segmentação de mãos/objetos finos garantida em todos os frames.
|
|
76
|
+
- O pack de fundo é escolha editorial, não automática.
|
|
77
|
+
|
|
78
|
+
Critérios de aceite:
|
|
79
|
+
|
|
80
|
+
- [x] `studio cutout --background` gera 1080×1920 com áudio e passa no QA.
|
|
81
|
+
- [x] Pele e cores originais preservadas (RGB→BGR).
|
|
82
|
+
- [x] Pack silenciado; áudio original do podcast.
|
|
83
|
+
- [x] Sem `rembg`: exit 1 com instrução de instalação.
|
|
84
|
+
- [x] Teste de contrato em `tests/cutout.test.js` cobre validação e help.
|
|
85
|
+
- [ ] Cache de máscaras.
|
|
86
|
+
- [ ] Aceleração GPU / processamento em lote.
|
|
87
|
+
- [ ] Matting temporal para eliminar halo em movimento.
|
|
88
|
+
|
|
89
|
+
## 3. Regra de comunicação
|
|
90
|
+
|
|
91
|
+
- Pode afirmar que o CLI 1.6.0 faz split permanente e cutout, **desde que** qualifique o cutout como experimental e informe as dependências Python e o custo de CPU.
|
|
92
|
+
- Não prometa tempo real, qualidade de estúdio ou ausência total de halo.
|
|
93
|
+
- `split_top` e ducking dinâmico continuam pendentes.
|
|
94
|
+
|
|
95
|
+
## 4. Evidências
|
|
96
|
+
|
|
97
|
+
- Split: `podpah-neymar-split-pack.mp4` (protótipo externo, 60 s, 1080×1920) e teste `split_bottom full loops a short b-roll`.
|
|
98
|
+
- Cutout: `podpah-neymar-cutout-pack.mp4` (protótipo externo, 60 s, 1080×1920, cor corrigida) e teste de contrato do comando.
|
|
99
|
+
- Suíte: 91 testes, lint em 38 arquivos.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# Configuração inicial do Esquadrão Studio
|
|
2
|
+
|
|
3
|
+
Guia para Windows / PowerShell: instalar, escolher proporção, configurar cortes e legendas, renderizar e verificar o MP4. Execute os blocos na mesma sessão. O Studio executa localmente pelo CLI, com Node.js e FFmpeg.
|
|
4
|
+
|
|
5
|
+
## 1. Pré-requisitos e instalação
|
|
6
|
+
|
|
7
|
+
Use Node.js 18 ou superior. Confira:
|
|
8
|
+
|
|
9
|
+
```powershell
|
|
10
|
+
node --version
|
|
11
|
+
npm --version
|
|
12
|
+
ffmpeg -version
|
|
13
|
+
ffprobe -version
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Se precisar instalar FFmpeg:
|
|
17
|
+
|
|
18
|
+
```powershell
|
|
19
|
+
winget install --id Gyan.FFmpeg -e
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Abra um novo PowerShell após instalar para atualizar o PATH.
|
|
23
|
+
|
|
24
|
+
Se você já tem o repositório clonado, defina o caminho absoluto para `bin\cli.js`:
|
|
25
|
+
|
|
26
|
+
```powershell
|
|
27
|
+
$cli = "C:\caminho\esquadrao-cli\bin\cli.js"
|
|
28
|
+
node $cli studio --help
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Alternativamente, após a publicação do pacote no npm, instale com `npm install -g @esquadrao/cli` e substitua `node $cli` por `esquadrao` nos comandos deste guia.
|
|
32
|
+
|
|
33
|
+
## 2. Criar o projeto e instalar as skills
|
|
34
|
+
|
|
35
|
+
Escolha uma pasta exclusiva para o vídeo. `setup` copia as skills e atualiza as integrações de agentes detectadas nessa pasta; use uma pasta nova para preservar configurações de outros projetos.
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
$projeto = Join-Path $env:USERPROFILE "Videos\StudioEsquadrao\meu-primeiro-video"
|
|
39
|
+
New-Item -ItemType Directory -Force -Path $projeto | Out-Null
|
|
40
|
+
Set-Location $projeto
|
|
41
|
+
node $cli setup
|
|
42
|
+
if ($LASTEXITCODE -ne 0) { throw "Falha ao instalar as skills." }
|
|
43
|
+
node $cli studio init --dest $projeto
|
|
44
|
+
if ($LASTEXITCODE -ne 0) { throw "Falha ao inicializar o Studio." }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Para Claude Code em um projeto novo, prepare a integração e execute novamente o setup:
|
|
48
|
+
|
|
49
|
+
```powershell
|
|
50
|
+
New-Item -ItemType Directory -Force -Path (Join-Path $projeto ".claude") | Out-Null
|
|
51
|
+
node $cli setup
|
|
52
|
+
if ($LASTEXITCODE -ne 0) { throw "Falha ao instalar as skills para Claude Code." }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Abra o agente nessa pasta em uma nova sessão para carregar `skill-media-producer`. `assets/` guarda cópias das fontes, `packages/` guarda os planos, `artifacts/` recebe os MP4 e `studio.json` registra as importações e resultados. `studio init` cria exclusivamente essas pastas e arquivos.
|
|
56
|
+
|
|
57
|
+
Para experimentar o fluxo guiado com valores padrão, use `node $cli onboard --mode podcast_clip --file <video> --captions <legendas.srt>`. Sem SRT/OpenAI/motor local, o onboard aplica `--no-captions`, gera um corte real sem legendas e avisa. Para controlar proporção, cortes e legendas explicitamente, siga os próximos passos.
|
|
58
|
+
|
|
59
|
+
## 3. Importar um vídeo com áudio
|
|
60
|
+
|
|
61
|
+
Substitua o caminho por um arquivo com pelo menos 8 segundos e áudio. O original permanece preservado; a importação cria uma cópia.
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
$origem = "C:\caminho\seu-video.mp4"
|
|
65
|
+
$resultado = node $cli studio import $origem --dest $projeto --json
|
|
66
|
+
if ($LASTEXITCODE -ne 0) { throw "Falha ao importar o vídeo." }
|
|
67
|
+
$asset = ($resultado -join "`n") | ConvertFrom-Json
|
|
68
|
+
$asset | Select-Object id, name, metadata
|
|
69
|
+
if ($asset.metadata.duration_s -lt 8 -or !$asset.metadata.audio_codec) {
|
|
70
|
+
throw "O exemplo requer uma fonte com áudio e pelo menos 8 segundos."
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## 4. Criar o plano de edição
|
|
75
|
+
|
|
76
|
+
Crie `packages/editplan.json` a partir deste modelo. Os tempos são inteiros em milissegundos: `1000` equivale a um segundo.
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"schema_version": 1,
|
|
81
|
+
"mode": "edit_only",
|
|
82
|
+
"output": {
|
|
83
|
+
"width": 1080,
|
|
84
|
+
"height": 1920,
|
|
85
|
+
"fps_num": 30,
|
|
86
|
+
"fps_den": 1,
|
|
87
|
+
"video_codec": "h264",
|
|
88
|
+
"audio_codec": "aac"
|
|
89
|
+
},
|
|
90
|
+
"clips": [
|
|
91
|
+
{
|
|
92
|
+
"kind": "video",
|
|
93
|
+
"clip_id": "corte-1",
|
|
94
|
+
"asset_id": "AST-SUBSTITUIR",
|
|
95
|
+
"in_ms": 0,
|
|
96
|
+
"out_ms": 4000,
|
|
97
|
+
"timeline_start_ms": 0
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"kind": "video",
|
|
101
|
+
"clip_id": "corte-2",
|
|
102
|
+
"asset_id": "AST-SUBSTITUIR",
|
|
103
|
+
"in_ms": 4000,
|
|
104
|
+
"out_ms": 8000,
|
|
105
|
+
"timeline_start_ms": 4000
|
|
106
|
+
}
|
|
107
|
+
],
|
|
108
|
+
"audio_tracks": [
|
|
109
|
+
{ "kind": "source", "clip_id": "corte-1", "gain_db": 0 },
|
|
110
|
+
{ "kind": "source", "clip_id": "corte-2", "gain_db": 0 }
|
|
111
|
+
],
|
|
112
|
+
"captions": [
|
|
113
|
+
{ "text": "Sua primeira frase", "timeline_start_ms": 0, "duration_ms": 4000 },
|
|
114
|
+
{ "text": "Sua segunda frase", "timeline_start_ms": 4000, "duration_ms": 4000 }
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Para criar o arquivo, execute e cole apenas o JSON acima no editor, depois salve e feche:
|
|
120
|
+
|
|
121
|
+
```powershell
|
|
122
|
+
$arquivoPlano = Join-Path $projeto "packages\editplan.json"
|
|
123
|
+
notepad $arquivoPlano
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Carregue o arquivo e vincule os dois cortes ao vídeo importado:
|
|
127
|
+
|
|
128
|
+
```powershell
|
|
129
|
+
$plano = Get-Content -Raw -Encoding UTF8 $arquivoPlano | ConvertFrom-Json
|
|
130
|
+
$plano.clips[0].asset_id = $asset.id
|
|
131
|
+
$plano.clips[1].asset_id = $asset.id
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## 5. Escolher proporção e cortes
|
|
135
|
+
|
|
136
|
+
> **Nota de Escolha do Usuário:** O formato e o estilo de edição são definidos livremente por você. O sistema não impõe fundo preto nem formato widescreen como padrão. Você escolhe entre a proporção vertical 9:16 (mobile) ou horizontal 16:9 (widescreen), e define se usará suas filmagens, packs de apoio ou telas tipográficas.
|
|
137
|
+
|
|
138
|
+
| Formato | Largura | Altura | Uso |
|
|
139
|
+
|---|---:|---:|---|
|
|
140
|
+
| 9:16 | 1080 | 1920 | Reels, Shorts, TikTok |
|
|
141
|
+
| 16:9 | 1920 | 1080 | Vídeo horizontal |
|
|
142
|
+
|
|
143
|
+
Para vertical:
|
|
144
|
+
|
|
145
|
+
```powershell
|
|
146
|
+
$plano.output.width = 1080
|
|
147
|
+
$plano.output.height = 1920
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Para horizontal, use `width = 1920` e `height = 1080`. Estes são os dois formatos aceitos, a 30 fps com H.264/AAC. O enquadramento preserva a proporção da fonte e completa o espaço restante com bordas. Recorte automático e saída quadrada ficam fora das opções atuais.
|
|
151
|
+
|
|
152
|
+
`in_ms` e `out_ms` selecionam o trecho do original. `timeline_start_ms` posiciona esse trecho no vídeo final. O modo `edit_only` exige exatamente dois cortes consecutivos na montagem, com uma faixa de áudio original por corte.
|
|
153
|
+
|
|
154
|
+
Exemplo opcional para uma fonte de pelo menos 34 segundos: selecionar 10–14s e 30–34s, mantendo 8 segundos de montagem:
|
|
155
|
+
|
|
156
|
+
```powershell
|
|
157
|
+
$plano.clips[0].in_ms = 10000
|
|
158
|
+
$plano.clips[0].out_ms = 14000
|
|
159
|
+
$plano.clips[1].in_ms = 30000
|
|
160
|
+
$plano.clips[1].out_ms = 34000
|
|
161
|
+
$plano.clips[1].timeline_start_ms = 4000
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Ao alterar a duração do primeiro corte, ajuste o início do segundo para a nova duração. Mantenha os pontos de saída dentro da duração da fonte.
|
|
165
|
+
|
|
166
|
+
## 6. Configurar legenda e áudio
|
|
167
|
+
|
|
168
|
+
Texto, início e duração são configuráveis:
|
|
169
|
+
|
|
170
|
+
```powershell
|
|
171
|
+
$plano.captions[0].text = "Veja como configurar seu vídeo"
|
|
172
|
+
$plano.captions[0].timeline_start_ms = 0
|
|
173
|
+
$plano.captions[0].duration_ms = 4000
|
|
174
|
+
$plano.captions[1].text = "Agora é só renderizar"
|
|
175
|
+
$plano.captions[1].timeline_start_ms = 4000
|
|
176
|
+
$plano.captions[1].duration_ms = 4000
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Use frases curtas de até 200 caracteres, sem HTML, com início e duração dentro do vídeo final. O renderizador atual usa texto branco, tamanho 48 pixels, centralizado horizontalmente e posicionado 200 pixels acima da borda inferior. A fonte é do sistema; no Windows, Arial é a primeira opção. As legendas ficam gravadas na imagem. O modo `dark` posiciona seus textos no centro da tela.
|
|
180
|
+
|
|
181
|
+
Cor, tamanho, fonte, contorno, fundo, posição e quebra automática de linha ainda dependem de alterações no renderizador. Campos extras de estilo no JSON não configuram essas propriedades. Transcrição automática e importação SRT também ficam fora deste fluxo atual.
|
|
182
|
+
|
|
183
|
+
Para remover as legendas, use `$plano.captions = @()`.
|
|
184
|
+
|
|
185
|
+
O ganho de cada corte aceita -60 a +12 dB. Zero preserva o volume, valores negativos reduzem e valores positivos aumentam. Confira distorção ao aumentar o ganho. Caso utilize trilha musical (`music_tracks`) com `ducking: true`, a atenuação aplicada é fixa em `-22dB` via mixagem `amix`, e não ducking dinâmico via sidechain (previsto no backlog CLI-05).
|
|
186
|
+
|
|
187
|
+
```powershell
|
|
188
|
+
$plano.audio_tracks[0].gain_db = 0
|
|
189
|
+
$plano.audio_tracks[1].gain_db = 0
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## 7. Salvar, renderizar e verificar
|
|
193
|
+
|
|
194
|
+
Após qualquer ajuste, salve em UTF-8 sem BOM para compatibilidade com o leitor JSON:
|
|
195
|
+
|
|
196
|
+
```powershell
|
|
197
|
+
$utf8 = [System.Text.UTF8Encoding]::new($false)
|
|
198
|
+
[System.IO.File]::WriteAllText(
|
|
199
|
+
$arquivoPlano,
|
|
200
|
+
($plano | ConvertTo-Json -Depth 10),
|
|
201
|
+
$utf8
|
|
202
|
+
)
|
|
203
|
+
$resultado = node $cli studio render $arquivoPlano --dest $projeto --json
|
|
204
|
+
if ($LASTEXITCODE -ne 0) { throw "Falha ao renderizar o vídeo." }
|
|
205
|
+
$render = ($resultado -join "`n") | ConvertFrom-Json
|
|
206
|
+
$videoFinal = Join-Path $projeto $render.path
|
|
207
|
+
node $cli studio qa $videoFinal --plan $arquivoPlano
|
|
208
|
+
if ($LASTEXITCODE -ne 0) { throw "O vídeo falhou na verificação técnica." }
|
|
209
|
+
Start-Process -FilePath $videoFinal
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
O QA compara dimensões, fps e duração com o plano e verifica os streams. Assista ao resultado para avaliar sincronização das frases, legibilidade, enquadramento e volume. Detecção de quadros pretos e avaliação visual de sincronização exigem revisão adicional.
|
|
213
|
+
|
|
214
|
+
## Pedido pronto para o agente
|
|
215
|
+
|
|
216
|
+
> Use skill-media-producer e o guia de configuração inicial. Pergunte o arquivo de origem, formato vertical ou horizontal, dois trechos, frases e horários das legendas e ganho do áudio. Prepare packages/editplan.json com as opções disponíveis. Antes de renderizar, mostre os cortes e a duração final para aprovação. Depois execute render e qa com --plan e informe o caminho do MP4.
|
|
217
|
+
|
|
218
|
+
## 8. Esteira rápida de auto-corte de silêncios e legendas (`auto-clip`)
|
|
219
|
+
|
|
220
|
+
Se você possui um vídeo falado (ex.: podcast, aula ou gravação direta) e deseja cortar pausas e silêncios maiores que 0.8s:
|
|
221
|
+
|
|
222
|
+
```powershell
|
|
223
|
+
# Auto-corte com arquivo SRT de legendas, gerando plano em packages/ e MP4 em artifacts/:
|
|
224
|
+
node $cli studio auto-clip $origem --dest $projeto --captions (Join-Path $projeto "packages\legendas.srt")
|
|
225
|
+
|
|
226
|
+
# Ou apenas analisar silêncios e pausas mortas antes de renderizar:
|
|
227
|
+
node $cli studio detect-silence $origem
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
O comando expurga as pausas, transcreve o áudio caso um arquivo SRT ou provedor de transcrição esteja configurado, remapeia as legendas quando existentes para a linha de tempo pós-corte e valida o arquivo MP4 final em `artifacts/`.
|
|
231
|
+
|
|
232
|
+
Três caminhos de legendas no `auto-clip`:
|
|
233
|
+
1. `--captions <arquivo.srt>`: Determinístico, offline e testado (recomendado).
|
|
234
|
+
2. `--openai`: Requer a variável de ambiente `OPENAI_API_KEY` para transcrição via API remota da OpenAI.
|
|
235
|
+
3. `--local`: Utiliza `@xenova/transformers` + `Xenova/whisper-tiny`, declarada em `optionalDependencies`. Se o pacote opcional não estiver instalado, o comando falha com instrução acionável; use `--no-captions` para cortar sem legendas.
|
|
236
|
+
|
|
237
|
+
> **Templates:** o catálogo de nove presets está em [`caption-templates.md`](caption-templates.md). Use `--caption-template <id>` no `auto-clip`/`render` ou `captions[].template` no EditPlan; `--caption-style impact|word|full` continua como legado.
|
|
238
|
+
|
|
239
|
+
Caso adicione trilha de fundo (`--music`), a atenuação aplicada é fixa em `-22dB`, sem ducking dinâmico por sidechain.
|