primocode 8.42.2 → 9.1.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/README.md +41 -37
- package/bin/primocode.js +598 -360
- package/lib/acervo.js +8 -1
- package/lib/act.js +205 -114
- package/lib/api.js +35 -4
- package/lib/boas-vindas.js +42 -195
- package/lib/catalogo.js +100 -61
- package/lib/config.js +1 -1
- package/lib/conta.js +3 -24
- package/lib/diff.js +161 -0
- package/lib/diretor.js +37 -47
- package/lib/entrada.js +576 -0
- package/lib/especialistas.js +2 -2
- package/lib/estudio/assets.js +343 -0
- package/lib/estudio/identidade.js +560 -0
- package/lib/estudio/index.js +565 -0
- package/lib/estudio/plano.js +327 -0
- package/lib/estudio/projeto.js +246 -0
- package/lib/estudio/remotion.js +644 -0
- package/lib/estudio/slides.js +190 -0
- package/lib/estudio/video.js +296 -0
- package/lib/fala.js +49 -6
- package/lib/marca.js +4 -1
- package/lib/markdown.js +376 -0
- package/lib/marketplace.js +189 -0
- package/lib/pasta.js +15 -4
- package/lib/permissao.js +137 -0
- package/lib/registro.js +229 -0
- package/lib/skills.js +329 -0
- package/lib/tools.js +106 -187
- package/lib/ui.js +7 -3
- package/lib/voz.js +239 -0
- package/package.json +12 -3
- package/skills/acessibilidade/SKILL.md +28 -0
- package/skills/api-que-nao-quebra/SKILL.md +27 -0
- package/skills/depurar-de-verdade/SKILL.md +29 -0
- package/skills/editar-meu-video/SKILL.md +59 -0
- package/skills/escrever-em-portugues/SKILL.md +28 -0
- package/skills/git-limpo/SKILL.md +28 -0
- package/skills/motion-de-primeira/SKILL.md +62 -0
- package/skills/pagina-que-converte/SKILL.md +28 -0
- package/skills/performance-web/SKILL.md +28 -0
- package/skills/revisao-antes-de-entregar/SKILL.md +27 -0
- package/skills/slides-que-prendem/SKILL.md +40 -0
- package/studio/edge.py +16 -66
- package/studio/narrar.py +274 -0
- package/studio/pessoa.py +199 -0
- package/voz/primo_voz/__init__.py +0 -0
- package/voz/primo_voz/__main__.py +383 -0
- package/voz/primo_voz/escuta.py +235 -0
- package/voz/primo_voz/orbe.py +216 -0
- package/lib/audio-livre.js +0 -177
- package/lib/chaves.js +0 -149
- package/lib/claude-engine.js +0 -631
- package/lib/codex-engine.js +0 -208
- package/lib/remotion.js +0 -663
- package/lib/studio.js +0 -960
- package/studio/PRIMOCODE.md +0 -58
- package/studio/README.md +0 -154
- package/studio/__pycache__/edge.cpython-311.pyc +0 -0
- package/studio/__pycache__/elevenlabs.cpython-311.pyc +0 -0
- package/studio/__pycache__/voz.cpython-311.pyc +0 -0
- package/studio/arquivos/corte-teste-de-camera-fb823.json +0 -57
- package/studio/ferramentas/00-protocolo.md +0 -125
- package/studio/ferramentas/01-modelos.md +0 -270
- package/studio/ferramentas/README.md +0 -32
- package/studio/ferramentas/corte.md +0 -919
- package/studio/ferramentas/grade.md +0 -92
- package/studio/ferramentas/prisma.md +0 -107
- package/studio/ferramentas/prosa.md +0 -86
- package/studio/ferramentas/tela.md +0 -93
- package/studio/ferramentas/traco.md +0 -79
- package/studio/server.py +0 -2254
- package/studio/studio.log +0 -57
- package/studio/voz.py +0 -388
- package/studio/web/analise.html +0 -52
- package/studio/web/core.css +0 -1167
- package/studio/web/fontes/bebas.woff2 +0 -0
- package/studio/web/fontes/grotesk-700.woff2 +0 -0
- package/studio/web/fontes/inter-400.woff2 +0 -0
- package/studio/web/fontes/inter-700.woff2 +0 -0
- package/studio/web/fontes/jetbrains-400.woff2 +0 -0
- package/studio/web/fontes/playfair-700.woff2 +0 -0
- package/studio/web/fontes.css +0 -23
- package/studio/web/home.html +0 -217
- package/studio/web/js/analise.js +0 -510
- package/studio/web/js/audio.js +0 -607
- package/studio/web/js/editor.js +0 -1802
- package/studio/web/js/exportar.js +0 -222
- package/studio/web/js/ferramentas.js +0 -108
- package/studio/web/js/icones.js +0 -120
- package/studio/web/js/midia.js +0 -157
- package/studio/web/js/narracao.js +0 -325
- package/studio/web/js/player.js +0 -903
- package/studio/web/js/render-grade.js +0 -243
- package/studio/web/js/render-prosa.js +0 -104
- package/studio/web/js/render.js +0 -1852
- package/studio/web/js/sfx.js +0 -233
- package/studio/web/js/video.js +0 -464
- package/studio/web/js/voz-neural.js +0 -152
- package/studio/web/render.css +0 -1352
- package/studio/web/tf.html +0 -15
- package/studio/web/tool.html +0 -78
- package/studio/web/view.html +0 -27
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "primocode",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.1.0",
|
|
4
4
|
"description": "PrimoCode — agente de engenharia com IA e cursor próprio. Requer conta Conecta Primo AI (Premium ou Super). Cria arquivos, roda comandos, controla navegador e desktop: abre apps, clica em botões e ícones pelo nome, digita e usa atalhos.",
|
|
5
5
|
"main": "bin/primocode.js",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node bin/primocode.js",
|
|
11
|
-
"test": "node test/tools.test.js && node test/ui.test.js && node test/
|
|
11
|
+
"test": "node test/tools.test.js && node test/ui.test.js && node test/entrada.test.js && node test/transparencia.test.js && node test/permissao.test.js && node test/skills.test.js && node test/estudio.test.js && node test/voz.test.js && node test/modo.test.js && node test/pasta.test.js && node test/catalogo.test.js && node test/desktop.test.js && node test/effort.test.js && node test/regressao.test.js && node test/memoria-conversa.test.js && node test/repeticao.test.js && node test/referencia.test.js && node test/parar.test.js && node test/continuar.test.js && node test/pipeline.test.js && node test/app.test.js && node test/aplicativo.test.js && node test/conta.test.mjs && node test/nuvem.test.js && node test/prazo.test.js && node test/primeira-vez.test.js && node test/janela.test.js && node test/pareamento.test.js && node test/fala.test.js && node test/especialistas.test.js && node test/empurrao.test.js && node test/terminal-novo.test.js && node test/markdown.test.js"
|
|
12
12
|
},
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">=18.17.0"
|
|
@@ -29,6 +29,15 @@
|
|
|
29
29
|
"lib/",
|
|
30
30
|
"app/",
|
|
31
31
|
"studio/",
|
|
32
|
-
"
|
|
32
|
+
"skills/",
|
|
33
|
+
"voz/",
|
|
34
|
+
"README.md",
|
|
35
|
+
"!**/__pycache__",
|
|
36
|
+
"!**/*.pyc",
|
|
37
|
+
"!**/*.pyo",
|
|
38
|
+
"!**/*.log",
|
|
39
|
+
"!studio/arquivos",
|
|
40
|
+
"!studio/midia",
|
|
41
|
+
"!studio/saida"
|
|
33
42
|
]
|
|
34
43
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Acessibilidade
|
|
3
|
+
descricao: interface que funciona para quem não usa mouse nem enxerga a tela
|
|
4
|
+
quando: acessibilidade, acessível, acessivel, a11y, aria, teclado, leitor de tela, contraste, semântica, semantica, html
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Acessibilidade não é uma camada que se adiciona no fim. É como o HTML é
|
|
8
|
+
escrito.
|
|
9
|
+
|
|
10
|
+
**HTML semântico primeiro**: `button` para ação, `a` para navegação, `header`,
|
|
11
|
+
`nav`, `main`, `section`, `label`. Uma `div` com `onclick` não recebe foco,
|
|
12
|
+
não responde ao Enter e não existe para um leitor de tela. ARIA só entra
|
|
13
|
+
quando o elemento certo não existe — `aria-label` num `button` de ícone, sim;
|
|
14
|
+
`role="button"` numa `div`, não.
|
|
15
|
+
|
|
16
|
+
**Teclado**: dá para percorrer a página inteira com Tab, na ordem visual, e o
|
|
17
|
+
foco é VISÍVEL (`:focus-visible` com contorno de verdade — nunca
|
|
18
|
+
`outline: none` sem substituto). Modal prende o foco dentro e volta ao botão
|
|
19
|
+
que o abriu no Esc.
|
|
20
|
+
|
|
21
|
+
**Contraste**: 4.5:1 em texto normal, 3:1 em texto grande e em borda de
|
|
22
|
+
controle. Cinza-claro sobre branco é a falha mais comum.
|
|
23
|
+
|
|
24
|
+
**Imagem** tem `alt` que descreve a função, não o arquivo. Decorativa leva
|
|
25
|
+
`alt=""`.
|
|
26
|
+
|
|
27
|
+
**Formulário**: todo campo com `label` ligado, erro em texto (não só em
|
|
28
|
+
vermelho) e ligado ao campo por `aria-describedby`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: API que não quebra
|
|
3
|
+
descricao: rotas, validação, erro e segurança em servidor
|
|
4
|
+
quando: api, rota, rotas, endpoint, servidor, backend, express, fastapi, flask, django, rest, webhook, autenticação, autenticacao, token, banco de dados
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Leia o que já existe (rotas, modelos, como o projeto trata erro e
|
|
8
|
+
configuração) e siga o padrão dele. Um projeto com dois padrões é pior que um
|
|
9
|
+
projeto com um padrão ruim.
|
|
10
|
+
|
|
11
|
+
**Valide na borda.** Toda entrada: tipo, tamanho, faixa. O erro responde com o
|
|
12
|
+
código HTTP certo e uma mensagem que diz o que corrigir — "Bad Request" não
|
|
13
|
+
diz nada a ninguém.
|
|
14
|
+
|
|
15
|
+
**Nunca**: segredo no código (vai para variável de ambiente, com o
|
|
16
|
+
`.env.example` atualizado); entrada do usuário concatenada em SQL, comando de
|
|
17
|
+
shell ou caminho de arquivo; catch vazio; dado pessoal no log.
|
|
18
|
+
|
|
19
|
+
**Separe** rota, regra de negócio e acesso a dados. A rota lê e responde; ela
|
|
20
|
+
não sabe fazer conta.
|
|
21
|
+
|
|
22
|
+
**Pense no que falha**: rede fora, disco cheio, campo ausente, mesmo pedido
|
|
23
|
+
chegando duas vezes. Uma rota que só funciona com o caminho feliz não está
|
|
24
|
+
pronta.
|
|
25
|
+
|
|
26
|
+
Antes de terminar, suba o servidor e mostre uma requisição respondendo de
|
|
27
|
+
verdade — com o corpo da resposta, não só o status.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Depurar de verdade
|
|
3
|
+
descricao: achar a causa do defeito em vez de tentar consertos no escuro
|
|
4
|
+
quando: bug, erro, defeito, quebrado, não funciona, nao funciona, falha, corrigir, consertar, debug, depurar, travando
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Não conserte antes de reproduzir. Conserto sem reprodução é chute, e chute que
|
|
8
|
+
"parece ter resolvido" esconde o defeito para ele voltar depois.
|
|
9
|
+
|
|
10
|
+
**A ordem**:
|
|
11
|
+
|
|
12
|
+
1. **Reproduza.** Qual entrada, qual passo, o que aconteceu, o que deveria ter
|
|
13
|
+
acontecido. Se não reproduz, o defeito não está onde você acha.
|
|
14
|
+
2. **Leia o erro inteiro.** A primeira linha diz o sintoma; a pilha diz o
|
|
15
|
+
lugar. A linha que importa costuma ser a primeira que é do PROJETO, não da
|
|
16
|
+
biblioteca.
|
|
17
|
+
3. **Isole.** Metade de cada vez: o dado está errado ao entrar ou ao sair?
|
|
18
|
+
Antes ou depois desta função? Cada medição corta o espaço de busca pela
|
|
19
|
+
metade.
|
|
20
|
+
4. **Entenda a causa.** "Adicionei um try/catch e parou de aparecer" não é
|
|
21
|
+
causa, é mordaça.
|
|
22
|
+
5. **Conserte** o menor pedaço possível, e **prove** rodando a reprodução do
|
|
23
|
+
passo 1.
|
|
24
|
+
|
|
25
|
+
Se o projeto tem teste, escreva PRIMEIRO o que falha, depois a correção,
|
|
26
|
+
depois veja-o passar. Assim o defeito não volta sem ninguém ver.
|
|
27
|
+
|
|
28
|
+
Quando a suspeita for de ambiente (versão, variável, caminho), confira em vez
|
|
29
|
+
de supor: rode `--version`, imprima a variável, liste a pasta.
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Editar o vídeo gravado
|
|
3
|
+
descricao: como tratar uma gravação do usuário sem estragar o ritmo dela
|
|
4
|
+
quando: gravei, gravação, gravacao, meu vídeo, meu video, editar, edição, edicao, corte, legenda, legendas, b-roll, broll
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
O vídeo é da pessoa. Ela apareceu, falou e errou — o seu trabalho é tirar o
|
|
8
|
+
que atrapalha, não refazer o que ela fez.
|
|
9
|
+
|
|
10
|
+
## A ordem que funciona
|
|
11
|
+
|
|
12
|
+
1. `estudio_video acao:"importar"` — o original entra na pasta do projeto, e
|
|
13
|
+
fica intocado. Nunca escreva por cima do arquivo dela.
|
|
14
|
+
2. `acao:"medir"` — duração, tamanho, fps. Enquadramento vertical e
|
|
15
|
+
horizontal mudam tudo o que vem depois.
|
|
16
|
+
3. `acao:"legendas"` — a transcrição com tempo. Ela serve para duas coisas: a
|
|
17
|
+
legenda em si e saber DO QUE ela está falando em cada instante, que é o
|
|
18
|
+
que decide onde entra apoio.
|
|
19
|
+
4. `acao:"cortar-silencio"` — depois de ler, não antes.
|
|
20
|
+
5. O plano, com a gravação como elemento de vídeo.
|
|
21
|
+
|
|
22
|
+
## Corte de silêncio
|
|
23
|
+
|
|
24
|
+
Pausa curta é fala, não erro. Corte só o que passa de ~0,6s, e deixe respiro
|
|
25
|
+
nas pontas (~0,18s). O padrão já faz isso; mexer nele é decisão, não ajuste.
|
|
26
|
+
|
|
27
|
+
Depois do corte, ASSISTA: peça quadros (`acao:"quadro"`) em alguns pontos de
|
|
28
|
+
emenda. Corte que fica bom no papel e ruim no ouvido é o normal, não a
|
|
29
|
+
exceção.
|
|
30
|
+
|
|
31
|
+
## Legenda
|
|
32
|
+
|
|
33
|
+
A legenda tem estilo — fonte, peso, cor, contorno, posição, animação. Ela não
|
|
34
|
+
é uma linha branca no rodapé por obrigação.
|
|
35
|
+
|
|
36
|
+
Regras que valem: no máximo 5 ou 6 palavras por vez; posição alta o bastante
|
|
37
|
+
para não ser coberta pela interface do aplicativo onde o vídeo vai; contorno
|
|
38
|
+
ou sombra, porque o fundo muda; e nunca cobrindo o rosto de quem fala.
|
|
39
|
+
|
|
40
|
+
## B-roll
|
|
41
|
+
|
|
42
|
+
Quando ela cita uma coisa concreta, essa coisa aparece — e ela some da tela
|
|
43
|
+
por 1 a 3 segundos. Depois volta. É isso que dá ritmo a vídeo falado.
|
|
44
|
+
|
|
45
|
+
Busque a imagem pelo que ela DISSE naquele instante (você tem os tempos da
|
|
46
|
+
transcrição). Volte sempre antes de a frase acabar.
|
|
47
|
+
|
|
48
|
+
## Troca de fundo
|
|
49
|
+
|
|
50
|
+
`acao:"recortar-pessoa"` devolve a pessoa com fundo transparente. Ponha uma
|
|
51
|
+
imagem relacionada ao assunto atrás — não uma textura decorativa.
|
|
52
|
+
|
|
53
|
+
O recorte erra na borda do cabelo. Se ficar com cara de adesivo, aumente o
|
|
54
|
+
`suavizar` e o `encolher` antes de desistir.
|
|
55
|
+
|
|
56
|
+
## O que contar para ela
|
|
57
|
+
|
|
58
|
+
Diga quantos segundos saíram e quantos cortes foram feitos. É fala dela que
|
|
59
|
+
sumiu do vídeo — ela tem o direito de saber, e de discordar.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Escrever em português
|
|
3
|
+
descricao: texto de produto que soa como gente, não como manual traduzido
|
|
4
|
+
quando: texto, copy, escrever, redação, redacao, mensagem, microcopy, erro, aviso, botão, botao, e-mail, email, post, legenda
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Escreva como alguém que conhece o assunto falaria com um colega — em português
|
|
8
|
+
do Brasil, não em inglês traduzido.
|
|
9
|
+
|
|
10
|
+
**O que denuncia tradução**: "Nós fornecemos soluções", "Clique aqui para",
|
|
11
|
+
"Oops! Algo deu errado", voz passiva em tudo, "seu/sua" em toda frase,
|
|
12
|
+
gerúndio de call center ("vou estar enviando").
|
|
13
|
+
|
|
14
|
+
**Mensagem de erro** diz três coisas, nesta ordem: o que aconteceu, por que, e
|
|
15
|
+
o que fazer agora. "Erro 500" não é nenhuma das três. Sem culpar a pessoa: "o
|
|
16
|
+
e-mail precisa de @" e não "você digitou errado".
|
|
17
|
+
|
|
18
|
+
**Botão** é um verbo que descreve o resultado: "Salvar alterações", "Enviar
|
|
19
|
+
pedido" — nunca "OK", "Enviar" solto ou "Clique aqui".
|
|
20
|
+
|
|
21
|
+
**Frase curta.** Se precisou de vírgula para respirar duas vezes, são duas
|
|
22
|
+
frases. Corte advérbio ("simplesmente", "basicamente", "rapidamente") e
|
|
23
|
+
superlativo sem número.
|
|
24
|
+
|
|
25
|
+
Número concreto vence adjetivo: "responde em 2 segundos" vale mais que
|
|
26
|
+
"ultrarrápido".
|
|
27
|
+
|
|
28
|
+
Não use emoji para dar emoção a um texto que não tem nenhuma.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Git limpo
|
|
3
|
+
descricao: commit, branch e histórico que alguém consegue ler depois
|
|
4
|
+
quando: git, commit, commitar, branch, pull request, pr, merge, histórico, historico, versionar
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
O histórico é documentação. Quem vai lê-lo é você daqui a seis meses,
|
|
8
|
+
procurando por que uma linha existe.
|
|
9
|
+
|
|
10
|
+
**Commit**: um assunto por commit. A primeira linha diz o que MUDA no
|
|
11
|
+
comportamento, no imperativo e sem ponto final ("corrige o cálculo do frete
|
|
12
|
+
para pedido sem CEP"). O corpo diz POR QUE — o que estava errado e o que se
|
|
13
|
+
tentou antes. O código já mostra o que foi feito; o que ele não mostra é o
|
|
14
|
+
motivo.
|
|
15
|
+
|
|
16
|
+
**Nunca** commite: segredo, chave, `.env`, `node_modules`, pasta de build,
|
|
17
|
+
arquivo de editor. Confira com `git status` antes, e com `git diff --staged`
|
|
18
|
+
antes de fechar.
|
|
19
|
+
|
|
20
|
+
**Antes de commitar**, rode o que o projeto roda (lint, teste). Commit que
|
|
21
|
+
quebra a build custa o tempo de todo mundo que der pull.
|
|
22
|
+
|
|
23
|
+
**Branch** com nome que diz o assunto, não o seu nome.
|
|
24
|
+
|
|
25
|
+
**Pull request**: título que é a frase do commit; corpo com o que muda, por
|
|
26
|
+
que, e como conferir. Se o projeto tem template de PR, siga o template.
|
|
27
|
+
|
|
28
|
+
Nunca reescreva histórico que já foi empurrado e que outra pessoa pode ter.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Motion de primeira
|
|
3
|
+
descricao: como um vídeo criado do zero deixa de parecer feito por máquina
|
|
4
|
+
quando: vídeo, video, motion, animação, animacao, anúncio, anuncio, reels, teaser, abertura, comercial, propaganda, estúdio, estudio
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Não existe template. Cada propriedade deste vídeo é uma decisão sua, e a
|
|
8
|
+
primeira decisão é **não repetir o vídeo anterior**.
|
|
9
|
+
|
|
10
|
+
## O que denuncia vídeo feito por IA
|
|
11
|
+
|
|
12
|
+
Não faça nada disto, em nenhum vídeo:
|
|
13
|
+
|
|
14
|
+
- gradiente roxo-para-azul (o mais reconhecível de todos), e gradiente de duas
|
|
15
|
+
cores que não têm relação com o assunto;
|
|
16
|
+
- tudo centralizado, do primeiro ao último quadro;
|
|
17
|
+
- uma fonte só, em todos os tamanhos;
|
|
18
|
+
- texto que aparece com `opacidade 0→1` e mais nada, cena após cena;
|
|
19
|
+
- ícone genérico flutuando ao lado de cada frase;
|
|
20
|
+
- tempo igual em todas as cenas;
|
|
21
|
+
- transição igual entre todas.
|
|
22
|
+
|
|
23
|
+
## O que separa motion bom de slide animado
|
|
24
|
+
|
|
25
|
+
**A câmera existe.** Zoom, pan e dolly são da CENA, não do elemento. Um zoom
|
|
26
|
+
lento de 1.0 para 1.08 ao longo de uma cena dá vida a um quadro parado — e
|
|
27
|
+
quase nenhum vídeo automático faz isso.
|
|
28
|
+
|
|
29
|
+
**Nada entra do nada.** Um elemento entra vindo de algum lugar (de baixo, de
|
|
30
|
+
trás, de fora do quadro), com `saida` ou `elastico` na suavização. Movimento
|
|
31
|
+
linear é a assinatura da máquina: no mundo físico nada começa e para na mesma
|
|
32
|
+
velocidade.
|
|
33
|
+
|
|
34
|
+
**Profundidade.** Camadas que se movem em velocidades diferentes (parallax)
|
|
35
|
+
custam duas linhas e mudam a cena inteira: fundo devagar, meio médio, frente
|
|
36
|
+
rápido. Com `perspectiva` na cena, `rotacaoX`/`rotacaoY`/`z` viram 3D de
|
|
37
|
+
verdade.
|
|
38
|
+
|
|
39
|
+
**Ritmo.** Cena de informação simples: 1,5 a 2,5s. Cena com frase para ler: 3
|
|
40
|
+
a 4s. Fecho: 2s. Variar a duração é o que cria ritmo; repetir cria sono.
|
|
41
|
+
|
|
42
|
+
**Silêncio visual.** Um quadro com uma frase e mais nada vale mais que um com
|
|
43
|
+
seis elementos. Espaço vazio é composição, não desperdício.
|
|
44
|
+
|
|
45
|
+
## Cor e tipo
|
|
46
|
+
|
|
47
|
+
Escolha a paleta a partir do ASSUNTO, e escreva os valores. Três a cinco
|
|
48
|
+
cores: uma dominante, uma de destaque, neutros com viés da dominante. Se a
|
|
49
|
+
marca existe, leia o site dela com `estudio_site` e use as cores medidas —
|
|
50
|
+
não as que você imagina que ela usa.
|
|
51
|
+
|
|
52
|
+
Duas fontes, no máximo: uma de display para o que grita, uma neutra para o
|
|
53
|
+
que se lê. `estudio_midia acao:"fontes"` mostra um leque grande — sair do
|
|
54
|
+
Inter/Montserrat é metade do trabalho de não parecer genérico.
|
|
55
|
+
|
|
56
|
+
## Antes de renderizar
|
|
57
|
+
|
|
58
|
+
- Todo `src` aponta para arquivo que existe na pasta (baixe antes).
|
|
59
|
+
- Os tempos das cenas batem com os tempos MEDIDOS da narração.
|
|
60
|
+
- Nenhuma cena tem a mesma composição da anterior.
|
|
61
|
+
- Leia o seu próprio plano e pergunte: em que este vídeo é diferente do
|
|
62
|
+
último que eu fiz? Se não houver resposta, refaça antes de renderizar.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Página que converte
|
|
3
|
+
descricao: estrutura e acabamento de landing page, site e página de venda
|
|
4
|
+
quando: landing, landing page, site, página, pagina, home, hero, seção, secao, cta, conversão, conversao, vendas, institucional
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Uma página que converte tem ordem, não mais elementos.
|
|
8
|
+
|
|
9
|
+
**A ordem que funciona**: promessa clara em até 8 palavras → uma linha que
|
|
10
|
+
explica para quem é → prova (número real, print, nome de cliente) → o que a
|
|
11
|
+
pessoa ganha, em 3 blocos → objeção respondida → um único pedido de ação,
|
|
12
|
+
repetido no fim.
|
|
13
|
+
|
|
14
|
+
**Um CTA por página.** Dois pedidos de ação competem entre si e a pessoa não
|
|
15
|
+
faz nenhum.
|
|
16
|
+
|
|
17
|
+
**O que denuncia página genérica** — não faça nada disto:
|
|
18
|
+
gradiente roxo-para-azul no fundo, tudo centralizado do topo ao rodapé,
|
|
19
|
+
sombra em todo cartão, emoji no lugar de ícone, "Bem-vindo ao nosso site",
|
|
20
|
+
"Soluções inovadoras", texto de exemplo em qualquer lugar.
|
|
21
|
+
|
|
22
|
+
**Acabamento**: escala de espaço consistente (4/8/12/16/24/32/48), no máximo
|
|
23
|
+
dois pesos de fonte, contraste de 4.5:1 no texto, botão com hover e
|
|
24
|
+
focus-visible, largura de leitura entre 60 e 75 caracteres. Funciona de 360px
|
|
25
|
+
a 1440px sem rolagem horizontal.
|
|
26
|
+
|
|
27
|
+
Escreva o texto de verdade, sobre o assunto de verdade. Uma página bonita com
|
|
28
|
+
texto vazio não convence ninguém.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Performance web
|
|
3
|
+
descricao: página que carrega rápido de verdade, não no papel
|
|
4
|
+
quando: performance, lento, lenta, rápido, rapido, otimizar, otimização, otimizacao, carregamento, lighthouse, bundle, imagem, imagens
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Meça antes de otimizar. Otimizar por palpite muda código sem mudar o tempo.
|
|
8
|
+
|
|
9
|
+
**O que quase sempre é o culpado, nesta ordem**: imagem gigante servida em
|
|
10
|
+
tamanho de tela cheia; fonte externa bloqueando a renderização; JavaScript que
|
|
11
|
+
roda antes de a página aparecer; biblioteca inteira importada para usar uma
|
|
12
|
+
função.
|
|
13
|
+
|
|
14
|
+
**Imagem**: dimensione para o tamanho em que aparece, use formato moderno
|
|
15
|
+
(WebP/AVIF), declare `width` e `height` no HTML (sem isso a página pula
|
|
16
|
+
enquanto carrega) e `loading="lazy"` no que está abaixo da dobra.
|
|
17
|
+
|
|
18
|
+
**Fonte**: `font-display: swap`, e prefira a fonte do sistema quando a marca
|
|
19
|
+
não exige outra. Uma fonte externa custa uma conexão e um bloqueio.
|
|
20
|
+
|
|
21
|
+
**JavaScript**: nada que não seja necessário para a primeira tela. `defer` no
|
|
22
|
+
que puder esperar. Antes de adicionar uma biblioteca, escreva a função — três
|
|
23
|
+
linhas suas custam menos que 40 KB de dependência.
|
|
24
|
+
|
|
25
|
+
**CSS**: evite seletor que força recálculo em rolagem; anime só `transform` e
|
|
26
|
+
`opacity`.
|
|
27
|
+
|
|
28
|
+
Prove com número: o tamanho do que é baixado antes e depois.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Revisão antes de entregar
|
|
3
|
+
descricao: confere o próprio trabalho antes de dizer que acabou
|
|
4
|
+
quando: pronto, terminar, entregar, finalizar, revisar, conferir, testar, verificar
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Antes de dizer que terminou, PROVE. A mentira mais comum de um agente é
|
|
8
|
+
"pronto" sem prova, e ela custa a confiança inteira.
|
|
9
|
+
|
|
10
|
+
O que conta como prova, por tipo de entrega:
|
|
11
|
+
|
|
12
|
+
- **Página HTML**: abra com `browser_open` e leia o console. Erro no console é
|
|
13
|
+
tarefa inacabada, mesmo que a página pareça certa. Confira que o texto
|
|
14
|
+
aparece de verdade — página em branco por TypeError na primeira linha
|
|
15
|
+
responde 200 e tem título.
|
|
16
|
+
- **Código com teste**: rode o comando de teste do projeto e mostre a saída
|
|
17
|
+
real. Nunca escreva "os testes passam" sem a saída na mão.
|
|
18
|
+
- **Código sem teste**: execute o caminho principal uma vez. Se não dá para
|
|
19
|
+
executar, diga isso em vez de afirmar que funciona.
|
|
20
|
+
- **Arquivo de configuração**: leia de volta o que escreveu.
|
|
21
|
+
|
|
22
|
+
Releia o seu próprio diff antes de terminar, procurando o que você mesmo
|
|
23
|
+
quebraria: caminho que não existe, promessa sem await, variável que só existe
|
|
24
|
+
num dos ramos, texto de exemplo esquecido.
|
|
25
|
+
|
|
26
|
+
Se algo ficou por fazer, diga em UMA linha o que foi e por quê. Entregar 90%
|
|
27
|
+
dizendo a verdade vale mais que entregar 90% dizendo 100%.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
nome: Slides que prendem
|
|
3
|
+
descricao: apresentação sem template, que se lê de longe e não entedia
|
|
4
|
+
quando: slides, slide, apresentação, apresentacao, deck, pitch, palestra
|
|
5
|
+
autor: PrimoCode
|
|
6
|
+
---
|
|
7
|
+
Slide não é documento projetado. Se ele se lê inteiro em voz alta, é um
|
|
8
|
+
documento — e o público já leu antes de você falar.
|
|
9
|
+
|
|
10
|
+
## A estrutura, sem modelo pronto
|
|
11
|
+
|
|
12
|
+
Não existe "layout capa" nem "layout duas colunas". Cada slide é composto do
|
|
13
|
+
zero, como uma cena: fundo, elementos posicionados, tipografia escolhida.
|
|
14
|
+
|
|
15
|
+
O que existe é uma ORDEM que funciona: a tensão antes da solução. Comece pelo
|
|
16
|
+
problema que a plateia reconhece, não pela apresentação de quem fala.
|
|
17
|
+
|
|
18
|
+
## Uma ideia por slide
|
|
19
|
+
|
|
20
|
+
Se precisa rolar o olho para ler, dividiu errado. Título que é uma AFIRMAÇÃO
|
|
21
|
+
("o custo dobrou em 6 meses"), não um rótulo ("custos").
|
|
22
|
+
|
|
23
|
+
Número grande é slide inteiro: um número, uma linha do que ele significa, e
|
|
24
|
+
mais nada.
|
|
25
|
+
|
|
26
|
+
## Legibilidade antes de beleza
|
|
27
|
+
|
|
28
|
+
Texto de corpo nunca abaixo de 28pt no 1920×1080. Contraste alto — slide é
|
|
29
|
+
visto em sala com luz. No máximo duas fontes e três cores.
|
|
30
|
+
|
|
31
|
+
## Ritmo
|
|
32
|
+
|
|
33
|
+
Varie: slide denso, slide de respiro, slide de número, slide de citação.
|
|
34
|
+
Quinze slides iguais em sequência perdem qualquer plateia, por melhores que
|
|
35
|
+
sejam.
|
|
36
|
+
|
|
37
|
+
## Prova
|
|
38
|
+
|
|
39
|
+
Todo dado tem origem escrita ao lado, pequena. Dado sem fonte é opinião com
|
|
40
|
+
fonte tipográfica melhor — e alguém vai perguntar.
|
package/studio/edge.py
CHANGED
|
@@ -117,81 +117,32 @@ def disponivel():
|
|
|
117
117
|
return _verificado
|
|
118
118
|
|
|
119
119
|
|
|
120
|
-
# Por que a instalação falhava calada, e o vídeo saía com a voz do Google:
|
|
121
|
-
# `pip install --user` é recusado pelo Python do sistema em Debian/Ubuntu e
|
|
122
|
-
# no do Homebrew ("externally-managed-environment", PEP 668), e em máquina
|
|
123
|
-
# sem pip o `-m pip` nem existe. Um `pip install` só, em segundo plano, com a
|
|
124
|
-
# saída jogada fora, era exatamente a falha que ninguém vê. Agora são várias
|
|
125
|
-
# tentativas, em ordem, e a última linha do erro de cada uma fica guardada
|
|
126
|
-
# para o status contar o que houve.
|
|
127
|
-
ESTRATEGIAS = [
|
|
128
|
-
["-m", "pip", "install", "--user", "--quiet", "edge-tts"],
|
|
129
|
-
["-m", "pip", "install", "--user", "--quiet", "--break-system-packages", "edge-tts"],
|
|
130
|
-
["-m", "pip", "install", "--quiet", "edge-tts"],
|
|
131
|
-
["-m", "pip", "install", "--quiet", "--break-system-packages", "edge-tts"],
|
|
132
|
-
]
|
|
133
|
-
_ultimo_erro = ""
|
|
134
|
-
_thread = None
|
|
135
|
-
|
|
136
|
-
|
|
137
120
|
def _rotina_instalar():
|
|
138
|
-
global _instalando, _verificado
|
|
121
|
+
global _instalando, _verificado
|
|
139
122
|
try:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if r.returncode != 0:
|
|
146
|
-
subprocess.run([sys.executable, "-m", "ensurepip", "--user", "--default-pip"],
|
|
147
|
-
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=120)
|
|
148
|
-
except Exception:
|
|
149
|
-
pass
|
|
150
|
-
for args in ESTRATEGIAS:
|
|
151
|
-
try:
|
|
152
|
-
r = subprocess.run([sys.executable] + args, stdout=subprocess.DEVNULL,
|
|
153
|
-
stderr=subprocess.PIPE, timeout=240)
|
|
154
|
-
except Exception as e:
|
|
155
|
-
_ultimo_erro = str(e)[-200:]
|
|
156
|
-
continue
|
|
157
|
-
_verificado = None
|
|
158
|
-
if r.returncode == 0 and disponivel():
|
|
159
|
-
_ultimo_erro = ""
|
|
160
|
-
sys.stderr.write("[edge] edge-tts instalado (%s)\n" % " ".join(args[2:]))
|
|
161
|
-
return
|
|
162
|
-
_ultimo_erro = (r.stderr or b"").decode("utf-8", "replace").strip().splitlines()[-1:][0][-200:] \
|
|
163
|
-
if (r.stderr or b"").strip() else "pip devolveu %s" % r.returncode
|
|
164
|
-
sys.stderr.write("[edge] não consegui instalar o edge-tts: %s\n" % _ultimo_erro)
|
|
123
|
+
subprocess.run(
|
|
124
|
+
[sys.executable, "-m", "pip", "install", "--user", "--quiet", "edge-tts"],
|
|
125
|
+
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=180)
|
|
126
|
+
except Exception as e:
|
|
127
|
+
sys.stderr.write("[edge] pip install falhou: %s\n" % e)
|
|
165
128
|
finally:
|
|
166
129
|
_verificado = None # força nova checagem
|
|
167
130
|
with _tranca:
|
|
168
131
|
_instalando = False
|
|
169
132
|
|
|
170
133
|
|
|
171
|
-
def instalar(
|
|
172
|
-
"""
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
reserva só porque o pip ainda estava rodando: quem pede voz agora e tem
|
|
177
|
-
internet merece a voz neural agora. Meio minuto de pip é menos ruim que
|
|
178
|
-
um vídeo inteiro com voz de robô."""
|
|
179
|
-
global _instalando, _thread
|
|
134
|
+
def instalar():
|
|
135
|
+
"""Tenta trazer o pacote em segundo plano, uma vez. Não bloqueia: quem
|
|
136
|
+
pediu narração agora ouve o próximo motor da corrente, e a partir da
|
|
137
|
+
próxima vez o Edge já responde."""
|
|
138
|
+
global _instalando
|
|
180
139
|
if disponivel():
|
|
181
|
-
return
|
|
140
|
+
return
|
|
182
141
|
with _tranca:
|
|
183
|
-
if
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
t = _thread
|
|
188
|
-
if t and esperar:
|
|
189
|
-
t.join(esperar)
|
|
190
|
-
return disponivel()
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
def ultimo_erro():
|
|
194
|
-
return _ultimo_erro
|
|
142
|
+
if _instalando:
|
|
143
|
+
return
|
|
144
|
+
_instalando = True
|
|
145
|
+
threading.Thread(target=_rotina_instalar, daemon=True).start()
|
|
195
146
|
|
|
196
147
|
|
|
197
148
|
def _dur_do_vtt(caminho):
|
|
@@ -264,7 +215,6 @@ def estado():
|
|
|
264
215
|
"motor": "edge",
|
|
265
216
|
"disponivel": disponivel(),
|
|
266
217
|
"instalando": inst,
|
|
267
|
-
"erro": _ultimo_erro or None,
|
|
268
218
|
"precisa_internet": True,
|
|
269
219
|
"vozes": [{"id": v["id"], "nome": v["nome"], "genero": v["genero"],
|
|
270
220
|
"padrao": bool(v.get("padrao"))} for v in CATALOGO],
|