@neetru/cli 2.10.0 → 2.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 (51) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +11 -7
  3. package/dist/commands/agent-release.js +1 -1
  4. package/dist/commands/agent-release.js.map +1 -1
  5. package/dist/commands/autocomplete.d.ts +8 -1
  6. package/dist/commands/autocomplete.js +60 -18
  7. package/dist/commands/autocomplete.js.map +1 -1
  8. package/dist/commands/build.js +95 -14
  9. package/dist/commands/build.js.map +1 -1
  10. package/dist/commands/config.d.ts +4 -1
  11. package/dist/commands/config.js +32 -1
  12. package/dist/commands/config.js.map +1 -1
  13. package/dist/commands/deploy.js +46 -10
  14. package/dist/commands/deploy.js.map +1 -1
  15. package/dist/commands/doctor.js +3 -2
  16. package/dist/commands/doctor.js.map +1 -1
  17. package/dist/commands/logs.js +6 -4
  18. package/dist/commands/logs.js.map +1 -1
  19. package/dist/commands/promote.js +6 -6
  20. package/dist/commands/promote.js.map +1 -1
  21. package/dist/commands/publish.js +3 -2
  22. package/dist/commands/publish.js.map +1 -1
  23. package/dist/commands/status.js +2 -2
  24. package/dist/commands/status.js.map +1 -1
  25. package/dist/commands/validate.js +3 -2
  26. package/dist/commands/validate.js.map +1 -1
  27. package/dist/commands/whoami.js +3 -20
  28. package/dist/commands/whoami.js.map +1 -1
  29. package/dist/index.js +45 -17
  30. package/dist/index.js.map +1 -1
  31. package/dist/lib/api-client.d.ts +2 -0
  32. package/dist/lib/api-client.js +30 -2
  33. package/dist/lib/api-client.js.map +1 -1
  34. package/dist/lib/auth.d.ts +10 -0
  35. package/dist/lib/auth.js +33 -1
  36. package/dist/lib/auth.js.map +1 -1
  37. package/dist/lib/cli-read.d.ts +3 -0
  38. package/dist/lib/cli-read.js +5 -2
  39. package/dist/lib/cli-read.js.map +1 -1
  40. package/dist/lib/telemetry.d.ts +45 -0
  41. package/dist/lib/telemetry.js +199 -0
  42. package/dist/lib/telemetry.js.map +1 -0
  43. package/dist/lib/token-resolver.d.ts +11 -0
  44. package/dist/lib/token-resolver.js +52 -0
  45. package/dist/lib/token-resolver.js.map +1 -0
  46. package/dist/lib/url-allowlist.d.ts +30 -0
  47. package/dist/lib/url-allowlist.js +90 -0
  48. package/dist/lib/url-allowlist.js.map +1 -0
  49. package/dist/utils/safe-exit.js +8 -15
  50. package/dist/utils/safe-exit.js.map +1 -1
  51. package/package.json +66 -66
