dd-harness 0.10.0 → 0.11.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.
Files changed (2) hide show
  1. package/dist/index.js +55 -6
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2,6 +2,15 @@
2
2
  import { spawn } from "node:child_process";
3
3
  import { access } from "node:fs/promises";
4
4
  import { join } from "node:path";
5
+ // DEP0190: Node imprime esse warning direto no stderr no instante em que
6
+ // `spawn(..., { shell: true })` recebe um array de args — de forma sincrona, ANTES de
7
+ // qualquer listener rodar, entao filtrar dentro de um `process.on("warning")` normal nao
8
+ // bloqueia a impressao (so o listener default e que imprime, e ele continua registrado
9
+ // junto do nosso). Por isso remover o listener default e a unica forma de suprimir.
10
+ // Real quando algum arg vem de fora, mas `instalaMcp` (mais abaixo) so passa literais
11
+ // fixos — sem isto o wizard de `start` mostrava um "DeprecationWarning" no meio do fluxo
12
+ // que parecia falha para quem esta vendo por dentro pela primeira vez.
13
+ process.removeAllListeners("warning");
5
14
  import { termosDaConsulta } from "./argv.js";
6
15
  import { check, status } from "./check.js";
7
16
  import { CAMINHO_CONFIG, guardaConfigDaMaquina, guardaToken, leConfigDaMaquina, leConfigDoRepo, leToken, } from "./config.js";
@@ -87,14 +96,44 @@ const API_PADRAO = "https://dd-harness.vercel.app";
87
96
  */
88
97
  function instalaMcp() {
89
98
  return new Promise((resolve) => {
99
+ // stdio "inherit": o usuario ve o download do npx acontecendo (pode levar alguns
100
+ // segundos) e, se falhar, ve POR QUE — em vez do "nao consegui" mudo que nao dava
101
+ // pista nenhuma para diagnosticar. O DEP0190 que isto dispara e suprimido no topo
102
+ // do arquivo (`process.removeAllListeners("warning")`).
90
103
  const p = spawn("npx", ["-y", "dd-harness-mcp", "--help"], {
91
104
  shell: process.platform === "win32",
92
- stdio: "ignore",
105
+ stdio: "inherit",
93
106
  });
94
- p.on("exit", (code) => resolve(code === 0));
95
- p.on("error", () => resolve(false));
107
+ p.on("exit", (code) => resolve({ ok: code === 0, erro: code === 0 ? undefined : `código de saída ${code}` }));
108
+ p.on("error", (e) => resolve({ ok: false, erro: e.message }));
96
109
  });
97
110
  }
111
+ /**
112
+ * `start` e o primeiro comando de quem esta chegando — rodar desatualizado aqui e o
113
+ * peor lugar para isso: foi assim que a pre-instalacao do MCP (esta mesma funcao,
114
+ * mais abaixo) ficou muda numa versao anterior que nao tinha essa etapa ainda.
115
+ * Falha de rede aqui nunca trava o wizard — so segue sem avisar.
116
+ */
117
+ async function versaoDesatualizada() {
118
+ try {
119
+ const atual = await versao();
120
+ const controle = new AbortController();
121
+ const corte = setTimeout(() => controle.abort(), 3000);
122
+ const resp = await fetch("https://registry.npmjs.org/dd-harness/latest", {
123
+ signal: controle.signal,
124
+ });
125
+ clearTimeout(corte);
126
+ if (!resp.ok)
127
+ return null;
128
+ const { version: ultima } = (await resp.json());
129
+ if (!ultima || ultima === atual)
130
+ return null;
131
+ return { atual, ultima };
132
+ }
133
+ catch {
134
+ return null;
135
+ }
136
+ }
98
137
  /**
99
138
  * Tenta abrir o navegador padrao. Nunca lanca — falhar em abrir nao pode travar o
100
139
  * wizard, so degrada para "aqui esta a URL, abra voce mesmo".
@@ -136,6 +175,15 @@ async function comandoStart() {
136
175
  // ENOENT: exatamente o caso esperado, segue.
137
176
  }
138
177
  console.log("Iniciando o dd-harness nesta pasta.\n");
178
+ // 0. Versao. `start` e o comando de bootstrap: rodar velho aqui significa perder
179
+ // correcoes deste proprio wizard sem nenhum aviso (foi o que aconteceu com a
180
+ // pre-instalacao do MCP, passo 5.5 abaixo, numa versao anterior a ela existir).
181
+ const desatualizado = await versaoDesatualizada();
182
+ if (desatualizado) {
183
+ console.log(`AVISO: você está na versão ${desatualizado.atual}, e a mais recente é ` +
184
+ `${desatualizado.ultima}. Rode \`npm install -g dd-harness@latest\` e comece de ` +
185
+ "novo — start segue mesmo assim, mas pode faltar correção.\n");
186
+ }
139
187
  // 1. Credencial. Sem ela nada do resto e possivel — nem listar tenant.
140
188
  let token = await leToken(API_PADRAO);
141
189
  if (!token) {
@@ -204,11 +252,12 @@ async function comandoStart() {
204
252
  }
205
253
  if (mcp.ok) {
206
254
  console.log("\nInstalando o servidor dd-harness-mcp (primeira vez pode demorar um pouco)...");
207
- const instalou = await instalaMcp();
255
+ const { ok: instalou, erro: erroInstalacao } = await instalaMcp();
208
256
  console.log(instalou
209
257
  ? "dd-harness-mcp instalado — a próxima sessão do Claude Code conecta na hora."
210
- : "AVISO: não consegui pré-instalar dd-harness-mcp. A primeira conexão do Claude " +
211
- "Code pode demorar ou falhar; se falhar, abra uma nova sessão e tente de novo.");
258
+ : `AVISO: não consegui pré-instalar dd-harness-mcp (${erroInstalacao}). A primeira ` +
259
+ "conexão do Claude Code pode demorar ou falhar; se falhar, abra uma nova sessão " +
260
+ "e tente de novo.");
212
261
  }
213
262
  // 6. AGENTS.md — so quem usa outra ferramenta alem do Claude Code precisa.
214
263
  const outraFerramenta = await pergunta("\nVai abrir este projeto em Codex, Cursor ou outra ferramenta além do Claude " +
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dd-harness",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "type": "module",
5
5
  "description": "Cliente do dd-harness: politica no inicio da sessao, e memoria por busca — nada em disco. Sem dependencia: fetch, crypto e fs sao do Node.",
6
6
  "license": "UNLICENSED",