@neetru/cli 1.0.1 → 2.0.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 (135) hide show
  1. package/CHANGELOG.md +136 -0
  2. package/README.md +109 -152
  3. package/dist/commands/add.d.ts +8 -3
  4. package/dist/commands/add.js +70 -143
  5. package/dist/commands/add.js.map +1 -1
  6. package/dist/commands/ai.d.ts +4 -0
  7. package/dist/commands/ai.js +88 -0
  8. package/dist/commands/ai.js.map +1 -0
  9. package/dist/commands/autocomplete.d.ts +7 -0
  10. package/dist/commands/autocomplete.js +107 -0
  11. package/dist/commands/autocomplete.js.map +1 -0
  12. package/dist/commands/build.d.ts +18 -0
  13. package/dist/commands/build.js +288 -0
  14. package/dist/commands/build.js.map +1 -0
  15. package/dist/commands/config.d.ts +3 -0
  16. package/dist/commands/config.js +70 -0
  17. package/dist/commands/config.js.map +1 -0
  18. package/dist/commands/db.d.ts +14 -0
  19. package/dist/commands/db.js +187 -0
  20. package/dist/commands/db.js.map +1 -0
  21. package/dist/commands/deploy.d.ts +16 -3
  22. package/dist/commands/deploy.js +400 -180
  23. package/dist/commands/deploy.js.map +1 -1
  24. package/dist/commands/doctor.d.ts +27 -0
  25. package/dist/commands/doctor.js +211 -0
  26. package/dist/commands/doctor.js.map +1 -0
  27. package/dist/commands/env.d.ts +15 -0
  28. package/dist/commands/env.js +56 -0
  29. package/dist/commands/env.js.map +1 -0
  30. package/dist/commands/fn.d.ts +6 -0
  31. package/dist/commands/fn.js +87 -0
  32. package/dist/commands/fn.js.map +1 -0
  33. package/dist/commands/init.d.ts +10 -3
  34. package/dist/commands/init.js +212 -143
  35. package/dist/commands/init.js.map +1 -1
  36. package/dist/commands/login.d.ts +6 -3
  37. package/dist/commands/login.js +222 -92
  38. package/dist/commands/login.js.map +1 -1
  39. package/dist/commands/logout.d.ts +1 -0
  40. package/dist/commands/logout.js +28 -0
  41. package/dist/commands/logout.js.map +1 -0
  42. package/dist/commands/logs.d.ts +14 -3
  43. package/dist/commands/logs.js +132 -106
  44. package/dist/commands/logs.js.map +1 -1
  45. package/dist/commands/mocks.d.ts +5 -0
  46. package/dist/commands/mocks.js +23 -0
  47. package/dist/commands/mocks.js.map +1 -0
  48. package/dist/commands/open.d.ts +4 -3
  49. package/dist/commands/open.js +53 -85
  50. package/dist/commands/open.js.map +1 -1
  51. package/dist/commands/promote.d.ts +9 -0
  52. package/dist/commands/promote.js +114 -0
  53. package/dist/commands/promote.js.map +1 -0
  54. package/dist/commands/publish.d.ts +14 -0
  55. package/dist/commands/publish.js +180 -0
  56. package/dist/commands/publish.js.map +1 -0
  57. package/dist/commands/status.d.ts +5 -3
  58. package/dist/commands/status.js +91 -93
  59. package/dist/commands/status.js.map +1 -1
  60. package/dist/commands/upgrade.d.ts +12 -0
  61. package/dist/commands/upgrade.js +77 -0
  62. package/dist/commands/upgrade.js.map +1 -0
  63. package/dist/commands/validate.d.ts +1 -3
  64. package/dist/commands/validate.js +83 -91
  65. package/dist/commands/validate.js.map +1 -1
  66. package/dist/commands/whoami.d.ts +5 -3
  67. package/dist/commands/whoami.js +76 -28
  68. package/dist/commands/whoami.js.map +1 -1
  69. package/dist/index.d.ts +0 -1
  70. package/dist/index.js +337 -36
  71. package/dist/index.js.map +1 -1
  72. package/dist/lib/ai/context.d.ts +11 -0
  73. package/dist/lib/ai/context.js +112 -0
  74. package/dist/lib/ai/context.js.map +1 -0
  75. package/dist/lib/ai/orchestrator.d.ts +10 -0
  76. package/dist/lib/ai/orchestrator.js +92 -0
  77. package/dist/lib/ai/orchestrator.js.map +1 -0
  78. package/dist/lib/api-client.d.ts +21 -0
  79. package/dist/lib/api-client.js +65 -0
  80. package/dist/lib/api-client.js.map +1 -0
  81. package/dist/lib/auth.d.ts +15 -0
  82. package/dist/lib/auth.js +98 -0
  83. package/dist/lib/auth.js.map +1 -0
  84. package/dist/lib/config-schema.d.ts +165 -0
  85. package/dist/lib/config-schema.js +57 -0
  86. package/dist/lib/config-schema.js.map +1 -0
  87. package/dist/lib/config.d.ts +15 -0
  88. package/dist/lib/config.js +33 -0
  89. package/dist/lib/config.js.map +1 -0
  90. package/dist/utils/logger.d.ts +13 -0
  91. package/dist/utils/logger.js +27 -0
  92. package/dist/utils/logger.js.map +1 -0
  93. package/package.json +35 -33
  94. package/templates/auth/callback.ts +22 -0
  95. package/templates/auth/sign-in.tsx +41 -0
  96. package/templates/billing/checkout.ts +22 -0
  97. package/templates/billing/page.tsx +43 -0
  98. package/templates/support/ticket-form.tsx +68 -0
  99. package/templates/usage/track.ts +30 -0
  100. package/templates/users/profile.tsx +43 -0
  101. package/LICENSE +0 -21
  102. package/dist/commands/add.d.ts.map +0 -1
  103. package/dist/commands/deploy.d.ts.map +0 -1
  104. package/dist/commands/generate-types.d.ts +0 -3
  105. package/dist/commands/generate-types.d.ts.map +0 -1
  106. package/dist/commands/generate-types.js +0 -150
  107. package/dist/commands/generate-types.js.map +0 -1
  108. package/dist/commands/init.d.ts.map +0 -1
  109. package/dist/commands/login.d.ts.map +0 -1
  110. package/dist/commands/logs.d.ts.map +0 -1
  111. package/dist/commands/open.d.ts.map +0 -1
  112. package/dist/commands/status.d.ts.map +0 -1
  113. package/dist/commands/validate.d.ts.map +0 -1
  114. package/dist/commands/whoami.d.ts.map +0 -1
  115. package/dist/config.d.ts +0 -14
  116. package/dist/config.d.ts.map +0 -1
  117. package/dist/config.js +0 -83
  118. package/dist/config.js.map +0 -1
  119. package/dist/index.d.ts.map +0 -1
  120. package/dist/scaffold/auth.d.ts +0 -3
  121. package/dist/scaffold/auth.d.ts.map +0 -1
  122. package/dist/scaffold/auth.js +0 -228
  123. package/dist/scaffold/auth.js.map +0 -1
  124. package/dist/scaffold/billing.d.ts +0 -3
  125. package/dist/scaffold/billing.d.ts.map +0 -1
  126. package/dist/scaffold/billing.js +0 -184
  127. package/dist/scaffold/billing.js.map +0 -1
  128. package/dist/scaffold/usage.d.ts +0 -3
  129. package/dist/scaffold/usage.d.ts.map +0 -1
  130. package/dist/scaffold/usage.js +0 -173
  131. package/dist/scaffold/usage.js.map +0 -1
  132. package/dist/scaffold/users.d.ts +0 -3
  133. package/dist/scaffold/users.d.ts.map +0 -1
  134. package/dist/scaffold/users.js +0 -135
  135. package/dist/scaffold/users.js.map +0 -1
