primocode 10.4.1 → 10.4.2

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 CHANGED
@@ -1,4 +1,4 @@
1
- # PrimoCode v10.4.1
1
+ # PrimoCode v10.4.2
2
2
 
3
3
  Agente de engenharia brasileiro para o terminal, no estilo Claude Code.
4
4
  Cria arquivos de verdade, roda comandos, **controla o navegador e o desktop** —
@@ -9,7 +9,7 @@ OpenRouter, e cada apelido (`top`/`main`/`fast`) é uma **corrente**: se um mode
9
9
  está no limite de pedidos, o próximo atende. Você não vê o erro, e não paga nada.
10
10
 
11
11
  ```
12
- ▐▛███▜▌ Primo Code v10.4.1
12
+ ▐▛███▜▌ Primo Code v10.4.2
13
13
  ▝▜█████▛▘ Bem-vindo de volta, Joel
14
14
  ▘▘ ▝▝ ~/primocode · /dir <pasta> muda
15
15
  ```
package/bin/primocode.js CHANGED
@@ -2761,6 +2761,7 @@ async function main() {
2761
2761
  telaCheia,
2762
2762
  lateral: barraLateral,
2763
2763
  versao: VERSION,
2764
+ logo: ui.logoComMascote(state.config.mascot),
2764
2765
  pasta: () => {
2765
2766
  const dir = state.workDir || process.cwd();
2766
2767
  const ramo = ramoDoGit(dir);
package/lib/entrada.js CHANGED
@@ -449,6 +449,7 @@ class Entrada extends EventEmitter {
449
449
  caixa: (colunas, centro) => montar({ ...this._estado(), colunas, centro, menuAcima: true }),
450
450
  lateral: { titulo: this.titulo, ...(this.op.lateral ? this.op.lateral() : {}) },
451
451
  versao: this.op.versao || '',
452
+ logo: this.op.logo,
452
453
  pasta: this.op.pasta ? this.op.pasta() : '',
453
454
  });
454
455
  }
@@ -856,7 +857,12 @@ class Entrada extends EventEmitter {
856
857
  const W = this._colunasReais || 80;
857
858
  const mainW = W >= tela.LATERAL_MIN ? W - tela.LATERAL_W : W;
858
859
  this.rolagem = 0;
859
- tela.acrescentar(this.conversa, (this.conversa.some((l) => /\S/.test(l)) ? '\n' : '') + pedidoNaTela(visto, mainW - 1) + '\n');
860
+ /* Uma linha em branco antes e outra depois do pedido: cada
861
+ troca (pedido, resposta) é um bloco separado na tela. */
862
+ const temAlgo = this.conversa.some((l) => /\S/.test(l));
863
+ const ultima = this.conversa[this.conversa.length - 1] || '';
864
+ const antes = !temAlgo ? '' : /\S/.test(ultima) ? '\n\n' : '\n';
865
+ tela.acrescentar(this.conversa, antes + pedidoNaTela(visto, mainW - 1) + '\n\n');
860
866
  } else this.escreverCru(pedidoNaTela(visto, process.stdout.columns || 80) + '\n');
861
867
  if (this.historico[this.historico.length - 1] !== texto) this.historico.push(texto);
862
868
  }
package/lib/tela.js CHANGED
@@ -33,6 +33,7 @@ const RESET = '\x1b[0m';
33
33
  const FUNDO_LATERAL = '\x1b[48;5;234m';
34
34
  const LATERAL_W = 42; // a largura da barra da direita
35
35
  const LATERAL_MIN = 110; // abaixo disso a barra some: a conversa precisa do espaço
36
+ const RECUO = 3; // quanto a resposta entra em relação ao painel do pedido
36
37
 
37
38
  /* ── A conversa como texto ───────────────────────────────────────────────
38
39
  O que o programa escreve (console.log, o fluxo da resposta) chega aqui
@@ -153,7 +154,7 @@ function quadro(e) {
153
154
 
154
155
  if (e.home) {
155
156
  const caixa = e.caixa(W, true);
156
- const lg = W >= 50 ? logo() : [c.bold(c.white('primocode'))];
157
+ const lg = W >= 60 && e.logo ? e.logo : W >= 50 ? logo() : [c.bold(c.white('primocode'))];
157
158
  /* O painel fica PARADO no lugar dele: o menu, quando abre, cobre o
158
159
  que está em cima (o logo), em vez de empurrar tudo para cima. */
159
160
  const menu = Math.max(0, caixa.linhas.findIndex((l) => l.includes('┃')) - (/┃/.test(caixa.linhas[0]) ? 0 : 0));