package/dist/lib/auth.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * }
14
14
  * ```
15
15
  */
16
- import { promises as fs, existsSync } from 'node:fs';
16
+ import { promises as fs, existsSync, readFileSync } from 'node:fs';
17
17
  import { dirname, join } from 'node:path';
18
18
  import { homedir } from 'node:os';
19
19
  export function getAuthFilePath() {
@@ -102,6 +102,38 @@ export async function resolveSessionEmail() {
102
102
  return null;
103
103
  }
104
104
  }
105
+ /**
106
+ * MASTER-HIGH-048 (2.11.0) — leitura sincrona APENAS do `auth.json`.
107
+ *
108
+ * Helper interno usado por `getActiveTokenSync()` (em `token-resolver.ts`).
109
+ * Mantido aqui pra preservar o limite de escopo `auth.ts` = `auth.json`-only.
110
+ *
111
+ * Retorna `null` em qualquer falha (arquivo ausente, JSON invalido, token
112
+ * vazio). Pra erro detalhado, usar `loadToken()` async.
113
+ */
114
+ export function readAuthJsonSync() {
115
+ const authPath = getAuthFilePath();
116
+ if (!existsSync(authPath))
117
+ return null;
118
+ try {
119
+ const raw = readFileSync(authPath, 'utf8');
120
+ const parsed = JSON.parse(raw);
121
+ if (parsed &&
122
+ typeof parsed.token === 'string' &&
123
+ parsed.token.length > 0 &&
124
+ typeof parsed.email === 'string') {
125
+ return {
126
+ token: parsed.token,
127
+ email: parsed.email,
128
+ savedAt: parsed.savedAt ?? '',
129
+ };
130
+ }
131
+ }
132
+ catch {
133
+ // ignora — token ausente
134
+ }
135
+ return null;
136
+ }
105
137
  export async function clearToken() {
106
138
  const path = getAuthFilePath();
107
139
  if (!existsSync(path))
@@ -1 +1 @@
1
- {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
1
  /**
2
2
  * Resolve o Bearer token corrente. Retorna `null` se não houver sessão.
3
+ *
4
+ * MASTER-HIGH-048 (2.11.0): wrapper sobre `getActiveTokenSync()` —
5
+ * mantem `async` por compat com call-sites que esperam Promise.
3
6
  */
4
7
  export declare function resolveToken(): Promise<string | null>;
5
8
  /**
@@ -9,13 +9,16 @@
9
9
  * 1 — não autenticado / não encontrado (4xx semântico do usuário)
10
10
  * 2 — token inválido/revogado, erro de rede, erro de servidor
11
11
  */
12
- import { config } from './config.js';
13
12
  import { loadToken, AuthFileMissingError, AuthFileInvalidError, } from './auth.js';
13
+ import { getActiveTokenSync } from './token-resolver.js';
14
14
  import { CliApiError, CliNetworkError } from './api-client.js';
15
15
  import { log } from '../utils/logger.js';
16
16
  import { safeExit } from '../utils/safe-exit.js';
17
17
  /**
18
18
  * Resolve o Bearer token corrente. Retorna `null` se não houver sessão.
19
+ *
20
+ * MASTER-HIGH-048 (2.11.0): wrapper sobre `getActiveTokenSync()` —
21
+ * mantem `async` por compat com call-sites que esperam Promise.
19
22
  */
20
23
  export async function resolveToken() {
21
24
  try {
@@ -25,7 +28,7 @@ export async function resolveToken() {
25
28
  catch (err) {
26
29
  if (err instanceof AuthFileMissingError) {
27
30
  // Fallback: Conf storage (legacy `neetru login --token <nrt_...>`).
28
- return config.get('neetruApiKey') ?? null;
31
+ return getActiveTokenSync();
29
32
  }
30
33
  if (err instanceof AuthFileInvalidError) {
31
34
  log.error(err.message);
@@ -1 +1 @@
1
- {"version":3,"file":"cli-read.js","sourceRoot":"","sources":["../../src/lib/cli-read.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-read.js","sourceRoot":"","sources":["../../src/lib/cli-read.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ export interface TelemetryEvent {
2
+ /** Nome do comando (ex: `db.apply`, `deploy`, `whoami`). */
3
+ command: string;
4
+ /** Duracao em ms (best-effort). */
5
+ durationMs: number;
6
+ /** Sucesso (exit code 0) ou falha. */
7
+ ok: boolean;
8
+ /** Exit code reportado (0..N). */
9
+ exitCode: number;
10
+ /** Carimbo ISO do evento. */
11
+ ts: string;
12
+ }
13
+ export declare function isTelemetryEnabled(): boolean;
14
+ /**
15
+ * Adiciona um evento ao buffer. Drop silencioso quando opt-in nao foi dado.
16
+ *
17
+ * Nao deve falhar — qualquer excecao eh engolida pra nao quebrar o comando.
18
+ */
19
+ export declare function trackEvent(event: Omit<TelemetryEvent, 'ts'>): void;
20
+ /**
21
+ * Drena o buffer para o endpoint. Idempotente — chamadas subsequentes
22
+ * sao no-op apos primeira drenagem.
23
+ *
24
+ * **H-01 fix (Opus review 2026-05-27):** `keepalive: true` permite que a
25
+ * request POST sobreviva o `process.exit()` chamado por safeExit. Antes
26
+ * o request era abortado quando o event loop morria, e como safeExit
27
+ * tambem destruia o globalAgent (M-05), o fetch sequer chegava a sair.
28
+ */
29
+ export declare function flushTelemetry(): Promise<void>;
30
+ /**
31
+ * Instala hooks de flush:
32
+ * - `beforeExit` — drena via event loop natural (sucesso, comandos que retornam)
33
+ * - `exit` — best-effort em paths que chamam `process.exit` direto (safeExit)
34
+ *
35
+ * **H-01 fix (Opus review 2026-05-27):** chamar no ENTRY-POINT do CLI
36
+ * (src/index.ts antes do parse), nao dentro de postAction (que nem dispara
37
+ * pra comandos que falham). Idempotente — subsequente eh no-op.
38
+ */
39
+ export declare function installTelemetryFlushHook(): void;
40
+ export declare function markCommandStart(commandName: string): void;
41
+ export declare function markCommandEnd(exitCode: number): void;
42
+ /** Para tests — esvazia o estado de comando atual. */
43
+ export declare function _resetCurrentCommandForTests(): void;
44
+ /** Para tests — esvazia o buffer e o flag de flush. */
45
+ export declare function _resetTelemetryForTests(): void;
@@ -0,0 +1,199 @@
1
+ /**
2
+ * MASTER-HIGH-052 (2.11.0) — emitter de telemetry CLI.
3
+ *
4
+ * Pre-2.11 a flag `telemetry.enabled` existia no `config.ts` schema, era
5
+ * settable via `neetru config set telemetry.enabled true`, mas NENHUM
6
+ * call-site emitia evento. Comentario placeholder `// Sprint 11` ficou la
7
+ * por umas seis sprints. (HIGH-10 chefe-CLI HIGH-05.)
8
+ *
9
+ * Implementacao 2.11:
10
+ * - Buffer in-memory (max 50 eventos) drenado em processo `beforeExit`.
11
+ * - Opt-in default-OFF (`config.get('telemetry.enabled') === true`).
12
+ * - Anonimo: instalacao identificada por `installId` (UUID gerado uma
13
+ * vez em ~/.config/neetru-cli/install-id) — sem email, sem token,
14
+ * sem path absoluto, sem env vars, sem arg do usuario.
15
+ * - Endpoint: POST /api/sdk/v1/telemetry/log (Core ja tem rota viva).
16
+ * - Fire-and-forget: erro de rede NUNCA atrapalha o comando do usuario.
17
+ *
18
+ * Override pra dev/CI:
19
+ * - `NEETRU_TELEMETRY_DISABLED=1` desliga forcado.
20
+ * - `NEETRU_TELEMETRY_URL=...` redireciona (usado em vitest).
21
+ */
22
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
23
+ import { join, dirname } from 'node:path';
24
+ import { homedir } from 'node:os';
25
+ import { randomUUID } from 'node:crypto';
26
+ import { config } from './config.js';
27
+ import { CLI_VERSION } from '../version.js';
28
+ const MAX_BUFFER = 50;
29
+ const buffer = [];
30
+ let flushed = false;
31
+ let cachedInstallId = null;
32
+ function getInstallIdPath() {
33
+ return join(homedir(), '.config', 'neetru-cli', 'install-id');
34
+ }
35
+ function readOrCreateInstallId() {
36
+ if (cachedInstallId)
37
+ return cachedInstallId;
38
+ const filePath = getInstallIdPath();
39
+ if (existsSync(filePath)) {
40
+ try {
41
+ const raw = readFileSync(filePath, 'utf8').trim();
42
+ if (raw.length >= 8) {
43
+ cachedInstallId = raw;
44
+ return raw;
45
+ }
46
+ }
47
+ catch {
48
+ // re-cria
49
+ }
50
+ }
51
+ const id = randomUUID();
52
+ try {
53
+ mkdirSync(dirname(filePath), { recursive: true, mode: 0o700 });
54
+ writeFileSync(filePath, id, { encoding: 'utf8', mode: 0o600 });
55
+ }
56
+ catch {
57
+ // sem permissao — segue com installId em-memoria, sem persistencia
58
+ }
59
+ cachedInstallId = id;
60
+ return id;
61
+ }
62
+ function getEndpoint() {
63
+ if (process.env.NEETRU_TELEMETRY_URL)
64
+ return process.env.NEETRU_TELEMETRY_URL;
65
+ const base = config.get('neetruApiUrl') ??
66
+ 'https://api.neetru.com';
67
+ return `${base.replace(/\/+$/, '')}/api/sdk/v1/telemetry/log`;
68
+ }
69
+ export function isTelemetryEnabled() {
70
+ if (process.env.NEETRU_TELEMETRY_DISABLED === '1')
71
+ return false;
72
+ const v = config.get('telemetry.enabled');
73
+ return v === true;
74
+ }
75
+ /**
76
+ * Adiciona um evento ao buffer. Drop silencioso quando opt-in nao foi dado.
77
+ *
78
+ * Nao deve falhar — qualquer excecao eh engolida pra nao quebrar o comando.
79
+ */
80
+ export function trackEvent(event) {
81
+ try {
82
+ if (!isTelemetryEnabled())
83
+ return;
84
+ if (buffer.length >= MAX_BUFFER)
85
+ return; // soft cap, nao bloqueia comando
86
+ buffer.push({ ...event, ts: new Date().toISOString() });
87
+ }
88
+ catch {
89
+ // engole
90
+ }
91
+ }
92
+ /**
93
+ * Drena o buffer para o endpoint. Idempotente — chamadas subsequentes
94
+ * sao no-op apos primeira drenagem.
95
+ *
96
+ * **H-01 fix (Opus review 2026-05-27):** `keepalive: true` permite que a
97
+ * request POST sobreviva o `process.exit()` chamado por safeExit. Antes
98
+ * o request era abortado quando o event loop morria, e como safeExit
99
+ * tambem destruia o globalAgent (M-05), o fetch sequer chegava a sair.
100
+ */
101
+ export async function flushTelemetry() {
102
+ if (flushed)
103
+ return;
104
+ flushed = true;
105
+ if (!isTelemetryEnabled())
106
+ return;
107
+ if (buffer.length === 0)
108
+ return;
109
+ const envelope = {
110
+ cliVersion: CLI_VERSION,
111
+ installId: readOrCreateInstallId(),
112
+ os: `${process.platform}-${process.arch}`,
113
+ events: buffer.splice(0, buffer.length),
114
+ };
115
+ const endpoint = getEndpoint();
116
+ // Fire-and-forget com timeout curto (1.5s). Erro de rede engolido.
117
+ const controller = new AbortController();
118
+ const tid = setTimeout(() => controller.abort(), 1500);
119
+ try {
120
+ await fetch(endpoint, {
121
+ method: 'POST',
122
+ headers: { 'content-type': 'application/json' },
123
+ body: JSON.stringify(envelope),
124
+ signal: controller.signal,
125
+ // H-01 fix: garante que request sobrevive process.exit() do safeExit.
126
+ // Suportado em Node 18+ (undici) e em todos browsers/Edge runtimes.
127
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
128
+ // @ts-ignore — RequestInit em Node DOM types nao expoe `keepalive`
129
+ keepalive: true,
130
+ });
131
+ }
132
+ catch {
133
+ // engole — falha de telemetry nao afeta o usuario
134
+ }
135
+ finally {
136
+ clearTimeout(tid);
137
+ }
138
+ }
139
+ let exitHookInstalled = false;
140
+ /**
141
+ * Instala hooks de flush:
142
+ * - `beforeExit` — drena via event loop natural (sucesso, comandos que retornam)
143
+ * - `exit` — best-effort em paths que chamam `process.exit` direto (safeExit)
144
+ *
145
+ * **H-01 fix (Opus review 2026-05-27):** chamar no ENTRY-POINT do CLI
146
+ * (src/index.ts antes do parse), nao dentro de postAction (que nem dispara
147
+ * pra comandos que falham). Idempotente — subsequente eh no-op.
148
+ */
149
+ export function installTelemetryFlushHook() {
150
+ if (exitHookInstalled)
151
+ return;
152
+ exitHookInstalled = true;
153
+ process.once('beforeExit', () => {
154
+ void flushTelemetry();
155
+ });
156
+ // exit hook adicional: capa comandos que chamam process.exit() direto
157
+ // (sem deixar event loop drenar). fetch keepalive:true permite que a
158
+ // request sobreviva. Note: process.on('exit') eh SINCRONO, void fetch
159
+ // nao bloqueia — best-effort.
160
+ process.once('exit', () => {
161
+ void flushTelemetry();
162
+ });
163
+ }
164
+ /**
165
+ * **H-01 fix camada 2 (Opus review):** captura comandos que terminam via
166
+ * `safeExit(N != 0)` ou `process.exit(N)`. Sem isso, comandos que falham
167
+ * (a porcao mais importante pra debug UX) NUNCA emitem evento de
168
+ * telemetria.
169
+ *
170
+ * Chamar no `preAction` hook do Commander pra marcar inicio do comando.
171
+ * O `process.exit` hook captura o exit code real.
172
+ */
173
+ let currentCommand = null;
174
+ export function markCommandStart(commandName) {
175
+ currentCommand = { name: commandName, start: Date.now() };
176
+ }
177
+ export function markCommandEnd(exitCode) {
178
+ if (!currentCommand)
179
+ return;
180
+ trackEvent({
181
+ command: currentCommand.name,
182
+ durationMs: Date.now() - currentCommand.start,
183
+ ok: exitCode === 0,
184
+ exitCode,
185
+ });
186
+ currentCommand = null;
187
+ }
188
+ /** Para tests — esvazia o estado de comando atual. */
189
+ export function _resetCurrentCommandForTests() {
190
+ currentCommand = null;
191
+ }
192
+ /** Para tests — esvazia o buffer e o flag de flush. */
193
+ export function _resetTelemetryForTests() {
194
+ buffer.length = 0;
195
+ flushed = false;
196
+ cachedInstallId = null;
197
+ exitHookInstalled = false;
198
+ }
199
+ //# sourceMappingURL=telemetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../../src/lib/telemetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Resolve o Bearer token corrente. Retorna `null` se nao houver sessao.
3
+ *
4
+ * Side effect: na primeira vez que o token vier do Conf (e nao do
5
+ * auth.json), emite um warning stderr (one-shot por processo) avisando da
6
+ * deprecacao da rota legacy. Comandos com `--json` ainda assim recebem o
7
+ * warning em stderr (machine-readable stdout fica limpo).
8
+ */
9
+ export declare function getActiveTokenSync(): string | null;
10
+ /** Para tests — reseta o flag de warning one-shot. */
11
+ export declare function _resetLegacyWarningForTests(): void;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * MASTER-HIGH-048 (2.11.0) — token resolver sincrono.
3
+ *
4
+ * Antes da 2.11, `api-client.ts` lia o token APENAS do `Conf` storage. Mas
5
+ * desde a Sprint 1 (2026-05-04) o storage canonico passou a ser
6
+ * `~/.config/neetru-cli/auth.json` (chmod 0600, fora do JSON do Conf).
7
+ * `login` gravava nos DOIS pra compat; comandos como `status`, `validate`,
8
+ * `db`, `deploy`, `vm`, `logs`, `doctor`, `publish` so conseguiam ler de
9
+ * Conf — entao copiar `auth.json` pra outra maquina deixava esses 8
10
+ * comandos "logado mas nao logado". Cause classica de bug de suporte.
11
+ *
12
+ * Solucao: resolver sincrono que prefere `auth.json` e usa Conf so como
13
+ * fallback. Quem chamava `config.get('neetruApiKey')` direto agora chama
14
+ * `getActiveTokenSync()`.
15
+ *
16
+ * Ordem:
17
+ * 1. `~/.config/neetru-cli/auth.json` (canonico)
18
+ * 2. Conf `neetruApiKey` (legacy — emite deprecation warning em 2.11; remove em 2.12.0)
19
+ * 3. null
20
+ */
21
+ import { readAuthJsonSync } from './auth.js';
22
+ import { config } from './config.js';
23
+ let legacyWarningEmitted = false;
24
+ /**
25
+ * Resolve o Bearer token corrente. Retorna `null` se nao houver sessao.
26
+ *
27
+ * Side effect: na primeira vez que o token vier do Conf (e nao do
28
+ * auth.json), emite um warning stderr (one-shot por processo) avisando da
29
+ * deprecacao da rota legacy. Comandos com `--json` ainda assim recebem o
30
+ * warning em stderr (machine-readable stdout fica limpo).
31
+ */
32
+ export function getActiveTokenSync() {
33
+ const auth = readAuthJsonSync();
34
+ if (auth && auth.token)
35
+ return auth.token;
36
+ const legacy = config.get('neetruApiKey');
37
+ if (typeof legacy === 'string' && legacy.length > 0) {
38
+ if (!legacyWarningEmitted && !process.env.NEETRU_SUPPRESS_LEGACY_WARNINGS) {
39
+ legacyWarningEmitted = true;
40
+ // stderr — preserva pipe-friendly stdout.
41
+ process.stderr.write('⚠ Aviso: usando token do storage legacy (Conf). Execute `neetru logout && neetru login` pra migrar pra ~/.config/neetru-cli/auth.json.\n' +
42
+ ' Storage legacy sera removido em @neetru/cli@2.12.\n');
43
+ }
44
+ return legacy;
45
+ }
46
+ return null;
47
+ }
48
+ /** Para tests — reseta o flag de warning one-shot. */
49
+ export function _resetLegacyWarningForTests() {
50
+ legacyWarningEmitted = false;
51
+ }
52
+ //# sourceMappingURL=token-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-resolver.js","sourceRoot":"","sources":["../../src/lib/token-resolver.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,IAAI,oBAAoB,GAAG,KAAK,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,IAAI,IAAI,IAAI,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC,KAAK,CAAC;IAE1C,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC1C,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpD,IAAI,CAAC,oBAAoB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,CAAC;YAC1E,oBAAoB,GAAG,IAAI,CAAC;YAC5B,0CAA0C;YAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0IAA0I;gBACxI,uDAAuD,CAC1D,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,2BAA2B;IACzC,oBAAoB,GAAG,KAAK,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * MASTER-HIGH-049 (2.11.0) — allowlist de hosts pra `neetruApiUrl`.
3
+ *
4
+ * Pre-2.11, `neetru config set neetruApiUrl http://evil.com` era aceito sem
5
+ * warning. Proxima chamada `neetru whoami` mandava o Bearer
6
+ * `nrt_<keyId>_<secret>` direto pra `evil.com` — vetor de exfiltracao do
7
+ * token CLI. (HIGH-10 / chefe-CLI HIGH-02.)
8
+ *
9
+ * Politica:
10
+ * - Hosts trustred: api.neetru.com, core.neetru.com, *.neetru.com,
11
+ * localhost (qualquer porta), 127.0.0.1 (qualquer porta).
12
+ * - Hosts NAO trusted: warning vermelho + bloqueio sem
13
+ * `--allow-untrusted-url` (ou env `NEETRU_ALLOW_UNTRUSTED_URL=1`).
14
+ */
15
+ export interface AllowlistResult {
16
+ trusted: boolean;
17
+ host: string;
18
+ reason?: string;
19
+ }
20
+ /**
21
+ * Classifica a URL alvo. Retorna `trusted=true` quando o host bate na
22
+ * allowlist; `trusted=false` (com `reason`) caso contrario.
23
+ */
24
+ export declare function classifyApiUrl(rawUrl: string): AllowlistResult;
25
+ /**
26
+ * Override por env. Setar `NEETRU_ALLOW_UNTRUSTED_URL=1` pula a checagem
27
+ * tanto em `config set` quanto em runtime warnings — util pra dev em
28
+ * ambientes corporativos com proxy.
29
+ */
30
+ export declare function isOverrideEnabled(): boolean;
@@ -0,0 +1,90 @@
1
+ /**
2
+ * MASTER-HIGH-049 (2.11.0) — allowlist de hosts pra `neetruApiUrl`.
3
+ *
4
+ * Pre-2.11, `neetru config set neetruApiUrl http://evil.com` era aceito sem
5
+ * warning. Proxima chamada `neetru whoami` mandava o Bearer
6
+ * `nrt_<keyId>_<secret>` direto pra `evil.com` — vetor de exfiltracao do
7
+ * token CLI. (HIGH-10 / chefe-CLI HIGH-02.)
8
+ *
9
+ * Politica:
10
+ * - Hosts trustred: api.neetru.com, core.neetru.com, *.neetru.com,
11
+ * localhost (qualquer porta), 127.0.0.1 (qualquer porta).
12
+ * - Hosts NAO trusted: warning vermelho + bloqueio sem
13
+ * `--allow-untrusted-url` (ou env `NEETRU_ALLOW_UNTRUSTED_URL=1`).
14
+ */
15
+ const TRUSTED_HOSTS_EXACT = new Set([
16
+ 'api.neetru.com',
17
+ 'core.neetru.com',
18
+ 'neetru.com',
19
+ ]);
20
+ const TRUSTED_HOST_PATTERNS = [
21
+ /\.neetru\.com$/i, // qualquer subdominio de neetru.com (auth.neetru.com etc)
22
+ /^localhost$/i, // dev
23
+ /^127\.0\.0\.1$/, // dev IPv4 loopback
24
+ /^\[::1\]$/, // dev IPv6 loopback (URL host com bracket)
25
+ ];
26
+ /**
27
+ * Classifica a URL alvo. Retorna `trusted=true` quando o host bate na
28
+ * allowlist; `trusted=false` (com `reason`) caso contrario.
29
+ */
30
+ export function classifyApiUrl(rawUrl) {
31
+ let parsed;
32
+ try {
33
+ parsed = new URL(rawUrl);
34
+ }
35
+ catch (err) {
36
+ return {
37
+ trusted: false,
38
+ host: rawUrl,
39
+ reason: `URL invalida: ${err.message}`,
40
+ };
41
+ }
42
+ if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
43
+ return {
44
+ trusted: false,
45
+ host: parsed.host,
46
+ reason: `Protocolo nao suportado: ${parsed.protocol}`,
47
+ };
48
+ }
49
+ // Hostname (sem porta).
50
+ const hostname = parsed.hostname.toLowerCase();
51
+ const isLoopback = hostname === 'localhost' ||
52
+ hostname === '127.0.0.1' ||
53
+ hostname === '::1';
54
+ // Match contra allowlist (exact + pattern).
55
+ let hostnameAllowed = TRUSTED_HOSTS_EXACT.has(hostname);
56
+ if (!hostnameAllowed) {
57
+ for (const pattern of TRUSTED_HOST_PATTERNS) {
58
+ if (pattern.test(hostname)) {
59
+ hostnameAllowed = true;
60
+ break;
61
+ }
62
+ }
63
+ }
64
+ if (!hostnameAllowed) {
65
+ return {
66
+ trusted: false,
67
+ host: parsed.host,
68
+ reason: 'Host fora da allowlist neetru.com / localhost',
69
+ };
70
+ }
71
+ // Hostname permitido. Para hosts NAO-loopback, exige HTTPS (HTTP em
72
+ // host de producao expoe Bearer token a sniffing trivial).
73
+ if (!isLoopback && parsed.protocol === 'http:') {
74
+ return {
75
+ trusted: false,
76
+ host: parsed.host,
77
+ reason: `HTTP nao-cifrado para host nao-loopback (${hostname}). Use https://`,
78
+ };
79
+ }
80
+ return { trusted: true, host: parsed.host };
81
+ }
82
+ /**
83
+ * Override por env. Setar `NEETRU_ALLOW_UNTRUSTED_URL=1` pula a checagem
84
+ * tanto em `config set` quanto em runtime warnings — util pra dev em
85
+ * ambientes corporativos com proxy.
86
+ */
87
+ export function isOverrideEnabled() {
88
+ return process.env.NEETRU_ALLOW_UNTRUSTED_URL === '1';
89
+ }
90
+ //# sourceMappingURL=url-allowlist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"url-allowlist.js","sourceRoot":"","sources":["../../src/lib/url-allowlist.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,gBAAgB;IAChB,iBAAiB;IACjB,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAA0B;IACnD,iBAAiB,EAAE,0DAA0D;IAC7E,cAAc,EAAE,MAAM;IACtB,gBAAgB,EAAE,oBAAoB;IACtC,WAAW,EAAE,2CAA2C;CACzD,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,iBAAkB,GAAa,CAAC,OAAO,EAAE;SAClD,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAChE,OAAO;YACL,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,4BAA4B,MAAM,CAAC,QAAQ,EAAE;SACtD,CAAC;IACJ,CAAC;IAED,wBAAwB;IACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;IAE/C,MAAM,UAAU,GACd,QAAQ,KAAK,WAAW;QACxB,QAAQ,KAAK,WAAW;QACxB,QAAQ,KAAK,KAAK,CAAC;IAErB,4CAA4C;IAC5C,IAAI,eAAe,GAAG,mBAAmB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxD,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,KAAK,MAAM,OAAO,IAAI,qBAAqB,EAAE,CAAC;YAC5C,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC3B,eAAe,GAAG,IAAI,CAAC;gBACvB,MAAM;YACR,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,+CAA+C;SACxD,CAAC;IACJ,CAAC;IAED,oEAAoE;IACpE,2DAA2D;IAC3D,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC/C,OAAO;YACL,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,4CAA4C,QAAQ,iBAAiB;SAC9E,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC;AAC9C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,0BAA0B,KAAK,GAAG,CAAC;AACxD,CAAC"}
@@ -37,21 +37,14 @@ function cleanupHandles() {
37
37
  process.stdin.destroy();
38
38
  }