@@ -0,0 +1,21 @@
1
+ export interface ApiError {
2
+ code: string;
3
+ message: string;
4
+ }
5
+ export declare class CliApiError extends Error {
6
+ readonly status: number;
7
+ readonly code: string;
8
+ constructor(status: number, code: string, message: string);
9
+ }
10
+ export declare class CliNetworkError extends Error {
11
+ readonly cause?: unknown;
12
+ constructor(message: string, cause?: unknown);
13
+ }
14
+ interface RequestOptions {
15
+ method?: 'GET' | 'POST';
16
+ body?: unknown;
17
+ token?: string;
18
+ signal?: AbortSignal;
19
+ }
20
+ export declare function apiRequest<T>(path: string, opts?: RequestOptions): Promise<T>;
21
+ export {};
@@ -0,0 +1,65 @@
1
+ import { config } from './config.js';
2
+ export class CliApiError extends Error {
3
+ status;
4
+ code;
5
+ constructor(status, code, message) {
6
+ super(message);
7
+ this.name = 'CliApiError';
8
+ this.status = status;
9
+ this.code = code;
10
+ }
11
+ }
12
+ export class CliNetworkError extends Error {
13
+ cause;
14
+ constructor(message, cause) {
15
+ super(message);
16
+ this.name = 'CliNetworkError';
17
+ this.cause = cause;
18
+ }
19
+ }
20
+ function buildBaseUrl() {
21
+ const raw = config.get('neetruApiUrl') ?? 'https://api.neetru.com';
22
+ return raw.replace(/\/+$/, '');
23
+ }
24
+ export async function apiRequest(path, opts = {}) {
25
+ const baseUrl = buildBaseUrl();
26
+ const url = `${baseUrl}${path.startsWith('/') ? path : `/${path}`}`;
27
+ const token = opts.token ?? config.get('neetruApiKey');
28
+ const headers = {
29
+ 'content-type': 'application/json',
30
+ accept: 'application/json',
31
+ };
32
+ if (token)
33
+ headers['authorization'] = `Bearer ${token}`;
34
+ let response;
35
+ try {
36
+ response = await fetch(url, {
37
+ method: opts.method ?? 'GET',
38
+ headers,
39
+ body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,
40
+ signal: opts.signal,
41
+ });
42
+ }
43
+ catch (error) {
44
+ throw new CliNetworkError(`Falha ao contactar ${url}: ${error.message}`, error);
45
+ }
46
+ const text = await response.text();
47
+ let parsed = undefined;
48
+ if (text) {
49
+ try {
50
+ parsed = JSON.parse(text);
51
+ }
52
+ catch {
53
+ // server returned non-JSON (e.g. 502 from infra) — surface as error
54
+ }
55
+ }
56
+ if (!response.ok) {
57
+ const errBody = parsed;
58
+ const code = errBody?.error?.code ?? `http_${response.status}`;
59
+ const message = errBody?.error?.message ??
60
+ (typeof parsed === 'string' ? parsed : `Erro HTTP ${response.status}`);
61
+ throw new CliApiError(response.status, code, message);
62
+ }
63
+ return parsed;
64
+ }
65
+ //# sourceMappingURL=api-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-client.js","sourceRoot":"","sources":["../../src/lib/api-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface NeetruAuth {
2
+ token: string;
3
+ email: string;
4
+ savedAt: string;
5
+ }
6
+ export declare function getAuthFilePath(): string;
7
+ export declare class AuthFileMissingError extends Error {
8
+ constructor();
9
+ }
10
+ export declare class AuthFileInvalidError extends Error {
11
+ constructor(message: string);
12
+ }
13
+ export declare function loadToken(): Promise<NeetruAuth>;
14
+ export declare function saveToken(token: string, email: string): Promise<string>;
15
+ export declare function clearToken(): Promise<boolean>;
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Token storage for `neetru` CLI — `~/.config/neetru-cli/auth.json`.
3
+ *
4
+ * Sprint 1 — Device Code OAuth (RFC 8628). Replaces the legacy `Conf`-based
5
+ * `neetruApiKey` storage with a dedicated file we can chmod 0600 explicitly.
6
+ *
7
+ * File shape:
8
+ * ```json
9
+ * {
10
+ * "token": "nrt_<keyId>_<secret>",
11
+ * "email": "owner@neetru.com",
12
+ * "savedAt": "2026-05-05T12:00:00.000Z"
13
+ * }
14
+ * ```
15
+ */
16
+ import { promises as fs, existsSync } from 'node:fs';
17
+ import { dirname, join } from 'node:path';
18
+ import { homedir } from 'node:os';
19
+ export function getAuthFilePath() {
20
+ // XDG-ish location; works on Linux, macOS, and Windows (homedir resolves
21
+ // %USERPROFILE%). We deliberately don't honor $XDG_CONFIG_HOME — keeps the
22
+ // path stable for `neetru logout` and docs.
23
+ return join(homedir(), '.config', 'neetru-cli', 'auth.json');
24
+ }
25
+ export class AuthFileMissingError extends Error {
26
+ constructor() {
27
+ super('Não autenticado. Execute: neetru login');
28
+ this.name = 'AuthFileMissingError';
29
+ }
30
+ }
31
+ export class AuthFileInvalidError extends Error {
32
+ constructor(message) {
33
+ super(message);
34
+ this.name = 'AuthFileInvalidError';
35
+ }
36
+ }
37
+ export async function loadToken() {
38
+ const path = getAuthFilePath();
39
+ if (!existsSync(path)) {
40
+ throw new AuthFileMissingError();
41
+ }
42
+ let raw;
43
+ try {
44
+ raw = await fs.readFile(path, 'utf8');
45
+ }
46
+ catch (err) {
47
+ throw new AuthFileInvalidError(`Falha ao ler ${path}: ${err.message}`);
48
+ }
49
+ let parsed;
50
+ try {
51
+ parsed = JSON.parse(raw);
52
+ }
53
+ catch {
54
+ throw new AuthFileInvalidError(`Arquivo ${path} corrompido. Execute: neetru logout && neetru login`);
55
+ }
56
+ const data = parsed;
57
+ if (!data ||
58
+ typeof data.token !== 'string' ||
59
+ typeof data.email !== 'string' ||
60
+ typeof data.savedAt !== 'string') {
61
+ throw new AuthFileInvalidError(`Arquivo ${path} incompleto. Execute: neetru logout && neetru login`);
62
+ }
63
+ return { token: data.token, email: data.email, savedAt: data.savedAt };
64
+ }
65
+ export async function saveToken(token, email) {
66
+ const path = getAuthFilePath();
67
+ const dir = dirname(path);
68
+ // Garante diretório (mode 0700 é redundante em Windows mas é o intent).
69
+ await fs.mkdir(dir, { recursive: true, mode: 0o700 });
70
+ const payload = {
71
+ token,
72
+ email,
73
+ savedAt: new Date().toISOString(),
74
+ };
75
+ // Escreve com mode restritivo. Em Windows, fs.chmod no-ops em parte mas o
76
+ // arquivo continua visível só pra owner via NTFS herdado de %USERPROFILE%.
77
+ await fs.writeFile(path, JSON.stringify(payload, null, 2), {
78
+ encoding: 'utf8',
79
+ mode: 0o600,
80
+ });
81
+ // Defensive chmod — writeFile mode acima é só a cria; se já existia, força.
82
+ try {
83
+ await fs.chmod(path, 0o600);
84
+ }
85
+ catch {
86
+ // Em Windows alguns runtimes tratam mode 0600 como read-only flag;
87
+ // ignoramos erro silenciosamente.
88
+ }
89
+ return path;
90
+ }
91
+ export async function clearToken() {
92
+ const path = getAuthFilePath();
93
+ if (!existsSync(path))
94
+ return false;
95
+ await fs.unlink(path);
96
+ return true;
97
+ }
98
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ import { z } from 'zod';
2
+ export declare const PUBLIC_PRODUCT_ICON_KEYS: readonly ["activity", "factory", "chart", "shield", "spark", "target", "trending"];
3
+ export declare const PUBLIC_PRODUCT_STATUSES: readonly ["live", "soon", "beta"];
4
+ export declare const RUNTIMES: readonly ["nextjs", "node-api"];
5
+ export declare const slugSchema: z.ZodString;
6
+ export declare const publishBlockSchema: z.ZodObject<{
7
+ tagline: z.ZodString;
8
+ description: z.ZodString;
9
+ iconKey: z.ZodEnum<["activity", "factory", "chart", "shield", "spark", "target", "trending"]>;
10
+ status: z.ZodEnum<["live", "soon", "beta"]>;
11
+ order: z.ZodOptional<z.ZodNumber>;
12
+ ctaHref: z.ZodOptional<z.ZodString>;
13
+ ctaLabel: z.ZodOptional<z.ZodString>;
14
+ }, "strip", z.ZodTypeAny, {
15
+ description: string;
16
+ status: "soon" | "live" | "beta";
17
+ tagline: string;
18
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
19
+ order?: number | undefined;
20
+ ctaHref?: string | undefined;
21
+ ctaLabel?: string | undefined;
22
+ }, {
23
+ description: string;
24
+ status: "soon" | "live" | "beta";
25
+ tagline: string;
26
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
27
+ order?: number | undefined;
28
+ ctaHref?: string | undefined;
29
+ ctaLabel?: string | undefined;
30
+ }>;
31
+ export declare const deployBlockSchema: z.ZodObject<{
32
+ region: z.ZodOptional<z.ZodString>;
33
+ serviceName: z.ZodOptional<z.ZodString>;
34
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
35
+ region: z.ZodOptional<z.ZodString>;
36
+ serviceName: z.ZodOptional<z.ZodString>;
37
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
38
+ region: z.ZodOptional<z.ZodString>;
39
+ serviceName: z.ZodOptional<z.ZodString>;
40
+ }, z.ZodTypeAny, "passthrough">>;
41
+ export declare const neetruConfigSchema: z.ZodObject<{
42
+ $schema: z.ZodOptional<z.ZodString>;
43
+ slug: z.ZodString;
44
+ name: z.ZodString;
45
+ runtime: z.ZodEnum<["nextjs", "node-api"]>;
46
+ tenantId: z.ZodOptional<z.ZodString>;
47
+ publish: z.ZodOptional<z.ZodObject<{
48
+ tagline: z.ZodString;
49
+ description: z.ZodString;
50
+ iconKey: z.ZodEnum<["activity", "factory", "chart", "shield", "spark", "target", "trending"]>;
51
+ status: z.ZodEnum<["live", "soon", "beta"]>;
52
+ order: z.ZodOptional<z.ZodNumber>;
53
+ ctaHref: z.ZodOptional<z.ZodString>;
54
+ ctaLabel: z.ZodOptional<z.ZodString>;
55
+ }, "strip", z.ZodTypeAny, {
56
+ description: string;
57
+ status: "soon" | "live" | "beta";
58
+ tagline: string;
59
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
60
+ order?: number | undefined;
61
+ ctaHref?: string | undefined;
62
+ ctaLabel?: string | undefined;
63
+ }, {
64
+ description: string;
65
+ status: "soon" | "live" | "beta";
66
+ tagline: string;
67
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
68
+ order?: number | undefined;
69
+ ctaHref?: string | undefined;
70
+ ctaLabel?: string | undefined;
71
+ }>>;
72
+ deploy: z.ZodOptional<z.ZodObject<{
73
+ region: z.ZodOptional<z.ZodString>;
74
+ serviceName: z.ZodOptional<z.ZodString>;
75
+ }, "passthrough", z.ZodTypeAny, z.objectOutputType<{
76
+ region: z.ZodOptional<z.ZodString>;
77
+ serviceName: z.ZodOptional<z.ZodString>;
78
+ }, z.ZodTypeAny, "passthrough">, z.objectInputType<{
79
+ region: z.ZodOptional<z.ZodString>;
80
+ serviceName: z.ZodOptional<z.ZodString>;
81
+ }, z.ZodTypeAny, "passthrough">>>;
82
+ }, "strip", z.ZodTypeAny, {
83
+ name: string;
84
+ slug: string;
85
+ runtime: "nextjs" | "node-api";
86
+ $schema?: string | undefined;
87
+ tenantId?: string | undefined;
88
+ publish?: {
89
+ description: string;
90
+ status: "soon" | "live" | "beta";
91
+ tagline: string;
92
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
93
+ order?: number | undefined;
94
+ ctaHref?: string | undefined;
95
+ ctaLabel?: string | undefined;
96
+ } | undefined;
97
+ deploy?: z.objectOutputType<{
98
+ region: z.ZodOptional<z.ZodString>;
99
+ serviceName: z.ZodOptional<z.ZodString>;
100
+ }, z.ZodTypeAny, "passthrough"> | undefined;
101
+ }, {
102
+ name: string;
103
+ slug: string;
104
+ runtime: "nextjs" | "node-api";
105
+ $schema?: string | undefined;
106
+ tenantId?: string | undefined;
107
+ publish?: {
108
+ description: string;
109
+ status: "soon" | "live" | "beta";
110
+ tagline: string;
111
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
112
+ order?: number | undefined;
113
+ ctaHref?: string | undefined;
114
+ ctaLabel?: string | undefined;
115
+ } | undefined;
116
+ deploy?: z.objectInputType<{
117
+ region: z.ZodOptional<z.ZodString>;
118
+ serviceName: z.ZodOptional<z.ZodString>;
119
+ }, z.ZodTypeAny, "passthrough"> | undefined;
120
+ }>;
121
+ export type NeetruConfig = z.infer<typeof neetruConfigSchema>;
122
+ export type PublishBlock = z.infer<typeof publishBlockSchema>;
123
+ export declare const catalogUpsertPayloadSchema: z.ZodObject<{
124
+ slug: z.ZodString;
125
+ name: z.ZodString;
126
+ tagline: z.ZodString;
127
+ description: z.ZodString;
128
+ iconKey: z.ZodEnum<["activity", "factory", "chart", "shield", "spark", "target", "trending"]>;
129
+ status: z.ZodEnum<["live", "soon", "beta"]>;
130
+ order: z.ZodNumber;
131
+ published: z.ZodBoolean;
132
+ ctaHref: z.ZodOptional<z.ZodString>;
133
+ ctaLabel: z.ZodOptional<z.ZodString>;
134
+ }, "strip", z.ZodTypeAny, {
135
+ description: string;
136
+ name: string;
137
+ status: "soon" | "live" | "beta";
138
+ slug: string;
139
+ tagline: string;
140
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
141
+ order: number;
142
+ published: boolean;
143
+ ctaHref?: string | undefined;
144
+ ctaLabel?: string | undefined;
145
+ }, {
146
+ description: string;
147
+ name: string;
148
+ status: "soon" | "live" | "beta";
149
+ slug: string;
150
+ tagline: string;
151
+ iconKey: "spark" | "target" | "activity" | "factory" | "chart" | "shield" | "trending";
152
+ order: number;
153
+ published: boolean;
154
+ ctaHref?: string | undefined;
155
+ ctaLabel?: string | undefined;
156
+ }>;
157
+ export type CatalogUpsertPayload = z.infer<typeof catalogUpsertPayloadSchema>;
158
+ export declare const catalogUnpublishPayloadSchema: z.ZodObject<{
159
+ slug: z.ZodString;
160
+ }, "strip", z.ZodTypeAny, {
161
+ slug: string;
162
+ }, {
163
+ slug: string;
164
+ }>;
165
+ export type CatalogUnpublishPayload = z.infer<typeof catalogUnpublishPayloadSchema>;
@@ -0,0 +1,57 @@
1
+ import { z } from 'zod';
2
+ export const PUBLIC_PRODUCT_ICON_KEYS = [
3
+ 'activity',
4
+ 'factory',
5
+ 'chart',
6
+ 'shield',
7
+ 'spark',
8
+ 'target',
9
+ 'trending',
10
+ ];
11
+ export const PUBLIC_PRODUCT_STATUSES = ['live', 'soon', 'beta'];
12
+ export const RUNTIMES = ['nextjs', 'node-api'];
13
+ export const slugSchema = z
14
+ .string()
15
+ .min(2, 'slug deve ter pelo menos 2 caracteres')
16
+ .max(64, 'slug deve ter no máximo 64 caracteres')
17
+ .regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, 'slug deve estar em kebab-case (lowercase, dígitos, hífens)');
18
+ export const publishBlockSchema = z.object({
19
+ tagline: z.string().min(2).max(120),
20
+ description: z.string().min(10).max(2000),
21
+ iconKey: z.enum(PUBLIC_PRODUCT_ICON_KEYS),
22
+ status: z.enum(PUBLIC_PRODUCT_STATUSES),
23
+ order: z.number().int().nonnegative().optional(),
24
+ ctaHref: z.string().url().optional(),
25
+ ctaLabel: z.string().min(1).max(60).optional(),
26
+ });
27
+ export const deployBlockSchema = z
28
+ .object({
29
+ region: z.string().optional(),
30
+ serviceName: z.string().optional(),
31
+ })
32
+ .passthrough();
33
+ export const neetruConfigSchema = z.object({
34
+ $schema: z.string().optional(),
35
+ slug: slugSchema,
36
+ name: z.string().min(2).max(80),
37
+ runtime: z.enum(RUNTIMES),
38
+ tenantId: z.string().optional(),
39
+ publish: publishBlockSchema.optional(),
40
+ deploy: deployBlockSchema.optional(),
41
+ });
42
+ export const catalogUpsertPayloadSchema = z.object({
43
+ slug: slugSchema,
44
+ name: z.string().min(2).max(80),
45
+ tagline: z.string().min(2).max(120),
46
+ description: z.string().min(10).max(2000),
47
+ iconKey: z.enum(PUBLIC_PRODUCT_ICON_KEYS),
48
+ status: z.enum(PUBLIC_PRODUCT_STATUSES),
49
+ order: z.number().int().nonnegative(),
50
+ published: z.boolean(),
51
+ ctaHref: z.string().url().optional(),
52
+ ctaLabel: z.string().min(1).max(60).optional(),
53
+ });
54
+ export const catalogUnpublishPayloadSchema = z.object({
55
+ slug: slugSchema,
56
+ });
57
+ //# sourceMappingURL=config-schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-schema.js","sourceRoot":"","sources":["../../src/lib/config-schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import Conf from 'conf';
2
+ interface NeetruConfig {
3
+ anthropicApiKey?: string;
4
+ openaiApiKey?: string;
5
+ geminiApiKey?: string;
6
+ neetruApiKey?: string;
7
+ neetruApiUrl: string;
8
+ defaultModel: 'claude' | 'openai' | 'gemini' | 'auto';
9
+ projectName?: string;
10
+ 'telemetry.enabled'?: boolean;
11
+ }
12
+ export declare const config: Conf<NeetruConfig>;
13
+ export declare function getKey(name: keyof NeetruConfig): string | boolean | undefined;
14
+ export declare function requireKey(name: 'anthropicApiKey' | 'openaiApiKey' | 'geminiApiKey' | 'neetruApiKey'): string;
15
+ export {};
@@ -0,0 +1,33 @@
1
+ import Conf from 'conf';
2
+ const defaults = {
3
+ neetruApiUrl: 'https://api.neetru.com',
4
+ defaultModel: 'auto',
5
+ };
6
+ export const config = new Conf({
7
+ projectName: 'neetru-cli',
8
+ defaults,
9
+ schema: {
10
+ anthropicApiKey: { type: 'string' },
11
+ openaiApiKey: { type: 'string' },
12
+ geminiApiKey: { type: 'string' },
13
+ neetruApiKey: { type: 'string' },
14
+ neetruApiUrl: { type: 'string', default: 'https://api.neetru.com' },
15
+ defaultModel: {
16
+ type: 'string',
17
+ enum: ['claude', 'openai', 'gemini', 'auto'],
18
+ default: 'auto',
19
+ },
20
+ 'telemetry.enabled': { type: 'boolean' },
21
+ },
22
+ });
23
+ export function getKey(name) {
24
+ return config.get(name);
25
+ }
26
+ export function requireKey(name) {
27
+ const val = config.get(name);
28
+ if (!val) {
29
+ throw new Error(`Chave "${name}" não configurada. Execute: neetru config set ${name} <valor>`);
30
+ }
31
+ return val;
32
+ }
33
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAiBxB,MAAM,QAAQ,GAAiB;IAC7B,YAAY,EAAE,wBAAwB;IACtC,YAAY,EAAE,MAAM;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IAC3C,WAAW,EAAE,YAAY;IACzB,QAAQ;IACR,MAAM,EAAE;QACN,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QACnC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;QAChC,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,wBAAwB,EAAE;QACnE,YAAY,EAAE;YACZ,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC;YAC5C,OAAO,EAAE,MAAM;SAChB;QACD,mBAAmB,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;KACzC;CACF,CAAC,CAAC;AAEH,MAAM,UAAU,MAAM,CAAC,IAAwB;IAC7C,OAAO,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAA0E;IACnG,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,UAAU,IAAI,iDAAiD,IAAI,UAAU,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,13 @@
1
+ export declare const log: {
2
+ info: (msg: string) => void;
3
+ success: (msg: string) => void;
4
+ warn: (msg: string) => void;
5
+ error: (msg: string) => void;
6
+ dim: (msg: string) => void;
7
+ brand: (msg: string) => void;
8
+ heading: (msg: string) => void;
9
+ banner(): void;
10
+ separator(): void;
11
+ stream: (chunk: string) => boolean;
12
+ newline: () => boolean;
13
+ };
@@ -0,0 +1,27 @@
1
+ import chalk from 'chalk';
2
+ // Brand palette
3
+ const brand = chalk.hex('#1E90FF');
4
+ const brandDim = chalk.hex('#1E90FF').dim;
5
+ const ink = chalk.hex('#07090D');
6
+ export const log = {
7
+ info: (msg) => console.log(` ${chalk.blue('ℹ')} ${msg}`),
8
+ success: (msg) => console.log(` ${chalk.green('✓')} ${msg}`),
9
+ warn: (msg) => console.log(` ${chalk.yellow('⚠')} ${msg}`),
10
+ error: (msg) => console.error(` ${chalk.red('✖')} ${msg}`),
11
+ dim: (msg) => console.log(chalk.dim(` ${msg}`)),
12
+ brand: (msg) => console.log(brand(msg)),
13
+ heading: (msg) => console.log(`\n${chalk.bold(msg)}`),
14
+ banner() {
15
+ console.log();
16
+ console.log(brand.bold(' ◆ Neetru CLI'));
17
+ console.log(chalk.dim(' Developer Kit · neetru.com'));
18
+ console.log();
19
+ },
20
+ separator() {
21
+ console.log(chalk.dim(' ' + '─'.repeat(56)));
22
+ },
23
+ // Para streaming de AI: escreve sem newline
24
+ stream: (chunk) => process.stdout.write(chunk),
25
+ newline: () => process.stdout.write('\n'),
26
+ };
27
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/utils/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,gBAAgB;AAChB,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACnC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC;AAC1C,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAEjC,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACjE,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACrE,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACnE,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC;IACnE,GAAG,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IAExD,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/C,OAAO,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;IAE7D,MAAM;QACJ,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,SAAS;QACP,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,4CAA4C;IAC5C,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC;IACtD,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;CAC1C,CAAC"}
package/package.json CHANGED
@@ -1,58 +1,60 @@
1
1
  {
2
2
  "name": "@neetru/cli",
3
- "version": "1.0.1",
4
- "description": "Neetru CLI — SDK scaffolding e DevOps para integrar seu SaaS com Neetru Core (auth, billing, usage, deploy, logs)",
3
+ "version": "2.0.0",
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/core.git",
20
+ "directory": "cli"
21
+ },
22
+ "author": "Neetru Inc. <neetrucode@gmail.com>",
23
+ "license": "MIT",
5
24
  "bin": {
6
25
  "neetru": "./dist/index.js"
7
26
  },