@@ -186,10 +187,18 @@ function quadro(e) {
186
187
  const caixa = { ...caixa0, linhas: caixa0.linhas.map((l) => ' ' + l), cursorColuna: caixa0.cursorColuna + 1 };
187
188
  const altoConversa = Math.max(1, H - caixa.linhas.length);
188
189
 
189
- // A conversa, quebrada na largura da coluna, com 2 colunas de margem.
190
+ /* A conversa, quebrada na largura da coluna. Os PAINÉIS (o pedido que se
191
+ mandou) ficam na borda da caixa; o resto — a resposta, as ações, o
192
+ fecho "▣" — entra RECUADO, como no OpenCode. Sem o recuo, tudo saía
193
+ colado na borda e um bloco não se separava do outro. */
190
194
  const visiveis = [];
191
- for (const l of (e.conversa || [])) visiveis.push(...quebrarComCor(l, mainW - 2));
195
+ for (const l of (e.conversa || [])) {
196
+ const painel = /^(\x1b\[[0-9;]*m)*┃/.test(l);
197
+ const margem = painel ? ' ' : ' '.repeat(RECUO + 1);
198
+ for (const p of quebrarComCor(l, painel ? mainW - 2 : mainW - 2 - RECUO)) visiveis.push(margem + p);
199
+ }
192
200
  while (visiveis.length && !temTexto(visiveis[visiveis.length - 1])) visiveis.pop();
201
+ if (visiveis.length) visiveis.push(''); // um respiro entre a conversa e a caixa
193
202
  const rolagemMax = Math.max(0, visiveis.length - altoConversa);
194
203
  const rolagem = Math.max(0, Math.min(e.rolagem | 0, rolagemMax));
195
204
  const fim = visiveis.length - rolagem;
@@ -197,7 +206,7 @@ function quadro(e) {
197
206
  // A conversa encosta EMBAIXO, logo acima da caixa — como num chat.
198
207
  const conversa = [];
199
208
  for (let i = janela.length; i < altoConversa; i++) conversa.push('');
200
- for (const l of janela) conversa.push(' ' + l);
209
+ for (const l of janela) conversa.push(l);
201
210
  if (rolagem > 0) {
202
211
  conversa[0] = ' ' + c.dim(`↑ ${rolagem} linha${rolagem > 1 ? 's' : ''} abaixo · PgDn ou a roda do mouse para voltar`);
203
212
  }
@@ -217,7 +226,7 @@ function temTexto(l) { return visibleWidth(l) > 0 && /\S/.test(l.replace(/\x1b\[
217
226
  /** A largura que o texto da conversa tem, numa tela de `colunas`. */
218
227
  function larguraDaConversa(colunas) {
219
228
  const W = Math.max(30, colunas || 80);
220
- return (W >= LATERAL_MIN ? W - LATERAL_W : W) - 2;
229
+ return (W >= LATERAL_MIN ? W - LATERAL_W : W) - 2 - RECUO;
221
230
  }
222
231
 
223
- module.exports = { larguraDaConversa, quadro, acrescentar, quebrarComCor, lateral, caber, LATERAL_W, LATERAL_MIN };
232
+ module.exports = { RECUO, larguraDaConversa, quadro, acrescentar, quebrarComCor, lateral, caber, LATERAL_W, LATERAL_MIN };
package/lib/ui.js CHANGED
@@ -358,6 +358,14 @@ function logo() {
358
358
  }
359
359
  const LOGO_W = visibleWidth(logo()[0]);
360
360
 
361
+ /** O logo com o mascote do PrimoCode na frente — o desenho de 3 linhas
362
+ * alinhado às 3 linhas do corpo das letras (a 4ª é só a perna do p). */
363
+ function logoComMascote(style) {
364
+ const m = mascot(style);
365
+ const l = logo();
366
+ return l.map((linha, i) => (m[i] || ' '.repeat(ART_W)) + ' ' + linha);
367
+ }
368
+
361
369
  /** Centraliza uma linha (com cor) em `cols` colunas. */
362
370
  function centro(s, cols) {
363
371
  return ' '.repeat(Math.max(0, Math.floor((cols - visibleWidth(s)) / 2))) + s;
@@ -633,4 +641,4 @@ function friendlyError(raw) {
633
641
 
634
642
 
635
643
  module.exports = {
636
- titulo, c, logo, letreiro, convite, EXEMPLOS, mascot, MASCOTES, resolverMascote, mascoteInfo, galeriaMascotes, reacao, welcomeBox, Spinner, PENSANDO, actionHeader, friendlyError, visibleWidth, stripAnsi, truncate, padRight };
644
+ titulo, c, logo, logoComMascote, letreiro, convite, EXEMPLOS, mascot, MASCOTES, resolverMascote, mascoteInfo, galeriaMascotes, reacao, welcomeBox, Spinner, PENSANDO, actionHeader, friendlyError, visibleWidth, stripAnsi, truncate, padRight };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "primocode",
3
- "version": "10.4.1",
3
+ "version": "10.4.2",
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": {