dd-harness 0.37.0 → 0.38.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/dist/index.js CHANGED
@@ -44,94 +44,94 @@ import { REGRA_DE_COMMITS } from "./regras-de-commit.js";
44
44
  * em repositorio alheio tem que envelhecer bem, e cada dependencia e uma chance de nao
45
45
  * envelhecer.
46
46
  */
47
- const AJUDA = `dd-harness — a política e o Brain do projeto, no serviço
48
-
49
- dd-harness diagnostico [--mcp] confere projeto, contexto e conexão MCP
50
- dd-harness atualizar [--aplicar] diz o que neste projeto ficou para trás do
51
- harness atual (CLI, hooks, bloco do
52
- CLAUDE.md/AGENTS.md) e, com --aplicar,
53
- atualiza o que é seguro. O que está FORA
54
- do bloco é do projeto e nunca é tocado
55
- dd-harness integrar --host todos instala MCP/regras/hooks em projeto existente
56
- dd-harness sessao --host <host> hook de boot (stdin JSON)
57
- dd-harness guarda --host <host> hook antes de ferramentas (stdin JSON)
58
- dd-harness start [--host <host>] numa pasta vazia: conduz tudo (login,
59
- espaço, projeto, config) numa tacada.
60
- Instala os TRÊS hosts por padrão (claude,
61
- codex, antigravity) — cada um escreve no
62
- arquivo que a sua ferramenta lê, sem
63
- conflito. Use --host claude,codex para
64
- limitar
65
- dd-harness login --token <token> [--api <url>]
66
- guarda a credencial desta máquina
67
- dd-harness projeto <slug> --nome "<nome>" [--tenant <t>] [--api <url>]
68
- cria o projeto no serviço (antes do init)
69
- dd-harness init --tenant <t> --projeto <p> [--api <url>]
70
- escreve .dd-harness.json; depois rode integrar
71
- dd-harness pasta <slug> --definicao "o que entra e o que não entra"
72
- cria a pasta que o gravar exige
73
- dd-harness gravar <arquivo.md> registra uma memória a partir de um markdown
74
- dd-harness editar <arquivo.md> corrige o que já está gravado
75
- dd-harness arquivar <pasta>/<slug> --motivo <obsoleta|incorreta|fora_dos_filtros>
76
- [--substituida-por <pasta>/<slug>]
77
- tira de circulação sem apagar
78
- dd-harness promover <pasta>/<slug>
79
- torna a memória global: vale para TODO
80
- projeto do espaço, inclusive os futuros
81
- dd-harness despromover <pasta>/<slug>
82
- traz de volta ao alcance dos vínculos
83
- dd-harness apagar <pasta>/<slug> [--confirmar <espaço>]
84
- apaga de vez, em cascata — sem desfazer.
85
- Para tirar de circulação guardando o
86
- conteúdo, use "arquivar"
87
- dd-harness buscar "<pergunta>" acha memória por relevância, não por arquivo
88
- dd-harness ler <pasta>/<slug> imprime a memória inteira, no formato de gravar
89
- dd-harness reancorar <pasta>/<slug> --de "<alvo>" --para "<alvo>"
90
- troca o alvo de uma âncora que mudou de lugar
91
- dd-harness check [--commit <sha>] mede as âncoras e reporta a deriva
92
- dd-harness status só lê: o tamanho do Brain e o que espera julgamento
93
- dd-harness politica [--hook] imprime a política do serviço
94
- saída 0 = veio; 3 = projeto sem política;
95
- 1 = não consegui buscar
96
- --hook: fala o protocolo do SessionStart do
97
- Claude Code, para pôr a política no contexto
98
- dd-harness cinto o interceptador pré-voo: lê a edição no stdin
99
- e devolve a memória que fala daquele trecho.
100
- Quem chama é o hook PreToolUse, não você
101
- dd-harness skills as skills deste projeto e quando cada uma serve
102
- dd-harness skill <nome> o procedimento de uma delas (o mesmo que o
103
- agente recebe ao invocá-la)
104
- dd-harness roadmap as fases abertas: a atual inteira, as próximas
105
- por título (opcional — projeto sem fase não tem)
106
- dd-harness changelog [--versao <v>]
107
- o que já foi concluído, agrupado por versão
108
- dd-harness fase criar --titulo "<t>" [--conteudo <arquivo.md>] [--versao <v>]
109
- [--status ideia|aberta|concluida] [--slug <s>]
110
- dd-harness fase editar <slug> [--titulo "<t>"] [--conteudo <arquivo.md>]
111
- [--versao <v> | --sem-versao] [--status <s>] [--ordem <n>]
112
- concluir = --status concluida: a fase sai do
113
- roadmap e entra no changelog, nada migra
114
- dd-harness --help
115
- dd-harness --version qual binário está instalado nesta máquina
116
-
117
- Política e briefing chegam do serviço. O disco guarda configuração, ponteiros
118
- para skills e estado descartável em ~/.dd-harness. Hosts: claude, codex,
119
- antigravity, lista separada por vírgulas ou todos.
47
+ const AJUDA = `dd-harness — a política e o Brain do projeto, no serviço
48
+
49
+ dd-harness diagnostico [--mcp] confere projeto, contexto e conexão MCP
50
+ dd-harness atualizar [--aplicar] diz o que neste projeto ficou para trás do
51
+ harness atual (CLI, hooks, bloco do
52
+ CLAUDE.md/AGENTS.md) e, com --aplicar,
53
+ atualiza o que é seguro. O que está FORA
54
+ do bloco é do projeto e nunca é tocado
55
+ dd-harness integrar --host todos instala MCP/regras/hooks em projeto existente
56
+ dd-harness sessao --host <host> hook de boot (stdin JSON)
57
+ dd-harness guarda --host <host> hook antes de ferramentas (stdin JSON)
58
+ dd-harness start [--host <host>] numa pasta vazia: conduz tudo (login,
59
+ espaço, projeto, config) numa tacada.
60
+ Instala os TRÊS hosts por padrão (claude,
61
+ codex, antigravity) — cada um escreve no
62
+ arquivo que a sua ferramenta lê, sem
63
+ conflito. Use --host claude,codex para
64
+ limitar
65
+ dd-harness login --token <token> [--api <url>]
66
+ guarda a credencial desta máquina
67
+ dd-harness projeto <slug> --nome "<nome>" [--tenant <t>] [--api <url>]
68
+ cria o projeto no serviço (antes do init)
69
+ dd-harness init --tenant <t> --projeto <p> [--api <url>]
70
+ escreve .dd-harness.json; depois rode integrar
71
+ dd-harness pasta <slug> --definicao "o que entra e o que não entra"
72
+ cria a pasta que o gravar exige
73
+ dd-harness gravar <arquivo.md> registra uma memória a partir de um markdown
74
+ dd-harness editar <arquivo.md> corrige o que já está gravado
75
+ dd-harness arquivar <pasta>/<slug> --motivo <obsoleta|incorreta|fora_dos_filtros>
76
+ [--substituida-por <pasta>/<slug>]
77
+ tira de circulação sem apagar
78
+ dd-harness promover <pasta>/<slug>
79
+ torna a memória global: vale para TODO
80
+ projeto do espaço, inclusive os futuros
81
+ dd-harness despromover <pasta>/<slug>
82
+ traz de volta ao alcance dos vínculos
83
+ dd-harness apagar <pasta>/<slug> [--confirmar <espaço>]
84
+ apaga de vez, em cascata — sem desfazer.
85
+ Para tirar de circulação guardando o
86
+ conteúdo, use "arquivar"
87
+ dd-harness buscar "<pergunta>" acha memória por relevância, não por arquivo
88
+ dd-harness ler <pasta>/<slug> imprime a memória inteira, no formato de gravar
89
+ dd-harness reancorar <pasta>/<slug> --de "<alvo>" --para "<alvo>"
90
+ troca o alvo de uma âncora que mudou de lugar
91
+ dd-harness check [--commit <sha>] mede as âncoras e reporta a deriva
92
+ dd-harness status só lê: o tamanho do Brain e o que espera julgamento
93
+ dd-harness politica [--hook] imprime a política do serviço
94
+ saída 0 = veio; 3 = projeto sem política;
95
+ 1 = não consegui buscar
96
+ --hook: fala o protocolo do SessionStart do
97
+ Claude Code, para pôr a política no contexto
98
+ dd-harness cinto o interceptador pré-voo: lê a edição no stdin
99
+ e devolve a memória que fala daquele trecho.
100
+ Quem chama é o hook PreToolUse, não você
101
+ dd-harness skills as skills deste projeto e quando cada uma serve
102
+ dd-harness skill <nome> o procedimento de uma delas (o mesmo que o
103
+ agente recebe ao invocá-la)
104
+ dd-harness roadmap as fases abertas: a atual inteira, as próximas
105
+ por título (opcional — projeto sem fase não tem)
106
+ dd-harness changelog [--versao <v>]
107
+ o que já foi concluído, agrupado por versão
108
+ dd-harness fase criar --titulo "<t>" [--conteudo <arquivo.md>] [--versao <v>]
109
+ [--status ideia|aberta|concluida] [--slug <s>]
110
+ dd-harness fase editar <slug> [--titulo "<t>"] [--conteudo <arquivo.md>]
111
+ [--versao <v> | --sem-versao] [--status <s>] [--ordem <n>]
112
+ concluir = --status concluida: a fase sai do
113
+ roadmap e entra no changelog, nada migra
114
+ dd-harness --help
115
+ dd-harness --version qual binário está instalado nesta máquina
116
+
117
+ Política e briefing chegam do serviço. O disco guarda configuração, ponteiros
118
+ para skills e estado descartável em ~/.dd-harness. Hosts: claude, codex,
119
+ antigravity, lista separada por vírgulas ou todos.
120
120
  `;
121
121
  /**
122
122
  * Os ganchos sao IMPRESSOS, nunca instalados. `.git/hooks` nao e versionado e nao e
123
123
  * nosso: escrever la dentro sem a pessoa pedir e o mesmo tipo de invasao que
124
124
  * sobrescrever o CLAUDE.md dela. Quem cola, decide.
125
125
  */
126
- const GANCHOS = `
127
- Opcional — o gancho que devolve a memória ao code review:
128
-
129
- .git/hooks/post-commit (avisa quais memórias falam do que você mudou)
130
- #!/bin/sh
131
- dd-harness check --commit "$(git rev-parse HEAD)" || true
132
-
133
- Termina em sucesso mesmo com deriva: avisa, não bloqueia.
134
-
126
+ const GANCHOS = `
127
+ Opcional — o gancho que devolve a memória ao code review:
128
+
129
+ .git/hooks/post-commit (avisa quais memórias falam do que você mudou)
130
+ #!/bin/sh
131
+ dd-harness check --commit "$(git rev-parse HEAD)" || true
132
+
133
+ Termina em sucesso mesmo com deriva: avisa, não bloqueia.
134
+
135
135
  Instale os hooks de sessão e guarda com \`dd-harness integrar --host <host>\`.`;