8
27
  "main": "./dist/index.js",
9
28
  "files": [
10
29
  "dist",
30
+ "templates",
11
31
  "README.md",
12
- "LICENSE"
32
+ "CHANGELOG.md"
13
33
  ],
14
34
  "scripts": {
15
35
  "build": "tsc",
16
- "dev": "ts-node src/index.ts",
36
+ "dev": "tsx src/index.ts",
17
37
  "start": "node dist/index.js",
18
38
  "prepublishOnly": "npm run build"
19
39
  },
20
40
  "dependencies": {
21
- "chalk": "^5.3.0",
41
+ "@anthropic-ai/sdk": "^0.52.0",
42
+ "chalk": "^5.4.1",
22
43
  "commander": "^12.1.0",
23
- "inquirer": "^9.2.23",
24
- "ora": "^8.1.0",
25
- "fs-extra": "^11.2.0"
44
+ "conf": "^13.0.1",
45
+ "inquirer": "^10.2.2",
46
+ "openai": "^4.77.0",
47
+ "ora": "^8.1.1",
48
+ "zod": "^3.24.2"
26
49
  },
27
50
  "devDependencies": {
28
- "@types/fs-extra": "^11.0.4",
29
51
  "@types/inquirer": "^9.0.7",
30
- "@types/node": "^20.0.0",
31
- "typescript": "^5.4.0",
32
- "ts-node": "^10.9.2"
52
+ "@types/node": "^22.0.0",
53
+ "tsx": "^4.19.1",
54
+ "typescript": "^5.7.0"
33
55
  },
