brito-cli 0.7.3 → 0.7.5

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.
@@ -19,7 +19,7 @@ export const MCP_INSTRUCTIONS = [
19
19
  "- Para localizar código, use graph_search/graph_context antes de ler arquivos; antes de alterar, meça o impacto com graph_callers/graph_impact. O grafo se atualiza sozinho após edições (graph_index só força).",
20
20
  `- O grafo cobre ${INDEXED_EXTENSIONS.join(", ")} (em .svelte/.vue/.astro, o script e as chamadas do template). Imports relativos e por alias (paths/baseUrl do tsconfig, imports do package.json, $lib do SvelteKit) viram arestas. Em Java, Kotlin, Go, Ruby, PHP, C# e Rust os imports são resolvidos pelo pacote/namespace/módulo e o receptor de uma chamada é casado com o tipo pelo nome (sem inferência de tipos). Outras linguagens e arquivos ignorados pelo .gitignore não entram: use busca de texto para eles.`,
21
21
  "- recall/remember: notas duráveis (decisões, convenções, bugs descobertos). Consulte recall ao começar uma tarefa.",
22
- "- skill_load: carregue a skill antes de uma tarefa que ela cobre. No modo \"tudo liberado\", skill_save vira proposta pendente que o usuário aprova com /skills approve.",
22
+ "- skill_load: carregue a skill antes de uma tarefa que ela cobre. No modo \"tudo liberado\", skill_save grava em teste; só o arriscado (comando destrutivo, mudança em skill aprovada) vira proposta pendente para /skills approve.",
23
23
  ].join("\n");