136
136
  function argumento(argv, nome) {
137
137
  const i = argv.indexOf(`--${nome}`);
@@ -166,7 +166,7 @@ async function comandoSkill(argv) {
166
166
  throw new Error("uso: dd-harness skill <nome>");
167
167
  }
168
168
  const s = await leSkill(process.cwd(), slug);
169
- console.log(`# ${s.slug}
169
+ console.log(`# ${s.slug}
170
170
  `);
171
171
  console.log(s.descricao);
172
172
  console.log("");
@@ -260,13 +260,17 @@ function instalaMcp() {
260
260
  // pista nenhuma para diagnosticar. O DEP0190 que isto dispara e suprimido no topo
261
261
  // do arquivo (`process.removeAllListeners("warning")`).
262
262
  //
263
- // `@latest` EXPLICITO, e nao `dd-harness-mcp` pelado: sem a tag, o npx serve a copia
264
- // que ja estiver no cache dele e nem consulta o registro. Medido na rodada 006 — a
265
- // cobaia rodou uma sessao inteira contra um MCP defasado sem nada denunciar. O
266
- // `.mcp.json` continua declarando o pacote SEM versao, de proposito: o que precisa
267
- // estar fresco e o cache, e fixar versao no arquivo obrigaria a reescrever config em
268
- // todo repositorio a cada publicacao.
269
- const p = spawn("npx", ["-y", "dd-harness-mcp@latest", "--help"], {
263
+ // INSTALA, nao aquece cache do npx: o `.mcp.json` passou a declarar `node <caminho>`
264
+ // em vez de `npx`, porque o host lanca o servidor sem shell e ali nao ha forma de
265
+ // `npx` que suba no Windows (ENOENT pelado, EINVAL com .cmd). Com o pacote instalado
266
+ // ha o que apontar, e `integrar` resolve o caminho a partir dele.
267
+ //
268
+ // `@latest` EXPLICITO continua valendo, por outro motivo: sem a tag o npm pode dar por
269
+ // satisfeita a copia que ja esta instalada. Medido na rodada 006 — a cobaia rodou uma
270
+ // sessao inteira contra um MCP defasado sem nada denunciar. A contrapartida e que a
271
+ // versao agora fica congelada no caminho declarado: atualizar exige `integrar` de
272
+ // novo, que e o que o menu de edicao do `start` faz em seguida.
273
+ const p = spawn("npm", ["install", "-g", "dd-harness-mcp@latest"], {
270
274
  shell: process.platform === "win32",
271
275
  stdio: "inherit",
272
276
  });
@@ -347,6 +351,59 @@ function tentaAbrirNavegador(url) {
347
351
  function mascara(token) {
348
352
  return token.length <= 16 ? "***" : `${token.slice(0, 12)}...${token.slice(-4)}`;
349
353
  }
354
+ /**
355
+ * `dd-harness start` num repositorio que ja tem config: mostra o estado e edita o que for
356
+ * escolhido. Nada e reescrito sem a pessoa pedir — "Sair" e uma opcao, e o menu nao tem
357
+ * acao destrutiva.
358
+ */
359
+ async function editaProjeto(hosts) {
360
+ const c = await leConfigDoRepo(process.cwd());
361
+ const token = await leToken(c.api);
362
+ console.log(`Projeto: ${c.tenant}/${c.projeto}`);
363
+ console.log(`Credencial: ${token ? mascara(token) : "ausente"}`);
364
+ console.log(`API: ${c.api}\n`);
365
+ const acao = await escolha("O que você quer fazer?", [
366
+ { rotulo: "Atualizar CLI e MCP", valor: "atualizar" },
367
+ { rotulo: token ? "Trocar a credencial" : "Colar uma credencial", valor: "token" },
368
+ { rotulo: "Reinstalar integrações dos hosts", valor: "integrar" },
369
+ { rotulo: "Sair", valor: "sair" },
370
+ ]);
371
+ if (acao === "sair")
372
+ return;
373
+ if (acao === "token") {
374
+ const url = `${c.api}/tokens`;
375
+ console.log(`\nCrie um token pessoal em ${url} — abrindo no navegador...`);
376
+ tentaAbrirNavegador(url);
377
+ const novo = await pergunta("Cole o token aqui: ");
378
+ if (!novo)
379
+ throw new Error("nenhum token colado — nada foi alterado.");
380
+ await guardaToken(c.api, novo);
381
+ console.log("Credencial guardada.");
382
+ return;
383
+ }
384
+ if (acao === "atualizar") {
385
+ const desatualizado = await versaoDesatualizada();
386
+ if (desatualizado) {
387
+ console.log(`CLI: ${desatualizado.atual} → ${desatualizado.ultima}...`);
388
+ const ok = await atualizaCli(desatualizado.ultima);
389
+ console.log(ok
390
+ ? `CLI atualizado. Este processo segue na ${desatualizado.atual}; do próximo comando em diante, a nova.`
391
+ : "Não consegui atualizar o CLI — o npm explicou o motivo acima.");
392
+ }
393
+ else {
394
+ console.log("CLI já está na versão mais recente.");
395
+ }
396
+ console.log("\nMCP:");
397
+ const mcp = await instalaMcp();
398
+ console.log(mcp.ok ? "MCP atualizado." : `AVISO: não consegui instalar o MCP (${mcp.erro ?? "sem detalhe"}).`);
399
+ }
400
+ // Tanto "integrar" quanto "atualizar" terminam aqui: depois de instalar uma versao nova
401
+ // do MCP, o caminho declarado nos arquivos dos hosts aponta para a instalacao antiga ate
402
+ // alguem regravar. Atualizar sem isto deixaria o projeto rodando o servidor velho.
403
+ for (const aviso of await instalaHosts(process.cwd(), hosts))
404
+ console.log("AVISO: " + aviso);
405
+ console.log("Integrações regravadas: " + hosts.join(", "));
406
+ }
350
407
  /**
351
408
  * `dd-harness start` — o wizard para pasta vazia.
352
409
  *
@@ -367,16 +424,13 @@ async function comandoStart(argv) {
367
424
  // aceitando a lista explicita para quem quiser menos.
368
425
  const hosts = selecionaHosts(argumento(argv, "host") ?? "todos");
369
426
  const caminhoConfig = join(process.cwd(), CAMINHO_CONFIG);
370
- try {
371
- await access(caminhoConfig);
372
- throw new Error(`este repositório já tem ${CAMINHO_CONFIG} — start é só para pasta vazia. ` +
373
- "Use `dd-harness init` para ajustar um projeto já existente.");
374
- }
375
- catch (erro) {
376
- if (erro instanceof Error && erro.message.includes("já tem"))
377
- throw erro;
378
- // ENOENT: exatamente o caso esperado, segue.
379
- }
427
+ // Com config no repositorio, `start` EDITA em vez de recusar. Antes ele mandava usar
428
+ // `init`, o que exigia saber de cor qual dos quatro comandos serve para que — e o
429
+ // `start` existe justamente para nao exigir isso. O que se edita e so o que e editavel:
430
+ // um repositorio E um projeto, entao tenant/projeto nao entram no menu.
431
+ const jaConfigurado = await access(caminhoConfig).then(() => true, () => false);
432
+ if (jaConfigurado)
433
+ return editaProjeto(hosts);
380
434
  console.log("Iniciando o dd-harness nesta pasta.\n");
381
435
  // 0. Versao. `start` e o comando de bootstrap: rodar velho aqui significa perder
382
436
  // correcoes deste proprio wizard sem nenhum aviso (foi o que aconteceu com a
@@ -398,9 +452,14 @@ async function comandoStart(argv) {
398
452
  // nao tinha como perceber — o wizard so falhava depois, ao listar espacos.
399
453
  let token = await leToken(API_PADRAO);
400
454
  if (token) {
401
- console.log(`Credencial: ${mascara(token)} (${API_PADRAO})`);
402
- const troca = await pergunta("Usar esta credencial? [S/n]: ");
403
- if (/^n/i.test(troca))
455
+ // Escolha nomeada em vez de `[S/n]`: ali o Enter aceitava a credencial salva sem que
456
+ // ninguem lesse qual era, e um token de outra conta so aparecia como erro varios
457
+ // passos adiante. Aqui as duas saidas estao escritas, e o valor truncado fica a vista.
458
+ const usar = await escolha(`Credencial em ${API_PADRAO}:`, [
459
+ { rotulo: `Usar esta credencial (${mascara(token)})`, valor: true },
460
+ { rotulo: "Colar outro token", valor: false },
461
+ ]);
462
+ if (!usar)
404
463
  token = null;
405
464
  }
406
465
  if (!token) {
@@ -479,13 +538,16 @@ async function comandoStart(argv) {
479
538
  // 4. Config do repositorio — o unico arquivo que `init` tambem escreveria.
480
539
  const r = await init(process.cwd(), { tenant, projeto: resultadoProjeto.projeto, api: API_PADRAO });
481
540
  console.log(r.config === "criada" ? `criado ${CAMINHO_CONFIG}` : `mantido ${CAMINHO_CONFIG}`);
541
+ // O MCP vem ANTES das integracoes: `instalaHosts` declara `node <caminho do pacote>`, e
542
+ // o caminho so existe depois da instalacao. Na ordem inversa a primeira execucao caia no
543
+ // fallback `npx`, que nao sobe no Windows — e so um segundo `integrar` consertava.
544
+ const instalacao = await instalaMcp();
545
+ if (!instalacao.ok)
546
+ console.log('AVISO: MCP não pré-instalado; execute diagnostico antes de usar.');
482
547
  const avisos = await instalaHosts(process.cwd(), hosts);
483
548
  console.log('Integrações instaladas: ' + hosts.join(', '));
484
549
  for (const aviso of avisos)
485
550
  console.log('AVISO: ' + aviso);
486
- const instalacao = await instalaMcp();
487
- if (!instalacao.ok)
488
- console.log('AVISO: MCP não pré-instalado; execute diagnostico antes de usar.');
489
551
  // 6.5. Os ponteiros das skills do projeto.
490
552
  //
491
553
  // O Claude Code descobre skill lendo `.claude/skills/*/SKILL.md` na ABERTURA da sessao,
@@ -653,7 +715,7 @@ async function comandoApagar(argv) {
653
715
  if (!r.apagou) {
654
716
  console.log(r.detalhe);
655
717
  if (r.confirmacaoEsperada) {
656
- console.log(`
718
+ console.log(`
657
719
  dd-harness apagar ${endereco} --confirmar ${r.confirmacaoEsperada}`);
658
720
  }
659
721
  // Sem exit diferente de zero: recusar por falta de confirmacao nao e falha, e o
package/dist/init.js CHANGED
@@ -8,13 +8,13 @@ import { CAMINHO_CONFIG } from "./config.js";
8
8
  * onde falha silenciosa nasce — entrada errada nao da erro, a ferramenta so nao aparece.
9
9
  * Quem cola sabe o que colou.
10
10
  */
11
- export const SUGESTAO_MCP = `{
12
- "mcpServers": {
13
- "dd-harness": {
14
- "command": "npx",
15
- "args": ["-y", "dd-harness-mcp"]
16
- }
17
- }
11
+ export const SUGESTAO_MCP = `{
12
+ "mcpServers": {
13
+ "dd-harness": {
14
+ "command": "npx",
15
+ "args": ["-y", "dd-harness-mcp"]
16
+ }
17
+ }
18
18
  }`;
19
19
  /**
20
20
  * Os dois hooks do dd-harness, pelas duas razoes que nenhuma instrucao em markdown
@@ -33,31 +33,31 @@ export const SUGESTAO_MCP = `{
33
33
  *
34
34
  * Sugerido e nao escrito, pelo mesmo motivo do `.mcp.json`.
35
35
  */
36
- export const SUGESTAO_HOOK = `{
37
- "hooks": {
38
- "SessionStart": [
39
- {
40
- "hooks": [
41
- {
42
- "type": "command",
43
- "command": "dd-harness politica --hook",
44
- "statusMessage": "Carregando a política do dd-harness..."
45
- }
46
- ]
47
- }
48
- ],
49
- "PreToolUse": [
50
- {
51
- "matcher": "Edit|Write|MultiEdit",
52
- "hooks": [
53
- {
54
- "type": "command",
55
- "command": "dd-harness cinto"
56
- }
57
- ]
58
- }
59
- ]
60
- }
36
+ export const SUGESTAO_HOOK = `{
37
+ "hooks": {
38
+ "SessionStart": [
39
+ {
40
+ "hooks": [
41
+ {
42
+ "type": "command",
43
+ "command": "dd-harness politica --hook",
44
+ "statusMessage": "Carregando a política do dd-harness..."
45
+ }
46
+ ]
47
+ }
48
+ ],
49
+ "PreToolUse": [
50
+ {
51
+ "matcher": "Edit|Write|MultiEdit",
52
+ "hooks": [
53
+ {
54
+ "type": "command",
55
+ "command": "dd-harness cinto"
56
+ }
57
+ ]
58
+ }
59
+ ]
60
+ }
61
61
  }`;
62
62
  /**
63
63
  * O que escrever num `AGENTS.md`, para agente que NAO e o Claude Code.
@@ -71,19 +71,19 @@ export const SUGESTAO_HOOK = `{
71
71
  * simplesmente nunca perguntar pela politica. Dai esta linha, que e curta de proposito —
72
72
  * ela manda buscar a regra, nao repete a regra.
73
73
  */
74
- export const SUGESTAO_AGENTS = `# AGENTS.md
75
-
76
- Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
77
-
78
- **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
79
- \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
80
- de ler código, responder ou planejar.
81
-
82
- - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
83
- avise o usuário e **não modifique nada** até ele resolver.
84
- - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
85
-
86
- O Claude Code carrega a política sozinho, por hook. Nas outras ferramentas, a
74
+ export const SUGESTAO_AGENTS = `# AGENTS.md
75
+
76
+ Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
77
+
78
+ **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
79
+ \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
80
+ de ler código, responder ou planejar.
81
+
82
+ - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
83
+ avise o usuário e **não modifique nada** até ele resolver.
84
+ - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
85
+
86
+ O Claude Code carrega a política sozinho, por hook. Nas outras ferramentas, a
87
87
  chamada acima é o que substitui esse hook.`;
88
88
  async function declaraMcp(raiz) {
89
89
  try {
@@ -28,14 +28,9 @@ function secaoDeFiltros(m) {
28
28
  ].join("\n");
29
29
  }
30
30
  export function arquivoDaMemoria(m) {
31
- // `titulo` vai no frontmatter porque `gravar` e `editar` o exigem la: sem ele o arquivo
32
- // materializado nao volta pelo `editar`, e o ciclo "sincroniza, corrige, manda de volta"
33
- // — que e como o agente cura memoria — para com "frontmatter sem `titulo`". O titulo
34
- // tambem aparece no indice, mas indice nao e o que se edita.
35
31
  const frontmatter = [
36
32
  "---",
37
33
  `name: ${m.slug}`,
38
- `titulo: ${m.titulo.replace(/\n/g, " ")}`,
39
34
  `description: ${m.resumo.replace(/\n/g, " ")}`,
40
35
  `pasta: ${m.pasta}`,
41
36
  ...(m.revisar_ate ? [`revisar-ate: ${m.revisar_ate.slice(0, 10)}`] : []),
@@ -10,81 +10,81 @@
10
10
  */
11
11
  export const MOLDES_HISTORICOS = [
12
12
  // ca1e529
13
- `## Protocolo do dd-harness
14
-
15
- Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
16
-
17
- **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
18
- \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
19
- de ler código, responder ou planejar.
20
-
21
- - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
22
- avise o usuário e **não modifique nada** até ele resolver.
23
- - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
24
-
25
- Leia também o briefing com a mesma ferramenta (tipo briefing). Os dois são obrigatórios.
26
-
27
- Depois, \`ler_roadmap\`: se houver uma fase **Agora**, é dela que saem os passos
28
- desta sessão. Lista vazia significa que este projeto não usa roadmap, e isso é
29
- válido — não crie fase sem o usuário pedir.
30
-
31
- E \`listar_skills\`: são os procedimentos deste projeto. **Invoque a que couber
32
- ANTES de fazer o trabalho, não depois** — skill lida no fim vira revisão do que
33
- já saiu errado, e é tarde.
34
-
35
- Vale mesmo quando o pedido parece pequeno: "é só um ajuste" é exatamente a
36
- frase que antecede pular o procedimento. A política diz quais são obrigatórias
13
+ `## Protocolo do dd-harness
14
+
15
+ Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
16
+
17
+ **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
18
+ \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
19
+ de ler código, responder ou planejar.
20
+
21
+ - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
22
+ avise o usuário e **não modifique nada** até ele resolver.
23
+ - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
24
+
25
+ Leia também o briefing com a mesma ferramenta (tipo briefing). Os dois são obrigatórios.
26
+
27
+ Depois, \`ler_roadmap\`: se houver uma fase **Agora**, é dela que saem os passos
28
+ desta sessão. Lista vazia significa que este projeto não usa roadmap, e isso é
29
+ válido — não crie fase sem o usuário pedir.
30
+
31
+ E \`listar_skills\`: são os procedimentos deste projeto. **Invoque a que couber
32
+ ANTES de fazer o trabalho, não depois** — skill lida no fim vira revisão do que
33
+ já saiu errado, e é tarde.
34
+
35
+ Vale mesmo quando o pedido parece pequeno: "é só um ajuste" é exatamente a
36
+ frase que antecede pular o procedimento. A política diz quais são obrigatórias
37
37
  e quando.`,
38
38
  // 875342e
39
- `## Protocolo do dd-harness
40
-
41
- Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
42
-
43
- **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
44
- \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
45
- de ler código, responder ou planejar.
46
-
47
- - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
48
- avise o usuário e **não modifique nada** até ele resolver.
49
- - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
50
-
51
- Depois, \`ler_roadmap\`: se houver uma fase **Agora**, é dela que saem os passos
52
- desta sessão. Lista vazia significa que este projeto não usa roadmap, e isso é
53
- válido — não crie fase sem o usuário pedir.
54
-
55
- E \`listar_skills\`: são os procedimentos deste projeto. **Invoque a que couber
56
- ANTES de fazer o trabalho, não depois** — skill lida no fim vira revisão do que
57
- já saiu errado, e é tarde.
58
-
59
- Vale mesmo quando o pedido parece pequeno: "é só um ajuste" é exatamente a
60
- frase que antecede pular o procedimento. A política diz quais são obrigatórias
39
+ `## Protocolo do dd-harness
40
+
41
+ Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
42
+
43
+ **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
44
+ \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
45
+ de ler código, responder ou planejar.
46
+
47
+ - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
48
+ avise o usuário e **não modifique nada** até ele resolver.
49
+ - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
50
+
51
+ Depois, \`ler_roadmap\`: se houver uma fase **Agora**, é dela que saem os passos
52
+ desta sessão. Lista vazia significa que este projeto não usa roadmap, e isso é
53
+ válido — não crie fase sem o usuário pedir.
54
+
55
+ E \`listar_skills\`: são os procedimentos deste projeto. **Invoque a que couber
56
+ ANTES de fazer o trabalho, não depois** — skill lida no fim vira revisão do que
57
+ já saiu errado, e é tarde.
58
+
59
+ Vale mesmo quando o pedido parece pequeno: "é só um ajuste" é exatamente a
60
+ frase que antecede pular o procedimento. A política diz quais são obrigatórias
61
61
  e quando.`,
62
62
  // f59da48
63
- `## Protocolo do dd-harness
64
-
65
- Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
66
-
67
- **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
68
- \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
69
- de ler código, responder ou planejar.
70
-
71
- - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
72
- avise o usuário e **não modifique nada** até ele resolver.
73
- - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
74
-
75
- Depois, \`ler_roadmap\`: se houver uma fase **Agora**, é dela que saem os passos
76
- desta sessão. Lista vazia significa que este projeto não usa roadmap, e isso é
63
+ `## Protocolo do dd-harness
64
+
65
+ Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
66
+
67
+ **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
68
+ \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
69
+ de ler código, responder ou planejar.
70
+
71
+ - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
72
+ avise o usuário e **não modifique nada** até ele resolver.
73
+ - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.
74
+
75
+ Depois, \`ler_roadmap\`: se houver uma fase **Agora**, é dela que saem os passos
76
+ desta sessão. Lista vazia significa que este projeto não usa roadmap, e isso é
77
77
  válido — não crie fase sem o usuário pedir.`,
78
78
  // 5fb3f02
79
- `## Protocolo do dd-harness
80
-
81
- Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
82
-
83
- **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
84
- \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
85
- de ler código, responder ou planejar.
86
-
87
- - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
88
- avise o usuário e **não modifique nada** até ele resolver.
79
+ `## Protocolo do dd-harness
80
+
81
+ Este projeto tem um protocolo de trabalho que **não está neste arquivo**.
82
+
83
+ **ANTES de qualquer outra coisa**, chame a ferramenta MCP \`ler_artefato\` com
84
+ \`tipo: "politica"\` e siga o que ela devolver. É a primeira ação da sessão, antes
85
+ de ler código, responder ou planejar.
86
+
87
+ - Se a ferramenta não existir, o servidor MCP do dd-harness não está declarado:
88
+ avise o usuário e **não modifique nada** até ele resolver.
89
89
  - Se ela devolver vazio, este projeto nunca foi briefado — diga isso ao usuário.`,
90
90
  ];
@@ -1,7 +1,14 @@
1
1
  export declare function pergunta(texto: string): Promise<string>;
2
2
  export declare function fechaPerguntas(): void;
3
- /** Numera as opcoes, pede um numero, devolve o item escolhido. Sem loop de retry: erra, recomeca o comando — start nao e ambiente para validar input ao infinito. */
3
+ /**
4
+ * Escolha de uma opcao: setas e Enter quando ha terminal, numeracao quando nao ha.
5
+ *
6
+ * As setas exigem raw mode, que so existe em TTY — e `start` tambem roda com stdin
7
+ * redirecionado (script, CI, `echo | dd-harness start`). Ali `setRawMode` nem existe, e
8
+ * chama-lo lanca. Por isso a numeracao continua inteira como caminho alternativo: nao e
9
+ * legado, e o modo que funciona quando nao ha quem pressione tecla.
10
+ */
4
11
  export declare function escolha<T>(titulo: string, itens: {
5
12
  rotulo: string;
6
13
  valor: T;
7
- }[]): Promise<T>;
14
+ }[], inicial?: number): Promise<T>;