34
56
  "engines": {
35
- "node": ">=18"
36
- },
37
- "keywords": [
38
- "neetru",
39
- "saas",
40
- "oauth",
41
- "billing",
42
- "cli",
43
- "sdk",
44
- "devops",
45
- "deploy",
46
- "metered-billing"
47
- ],
48
- "license": "MIT",
49
- "homepage": "https://github.com/neetru/cli#readme",
50
- "repository": {
51
- "type": "git",
52
- "url": "git+https://github.com/neetru/cli.git"
53
- },
54
- "bugs": {
55
- "url": "https://github.com/neetru/cli/issues"
57
+ "node": ">=20"
56
58
  },
57
59
  "publishConfig": {
58
60
  "access": "public"
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Template — `src/lib/neetru/auth/callback.ts` (gerado por `neetru add auth`).
3
+ *
4
+ * Handler de callback OIDC (auth code → id_token). Use em `app/oauth/callback/route.ts`.
5
+ */
6
+ import { NextRequest, NextResponse } from 'next/server';
7
+
8
+ export const runtime = 'nodejs';
9
+
10
+ export async function GET(request: NextRequest) {
11
+ const { searchParams } = new URL(request.url);
12
+ const code = searchParams.get('code');
13
+ const state = searchParams.get('state');
14
+
15
+ if (!code) {
16
+ return NextResponse.json({ error: 'missing_code' }, { status: 400 });
17
+ }
18
+
19
+ // Trocar code → id_token contra auth.neetru.com/token
20
+ // Implementação detalhada em docs/PLATFORM_AUTH.md §4
21
+ return NextResponse.redirect(state ?? '/');
22
+ }