24
24
  /**
25
25
  * O claude CLI adia as tools MCP atrás de uma busca (ToolSearch): o modelo só as usa se pensar em procurá-las, e o grafo
@@ -1,6 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { defineTool } from "./registry.js";
3
- import { bumpUses, deleteSkill, getSkill, listPending, savePending, saveSkill, validate } from "../skills/store.js";
3
+ import { bumpUses, deleteSkill, getSkill, listPending, saveSkill, validate } from "../skills/store.js";
4
+ import { saveAuto } from "../skills/trial.js";
4
5
  import { describeSave } from "../skills/describe.js";
5
6
  import { perms } from "../permissions.js";
6
7
  defineTool({
@@ -18,7 +19,7 @@ defineTool({
18
19
  });
19
20
  defineTool({
20
21
  name: "skill_save",
21
- description: "Cria ou atualiza uma skill: procedimento reutilizável aprendido numa tarefa. Só para padrões GERAIS e repetíveis (como fazer X neste projeto, armadilhas, como verificar) — nunca fatos de uma tarefa única, segredos ou caminhos absolutos. Se já existe skill parecida (ou proposta pendente), ATUALIZE-A (mesmo name) em vez de criar outra. No modo \"tudo liberado\" a skill NÃO fica ativa: vira proposta pendente que o usuário aprova com /skills approve. body em markdown: ## Quando usar, ## Passos, ## Armadilhas, ## Verificação.",
22
+ description: "Cria ou atualiza uma skill: procedimento reutilizável aprendido numa tarefa. Só para padrões GERAIS e repetíveis (como fazer X neste projeto, armadilhas, como verificar) — nunca fatos de uma tarefa única, segredos ou caminhos absolutos. Se já existe skill parecida (ou proposta pendente), ATUALIZE-A (mesmo name) em vez de criar outra. No modo \"tudo liberado\" a skill entra em teste (se for segura) ou vira proposta pendente (comando destrutivo, ou mudança numa skill aprovada pelo usuário). body em markdown: ## Quando usar, ## Passos, ## Armadilhas, ## Verificação.",
22
23
  schema: z.object({
23
24
  name: z.string().describe("kebab-case"),
24
25
  description: z.string().describe("uma frase: QUANDO usar (10–200 chars)"),
@@ -31,12 +32,9 @@ defineTool({
31
32
  describe: (i, ctx) => describeSave(ctx.root, i),
32
33
  async run({ name, description, body, refs, scope, reason }, ctx) {
33
34
  validate({ name, description, body });
34
- // Em bypass nada pede aprovação, então uma skill gravada aqui viraria instrução ativa sem nenhum humano ter visto.
35
- // Mesma política do reflect(): vai para a fila de revisão. Vale para o backend de API e para o servidor MCP.
36
- if (perms.mode === "bypass") {
37
- const target = savePending(ctx.root, { name, description, body, refs, reason }, scope);
38
- return `Skill ${name} proposta (${target}) e aguardando revisão: /skills approve ${name} (modo "tudo liberado": nenhuma skill fica ativa sem revisão).`;
39
- }
35
+ // Em bypass nada pede aprovação: usa a mesma política segura da reflexão autônoma (em teste; o arriscado vai para a fila de revisão).
36
+ if (perms.mode === "bypass")
37
+ return saveAuto(ctx.root, { name, description, body, refs, reason }).msg;
40
38
  const r = saveSkill(ctx.root, { name, description, body, refs }, scope);
41
39
  return r.created ? `Skill ${name} criada (${r.scope}, v1).` : `Skill ${name} atualizada (${r.scope}, v${r.version}); a anterior ficou em history/.`;
42
40
  },
package/dist/ui/dock.js CHANGED
@@ -43,6 +43,8 @@ export class Dock {
43
43
  started = false;
44
44
  onData = (d) => this.feed(d);
45
45
  resizeTimer;
46
+ reflowing = false;
47
+ reflowAgain = false;
46
48
  onResize = () => {
47
49
  this.rows = process.stdout.rows || 24;
48
50
  this.cols = process.stdout.columns || 80;
@@ -58,9 +60,30 @@ export class Dock {
58
60
  async reflow() {
59
61
  if (!this.started)
60
62
  return;
61
- const [r] = await this.getCursor();
63
+ if (this.reflowing) {
64
+ this.reflowAgain = true;
65
+ return;
66
+ } // um DSR por vez; refaz ao terminar
67
+ this.reflowing = true;
68
+ try {
69
+ do {
70
+ this.reflowAgain = false;
71
+ await this.reflowOnce();
72
+ } while (this.reflowAgain && this.started);
73
+ }
74
+ finally {
75
+ this.reflowing = false;
76
+ }
77
+ }
78
+ async reflowOnce() {
79
+ const pos = await this.getCursor(true);
62
80
  if (!this.started)
63
81
  return;
82
+ if (!pos) {
83
+ process.stdout.write(this.paintSeq(false));
84
+ return;
85
+ } // sem resposta do terminal: não chuta posição
86
+ const [r] = pos;
64
87
  const wrap = (w) => Math.max(1, Math.ceil(w / this.cols));
65
88
  const above = this.lastWidths.slice(0, this.lastCursor.line).reduce((n, w) => n + wrap(w), 0)
66
89
  + Math.floor(Math.max(0, this.lastCursor.col - 1) / this.cols);
@@ -119,9 +142,9 @@ export class Dock {
119
142
  }
120
143
  catch { /* já fechado */ }
121
144
  }
122
- getCursor() {
145
+ getCursor(strict = false) {
123
146
  return new Promise((resolve) => {
124
- const t = setTimeout(() => { this.dsr = undefined; resolve([this.rows, 1]); }, 400);
147
+ const t = setTimeout(() => { this.dsr = undefined; resolve(strict ? null : [this.rows, 1]); }, 400);
125
148
  this.dsr = (r, col) => { clearTimeout(t); this.dsr = undefined; resolve([r, col]); };
126
149
  process.stdout.write("\x1b[6n");
127
150
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brito-cli",
3
- "version": "0.7.3",
3
+ "version": "0.7.5",
4
4
  "description": "Coding-agent CLI with a code knowledge graph, memory and reviewable skills / CLI de agente de código com grafo de conhecimento, memória e skills revisáveis",
5
5
  "type": "module",
6
6
  "bin": {