@neetru/cli 2.11.1 → 2.11.3

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/README.md CHANGED
@@ -1,141 +1,141 @@
1
- # @neetru/cli
2
-
3
- > Developer Kit oficial da Neetru — scaffolding, IA Neetru-aware, deploy de produtos SaaS, gestão de workspaces, bancos isolados por produto, e mais 40+ comandos pra operar todo o ecossistema Neetru via terminal.
4
-
5
- <p>
6
- <img alt="npm" src="https://img.shields.io/npm/v/@neetru/cli?logo=npm">
7
- <img alt="downloads" src="https://img.shields.io/npm/dm/@neetru/cli?logo=npm">
8
- <img alt="Node" src="https://img.shields.io/badge/node-%3E%3D22-339933?logo=node.js&logoColor=white">
9
- <img alt="license" src="https://img.shields.io/badge/license-MIT-22c55e">
10
- </p>
11
-
12
- ## Instalação
13
-
14
- ```bash
15
- npm install -g @neetru/cli
16
- ```
17
-
18
- Bootstrap completo da máquina dev (Node, gcloud, Docker, Firebase CLI, deps NPM, GCP ADC):
19
-
20
- ```bash
21
- neetru bootstrap
22
- ```
23
-
24
- Login no Core via OAuth Device Code Flow:
25
-
26
- ```bash
27
- neetru login
28
- ```
29
-
30
- Validar estado:
31
-
32
- ```bash
33
- neetru doctor
34
- ```
35
-
36
- ## Quickstart — criar produto SaaS novo
37
-
38
- ```bash
39
- neetru new gestovendas --env=dev --tier=dev --customer=neetru
40
- ```
41
-
42
- Cria produto + workspace + scaffold local Next.js 15 + instala deps + abre cockpit no browser.
43
-
44
- ## Comandos principais
45
-
46
- | Comando | O que faz |
47
- |---|---|
48
- | `neetru bootstrap` | Setup da máquina dev (binários + deps + ADC) |
49
- | `neetru login` / `logout` / `whoami` | Auth OAuth Device Code Flow |
50
- | `neetru doctor` | Diagnóstico saúde (5 checks rápidos) |
51
- | `neetru new <slug>` | Criar produto completo (registry + workspace + scaffold) |
52
- | `neetru init <name>` | Só scaffold local Next.js + Firebase |
53
- | `neetru add <feature>` | Adicionar features ao scaffold (auth, billing, etc) |
54
- | `neetru deploy` | Pipeline de deploy interativo (cloud-run / vm / workspace) |
55
- | `neetru build` | Empacotar produto em tarball pra deploy |
56
- | `neetru promote` | Promover dev → staging → prod |
57
- | `neetru env switch <target>` | Trocar `NEETRU_ENV` no `.env.local` |
58
- | `neetru env set --service=X --set KEY=VAL` | Setar env vars de serviço Cloud Run |
59
- | `neetru ar create <name>` | Criar repositório Artifact Registry |
60
- | `neetru hosting create-mapping --service=X --domain=Y` | Domain mapping |
61
- | `neetru db create --product=X --engine=postgres` | Criar banco por produto |
62
- | `neetru db engines` | Listar engines disponíveis (firestore, postgres, mysql) |
63
- | `neetru cloud-run pause/resume/delete <service>` | Controle Cloud Run |
64
- | `neetru products list/create/update` | Registry de produtos |
65
- | `neetru workspaces create/list/get/advance` | Instâncias por cliente |
66
- | `neetru deployments create/rollback` | Histórico de deploys |
67
- | `neetru tenants list/create/update/suspend` | Gerenciar tenants |
68
- | `neetru audit tail` | Tail de `audit_logs/` em tempo real |
69
- | `neetru billing summary` | Resumo de billing |
70
- | `neetru servers list/provision/deactivate` | Gerenciar servidores |
71
- | `neetru agent release/yank/canary` | Gerenciar releases do agente |
72
- | `neetru support tickets list/reply/assign` | Suporte inbox staff |
73
- | `neetru dns zones list` / `hosting list` | Listar DNS + customer domains |
74
- | `neetru builds list` | Listar Cloud Build |
75
- | `neetru dr exports/restore` | Disaster Recovery |
76
- | `neetru logs` | Ver logs de produtos |
77
- | `neetru status` | Visão geral do ecossistema |
78
- | `neetru open <produto>` | Abrir cockpit do produto no browser |
79
- | `neetru ai` | REPL IA Neetru-aware (Claude/OpenAI/Gemini) |
80
- | `neetru ui` | Menu interativo do CLI |
81
- | `neetru publish` | Publicar produto no catálogo público |
82
- | `neetru upgrade` | Auto-update do CLI |
83
- | `neetru autocomplete <bash\|zsh\|pwsh>` | Gerar script autocomplete |
84
-
85
- **Atalhos:** `neetru ar` = `artifact-registry`, `neetru menu` = `ui`.
86
-
87
- 40+ subcomandos. Quase todos suportam `--json` pra automação.
88
-
89
- ## Configuração
90
-
91
- Token Bearer fica em `~/.config/neetru-cli/auth.json` (chmod 0600 em Unix, NTFS ACL em Windows) — gerado por `neetru login` via OAuth Device Code Flow. Configs gerais ficam em `~/.config/neetru-cli/config.json` (Linux/macOS) ou `%APPDATA%\neetru-cli\config.json` (Windows):
92
-
93
- | Chave | Valor |
94
- |---|---|
95
- | `neetruApiUrl` | URL base do Core (default `https://api.neetru.com`). **Allowlist** desde 2.11.0: `*.neetru.com` + `localhost`; demais hosts exigem `--allow-untrusted-url` |
96
- | `defaultModel` | `claude` / `openai` / `gemini` / `auto` (REPL `neetru ai`) |
97
- | `telemetry.enabled` | Telemetry opt-in (default `false`) — desde 2.11.0 emite eventos anônimos pra `/api/sdk/v1/telemetry/log` |
98
- | `neetruApiKey` | **(legado)** Token em Conf — substituído por `auth.json`. Será removido em 2.12.0 |
99
-
100
- ```bash
101
- neetru config set telemetry.enabled true
102
- neetru config get neetruApiUrl
103
- neetru config path # mostra caminho do config file
104
- neetru config set neetruApiUrl https://staging.neetru.com # subdomínio neetru.com — OK
105
- neetru config set neetruApiUrl http://my-proxy.local --allow-untrusted-url # explicit opt-in
106
- ```
107
-
108
- ## Output JSON
109
-
110
- ```bash
111
- neetru products list --json | jq '.[] | select(.status == "ativo")'
112
- neetru audit tail --json | jq 'select(.action | startswith("billing"))'
113
- ```
114
-
115
- ## Auth & Segurança
116
-
117
- - **OAuth Device Code Flow** (RFC 8628) pra login interativo — não armazena password
118
- - **Tokens** salvos em `~/.config/neetru-cli/auth.json` (chmod 0600 em Unix, NTFS ACL em Windows). Desde 2.11.0 o resolver canônico (`getActiveTokenSync`) prefere esse arquivo sobre o Conf storage legado (que será removido em 2.12.0)
119
- - **URL allowlist** (desde 2.11.0): `neetruApiUrl` rejeita hosts fora de `*.neetru.com` + `localhost` sem `--allow-untrusted-url` — fecha vetor de exfiltração do Bearer token
120
- - **Rate-limit** por método HTTP: GET 120/min, POST/PUT/PATCH 30/min, DELETE 5/min
121
- - **Step-up MFA** (TOTP) obrigatório em operações destrutivas: `--mfa-token <code>` ou prompt
122
- - **Dry-run** disponível em comandos de mutação: `--dry-run` mostra efeito SEM aplicar
123
- - **Telemetry** opt-in (desde 2.11.0): habilitando `telemetry.enabled=true` o CLI emite `{command, durationMs, ok, exitCode}` anônimo via `installId` UUID. Zero token/path/email/env vazam
124
-
125
- ## Stack
126
-
127
- - TypeScript 5 ESM-first
128
- - Node 22+ (LTS)
129
- - Sem `node-fetch`/`axios`: fetch global nativo
130
- - Commander 11 (CLI framework) + Inquirer 12 (prompts) + Chalk 5 + Ora (spinners)
131
-
132
- ## Mais info
133
-
134
- - **Repo:** [github.com/Neetru/neetru-core](https://github.com/Neetru/neetru-core)
135
- - **Docs:** [docs.neetru.com](https://docs.neetru.com)
136
- - **SDK complementar:** `npm install @neetru/sdk`
137
- - **Issues / suporte:** abrir issue no repo ou `neetru support`
138
-
139
- ## Licença
140
-
141
- MIT © Neetru
1
+ # @neetru/cli
2
+
3
+ > Developer Kit oficial da Neetru — scaffolding, IA Neetru-aware, deploy de produtos SaaS, gestão de workspaces, bancos isolados por produto, e mais 40+ comandos pra operar todo o ecossistema Neetru via terminal.
4
+
5
+ <p>
6
+ <img alt="npm" src="https://img.shields.io/npm/v/@neetru/cli?logo=npm">
7
+ <img alt="downloads" src="https://img.shields.io/npm/dm/@neetru/cli?logo=npm">
8
+ <img alt="Node" src="https://img.shields.io/badge/node-%3E%3D22-339933?logo=node.js&logoColor=white">
9
+ <img alt="license" src="https://img.shields.io/badge/license-MIT-22c55e">
10
+ </p>
11
+
12
+ ## Instalação
13
+
14
+ ```bash
15
+ npm install -g @neetru/cli
16
+ ```
17
+
18
+ Bootstrap completo da máquina dev (Node, gcloud, Docker, Firebase CLI, deps NPM, GCP ADC):
19
+
20
+ ```bash
21
+ neetru bootstrap
22
+ ```
23
+
24
+ Login no Core via OAuth Device Code Flow:
25
+
26
+ ```bash
27
+ neetru login
28
+ ```
29
+
30
+ Validar estado:
31
+
32
+ ```bash
33
+ neetru doctor
34
+ ```
35
+
36
+ ## Quickstart — criar produto SaaS novo
37
+
38
+ ```bash
39
+ neetru new gestovendas --env=dev --tier=dev --customer=neetru
40
+ ```
41
+
42
+ Cria produto + workspace + scaffold local Next.js 15 + instala deps + abre cockpit no browser.
43
+
44
+ ## Comandos principais
45
+
46
+ | Comando | O que faz |
47
+ |---|---|
48
+ | `neetru bootstrap` | Setup da máquina dev (binários + deps + ADC) |
49
+ | `neetru login` / `logout` / `whoami` | Auth OAuth Device Code Flow |
50
+ | `neetru doctor` | Diagnóstico saúde (5 checks rápidos) |
51
+ | `neetru new <slug>` | Criar produto completo (registry + workspace + scaffold) |
52
+ | `neetru init <name>` | Só scaffold local Next.js + Firebase |
53
+ | `neetru add <feature>` | Adicionar features ao scaffold (auth, billing, etc) |
54
+ | `neetru deploy` | Pipeline de deploy interativo (cloud-run / vm / workspace) |
55
+ | `neetru build` | Empacotar produto em tarball pra deploy |
56
+ | `neetru promote` | Promover dev → staging → prod |
57
+ | `neetru env switch <target>` | Trocar `NEETRU_ENV` no `.env.local` |
58
+ | `neetru env set --service=X --set KEY=VAL` | Setar env vars de serviço Cloud Run |
59
+ | `neetru ar create <name>` | Criar repositório Artifact Registry |
60
+ | `neetru hosting create-mapping --service=X --domain=Y` | Domain mapping |
61
+ | `neetru db create --product=X --engine=postgres` | Criar banco por produto |
62
+ | `neetru db engines` | Listar engines disponíveis (firestore, postgres, mysql) |
63
+ | `neetru cloud-run pause/resume/delete <service>` | Controle Cloud Run |
64
+ | `neetru products list/create/update` | Registry de produtos |
65
+ | `neetru workspaces create/list/get/advance` | Instâncias por cliente |
66
+ | `neetru deployments create/rollback` | Histórico de deploys |
67
+ | `neetru tenants list/create/update/suspend` | Gerenciar tenants |
68
+ | `neetru audit tail` | Tail de `audit_logs/` em tempo real |
69
+ | `neetru billing summary` | Resumo de billing |
70
+ | `neetru servers list/provision/deactivate` | Gerenciar servidores |
71
+ | `neetru agent release/yank/canary` | Gerenciar releases do agente |
72
+ | `neetru support tickets list/reply/assign` | Suporte inbox staff |
73
+ | `neetru dns zones list` / `hosting list` | Listar DNS + customer domains |
74
+ | `neetru builds list` | Listar Cloud Build |
75
+ | `neetru dr exports/restore` | Disaster Recovery |
76
+ | `neetru logs` | Ver logs de produtos |
77
+ | `neetru status` | Visão geral do ecossistema |
78
+ | `neetru open <produto>` | Abrir cockpit do produto no browser |
79
+ | `neetru ai` | REPL IA Neetru-aware (Claude/OpenAI/Gemini) |
80
+ | `neetru ui` | Menu interativo do CLI |
81
+ | `neetru publish` | Publicar produto no catálogo público |
82
+ | `neetru upgrade` | Auto-update do CLI |
83
+ | `neetru autocomplete <bash\|zsh\|pwsh>` | Gerar script autocomplete |
84
+
85
+ **Atalhos:** `neetru ar` = `artifact-registry`, `neetru menu` = `ui`.
86
+
87
+ 40+ subcomandos. Quase todos suportam `--json` pra automação.
88
+
89
+ ## Configuração
90
+
91
+ Token Bearer fica em `~/.config/neetru-cli/auth.json` (chmod 0600 em Unix, NTFS ACL em Windows) — gerado por `neetru login` via OAuth Device Code Flow. Configs gerais ficam em `~/.config/neetru-cli/config.json` (Linux/macOS) ou `%APPDATA%\neetru-cli\config.json` (Windows):
92
+
93
+ | Chave | Valor |
94
+ |---|---|
95
+ | `neetruApiUrl` | URL base do Core (default `https://api.neetru.com`). **Allowlist** desde 2.11.0: `*.neetru.com` + `localhost`; demais hosts exigem `--allow-untrusted-url` |
96
+ | `defaultModel` | `claude` / `openai` / `gemini` / `auto` (REPL `neetru ai`) |
97
+ | `telemetry.enabled` | Telemetry opt-in (default `false`) — desde 2.11.0 emite eventos anônimos pra `/api/sdk/v1/telemetry/log` |
98
+ | `neetruApiKey` | **(legado)** Token em Conf — substituído por `auth.json`. Será removido em 2.12.0 |
99
+
100
+ ```bash
101
+ neetru config set telemetry.enabled true
102
+ neetru config get neetruApiUrl
103
+ neetru config path # mostra caminho do config file
104
+ neetru config set neetruApiUrl https://staging.neetru.com # subdomínio neetru.com — OK
105
+ neetru config set neetruApiUrl http://my-proxy.local --allow-untrusted-url # explicit opt-in
106
+ ```
107
+
108
+ ## Output JSON
109
+
110
+ ```bash
111
+ neetru products list --json | jq '.[] | select(.status == "ativo")'
112
+ neetru audit tail --json | jq 'select(.action | startswith("billing"))'
113
+ ```
114
+
115
+ ## Auth & Segurança
116
+
117
+ - **OAuth Device Code Flow** (RFC 8628) pra login interativo — não armazena password
118
+ - **Tokens** salvos em `~/.config/neetru-cli/auth.json` (chmod 0600 em Unix, NTFS ACL em Windows). Desde 2.11.0 o resolver canônico (`getActiveTokenSync`) prefere esse arquivo sobre o Conf storage legado (que será removido em 2.12.0)
119
+ - **URL allowlist** (desde 2.11.0): `neetruApiUrl` rejeita hosts fora de `*.neetru.com` + `localhost` sem `--allow-untrusted-url` — fecha vetor de exfiltração do Bearer token
120
+ - **Rate-limit** por método HTTP: GET 120/min, POST/PUT/PATCH 30/min, DELETE 5/min
121
+ - **Step-up MFA** (TOTP) obrigatório em operações destrutivas: `--mfa-token <code>` ou prompt
122
+ - **Dry-run** disponível em comandos de mutação: `--dry-run` mostra efeito SEM aplicar
123
+ - **Telemetry** opt-in (desde 2.11.0): habilitando `telemetry.enabled=true` o CLI emite `{command, durationMs, ok, exitCode}` anônimo via `installId` UUID. Zero token/path/email/env vazam
124
+
125
+ ## Stack
126
+
127
+ - TypeScript 5 ESM-first
128
+ - Node 22+ (LTS)
129
+ - Sem `node-fetch`/`axios`: fetch global nativo
130
+ - Commander 11 (CLI framework) + Inquirer 12 (prompts) + Chalk 5 + Ora (spinners)
131
+
132
+ ## Mais info
133
+
134
+ - **Repo:** [github.com/Neetru/neetru-core](https://github.com/Neetru/neetru-core)
135
+ - **Docs:** [docs.neetru.com](https://docs.neetru.com)
136
+ - **SDK complementar:** `npm install @neetru/sdk`
137
+ - **Issues / suporte:** abrir issue no repo ou `neetru support`
138
+
139
+ ## Licença
140
+
141
+ MIT © Neetru
@@ -10,14 +10,14 @@ const PROMPT_PREFIX = chalk.hex('#1E90FF').bold(' › ');
10
10
  const ASSISTANT_PREFIX = chalk.dim(' ◆ ');
11
11
  // Help público — sem /modelo (orchestrator escolhe). /debug:model é o
12
12
  // override avançado pra quem quer forçar.
13
- const HELP_TEXT = `
14
- Comandos:
15
- /sair /exit encerrar sessão
16
- /limpar /clear limpar histórico de contexto
17
- /agentes <pergunta> consultar 2+ modelos em paralelo e comparar
18
- /auth rodar wizard de configuração (claude/codex/gemini)
19
- /help mostrar este texto
20
- /debug:model <nome> forçar modelo (claude|openai|gemini|auto)
13
+ const HELP_TEXT = `
14
+ Comandos:
15
+ /sair /exit encerrar sessão
16
+ /limpar /clear limpar histórico de contexto
17
+ /agentes <pergunta> consultar 2+ modelos em paralelo e comparar
18
+ /auth rodar wizard de configuração (claude/codex/gemini)
19
+ /help mostrar este texto
20
+ /debug:model <nome> forçar modelo (claude|openai|gemini|auto)
21
21
  `.trim();
22
22
  /**
23
23
  * Checa se o usuário tem pelo menos uma cred (local OU descoberta). Se zero,
@@ -84,49 +84,49 @@ export const TOP_LEVEL_COMMANDS = [
84
84
  ];
85
85
  function bashScript() {
86
86
  const cmds = TOP_LEVEL_COMMANDS.join(' ');
87
- return `# neetru CLI bash completion (v2.10.2)
88
- _neetru_complete() {
89
- local cur prev
90
- COMPREPLY=()
91
- cur="\${COMP_WORDS[COMP_CWORD]}"
92
- prev="\${COMP_WORDS[COMP_CWORD-1]}"
93
- if [ \${COMP_CWORD} -eq 1 ]; then
94
- COMPREPLY=( $(compgen -W "${cmds}" -- "\${cur}") )
95
- return 0
96
- fi
97
- }
98
- complete -F _neetru_complete neetru
87
+ return `# neetru CLI bash completion (v2.10.2)
88
+ _neetru_complete() {
89
+ local cur prev
90
+ COMPREPLY=()
91
+ cur="\${COMP_WORDS[COMP_CWORD]}"
92
+ prev="\${COMP_WORDS[COMP_CWORD-1]}"
93
+ if [ \${COMP_CWORD} -eq 1 ]; then
94
+ COMPREPLY=( $(compgen -W "${cmds}" -- "\${cur}") )
95
+ return 0
96
+ fi
97
+ }
98
+ complete -F _neetru_complete neetru
99
99
  `;
100
100
  }
101
101
  function zshScript() {
102
102
  // Formato compsys do zsh.
103
103
  const cmds = TOP_LEVEL_COMMANDS.map((c) => ` '${c}'`).join('\n');
104
- return `#compdef neetru
105
- # neetru CLI zsh completion (v2.10.2)
106
- _neetru() {
107
- local -a commands
108
- commands=(
109
- ${cmds}
110
- )
111
- if (( CURRENT == 2 )); then
112
- _describe 'command' commands
113
- fi
114
- }
115
- _neetru "$@"
104
+ return `#compdef neetru
105
+ # neetru CLI zsh completion (v2.10.2)
106
+ _neetru() {
107
+ local -a commands
108
+ commands=(
109
+ ${cmds}
110
+ )
111
+ if (( CURRENT == 2 )); then
112
+ _describe 'command' commands
113
+ fi
114
+ }
115
+ _neetru "$@"
116
116
  `;
117
117
  }
118
118
  function pwshScript() {
119
119
  const cmds = TOP_LEVEL_COMMANDS.map((c) => ` '${c}'`).join(',\n');
120
- return `# neetru CLI PowerShell completion (v2.10.2)
121
- Register-ArgumentCompleter -Native -CommandName neetru -ScriptBlock {
122
- param($wordToComplete, $commandAst, $cursorPosition)
123
- $commands = @(
124
- ${cmds}
125
- )
126
- $commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
127
- [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
128
- }
129
- }
120
+ return `# neetru CLI PowerShell completion (v2.10.2)
121
+ Register-ArgumentCompleter -Native -CommandName neetru -ScriptBlock {
122
+ param($wordToComplete, $commandAst, $cursorPosition)
123
+ $commands = @(
124
+ ${cmds}
125
+ )
126
+ $commands | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
127
+ [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
128
+ }
129
+ }
130
130
  `;
131
131
  }
132
132
  export function generateAutocompleteScript(shell) {
@@ -213,64 +213,64 @@ export async function runDbStatus(dbId, opts = {}) {
213
213
  }
214
214
  // pdv #7 fix: template diferenciado por família de engine.
215
215
  /** Template para engines NoSQL (firestore-instance). */
216
- const SCHEMA_STARTER_NOSQL = (productId, engine) => `/**
217
- * Schema do banco "${productId}" — ${ENGINE_LABELS[engine] ?? engine}.
218
- *
219
- * Gerado por \`neetru db init\`.
220
- * Edite este arquivo com as collections do seu produto.
221
- * Rode \`neetru db apply\` pra enviar a definição ao Core.
222
- *
223
- * Para bancos NoSQL (Firestore), o schema define a estrutura esperada
224
- * dos documentos. O Core usa essa definição para validação e auditoria —
225
- * o banco em si é schemaless (primeira escrita cria a estrutura).
226
- *
227
- * Documentação: https://core.neetru.com/docs/dev/db/nosql-schema
228
- */
229
-
230
- // Exemplo de collection com tipagem TypeScript pura:
231
-
232
- export interface Produto {
233
- id: string;
234
- nome: string;
235
- preco: number;
236
- ativo: boolean;
237
- criadoEm: Date;
238
- }
239
-
240
- export interface Pedido {
241
- id: string;
242
- produtoId: string;
243
- quantidade: number;
244
- total: number;
245
- status: 'pendente' | 'pago' | 'cancelado';
246
- criadoEm: Date;
247
- }
248
-
249
- // Exporte as collections que o SDK vai usar:
250
- // import { createNeetruClient } from '@neetru/sdk';
251
- // const neetru = createNeetruClient({ ... });
252
- // const produtos = neetru.db.collection<Produto>('produtos');
253
- // const pedidos = neetru.db.collection<Pedido>('pedidos');
216
+ const SCHEMA_STARTER_NOSQL = (productId, engine) => `/**
217
+ * Schema do banco "${productId}" — ${ENGINE_LABELS[engine] ?? engine}.
218
+ *
219
+ * Gerado por \`neetru db init\`.
220
+ * Edite este arquivo com as collections do seu produto.
221
+ * Rode \`neetru db apply\` pra enviar a definição ao Core.
222
+ *
223
+ * Para bancos NoSQL (Firestore), o schema define a estrutura esperada
224
+ * dos documentos. O Core usa essa definição para validação e auditoria —
225
+ * o banco em si é schemaless (primeira escrita cria a estrutura).
226
+ *
227
+ * Documentação: https://core.neetru.com/docs/dev/db/nosql-schema
228
+ */
229
+
230
+ // Exemplo de collection com tipagem TypeScript pura:
231
+
232
+ export interface Produto {
233
+ id: string;
234
+ nome: string;
235
+ preco: number;
236
+ ativo: boolean;
237
+ criadoEm: Date;
238
+ }
239
+
240
+ export interface Pedido {
241
+ id: string;
242
+ produtoId: string;
243
+ quantidade: number;
244
+ total: number;
245
+ status: 'pendente' | 'pago' | 'cancelado';
246
+ criadoEm: Date;
247
+ }
248
+
249
+ // Exporte as collections que o SDK vai usar:
250
+ // import { createNeetruClient } from '@neetru/sdk';
251
+ // const neetru = createNeetruClient({ ... });
252
+ // const produtos = neetru.db.collection<Produto>('produtos');
253
+ // const pedidos = neetru.db.collection<Pedido>('pedidos');
254
254
  `;
255
255
  /** Template padrão para engines SQL (PostgreSQL/MySQL). */
256
- const SCHEMA_STARTER_SQL = (productId, engine) => `/**
257
- * Schema do banco "${productId}" — ${ENGINE_LABELS[engine] ?? engine}.
258
- *
259
- * Gerado por \`neetru db init\`.
260
- * Edite este arquivo e rode \`neetru db apply\` pra enviar a migração ao Core.
261
- */
262
-
263
- // Exemplo com DrizzleORM (PostgreSQL):
264
- // import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
265
- //
266
- // export const usuarios = pgTable('usuarios', {
267
- // id: serial('id').primaryKey(),
268
- // email: text('email').notNull().unique(),
269
- // criadoEm: timestamp('criado_em').defaultNow(),
270
- // });
271
-
272
- // Remova o comentário acima e adapte ao seu schema.
273
- export {};
256
+ const SCHEMA_STARTER_SQL = (productId, engine) => `/**
257
+ * Schema do banco "${productId}" — ${ENGINE_LABELS[engine] ?? engine}.
258
+ *
259
+ * Gerado por \`neetru db init\`.
260
+ * Edite este arquivo e rode \`neetru db apply\` pra enviar a migração ao Core.
261
+ */
262
+
263
+ // Exemplo com DrizzleORM (PostgreSQL):
264
+ // import { pgTable, serial, text, timestamp } from 'drizzle-orm/pg-core';
265
+ //
266
+ // export const usuarios = pgTable('usuarios', {
267
+ // id: serial('id').primaryKey(),
268
+ // email: text('email').notNull().unique(),
269
+ // criadoEm: timestamp('criado_em').defaultNow(),
270
+ // });
271
+
272
+ // Remova o comentário acima e adapte ao seu schema.
273
+ export {};
274
274
  `;
275
275
  /** Conteúdo do `db/schema.ts` gerado durante o init. */
276
276
  const SCHEMA_STARTER = (productId, engine) => {
@@ -1,3 +1,14 @@
1
+ /**
2
+ * bug_a5786e03 (2026-05-31): o Core/agente só conhecem os stacks canônicos
3
+ * `node|docker|php-apache|static` (PRODUCT_STACKS). `nextjs` é um alias de
4
+ * conveniência da CLI — gera um Dockerfile Next.js (ensureDockerfile) e roda
5
+ * como `node` no agente VM (`next start` + reverse-proxy; o stack `docker` do
6
+ * agente nem é implementado em VM) e o Cloud Run builda o Dockerfile igual.
7
+ * Mandar `nextjs` literal ao Core dava 400 "invalid enum". Mapeamos pro stack
8
+ * canônico ANTES de enviar; o `--stack=nextjs` continua válido pro usuário e
9
+ * pra geração do Dockerfile.
10
+ */
11
+ export declare function toCoreStack(stack: string | undefined): string | undefined;
1
12
  export interface DeployOptions {
2
13
  product?: string;
3
14
  version?: string;
@@ -32,6 +32,19 @@ import { readDbJson, schemaFingerprint } from '../lib/db-local/index.js';
32
32
  import { assertIamReady } from '../lib/iam-preflight.js';
33
33
  import { getActiveTokenSync } from '../lib/token-resolver.js';
34
34
  import { safeExit } from '../utils/safe-exit.js';
35
+ /**
36
+ * bug_a5786e03 (2026-05-31): o Core/agente só conhecem os stacks canônicos
37
+ * `node|docker|php-apache|static` (PRODUCT_STACKS). `nextjs` é um alias de
38
+ * conveniência da CLI — gera um Dockerfile Next.js (ensureDockerfile) e roda
39
+ * como `node` no agente VM (`next start` + reverse-proxy; o stack `docker` do
40
+ * agente nem é implementado em VM) e o Cloud Run builda o Dockerfile igual.
41
+ * Mandar `nextjs` literal ao Core dava 400 "invalid enum". Mapeamos pro stack
42
+ * canônico ANTES de enviar; o `--stack=nextjs` continua válido pro usuário e
43
+ * pra geração do Dockerfile.
44
+ */
45
+ export function toCoreStack(stack) {
46
+ return stack === 'nextjs' ? 'node' : stack;
47
+ }
35
48
  const TERMINAL_STATUSES = new Set(['success', 'failed', 'cancelled']);
36
49
  /** Estágios de ambiente válidos para o deploy workspace. */
37
50
  const WORKSPACE_ENVS = new Set(['dev', 'staging', 'prod']);
@@ -1053,7 +1066,8 @@ export async function runDeploy(opts) {
1053
1066
  const body = {
1054
1067
  productSlug,
1055
1068
  version: artifact.manifest?.version ?? opts.version ?? '0.0.0',
1056
- stack: opts.stack ?? artifact.manifest?.stack ?? 'node',
1069
+ // bug_a5786e03: mapeia nextjs→node (Core/agente não conhecem `nextjs`).
1070
+ stack: toCoreStack(opts.stack ?? artifact.manifest?.stack) ?? 'node',
1057
1071
  target,
1058
1072
  artifactUrl: artifact.artifactUrl,
1059
1073
  artifactSha256: artifact.artifactSha256,