39
39
  catch { /* já fechado */ }
40
- // 3. Destroy http/https keep-alive sockets
41
- try {
42
- // eslint-disable-next-line @typescript-eslint/no-var-requires
43
- const http = require('node:http');
44
- if (http?.globalAgent?.destroy)
45
- http.globalAgent.destroy();
46
- }
47
- catch { /* best-effort */ }
48
- try {
49
- // eslint-disable-next-line @typescript-eslint/no-var-requires
50
- const https = require('node:https');
51
- if (https?.globalAgent?.destroy)
52
- https.globalAgent.destroy();
53
- }
54
- catch { /* best-effort */ }
40
+ // 3. M-05 fix (Opus review 2026-05-27): NÃO destruir globalAgent.
41
+ // Antes destruíamos http.globalAgent.destroy() + https.globalAgent.destroy()
42
+ // pra fechar keep-alive sockets — mas isso quebrava telemetria flush
43
+ // e qualquer retry em-flight. fetch() Node 20+ usa undici internamente
44
+ // e não depende do http.globalAgent legado. As assertions libuv
45
+ // UV_HANDLE_CLOSING em Windows resolvem com stdin.destroy() (acima)
46
+ // e o exit imediato — sockets http morrem com o processo de qualquer
47
+ // forma. Manter destroy aqui prejudicava telemetria keepalive:true.
55
48
  }
