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.
Files changed (104) hide show
  1. package/README.md +41 -37
  2. package/bin/primocode.js +598 -360
  3. package/lib/acervo.js +8 -1
  4. package/lib/act.js +205 -114
  5. package/lib/api.js +35 -4
  6. package/lib/boas-vindas.js +42 -195
  7. package/lib/catalogo.js +100 -61
  8. package/lib/config.js +1 -1
  9. package/lib/conta.js +3 -24
  10. package/lib/diff.js +161 -0
  11. package/lib/diretor.js +37 -47
  12. package/lib/entrada.js +576 -0
  13. package/lib/especialistas.js +2 -2
  14. package/lib/estudio/assets.js +343 -0
  15. package/lib/estudio/identidade.js +560 -0
  16. package/lib/estudio/index.js +565 -0
  17. package/lib/estudio/plano.js +327 -0
  18. package/lib/estudio/projeto.js +246 -0
  19. package/lib/estudio/remotion.js +644 -0
  20. package/lib/estudio/slides.js +190 -0
  21. package/lib/estudio/video.js +296 -0
  22. package/lib/fala.js +49 -6
  23. package/lib/marca.js +4 -1
  24. package/lib/markdown.js +376 -0
  25. package/lib/marketplace.js +189 -0
  26. package/lib/pasta.js +15 -4
  27. package/lib/permissao.js +137 -0
  28. package/lib/registro.js +229 -0
  29. package/lib/skills.js +329 -0
  30. package/lib/tools.js +106 -187
  31. package/lib/ui.js +7 -3
  32. package/lib/voz.js +239 -0
  33. package/package.json +12 -3
  34. package/skills/acessibilidade/SKILL.md +28 -0
  35. package/skills/api-que-nao-quebra/SKILL.md +27 -0
  36. package/skills/depurar-de-verdade/SKILL.md +29 -0
  37. package/skills/editar-meu-video/SKILL.md +59 -0
  38. package/skills/escrever-em-portugues/SKILL.md +28 -0
  39. package/skills/git-limpo/SKILL.md +28 -0
  40. package/skills/motion-de-primeira/SKILL.md +62 -0
  41. package/skills/pagina-que-converte/SKILL.md +28 -0
  42. package/skills/performance-web/SKILL.md +28 -0
  43. package/skills/revisao-antes-de-entregar/SKILL.md +27 -0
  44. package/skills/slides-que-prendem/SKILL.md +40 -0
  45. package/studio/edge.py +16 -66
  46. package/studio/narrar.py +274 -0
  47. package/studio/pessoa.py +199 -0
  48. package/voz/primo_voz/__init__.py +0 -0
  49. package/voz/primo_voz/__main__.py +383 -0
  50. package/voz/primo_voz/escuta.py +235 -0
  51. package/voz/primo_voz/orbe.py +216 -0
  52. package/lib/audio-livre.js +0 -177
  53. package/lib/chaves.js +0 -149
  54. package/lib/claude-engine.js +0 -631
  55. package/lib/codex-engine.js +0 -208
  56. package/lib/remotion.js +0 -663
  57. package/lib/studio.js +0 -960
  58. package/studio/PRIMOCODE.md +0 -58
  59. package/studio/README.md +0 -154
  60. package/studio/__pycache__/edge.cpython-311.pyc +0 -0
  61. package/studio/__pycache__/elevenlabs.cpython-311.pyc +0 -0
  62. package/studio/__pycache__/voz.cpython-311.pyc +0 -0
  63. package/studio/arquivos/corte-teste-de-camera-fb823.json +0 -57
  64. package/studio/ferramentas/00-protocolo.md +0 -125
  65. package/studio/ferramentas/01-modelos.md +0 -270
  66. package/studio/ferramentas/README.md +0 -32
  67. package/studio/ferramentas/corte.md +0 -919
  68. package/studio/ferramentas/grade.md +0 -92
  69. package/studio/ferramentas/prisma.md +0 -107
  70. package/studio/ferramentas/prosa.md +0 -86
  71. package/studio/ferramentas/tela.md +0 -93
  72. package/studio/ferramentas/traco.md +0 -79
  73. package/studio/server.py +0 -2254
  74. package/studio/studio.log +0 -57
  75. package/studio/voz.py +0 -388
  76. package/studio/web/analise.html +0 -52
  77. package/studio/web/core.css +0 -1167
  78. package/studio/web/fontes/bebas.woff2 +0 -0
  79. package/studio/web/fontes/grotesk-700.woff2 +0 -0
  80. package/studio/web/fontes/inter-400.woff2 +0 -0
  81. package/studio/web/fontes/inter-700.woff2 +0 -0
  82. package/studio/web/fontes/jetbrains-400.woff2 +0 -0
  83. package/studio/web/fontes/playfair-700.woff2 +0 -0
  84. package/studio/web/fontes.css +0 -23
  85. package/studio/web/home.html +0 -217
  86. package/studio/web/js/analise.js +0 -510
  87. package/studio/web/js/audio.js +0 -607
  88. package/studio/web/js/editor.js +0 -1802
  89. package/studio/web/js/exportar.js +0 -222
  90. package/studio/web/js/ferramentas.js +0 -108
  91. package/studio/web/js/icones.js +0 -120
  92. package/studio/web/js/midia.js +0 -157
  93. package/studio/web/js/narracao.js +0 -325
  94. package/studio/web/js/player.js +0 -903
  95. package/studio/web/js/render-grade.js +0 -243
  96. package/studio/web/js/render-prosa.js +0 -104
  97. package/studio/web/js/render.js +0 -1852
  98. package/studio/web/js/sfx.js +0 -233
  99. package/studio/web/js/video.js +0 -464
  100. package/studio/web/js/voz-neural.js +0 -152
  101. package/studio/web/render.css +0 -1352
  102. package/studio/web/tf.html +0 -15
  103. package/studio/web/tool.html +0 -78
  104. package/studio/web/view.html +0 -27
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primocode",
3
- "version": "8.42.2",
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/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/claude-engine.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/studio-spec.test.js && node test/studio-versoes.test.js && node test/voz.test.js && node test/editor.test.js && node test/estudio-projeto.test.js && node test/vocabulario.test.js && node test/video-export.test.js && node test/monotonia.test.js && node test/clipe.test.js && node test/midia-envio.test.js && node test/pausas.test.js && node test/fala-repetida.test.js && node test/trilha.test.js && node test/anuncio.test.js && node test/pipeline.test.js && node test/app.test.js && node test/elementos.test.js && node test/remotion.test.js && node test/aplicativo.test.js && node test/conta.test.mjs && node test/nuvem.test.js && node test/codex.test.js && node test/chaves.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/icone.test.js && node test/exportar.test.js && node test/ate-o-fim.test.js && node test/motion.test.js && node test/audio-marca.test.js && node test/diretor.test.js && node test/camera.test.js"
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
- "README.md"
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, _ultimo_erro
121
+ global _instalando, _verificado
139
122
  try:
140
- # Sem pip, primeiro o ensurepip — é o que o python.org e a Apple
141
- # trazem para o caso.
142
- try:
143
- r = subprocess.run([sys.executable, "-m", "pip", "--version"],
144
- stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=30)
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(esperar=0):
172
- """Traz o pacote — em segundo plano por padrão; com `esperar` (segundos),
173
- quem chamou fica aguardando até esse teto.
174
-
175
- Esperar existe porque a narração de um vídeo NÃO pode sair pela voz de
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 True
140
+ return
182
141
  with _tranca:
183
- if not _instalando:
184
- _instalando = True
185
- _thread = threading.Thread(target=_rotina_instalar, daemon=True)
186
- _thread.start()
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],