primocode 10.14.0 → 10.14.1
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/lib/act.js +8 -2
- package/lib/estudio/cota.js +10 -3
- package/lib/estudio/editor.js +5 -0
- package/lib/estudio/index.js +9 -2
- package/lib/estudio/projetos.js +13 -1
- package/lib/limites.js +100 -0
- package/lib/marca-kit.js +3 -0
- package/lib/planos.js +10 -8
- package/package.json +2 -2
package/lib/act.js
CHANGED
|
@@ -13,6 +13,8 @@
|
|
|
13
13
|
const { c, Spinner, PENSANDO } = require('./ui');
|
|
14
14
|
const fala = require('./fala');
|
|
15
15
|
const especialistas = require('./especialistas');
|
|
16
|
+
const limites = require('./limites');
|
|
17
|
+
let avisouParalelo = false;
|
|
16
18
|
const tools = require('./tools');
|
|
17
19
|
const api = require('./api');
|
|
18
20
|
const cfg = require('./config');
|
|
@@ -1322,8 +1324,12 @@ async function runAct(userPrompt, opts) {
|
|
|
1322
1324
|
const spawns = toolCalls.filter((tc) => tc.name === 'spawn_agent');
|
|
1323
1325
|
const resultadosSpawn = new Map();
|
|
1324
1326
|
if (spawns.length && !PARAR) garantirPasta();
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
+
/* O plano decide quantos subagentes rodam JUNTOS (lib/limites.js; grátis e
|
|
1328
|
+
Primo: um de cada vez, o resto continua em fila). Nunca recusa: só diz o porquê. */
|
|
1329
|
+
const par = spawns.length > 1 ? await limites.paralelo() : null;
|
|
1330
|
+
if (par) { const av = par.aviso(spawns.length); if (av && !avisouParalelo) { avisouParalelo = true; console.log(` ${av}`); } }
|
|
1331
|
+
if (spawns.length > 1 && par.max > 1 && !PARAR) {
|
|
1332
|
+
const juntos = spawns.slice(0, par.max);
|
|
1327
1333
|
fala.paralelo(juntos.length, profundidade);
|
|
1328
1334
|
const ids = juntos.map((tc) => anotar(tc, 'permitida'));
|
|
1329
1335
|
const rs = await Promise.all(juntos.map((tc) =>
|
package/lib/estudio/cota.js
CHANGED
|
@@ -19,7 +19,7 @@ const zlib = require('zlib');
|
|
|
19
19
|
const { spawnSync } = require('child_process');
|
|
20
20
|
|
|
21
21
|
const LOCAL = { ok: true, offline: true, liberado: true, plano: 'local', restam: null, usados: 0,
|
|
22
|
-
recursos: { videosMes: 0, resolucao: 2160, marcaDagua: false } };
|
|
22
|
+
recursos: { videosMes: 0, resolucao: 2160, marcaDagua: false, narracaoPremium: true, clubeCompleto: true, scriptsAE: true, subagentes: 7, kitsMarca: 0, versoesEditor: 0 } };
|
|
23
23
|
|
|
24
24
|
/** Pergunta (acao "checar") ou conta (acao "gastar") no servidor. */
|
|
25
25
|
async function consultar(acao = 'checar', { buscar = fetch, servidor, token, prazo = 6000 } = {}) {
|
|
@@ -33,6 +33,7 @@ async function consultar(acao = 'checar', { buscar = fetch, servidor, token, pra
|
|
|
33
33
|
});
|
|
34
34
|
const j = await r.json();
|
|
35
35
|
if (!r.ok || !j || !j.recursos) return LOCAL;
|
|
36
|
+
require('../limites.js').guardar(j);
|
|
36
37
|
return j;
|
|
37
38
|
} catch { return LOCAL; }
|
|
38
39
|
}
|
|
@@ -137,14 +138,20 @@ function aplicar(arquivo, recursos, { rodar = spawnSync, dim = dimensoes } = {})
|
|
|
137
138
|
async function comCota(render, deps = {}) {
|
|
138
139
|
const c = await (deps.consultar || consultar)('checar');
|
|
139
140
|
if (!c.liberado) return { ok: false, error: mensagemLimite(c), cota: { plano: c.plano, restam: 0, upgrade: c.upgrade } };
|
|
141
|
+
const lim = require('../limites.js');
|
|
142
|
+
lim.guardar(c); lim.pegarAvisos();
|
|
140
143
|
const r = await render();
|
|
144
|
+
const extra = lim.pegarAvisos();
|
|
141
145
|
if (!r || !r.ok) return r;
|
|
142
146
|
const a = c.offline ? { ok: true, mudou: false } : (deps.aplicar || aplicar)(r.video, c.recursos);
|
|
143
147
|
if (!c.offline) await (deps.consultar || consultar)('gastar');
|
|
144
148
|
const restam = c.restam == null ? null : Math.max(0, c.restam - 1);
|
|
145
149
|
return { ...r, plano: { id: c.plano, restam, resolucao: c.recursos.resolucao, marcaDagua: !!(a.mudou && c.recursos.marcaDagua) },
|
|
146
|
-
...(
|
|
147
|
-
|
|
150
|
+
...((() => {
|
|
151
|
+
const a = [...(c.offline ? ['sem rede: modo local, sem cota nem marca d\'água.'] : []),
|
|
152
|
+
...(!c.offline && restam === 0 ? ['Foi o seu último vídeo do mês. Veja os planos com: primocode planos'] : []), ...extra];
|
|
153
|
+
return a.length ? { aviso: a.join(' ') } : {};
|
|
154
|
+
})()) };
|
|
148
155
|
}
|
|
149
156
|
|
|
150
157
|
module.exports = { LOCAL, consultar, mensagemLimite, pngMarca, filtros, aplicar, comCota };
|
package/lib/estudio/editor.js
CHANGED
|
@@ -249,6 +249,11 @@ async function editar(args = {}, { pasta, deps = {} } = {}) {
|
|
|
249
249
|
return { ok: true, versao: v.n, video, versoes: lista(), nota: `voltou para a v${v.n}; a próxima mudança vira a v${ix.versoes.reduce((m, x) => Math.max(m, x.n), 0) + 1}.` };
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
+
// O plano limita as edições guardadas por vídeo (grátis 3). Prévia e a versão original não contam.
|
|
253
|
+
const gastas = indice(pasta).versoes.filter((v) => !v.previa && v.resumo !== 'original').length;
|
|
254
|
+
const lim = await (deps.cabeMais ? deps.cabeMais(gastas) : require('../limites.js').cabeMais('versoesEditor', gastas));
|
|
255
|
+
if (!lim.ok && !args.previa) return { ok: false, error: lim.error + ' Dá para voltar a uma versão (voltar_para) ou ver as prévias.' };
|
|
256
|
+
|
|
252
257
|
const spec = ler(ARQ(pasta));
|
|
253
258
|
const mudancas = Array.isArray(args.mudancas) ? args.mudancas : [];
|
|
254
259
|
if (!mudancas.length && !args.final) return { ok: false, error: 'mudancas está vazio (ou use final:true para renderizar a prévia em qualidade final).' };
|
package/lib/estudio/index.js
CHANGED
|
@@ -508,7 +508,7 @@ async function ferramentaMidia(args) {
|
|
|
508
508
|
if (args.id && !p) return semProjeto(args.id);
|
|
509
509
|
|
|
510
510
|
if (acao === 'projetos') return require('./projetos.js').procurar({ termo: args.termo, categoria: args.categoria, limite: args.limite });
|
|
511
|
-
if (acao === 'projeto') return require('./projetos.js').ver(args.nome || args.id_item || args.termo);
|
|
511
|
+
if (acao === 'projeto') return require('./projetos.js').ver(args.nome || args.id_item || args.termo, { c: await require('../limites.js').situacao() });
|
|
512
512
|
|
|
513
513
|
if (acao === 'fontes') {
|
|
514
514
|
if (args.conferir) return assets.conferirFonte(args.conferir);
|
|
@@ -712,8 +712,10 @@ async function ferramentaMotion(args) {
|
|
|
712
712
|
if (!args.id || !p) return semProjeto(args.id);
|
|
713
713
|
let receita = null;
|
|
714
714
|
if (args.receita) {
|
|
715
|
-
const r = require('./projetos.js').ver(args.receita);
|
|
715
|
+
const r = require('./projetos.js').ver(args.receita, { c: await require('../limites.js').situacao() });
|
|
716
716
|
if (!r.ok) return r;
|
|
717
|
+
// Grátis vê o resumo da receita, não monta a partir dela: diz o porquê em vez de renderizar pela metade.
|
|
718
|
+
if (r.bloqueado) return { ok: false, error: r.aviso, projeto: r.projeto };
|
|
717
719
|
receita = r.projeto;
|
|
718
720
|
}
|
|
719
721
|
return require('./cota.js').comCota(() => renderMotion(args, p, receita));
|
|
@@ -1204,6 +1206,11 @@ function vazamentoNoComeco(lista, palavras, direcao = '') {
|
|
|
1204
1206
|
}
|
|
1205
1207
|
|
|
1206
1208
|
async function narrarComGemini(lista, mp3, { voz, direcao } = {}) {
|
|
1209
|
+
/* A narração premium é do Pro em diante (lib/limites.js). Sem ela a corrente
|
|
1210
|
+
segue para a voz local (Kokoro/Edge) e o aviso explica o porquê. */
|
|
1211
|
+
const lim = require('../limites.js');
|
|
1212
|
+
const prem = await lim.exigir('narracaoPremium');
|
|
1213
|
+
if (!prem.ok) { lim.avisar(prem.error + ' A narração saiu com a voz local.'); return { ok: false, error: prem.error }; }
|
|
1207
1214
|
try {
|
|
1208
1215
|
const cfg = require('../config').loadConfig();
|
|
1209
1216
|
const api = require('../api');
|
package/lib/estudio/projetos.js
CHANGED
|
@@ -47,11 +47,23 @@ function procurar({ termo, categoria, limite = 10 } = {}) {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/** A receita inteira, pelo id (ou, na falta, o melhor palpite do texto). */
|
|
50
|
-
function ver(id) {
|
|
50
|
+
function ver(id, { c } = {}) {
|
|
51
51
|
const q = sem(id).trim();
|
|
52
52
|
if (!q) return { ok: false, error: 'diga o id da receita (acao:"projetos" lista).' };
|
|
53
53
|
const p = todos().find((x) => x.id === q) || procurar({ termo: q, limite: 1 }).projetos.map((x) => todos().find((y) => y.id === x.id))[0];
|
|
54
54
|
if (!p) return { ok: false, error: `não há receita "${id}".`, ids: todos().map((x) => x.id) };
|
|
55
|
+
// O plano decide (lib/limites.js): grátis vê o resumo; sem scriptsAE a receita vem sem os scripts.
|
|
56
|
+
if (c && c.recursos) {
|
|
57
|
+
const lim = require('../limites.js');
|
|
58
|
+
if (!c.recursos.clubeCompleto) {
|
|
59
|
+
const { id: i, titulo, categoria, resumo, indicado, estilo, ficha } = p;
|
|
60
|
+
return { ok: true, bloqueado: true, projeto: { id: i, titulo, categoria, resumo, indicado, estilo, ficha }, aviso: lim.bloqueio('clubeCompleto', c) };
|
|
61
|
+
}
|
|
62
|
+
if (p.scripts_ae && !c.recursos.scriptsAE) {
|
|
63
|
+
const { scripts_ae: _, ...resto } = p;
|
|
64
|
+
return { ok: true, projeto: resto, scripts_ae_bloqueado: lim.bloqueio('scriptsAE', c) };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
55
67
|
// Os scripts do After Effects ficam em disco: a resposta leva o caminho, e o agente lê só o que precisar.
|
|
56
68
|
if (p.scripts_ae) p.scripts_ae = { ...p.scripts_ae, caminho: path.join(__dirname, 'dados', 'projetos-ae', p.id.replace(/^clube-/, '')) };
|
|
57
69
|
return { ok: true, projeto: p };
|
package/lib/limites.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* limites.js — o que o plano libera, aplicado de verdade na CLI.
|
|
3
|
+
*
|
|
4
|
+
* A tabela mora em server/lib/planos.js; o servidor responde o plano da pessoa
|
|
5
|
+
* em POST /api/video/cota (recursos + o catálogo enxuto). Aqui ficam:
|
|
6
|
+
* - situacao(): o plano agora, guardado 5 min na memória do processo;
|
|
7
|
+
* - o MODO LOCAL generoso (sem rede, servidor mudo ou campo que o servidor
|
|
8
|
+
* ainda não manda): nada é barrado. Errar para o lado de quem trabalha;
|
|
9
|
+
* - bloqueio(): a mensagem curta e honesta — o quê, em que plano você está,
|
|
10
|
+
* qual plano libera e o comando para assinar. Nunca barra sem dizer o porquê.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const GENEROSO = { videosMes: 0, resolucao: 2160, marcaDagua: false, narracaoPremium: true, clubeCompleto: true,
|
|
16
|
+
scriptsAE: true, prioridade: 0, subagentes: 7, kitsMarca: 0, versoesEditor: 0 };
|
|
17
|
+
const MAX_PARALELO = 8;
|
|
18
|
+
const VALIDADE = 5 * 60000;
|
|
19
|
+
|
|
20
|
+
let cache = null;
|
|
21
|
+
const avisos = [];
|
|
22
|
+
|
|
23
|
+
/** Completa o que o servidor não mandou com o generoso (campo novo, servidor velho). */
|
|
24
|
+
function completar(c) {
|
|
25
|
+
const r = { ...GENEROSO };
|
|
26
|
+
for (const [k, v] of Object.entries((c && c.recursos) || {})) if (v !== undefined && v !== null) r[k] = v;
|
|
27
|
+
return { ...(c || {}), recursos: r };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function guardar(c) { cache = { em: Date.now(), c: completar(c) }; }
|
|
31
|
+
function esquecer() { cache = null; }
|
|
32
|
+
|
|
33
|
+
/** Nos testes (node test/x.test.js) ninguém bate no servidor de verdade: vale o modo local. */
|
|
34
|
+
const emTeste = () => /\.test\.m?js$/.test(String(process.argv[1] || '')) || process.env.PRIMOCODE_LIMITES === 'local';
|
|
35
|
+
|
|
36
|
+
/** O plano agora: {plano, recursos, planos, offline}. Nunca lança. */
|
|
37
|
+
async function situacao(deps = {}) {
|
|
38
|
+
if (cache && Date.now() - cache.em < VALIDADE) return cache.c;
|
|
39
|
+
if (emTeste() && !deps.consultar) return completar(require('./estudio/cota.js').LOCAL);
|
|
40
|
+
let c;
|
|
41
|
+
try { c = await (deps.consultar || require('./estudio/cota.js').consultar)('checar'); } catch { c = require('./estudio/cota.js').LOCAL; }
|
|
42
|
+
guardar(c);
|
|
43
|
+
return cache.c;
|
|
44
|
+
}
|
|
45
|
+
const recursos = async (deps) => (await situacao(deps)).recursos;
|
|
46
|
+
|
|
47
|
+
const reais = (n) => `R$ ${Number(n).toFixed(2).replace('.', ',')}`;
|
|
48
|
+
|
|
49
|
+
/* Cada recurso: o que o plano ganha ao passar, e o texto de quando bate. */
|
|
50
|
+
const RECURSOS = {
|
|
51
|
+
narracaoPremium: { de: (r) => !!r.narracaoPremium, texto: 'A narração premium (voz do Gemini)', libera: 'a narração premium' },
|
|
52
|
+
clubeCompleto: { de: (r) => !!r.clubeCompleto, texto: 'A receita completa do Clube (etapas e prompt)', libera: 'as receitas completas do Clube' },
|
|
53
|
+
scriptsAE: { de: (r) => !!r.scriptsAE, texto: 'Os scripts de After Effects modelo', libera: 'os scripts de After Effects modelo' },
|
|
54
|
+
kitsMarca: { n: (r) => r.kitsMarca, texto: (r) => `Você já tem ${r.kitsMarca} kit${r.kitsMarca > 1 ? 's' : ''} de marca, o limite do plano`, libera: (r) => (r.kitsMarca ? `${r.kitsMarca} kits de marca` : 'kits de marca sem teto') },
|
|
55
|
+
versoesEditor: { n: (r) => r.versoesEditor, texto: (r) => `Este vídeo já tem ${r.versoesEditor} edições, o limite do plano`, libera: (r) => (r.versoesEditor ? `${r.versoesEditor} edições por vídeo` : 'edições sem teto') },
|
|
56
|
+
subagentes: { n: (r) => r.subagentes + 1, texto: (r) => `Seu plano roda ${r.subagentes + 1} subagente${r.subagentes ? 's juntos' : ' por vez'}`, libera: (r) => (r.subagentes ? `${r.subagentes + 1} subagentes juntos` : 'subagentes em paralelo') },
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
/** O primeiro plano acima do atual que libera `chave` (ou null). */
|
|
60
|
+
function quemLibera(chave, c) {
|
|
61
|
+
const def = RECURSOS[chave], lista = c.planos || [];
|
|
62
|
+
const i = lista.findIndex((p) => p.id === c.plano);
|
|
63
|
+
return lista.slice(i + 1).find((p) => (def.de ? def.de(p.recursos) : (def.n(p.recursos) === 0 || def.n(p.recursos) > def.n(c.recursos)))) || null;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** A mensagem de limite: curta, com o motivo, o degrau que libera e o comando. */
|
|
67
|
+
function bloqueio(chave, c) {
|
|
68
|
+
const def = RECURSOS[chave], r = c.recursos;
|
|
69
|
+
const nome = ((c.planos || []).find((p) => p.id === c.plano) || {}).nome || c.plano;
|
|
70
|
+
const p = quemLibera(chave, c);
|
|
71
|
+
const texto = typeof def.texto === 'function' ? def.texto(r) : `${def.texto} não vêm no plano ${nome}`;
|
|
72
|
+
const libera = typeof def.libera === 'function' ? def.libera(p ? p.recursos : r) : def.libera;
|
|
73
|
+
return `${texto} (plano ${nome}).`
|
|
74
|
+
+ (p ? ` O ${p.nome} (${reais(p.preco)}/mês) libera ${libera}.` : '')
|
|
75
|
+
+ ' Veja e assine: primocode planos (ou primocode.web.app/planos).';
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** Libera o que é só ligado/desligado. {ok:true} ou {ok:false, error}. */
|
|
79
|
+
async function exigir(chave, deps) {
|
|
80
|
+
const c = await situacao(deps);
|
|
81
|
+
return RECURSOS[chave].de(c.recursos) ? { ok: true } : { ok: false, error: bloqueio(chave, c) };
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/** Limite numérico: `usados` já é o que existe; passa se o teto é 0 (sem teto) ou se ainda cabe mais um. */
|
|
85
|
+
async function cabeMais(chave, usados, deps) {
|
|
86
|
+
const c = await situacao(deps), teto = RECURSOS[chave].n(c.recursos);
|
|
87
|
+
return !teto || usados < teto ? { ok: true } : { ok: false, error: bloqueio(chave, c) };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/** Quantos subagentes rodam juntos na mesma rodada (o principal fica de fora). */
|
|
91
|
+
async function paralelo(deps) {
|
|
92
|
+
const c = await situacao(deps);
|
|
93
|
+
return { max: Math.min(MAX_PARALELO, c.recursos.subagentes + 1), aviso: (n) => (n > c.recursos.subagentes + 1 ? bloqueio('subagentes', c) : null) };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Avisos que o resultado da ferramenta leva ao fim da vez (ex.: narração premium trocada pela local). */
|
|
97
|
+
function avisar(msg) { if (msg && !avisos.includes(msg)) avisos.push(msg); }
|
|
98
|
+
function pegarAvisos() { return avisos.splice(0); }
|
|
99
|
+
|
|
100
|
+
module.exports = { GENEROSO, MAX_PARALELO, situacao, recursos, guardar, esquecer, completar, bloqueio, quemLibera, exigir, cabeMais, paralelo, avisar, pegarAvisos, RECURSOS };
|
package/lib/marca-kit.js
CHANGED
|
@@ -280,6 +280,9 @@ async function main(argv, { perguntar, dizer = console.log, pasta = process.cwd(
|
|
|
280
280
|
const aqui = resto.includes('aqui');
|
|
281
281
|
switch (op) {
|
|
282
282
|
case 'criar': {
|
|
283
|
+
// O plano limita quantos kits se guarda (grátis 1): diz o porquê antes de perguntar qualquer coisa.
|
|
284
|
+
const lim = await (deps && deps.cabeMais ? deps.cabeMais(listar().length) : require('./limites.js').cabeMais('kitsMarca', listar().length));
|
|
285
|
+
if (!lim.ok) { dizer(lim.error); return 1; }
|
|
283
286
|
const t = perguntar ? null : perguntarNoTerminal();
|
|
284
287
|
try {
|
|
285
288
|
const r = await criar({ perguntar: perguntar || t.ask, dizer, deps });
|
package/lib/planos.js
CHANGED
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
const https = require('https');
|
|
16
16
|
const http = require('http');
|
|
17
17
|
|
|
18
|
-
const R = (videosMes, resolucao, marcaDagua, narracaoPremium, clubeCompleto, scriptsAE, prioridade, subagentes) =>
|
|
19
|
-
({ videosMes, resolucao, marcaDagua, narracaoPremium, clubeCompleto, scriptsAE, prioridade, subagentes });
|
|
20
|
-
const GRATIS = { id: 'free', nome: 'Grátis', preco: 0, recursos: R(3, 720, true, false, false, false, 0, 0), inclui: [] };
|
|
18
|
+
const R = (videosMes, resolucao, marcaDagua, narracaoPremium, clubeCompleto, scriptsAE, prioridade, subagentes, kitsMarca, versoesEditor) =>
|
|
19
|
+
({ videosMes, resolucao, marcaDagua, narracaoPremium, clubeCompleto, scriptsAE, prioridade, subagentes, kitsMarca, versoesEditor });
|
|
20
|
+
const GRATIS = { id: 'free', nome: 'Grátis', preco: 0, recursos: R(3, 720, true, false, false, false, 0, 0, 1, 3), inclui: [] };
|
|
21
21
|
const RESERVA = [
|
|
22
|
-
{ id: 'primo', nome: 'Primo', preco: 69.9, recursos: R(15, 720, false, false, true, false, 0, 0), inclui: [] },
|
|
23
|
-
{ id: 'pro', nome: 'Primo Pro', preco: 129.9, recursos: R(60, 1080, false, true, true, true, 1, 1), inclui: [] },
|
|
24
|
-
{ id: 'max', nome: 'Primo Max', preco: 299.9, recursos: R(200, 2160, false, true, true, true, 2, 3), inclui: [] },
|
|
25
|
-
{ id: 'studio', nome: 'Primo Studio', preco: 599.9, recursos: R(800, 2160, false, true, true, true, 3, 8), inclui: [] },
|
|
22
|
+
{ id: 'primo', nome: 'Primo', preco: 69.9, recursos: R(15, 720, false, false, true, false, 0, 0, 5, 10), inclui: [] },
|
|
23
|
+
{ id: 'pro', nome: 'Primo Pro', preco: 129.9, recursos: R(60, 1080, false, true, true, true, 1, 1, 20, 30), inclui: [] },
|
|
24
|
+
{ id: 'max', nome: 'Primo Max', preco: 299.9, recursos: R(200, 2160, false, true, true, true, 2, 3, 100, 0), inclui: [] },
|
|
25
|
+
{ id: 'studio', nome: 'Primo Studio', preco: 599.9, recursos: R(800, 2160, false, true, true, true, 3, 8, 0, 0), inclui: [] },
|
|
26
26
|
];
|
|
27
27
|
|
|
28
28
|
function buscarPlanos(servidor, { timeout = 8000 } = {}) {
|
|
@@ -60,7 +60,9 @@ const LINHAS = [
|
|
|
60
60
|
['Projetos do Clube', (r) => (r.clubeCompleto ? 'completos' : 'resumo')],
|
|
61
61
|
['Scripts AE modelo', (r) => (r.scriptsAE ? '✓' : '—')],
|
|
62
62
|
['Prioridade na cadeia', (r) => (r.prioridade ? '●'.repeat(r.prioridade) : '—')],
|
|
63
|
-
['Subagentes', (r) => (r.subagentes ? String(r.subagentes) : '
|
|
63
|
+
['Subagentes juntos', (r) => (r.subagentes ? String(r.subagentes) : 'em fila')],
|
|
64
|
+
['Kits de marca', (r) => (r.kitsMarca == null || r.kitsMarca === 0 ? 'sem teto' : String(r.kitsMarca))],
|
|
65
|
+
['Edições por vídeo', (r) => (r.versoesEditor == null || r.versoesEditor === 0 ? 'sem teto' : String(r.versoesEditor))],
|
|
64
66
|
];
|
|
65
67
|
|
|
66
68
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "primocode",
|
|
3
|
-
"version": "10.14.
|
|
3
|
+
"version": "10.14.1",
|
|
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": {
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"start": "node bin/primocode.js",
|
|
11
11
|
"postinstall": "node lib/preparar.js || true",
|
|
12
12
|
"test:server": "cd server && npm test",
|
|
13
|
-
"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/planos-tela.test.js && 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/conferencia.test.js && node test/cor.test.js && node test/assinatura.test.js && node test/biblioteca.test.js && node test/mcp.test.js && node test/mcp-http.test.js && node test/personas.test.js && node test/efeitos.test.js && node test/auto.test.js && node test/colar.test.js && node test/rolar.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/travado.test.js && node test/leitura.test.js && node test/producao-provedores.test.js && node test/broll-frase.test.js && node test/vazamento.test.js && node test/colecao.test.js && node test/mundo.test.js && node test/mcp-procurar.test.js && node test/selecao.test.js && node test/nome-curto.test.js && node test/agents-md.test.js && node test/outra-pasta.test.js && node test/estudio-sem-id.test.js && node test/estudio-objeto-do-site.test.js && node test/cenarios.test.js && node test/movimentos.test.js && node test/gerativo-so-fala.test.js && node test/estilos.test.js && node test/proporcao.test.js && node test/cena.test.js && node test/sem-narracao.test.js && node test/camadas.test.js && node test/gerativo-referencias.test.js && node test/voicestudio.test.js && node test/effectcraft.test.js && node test/projetos.test.js && node test/maquina.test.js && node test/maquina-som.test.js && node test/maquina-voz.test.js && node test/prova-fresca.test.js && node test/cota-video.test.js && node test/hooks.test.js && node test/modo-plano.test.js && node test/headless.test.js && node test/retomar.test.js && node test/sandbox.test.js && node test/exportar.test.js && node test/editor-video.test.js && node test/marca-kit.test.js && node test/preparar.test.js"
|
|
13
|
+
"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/planos-tela.test.js && 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/conferencia.test.js && node test/cor.test.js && node test/assinatura.test.js && node test/biblioteca.test.js && node test/mcp.test.js && node test/mcp-http.test.js && node test/personas.test.js && node test/efeitos.test.js && node test/auto.test.js && node test/colar.test.js && node test/rolar.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/travado.test.js && node test/leitura.test.js && node test/producao-provedores.test.js && node test/broll-frase.test.js && node test/vazamento.test.js && node test/colecao.test.js && node test/mundo.test.js && node test/mcp-procurar.test.js && node test/selecao.test.js && node test/nome-curto.test.js && node test/agents-md.test.js && node test/outra-pasta.test.js && node test/estudio-sem-id.test.js && node test/estudio-objeto-do-site.test.js && node test/cenarios.test.js && node test/movimentos.test.js && node test/gerativo-so-fala.test.js && node test/estilos.test.js && node test/proporcao.test.js && node test/cena.test.js && node test/sem-narracao.test.js && node test/camadas.test.js && node test/gerativo-referencias.test.js && node test/voicestudio.test.js && node test/effectcraft.test.js && node test/projetos.test.js && node test/maquina.test.js && node test/maquina-som.test.js && node test/maquina-voz.test.js && node test/prova-fresca.test.js && node test/cota-video.test.js && node test/hooks.test.js && node test/modo-plano.test.js && node test/headless.test.js && node test/retomar.test.js && node test/sandbox.test.js && node test/exportar.test.js && node test/editor-video.test.js && node test/marca-kit.test.js && node test/preparar.test.js && node test/landing-planos.test.js && node test/limites.test.js"
|
|
14
14
|
},
|
|
15
15
|
"engines": {
|
|
16
16
|
"node": ">=18.17.0"
|