primocode 10.4.4 → 10.5.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 +2 -2
- package/lib/catalogo.js +7 -3
- package/lib/conta.js +9 -3
- package/lib/estudio/batida.js +95 -10
- package/lib/estudio/colecao.js +185 -0
- package/lib/estudio/dados/fluent-3d.json +1 -0
- package/lib/estudio/dados/noto-animado.json +1 -0
- package/lib/estudio/estilo.js +6 -2
- package/lib/estudio/gerativo.js +181 -29
- package/lib/estudio/index.js +97 -22
- package/lib/estudio/kit/animacao.jsx +41 -0
- package/lib/estudio/kit/gerativo.jsx +63 -5
- package/lib/estudio/kit/index.jsx +3 -1
- package/lib/estudio/kit/tres.jsx +156 -0
- package/lib/estudio/kit/voxel.jsx +609 -0
- package/lib/estudio/kit.js +5 -1
- package/lib/estudio/personagem.js +75 -4
- package/lib/estudio/remotion.js +2 -0
- package/package.json +2 -2
|
@@ -50,6 +50,26 @@ const CENARIOS = {
|
|
|
50
50
|
noite: { parede: '#120f1f', parede2: '#1a1530', chao: '#141218', acento: '#7b5cff', luz: '#c8b8ff', mesa: true, microfones: true, neon: 'ON' },
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
/* Os sets do VOXEL (kit/voxel.jsx, o padrão desde 11/10): o chão de
|
|
54
|
+
ladrilhos (duas cores alternadas), a parede escura, a cor das telas, o
|
|
55
|
+
acento (as luzinhas e o cartão de destaque), a luz principal e o recorte.
|
|
56
|
+
"telas" é o da referência do Joel: roxo, telas azuis e o laranja do Claude. */
|
|
57
|
+
const CENARIOS_VOXEL = {
|
|
58
|
+
telas: { parede: '#07061a', chao: '#4338ca', chao2: '#3b32b8', tela: '#101734', acento: '#ff7a45', luz: '#ffd2b0', recorte: '#8b7bff' },
|
|
59
|
+
neon: { parede: '#06030c', chao: '#6d28d9', chao2: '#5b21b6', tela: '#140b24', acento: '#22d3ee', luz: '#ffe1f5', recorte: '#ff4fd8' },
|
|
60
|
+
oceano: { parede: '#020c12', chao: '#0e7490', chao2: '#0b6079', tela: '#06202b', acento: '#f97316', luz: '#fff1dc', recorte: '#38bdf8' },
|
|
61
|
+
terra: { parede: '#120c08', chao: '#b45309', chao2: '#9a4708', tela: '#1c140e', acento: '#facc15', luz: '#fff4dc', recorte: '#fb923c' },
|
|
62
|
+
};
|
|
63
|
+
// O nome antigo do set (podcast, estúdio…) tem um par no voxel.
|
|
64
|
+
const VOXEL_DO_LISO = { podcast: 'telas', estudio: 'oceano', escritorio: 'terra', noite: 'neon' };
|
|
65
|
+
// O mascote é laranja (o do Claude) a menos que o roteiro diga a cor.
|
|
66
|
+
const CORES_MASCOTE = { claude: '#d97757', gpt: '#10a37f', chatgpt: '#10a37f', gemini: '#4f7cff', primo: '#22b8d8', primocode: '#22b8d8' };
|
|
67
|
+
const ROUPAS_VOXEL = ['#c2452f', '#2f4cdd', '#1f8a5b', '#d08a1e', '#7b5cff', '#e8e2d6'];
|
|
68
|
+
// A pele de bloco é um tom mais fundo: sob a luz quente, o tom claro estourava.
|
|
69
|
+
const PELES_VOXEL = ['#d9a07a', '#c08660', '#a8704c', '#8a5a3c', '#6b4229'];
|
|
70
|
+
// O cabelo de bloco é escuro: o loiro sumia na pele de bloco (11/10).
|
|
71
|
+
const CABELOS_VOXEL = ['#1d1612', '#3b2618', '#2b2b30', '#4a2e1c', '#141016'];
|
|
72
|
+
|
|
53
73
|
/** Um número de 0 a 1 a partir de um texto: a mesma pessoa sai sempre igual. */
|
|
54
74
|
function hashDe(txt) {
|
|
55
75
|
let h = 2166136261;
|
|
@@ -154,6 +174,38 @@ function planosDe(falas, { dois, duracao, aleatorio }) {
|
|
|
154
174
|
return planos;
|
|
155
175
|
}
|
|
156
176
|
|
|
177
|
+
/* OS CARTÕES DA PAREDE DE TELAS. Na referência, cada tela é um chat
|
|
178
|
+
trabalhando ("Leitura do app", "Testes", "Banco de dados"). Aqui os títulos
|
|
179
|
+
saem do ASSUNTO: o que o roteiro mandou (roteiro.paineis), o destaque de cada
|
|
180
|
+
fala e as palavras fortes — nunca texto inventado sem relação com o vídeo. */
|
|
181
|
+
const PALAVRA_FRACA = /^(que|com|para|pra|por|uma|um|uns|umas|não|nao|mas|mais|isso|esse|essa|este|esta|você|voce|eu|ele|ela|nós|nos|meu|minha|seu|sua|tudo|todo|toda|quando|como|onde|muito|muita|então|entao|aqui|agora|ainda|também|tambem|sobre|depois|antes|porque|qual|quem|cada|está|esta|estou|são|sao|foi|ser|ter|tem|vai|vou|faz|fazer|dele|dela|disso|nisso|desse|dessa|pelo|pela|seus|suas|isso)$/i;
|
|
182
|
+
// Corta no fim de uma palavra: "robô que não dá pa" é pior que "robô que não dá".
|
|
183
|
+
function cortarNaPalavra(txt, n) {
|
|
184
|
+
const t = String(txt).trim();
|
|
185
|
+
if (t.length <= n) return t;
|
|
186
|
+
const c = t.slice(0, n + 1).replace(/\s+\S*$/, '');
|
|
187
|
+
return (c || t.slice(0, n)).replace(/[,;:·-]+$/, '');
|
|
188
|
+
}
|
|
189
|
+
function paineisDe(falas, roteiro = {}) {
|
|
190
|
+
if (Array.isArray(roteiro.paineis) && roteiro.paineis.length) {
|
|
191
|
+
return roteiro.paineis.slice(0, 12).map((x) => (typeof x === 'string' ? { titulo: x.slice(0, 18), linha: '' } : { titulo: String(x.titulo || '').slice(0, 18), linha: String(x.linha || '').slice(0, 30) }));
|
|
192
|
+
}
|
|
193
|
+
const out = [];
|
|
194
|
+
const ja = new Set();
|
|
195
|
+
const por = (titulo, linha) => {
|
|
196
|
+
const tt = String(titulo || '').trim();
|
|
197
|
+
if (!tt || ja.has(tt.toLowerCase()) || out.length >= 8) return;
|
|
198
|
+
ja.add(tt.toLowerCase());
|
|
199
|
+
out.push({ titulo: cortarNaPalavra(tt, 18), linha: cortarNaPalavra(String(linha || ''), 30) });
|
|
200
|
+
};
|
|
201
|
+
for (const f of falas) if (f.destaque) por(f.destaque, f.texto);
|
|
202
|
+
for (const f of falas) {
|
|
203
|
+
const fortes = f.texto.split(/\s+/).map((w) => w.replace(/[^\p{L}\d%$-]/gu, '')).filter((w) => w.length >= 5 && !PALAVRA_FRACA.test(w));
|
|
204
|
+
if (fortes[0]) por(fortes[0].replace(/^./, (x) => x.toUpperCase()), f.texto);
|
|
205
|
+
}
|
|
206
|
+
return out.length ? out : [{ titulo: String(roteiro.titulo || 'Agora').slice(0, 18), linha: '' }];
|
|
207
|
+
}
|
|
208
|
+
|
|
157
209
|
/** A partitura inteira: o que o kit/personagem.jsx desenha, quadro a quadro. */
|
|
158
210
|
function partituraDe({ roteiro = {}, largura = 1920, altura = 1080, tempos = [] }) {
|
|
159
211
|
const partes = (roteiro.partes || []).filter((p) => p && typeof p === 'object' && falaDe(p));
|
|
@@ -194,8 +246,27 @@ function partituraDe({ roteiro = {}, largura = 1920, altura = 1080, tempos = []
|
|
|
194
246
|
if (roteiro.acento && /^#[0-9a-f]{6}$/i.test(roteiro.acento)) cenario.acento = roteiro.acento;
|
|
195
247
|
|
|
196
248
|
const planos = planosDe(falas, { dois: elenco.length > 1, duracao, aleatorio });
|
|
249
|
+
|
|
250
|
+
/* O VISUAL. "voxel" (blocos, kit/voxel.jsx) é o padrão: é o 3D da
|
|
251
|
+
referência do Joel (11/10). "liso" é o boneco de esferas de antes, só
|
|
252
|
+
quando o roteiro pede pelo nome. */
|
|
253
|
+
const visual = String(roteiro.visual || '').toLowerCase() === 'liso' ? 'liso' : 'voxel';
|
|
254
|
+
let cenarioFinal = cenario;
|
|
255
|
+
if (visual === 'voxel') {
|
|
256
|
+
const pedido = String(roteiro.cenario || '').toLowerCase();
|
|
257
|
+
const nomeV = CENARIOS_VOXEL[pedido] ? pedido : VOXEL_DO_LISO[pedido] || 'telas';
|
|
258
|
+
cenarioFinal = { nome: nomeV, ...CENARIOS_VOXEL[nomeV] };
|
|
259
|
+
if (roteiro.acento && /^#[0-9a-f]{6}$/i.test(roteiro.acento)) cenarioFinal.acento = roteiro.acento;
|
|
260
|
+
for (const e of elenco) {
|
|
261
|
+
if (e.tipo === 'robo' && !(pedidoDe(e.nome) || {}).cor) e.cor = CORES_MASCOTE[e.nome] || '#d97757';
|
|
262
|
+
if (e.tipo === 'pessoa' && !(pedidoDe(e.nome) || {}).roupa) e.roupa = pegar(ROUPAS_VOXEL, hashDe(e.nome + ':roupa'));
|
|
263
|
+
if (e.tipo === 'pessoa' && !(pedidoDe(e.nome) || {}).pele) e.pele = pegar(PELES_VOXEL, hashDe(e.nome + ':pele'));
|
|
264
|
+
if (e.tipo === 'pessoa' && !(pedidoDe(e.nome) || {}).corCabelo) e.corCabelo = pegar(CABELOS_VOXEL, hashDe(e.nome + ':corCabelo'));
|
|
265
|
+
}
|
|
266
|
+
}
|
|
197
267
|
return {
|
|
198
|
-
versao: 1, fps: FPS, largura, altura, duracao, semente, cenario, elenco, falas, planos,
|
|
268
|
+
versao: 1, fps: FPS, largura, altura, duracao, semente, cenario: cenarioFinal, elenco, falas, planos, visual,
|
|
269
|
+
paineis: paineisDe(falas, roteiro),
|
|
199
270
|
legenda: roteiro.legenda !== false,
|
|
200
271
|
titulo: typeof roteiro.titulo === 'string' ? roteiro.titulo.slice(0, 60) : '',
|
|
201
272
|
filme: { grao: roteiro.grao !== false, vinheta: true },
|
|
@@ -216,7 +287,7 @@ function montarPersonagem({ roteiro, largura = 1920, altura = 1080, tempos = [],
|
|
|
216
287
|
const plano = {
|
|
217
288
|
formato: { largura, altura, fps: FPS },
|
|
218
289
|
fundoGeral: partitura.cenario.parede,
|
|
219
|
-
cenas: [{ duracao: DUR, fundo: partitura.cenario.parede, elementos: [{ tipo: 'kit', peca: 'personagem', partitura, x: 0, y: 0, largura, altura }] }],
|
|
290
|
+
cenas: [{ duracao: DUR, fundo: partitura.cenario.parede, elementos: [{ tipo: 'kit', peca: partitura.visual === 'liso' ? 'personagem' : 'voxel', partitura, x: 0, y: 0, largura, altura }] }],
|
|
220
291
|
audio: {
|
|
221
292
|
...(narracao ? { narracao } : {}),
|
|
222
293
|
...(trilha ? { trilha: { src: trilha, volumes, loop: true } } : {}),
|
|
@@ -225,8 +296,8 @@ function montarPersonagem({ roteiro, largura = 1920, altura = 1080, tempos = [],
|
|
|
225
296
|
};
|
|
226
297
|
return {
|
|
227
298
|
ok: true, plano, partitura,
|
|
228
|
-
resumo: { cenas: 1, segundos: DUR, fps: FPS, cenario: partitura.cenario.nome, elenco: partitura.elenco.map((e) => `${e.rotulo} (${e.tipo})`), planos: partitura.planos.length, falas: partitura.falas.length },
|
|
299
|
+
resumo: { visual: partitura.visual, cenas: 1, segundos: DUR, fps: FPS, cenario: partitura.cenario.nome, elenco: partitura.elenco.map((e) => `${e.rotulo} (${e.tipo})`), planos: partitura.planos.length, falas: partitura.falas.length },
|
|
229
300
|
};
|
|
230
301
|
}
|
|
231
302
|
|
|
232
|
-
module.exports = { montarPersonagem, partituraDe, planosDe, aparencia, destaqueDe, emocaoDe, CENARIOS, EH_ROBO, FPS };
|
|
303
|
+
module.exports = { montarPersonagem, partituraDe, planosDe, paineisDe, aparencia, destaqueDe, emocaoDe, CENARIOS, CENARIOS_VOXEL, EH_ROBO, FPS };
|
package/lib/estudio/remotion.js
CHANGED
|
@@ -78,6 +78,8 @@ function pkgJson(nome) {
|
|
|
78
78
|
'@remotion/three': VERSAO_REMOTION,
|
|
79
79
|
three: '0.186.1',
|
|
80
80
|
'@react-three/fiber': '9.8.1',
|
|
81
|
+
// A animação pronta da biblioteca (kit/animacao.jsx): Lottie, tocado quadro a quadro.
|
|
82
|
+
'lottie-web': '5.13.0',
|
|
81
83
|
},
|
|
82
84
|
}, null, 2) + '\n';
|
|
83
85
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "primocode",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.5.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/entrada.test.js && node test/transparencia.test.js && node test/permissao.test.js && node test/compatibilidade.test.js && node test/skills.test.js && node test/skills-de-fora.test.js && node test/skills-novas.test.js && node test/comandos.test.js && node test/estudio.test.js && node test/voz.test.js && node test/modo.test.js && node test/pasta.test.js && node test/projeto.test.js && node test/nome-projeto.test.js && node test/api-propria.test.js && node test/claude-engine.test.js && node test/codex.test.js && node test/conferir.test.js && node test/catalogo.test.js && node test/desktop.test.js && node test/seta.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/casar.test.js && node test/recado.test.js && node test/releitura.test.js && node test/snapshot.test.js && node test/video.test.js && node test/limpeza.test.js && node test/autonomia.test.js && node test/desfazer.test.js && node test/desfazer-git.test.js && node test/referencia.test.js && node test/parar.test.js && node test/continuar.test.js && node test/pipeline.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/fala.test.js && node test/especialistas.test.js && node test/empurrao.test.js && node test/terminal-novo.test.js && node test/markdown.test.js && node test/coerencia.test.js && node test/contexto.test.js && node test/perigo.test.js && node test/rapidez.test.js && node test/mascotes.test.js && node test/comandos-extra.test.js && node test/offline.test.js && node test/edicao.test.js && node test/composicao.test.js && node test/acervo-site.test.js && node test/impacto.test.js && node test/cinema.test.js && node test/producao.test.js && node test/ende.test.js && node test/capa.test.js && node test/broll.test.js && node test/morfar.test.js && node test/motion.test.js && node test/motion-roteiro.test.js && node test/kit-motion.test.js && node test/gerativo.test.js && node test/gerativo-identidade.test.js && node test/gerativo-moldura.test.js && node test/gerativo-heroi.test.js && node test/gerativo-ambiente.test.js && node test/hibrido.test.js && node test/batida.test.js && node test/estudio-acervo.test.js && node test/estudio-diretor.test.js && node test/estudio-marca.test.js && node test/estudio-novo-projeto.test.js && node test/estudio-plano.test.js && node test/estudio-slides.test.js && node test/estudio-video.test.js && node test/revisor.test.js && node test/assinatura.test.js && node test/biblioteca.test.js && node test/mcp.test.js && node test/personas.test.js && node test/efeitos.test.js && node test/auto.test.js && node test/colar.test.js && node test/orquestra.test.js && node test/shell-limpo.test.js && node test/editar-remotion.test.js && node test/variacao3d.test.js && node test/portao-skill.test.js && node test/clones.test.js && node test/kokoro.test.js && node test/fluido.test.js && node test/zoom.test.js && node test/personagem.test.js && node test/tela.test.js && node test/margem.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/compatibilidade.test.js && node test/skills.test.js && node test/skills-de-fora.test.js && node test/skills-novas.test.js && node test/comandos.test.js && node test/estudio.test.js && node test/voz.test.js && node test/modo.test.js && node test/pasta.test.js && node test/projeto.test.js && node test/nome-projeto.test.js && node test/api-propria.test.js && node test/claude-engine.test.js && node test/codex.test.js && node test/conferir.test.js && node test/catalogo.test.js && node test/desktop.test.js && node test/seta.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/casar.test.js && node test/recado.test.js && node test/releitura.test.js && node test/snapshot.test.js && node test/video.test.js && node test/limpeza.test.js && node test/autonomia.test.js && node test/desfazer.test.js && node test/desfazer-git.test.js && node test/referencia.test.js && node test/parar.test.js && node test/continuar.test.js && node test/pipeline.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/fala.test.js && node test/especialistas.test.js && node test/empurrao.test.js && node test/terminal-novo.test.js && node test/markdown.test.js && node test/coerencia.test.js && node test/contexto.test.js && node test/perigo.test.js && node test/rapidez.test.js && node test/mascotes.test.js && node test/comandos-extra.test.js && node test/offline.test.js && node test/edicao.test.js && node test/composicao.test.js && node test/acervo-site.test.js && node test/impacto.test.js && node test/cinema.test.js && node test/producao.test.js && node test/ende.test.js && node test/capa.test.js && node test/broll.test.js && node test/morfar.test.js && node test/motion.test.js && node test/motion-roteiro.test.js && node test/kit-motion.test.js && node test/gerativo.test.js && node test/gerativo-identidade.test.js && node test/gerativo-moldura.test.js && node test/gerativo-heroi.test.js && node test/gerativo-ambiente.test.js && node test/gerativo-variedade.test.js && node test/hibrido.test.js && node test/batida.test.js && node test/estudio-acervo.test.js && node test/estudio-diretor.test.js && node test/estudio-marca.test.js && node test/estudio-novo-projeto.test.js && node test/estudio-plano.test.js && node test/estudio-slides.test.js && node test/estudio-video.test.js && node test/revisor.test.js && node test/assinatura.test.js && node test/biblioteca.test.js && node test/mcp.test.js && node test/personas.test.js && node test/efeitos.test.js && node test/auto.test.js && node test/colar.test.js && node test/orquestra.test.js && node test/shell-limpo.test.js && node test/editar-remotion.test.js && node test/variacao3d.test.js && node test/portao-skill.test.js && node test/clones.test.js && node test/kokoro.test.js && node test/fluido.test.js && node test/zoom.test.js && node test/personagem.test.js && node test/tela.test.js && node test/margem.test.js && node test/vazamento.test.js && node test/colecao.test.js"
|
|
12
12
|
},
|
|
13
13
|
"engines": {
|
|
14
14
|
"node": ">=18.17.0"
|