56
49
  /**
57
50
  * Sai com `code` após cleanup de handles libuv. NEVER returns.
@@ -1 +1 @@
1
- {"version":3,"file":"safe-exit.js","sourceRoot":"","sources":["../../src/utils/safe-exit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,SAAS,cAAc;IACrB,gEAAgE;IAChE,IAAI,CAAC;QAAC,eAAe,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAEtD,6CAA6C;IAC7C,IAAI,CAAC;QAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAE3D,2CAA2C;IAC3C,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,IAAI,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;QAClC,IAAI,IAAI,EAAE,WAAW,EAAE,OAAO;YAAE,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAC7B,IAAI,CAAC;QACH,8DAA8D;QAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;QACpC,IAAI,KAAK,EAAE,WAAW,EAAE,OAAO;YAAE,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC;IAC/D,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,cAAc,EAAE,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,cAAc,EAAE,CAAC;IACjB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC"}
1
+ {"version":3,"file":"safe-exit.js","sourceRoot":"","sources":["../../src/utils/safe-exit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD,SAAS,cAAc;IACrB,gEAAgE;IAChE,IAAI,CAAC;QAAC,eAAe,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAEtD,6CAA6C;IAC7C,IAAI,CAAC;QAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,gBAAgB,CAAC,CAAC;IAE3D,kEAAkE;IAClE,gFAAgF;IAChF,wEAAwE;IACxE,0EAA0E;IAC1E,mEAAmE;IACnE,uEAAuE;IACvE,wEAAwE;IACxE,0EAA0E;AAC5E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,cAAc,EAAE,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,cAAc,EAAE,CAAC;IACjB,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC;AAC1B,CAAC"}