@neetru/cli 2.28.10 → 2.31.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 (81) hide show
  1. package/CHANGELOG.md +92 -1
  2. package/README.md +61 -17
  3. package/dist/commands/code.js +10 -1
  4. package/dist/commands/code.js.map +1 -1
  5. package/dist/commands/db-move.d.ts +50 -1
  6. package/dist/commands/db-move.js +137 -13
  7. package/dist/commands/db-move.js.map +1 -1
  8. package/dist/commands/db.js +17 -9
  9. package/dist/commands/db.js.map +1 -1
  10. package/dist/commands/deploy.d.ts +45 -0
  11. package/dist/commands/deploy.js +181 -2
  12. package/dist/commands/deploy.js.map +1 -1
  13. package/dist/commands/deployments.d.ts +7 -1
  14. package/dist/commands/deployments.js +59 -8
  15. package/dist/commands/deployments.js.map +1 -1
  16. package/dist/commands/dev-up.d.ts +7 -5
  17. package/dist/commands/dev-up.js +24 -23
  18. package/dist/commands/dev-up.js.map +1 -1
  19. package/dist/commands/docs-produto.d.ts +65 -0
  20. package/dist/commands/docs-produto.js +322 -0
  21. package/dist/commands/docs-produto.js.map +1 -0
  22. package/dist/commands/init.d.ts +2 -0
  23. package/dist/commands/init.js +7 -0
  24. package/dist/commands/init.js.map +1 -1
  25. package/dist/commands/new.d.ts +2 -0
  26. package/dist/commands/new.js +2 -0
  27. package/dist/commands/new.js.map +1 -1
  28. package/dist/commands/servers.d.ts +28 -0
  29. package/dist/commands/servers.js +126 -1
  30. package/dist/commands/servers.js.map +1 -1
  31. package/dist/index.js +110 -11
  32. package/dist/index.js.map +1 -1
  33. package/dist/lib/api-client.d.ts +8 -1
  34. package/dist/lib/api-client.js +20 -2
  35. package/dist/lib/api-client.js.map +1 -1
  36. package/dist/lib/compose-generator.d.ts +13 -9
  37. package/dist/lib/compose-generator.js +28 -60
  38. package/dist/lib/compose-generator.js.map +1 -1
  39. package/dist/lib/config-schema.d.ts +40 -6
  40. package/dist/lib/config-schema.js +11 -0
  41. package/dist/lib/config-schema.js.map +1 -1
  42. package/dist/lib/product-docs/check.d.ts +62 -0
  43. package/dist/lib/product-docs/check.js +489 -0
  44. package/dist/lib/product-docs/check.js.map +1 -0
  45. package/dist/lib/product-docs/config.d.ts +66 -0
  46. package/dist/lib/product-docs/config.js +234 -0
  47. package/dist/lib/product-docs/config.js.map +1 -0
  48. package/dist/lib/product-docs/dates.d.ts +17 -0
  49. package/dist/lib/product-docs/dates.js +41 -0
  50. package/dist/lib/product-docs/dates.js.map +1 -0
  51. package/dist/lib/product-docs/frontmatter.d.ts +43 -0
  52. package/dist/lib/product-docs/frontmatter.js +302 -0
  53. package/dist/lib/product-docs/frontmatter.js.map +1 -0
  54. package/dist/lib/product-docs/git.d.ts +16 -0
  55. package/dist/lib/product-docs/git.js +92 -0
  56. package/dist/lib/product-docs/git.js.map +1 -0
  57. package/dist/lib/product-docs/markdown.d.ts +27 -0
  58. package/dist/lib/product-docs/markdown.js +98 -0
  59. package/dist/lib/product-docs/markdown.js.map +1 -0
  60. package/dist/lib/product-docs/ops.d.ts +133 -0
  61. package/dist/lib/product-docs/ops.js +975 -0
  62. package/dist/lib/product-docs/ops.js.map +1 -0
  63. package/dist/lib/product-docs/structure.d.ts +61 -0
  64. package/dist/lib/product-docs/structure.js +239 -0
  65. package/dist/lib/product-docs/structure.js.map +1 -0
  66. package/dist/lib/product-docs/sync.d.ts +101 -0
  67. package/dist/lib/product-docs/sync.js +313 -0
  68. package/dist/lib/product-docs/sync.js.map +1 -0
  69. package/dist/lib/product-docs/taxonomy.d.ts +46 -0
  70. package/dist/lib/product-docs/taxonomy.js +163 -0
  71. package/dist/lib/product-docs/taxonomy.js.map +1 -0
  72. package/dist/lib/product-docs/templates.d.ts +53 -0
  73. package/dist/lib/product-docs/templates.js +245 -0
  74. package/dist/lib/product-docs/templates.js.map +1 -0
  75. package/dist/lib/public-secret-scan.d.ts +76 -0
  76. package/dist/lib/public-secret-scan.js +446 -0
  77. package/dist/lib/public-secret-scan.js.map +1 -0
  78. package/package.json +2 -1
  79. package/templates/dev/Dockerfile.agent +0 -39
  80. package/templates/dev/agent-entrypoint.sh +0 -41
  81. package/templates/dev/docker-compose.dev.yml +0 -63
@@ -0,0 +1,313 @@
1
+ /**
2
+ * `neetru docs sync` — publica o `docs/` do produto no registro de docs por
3
+ * produto do Core (PROTOCOLO_DOCS_PRODUTOS_SAAS §8.1 + PROJ_PRODUCT_DOCS §4.2).
4
+ *
5
+ * CONTRATO (lado servidor no Core: PR #571, `src/app/api/cli/v1/products/[slug]/docs/route.ts`):
6
+ *
7
+ * GET /api/cli/v1/products/{productId}/docs
8
+ * → 200 { ok, count, docs: [{ slug, title?, status?, visibility?, sha256?, version?, … }] }
9
+ * → 404 { error: { code: 'product_not_found' } } produto não existe no Core
10
+ * → 404 (outro código / sem corpo) o Core ainda não tem a rota
11
+ * POST /api/cli/v1/products/{productId}/docs
12
+ * body { slug, content, frontmatter, visibility }
13
+ * → 200/201 { ok, slug, docId, gcsPath, sha256, version, bytes, created }
14
+ *
15
+ * - `productId` = slug do produto (o mesmo do `neetru.config.json`).
16
+ * - `slug` do doc = caminho relativo a `docs/`, sem `.md` (ex.: `produto/VISAO_DO_PRODUTO`).
17
+ * - `content` = corpo SEM o bloco de frontmatter; `frontmatter` vai como objeto
18
+ * (mesmo formato do `neetru docs publish` do Core).
19
+ * - `visibility` = `public` só quando `audience: publico` E `status: active`;
20
+ * todo o resto é `internal`.
21
+ *
22
+ * Regras do lado da CLI:
23
+ * - Só sobem docs SEM erro no `docs check`; `_archive/` e `_audit/` não sobem.
24
+ * - Doc igual ao do Core (mesmo sha256 do conteúdo, título, status e
25
+ * visibilidade) não é reenviado.
26
+ * - Nada é apagado no Core: doc que só existe lá aparece como "órfão" (a
27
+ * remoção de docs de produto ainda não existe no Core).
28
+ * - Limites operacionais (D-05): 200 docs / 10 MB por produto e 2 MB por doc
29
+ * (413 `doc_too_large` no Core) — conferidos ANTES de enviar.
30
+ * - Slug: o Core aceita só `[A-Za-z0-9._-]` por segmento e recusa `__`; arquivo
31
+ * com acento/espaço no caminho não sobe (explicado, sem gastar um 400).
32
+ * - Rate limit do Core (`cliWrite`, 30 POST/min por IP): no máximo
33
+ * `POSTS_PER_MINUTE` envios por janela de 60 s, um por vez; 429/503 esperam o
34
+ * `Retry-After` e tentam de novo (até 3 vezes).
35
+ * - "Igual ao Core" compara o sha256 do conteúdo E os metadados que o GET
36
+ * devolve (title, description, category, subcategory, type, status,
37
+ * audience, order, updated…): mudança só de metadado também sobe.
38
+ * - Rota ausente (404 sem `product_not_found`) = "o Core ainda não aceita docs
39
+ * de produto" — NÃO é erro fatal.
40
+ */
41
+ import { createHash } from 'node:crypto';
42
+ import * as fs from 'node:fs/promises';
43
+ import * as path from 'node:path';
44
+ import { apiRequest, CliApiError } from '../api-client.js';
45
+ import { resolveToken } from '../cli-read.js';
46
+ import { parseDoc } from './frontmatter.js';
47
+ import { checkProductDocs, listDocFiles } from './check.js';
48
+ import { topFolder } from './structure.js';
49
+ export const MAX_PRODUCT_DOCS = 200;
50
+ export const MAX_PRODUCT_DOCS_BYTES = 10 * 1024 * 1024;
51
+ /** Teto por doc no Core (`MAX_PRODUCT_DOC_BYTES`, 413 `doc_too_large`). */
52
+ export const MAX_PRODUCT_DOC_BYTES = 2 * 1024 * 1024;
53
+ /** Abaixo do `cliWrite` do Core (30/min por IP), com folga para outro comando na mesma rede. */
54
+ export const POSTS_PER_MINUTE = 25;
55
+ /** Tentativas extras quando o Core responde 429/503. */
56
+ export const MAX_RETRIES = 3;
57
+ /** Espera quando o 429 vem sem `Retry-After` (s) e teto da espera pedida (s). */
58
+ const DEFAULT_RETRY_AFTER_S = 20;
59
+ const MAX_RETRY_AFTER_S = 120;
60
+ /** Metadados que o GET do Core devolve e que a CLI compara (o que vier). */
61
+ export const COMPARED_METADATA = ['title', 'description', 'category', 'subcategory', 'type', 'status', 'audience', 'order', 'updated', 'date'];
62
+ export function visibilityFor(fm) {
63
+ return fm.audience === 'publico' && fm.status === 'active' ? 'public' : 'internal';
64
+ }
65
+ export function docSlugFor(relInDocs) {
66
+ return relInDocs.replace(/\\/g, '/').replace(/\.md$/i, '');
67
+ }
68
+ /**
69
+ * Motivo pelo qual o Core recusaria o slug (mesmas regras de
70
+ * `productDocSlugSchema`), ou null se ele passa.
71
+ */
72
+ export function slugProblem(slug) {
73
+ if (slug.length > 200)
74
+ return `o caminho tem ${slug.length} caracteres (máximo 200)`;
75
+ if (slug.includes('__'))
76
+ return 'o caminho tem "__" (reservado pelo Core)';
77
+ for (const seg of slug.split('/')) {
78
+ if (!seg)
79
+ return 'o caminho tem barra dupla';
80
+ if (/^\.+$/.test(seg))
81
+ return 'o caminho tem segmento "." ou ".."';
82
+ const bad = [...new Set(seg.replace(/[A-Za-z0-9._-]/g, ''))];
83
+ if (bad.length) {
84
+ const shown = bad.map((c) => (c === ' ' ? 'espaço' : `"${c}"`)).join(', ');
85
+ return `"${seg}" tem ${shown} — o Core só aceita letras sem acento, números, ".", "_" e "-"; renomeie (a regra de nome do protocolo já pede MAIÚSCULAS sem acento)`;
86
+ }
87
+ }
88
+ return null;
89
+ }
90
+ function sha256(s) {
91
+ return createHash('sha256').update(s, 'utf8').digest('hex');
92
+ }
93
+ function isRouteMissing(err) {
94
+ if (!(err instanceof CliApiError))
95
+ return false;
96
+ if (err.status === 404)
97
+ return err.code !== 'product_not_found';
98
+ return err.status === 405 || err.status === 501;
99
+ }
100
+ /** Monta o lote local (sem I/O de rede). */
101
+ export async function collectLocalDocs(repo, taxonomy) {
102
+ const check = await checkProductDocs(repo, { taxonomy });
103
+ const errorsByFile = new Map();
104
+ for (const f of check.findings) {
105
+ if (f.level !== 'erro')
106
+ continue;
107
+ const list = errorsByFile.get(f.file) ?? [];
108
+ if (!list.includes(f.code))
109
+ list.push(f.code);
110
+ errorsByFile.set(f.file, list);
111
+ }
112
+ const docs = [];
113
+ const bloqueados = [];
114
+ const recusados = [];
115
+ for (const rel of await listDocFiles(repo)) {
116
+ const top = topFolder(rel);
117
+ if (top === '_archive' || top === '_audit')
118
+ continue;
119
+ const file = `${repo.docs.root}/${rel}`;
120
+ // Caminho que o Core recusaria vem ANTES dos erros do check: um nome com
121
+ // acento/espaço também reprova a regra de nome (NM001), e "renomeie: o Core
122
+ // só aceita…" é mais útil que só o código da regra.
123
+ const slug = docSlugFor(rel);
124
+ const problem = slugProblem(slug);
125
+ if (problem) {
126
+ recusados.push({ file, motivo: problem });
127
+ continue;
128
+ }
129
+ const errs = errorsByFile.get(file);
130
+ if (errs) {
131
+ bloqueados.push({ file, codes: errs });
132
+ continue;
133
+ }
134
+ const raw = await fs.readFile(path.join(repo.cwd, repo.docs.root, rel), 'utf8');
135
+ const parsed = parseDoc(raw);
136
+ const content = parsed.body.replace(/^(\r?\n)+/, '');
137
+ const bytes = Buffer.byteLength(content, 'utf8');
138
+ if (bytes > MAX_PRODUCT_DOC_BYTES) {
139
+ recusados.push({
140
+ file,
141
+ motivo: `tem ${(bytes / 1024 / 1024).toFixed(2)} MB; o Core aceita até 2 MB por doc — divida em docs menores`,
142
+ });
143
+ continue;
144
+ }
145
+ docs.push({
146
+ file,
147
+ slug,
148
+ content,
149
+ frontmatter: parsed.data,
150
+ visibility: visibilityFor(parsed.data),
151
+ sha256: sha256(content),
152
+ bytes,
153
+ });
154
+ }
155
+ return { docs, bloqueados, recusados };
156
+ }
157
+ const realSleep = (ms) => new Promise((r) => setTimeout(r, ms));
158
+ /** Normaliza para comparar: null/undefined/'' iguais; números e strings como estão. */
159
+ function normMeta(v) {
160
+ if (v === null || v === undefined || v === '')
161
+ return '';
162
+ return typeof v === 'string' ? v.trim() : JSON.stringify(v);
163
+ }
164
+ /** O doc local é igual ao do Core (conteúdo + metadados que o GET devolve)? */
165
+ export function sameAsRemote(d, r) {
166
+ if (!r || r.sha256 !== d.sha256)
167
+ return false;
168
+ if ((r.visibility ?? d.visibility) !== d.visibility)
169
+ return false;
170
+ for (const k of COMPARED_METADATA) {
171
+ if (!(k in r))
172
+ continue; // o Core não devolveu esse campo: não dá para comparar
173
+ if (normMeta(r[k]) !== normMeta(d.frontmatter[k]))
174
+ return false;
175
+ }
176
+ return true;
177
+ }
178
+ /** Janela deslizante: no máximo `limit` envios em 60 s. */
179
+ export function createPacer(limit, now, sleep, onWait) {
180
+ const sent = [];
181
+ return async () => {
182
+ const t = now();
183
+ while (sent.length && t - sent[0] >= 60_000)
184
+ sent.shift();
185
+ if (sent.length >= limit) {
186
+ const wait = 60_000 - (t - sent[0]) + 50;
187
+ onWait?.(wait, 'ritmo');
188
+ await sleep(wait);
189
+ sent.shift();
190
+ }
191
+ sent.push(now());
192
+ };
193
+ }
194
+ export async function syncProductDocs(repo, opts) {
195
+ const product = repo.slug;
196
+ const dryRun = !!opts.dryRun;
197
+ const base = {
198
+ status: 'ok', message: '', product, dryRun,
199
+ enviados: [], inalterados: [], bloqueados: [], falhas: [], recusados: [], orfaos: [], planejados: [],
200
+ };
201
+ const now = opts.now ?? Date.now;
202
+ const sleep = opts.sleep ?? realSleep;
203
+ const pace = createPacer(POSTS_PER_MINUTE, now, sleep, opts.onWait);
204
+ if (!repo.docs.publish) {
205
+ return { ...base, status: 'desligado', message: '`docs.publish` está false no neetru.config.json: os docs ficam só no repositório.' };
206
+ }
207
+ const { docs, bloqueados, recusados } = await collectLocalDocs(repo, opts.taxonomy);
208
+ base.bloqueados = bloqueados;
209
+ base.recusados = recusados;
210
+ base.planejados = docs.map((d) => ({ slug: d.slug, visibility: d.visibility, bytes: d.bytes }));
211
+ const totalBytes = docs.reduce((n, d) => n + d.bytes, 0);
212
+ if (docs.length > MAX_PRODUCT_DOCS || totalBytes > MAX_PRODUCT_DOCS_BYTES) {
213
+ return {
214
+ ...base,
215
+ status: 'limite-excedido',
216
+ message: `O Core aceita até ${MAX_PRODUCT_DOCS} docs e 10 MB por produto; aqui são ${docs.length} docs e ${(totalBytes / 1024 / 1024).toFixed(1)} MB. Arquive o que não é mais usado.`,
217
+ };
218
+ }
219
+ if (docs.length === 0) {
220
+ return {
221
+ ...base,
222
+ status: 'nada-a-enviar',
223
+ message: bloqueados.length || recusados.length
224
+ ? 'Nenhum doc que o Core aceite para enviar — rode `neetru docs check` e veja os recusados.'
225
+ : 'Nenhum doc encontrado em ' + repo.docs.root + '/.',
226
+ };
227
+ }
228
+ const token = opts.token !== undefined ? opts.token : await resolveToken().catch(() => null);
229
+ if (!token) {
230
+ return {
231
+ ...base,
232
+ status: dryRun ? 'ok' : 'sem-login',
233
+ message: dryRun ? `Simulação sem login: ${docs.length} doc(s) seriam enviados.` : 'Nenhuma sessão ativa. Rode `neetru login` e tente de novo.',
234
+ };
235
+ }
236
+ const basePath = `/api/cli/v1/products/${encodeURIComponent(product)}/docs`;
237
+ let remote;
238
+ try {
239
+ const res = await apiRequest(basePath, { token, timeoutMs: 15_000 });
240
+ remote = Array.isArray(res?.docs) ? res.docs : [];
241
+ }
242
+ catch (err) {
243
+ if (isRouteMissing(err)) {
244
+ return { ...base, status: 'core-sem-suporte', message: 'O Core ainda não aceita docs de produto. Os docs continuam no repositório; rode `neetru docs sync` de novo quando o Core tiver a rota.' };
245
+ }
246
+ if (err instanceof CliApiError && err.status === 404) {
247
+ return { ...base, status: 'produto-nao-encontrado', message: `O produto "${product}" não existe no Core (ou está arquivado).` };
248
+ }
249
+ return { ...base, status: 'falha', message: `Falha ao consultar os docs no Core: ${err.message}` };
250
+ }
251
+ const remoteBySlug = new Map(remote.map((r) => [r.slug, r]));
252
+ const localSlugs = new Set(docs.map((d) => d.slug));
253
+ base.orfaos = remote.map((r) => r.slug).filter((s) => !localSlugs.has(s)).sort();
254
+ for (const d of docs) {
255
+ const r = remoteBySlug.get(d.slug);
256
+ if (sameAsRemote(d, r)) {
257
+ base.inalterados.push(d.slug);
258
+ continue;
259
+ }
260
+ if (dryRun) {
261
+ base.enviados.push({ slug: d.slug, visibility: d.visibility, created: !r });
262
+ continue;
263
+ }
264
+ let attempt = 0;
265
+ for (;;) {
266
+ await pace();
267
+ try {
268
+ const res = await apiRequest(basePath, {
269
+ method: 'POST',
270
+ token,
271
+ body: { slug: d.slug, content: d.content, frontmatter: d.frontmatter, visibility: d.visibility },
272
+ timeoutMs: 30_000,
273
+ });
274
+ if (res?.unchanged)
275
+ base.inalterados.push(d.slug);
276
+ else
277
+ base.enviados.push({ slug: d.slug, version: res?.version, created: res?.created, visibility: d.visibility });
278
+ break;
279
+ }
280
+ catch (err) {
281
+ if (isRouteMissing(err)) {
282
+ return { ...base, status: 'core-sem-suporte', message: 'O Core ainda não aceita docs de produto (a publicação não existe). Os docs continuam no repositório.' };
283
+ }
284
+ const status = err instanceof CliApiError ? err.status : 0;
285
+ if ((status === 429 || status === 503) && attempt < MAX_RETRIES) {
286
+ attempt++;
287
+ const ra = err.retryAfterSeconds;
288
+ const waitS = Math.min(MAX_RETRY_AFTER_S, ra !== undefined ? Math.max(1, ra) : DEFAULT_RETRY_AFTER_S * attempt);
289
+ opts.onWait?.(waitS * 1000, 'retry-after');
290
+ await sleep(waitS * 1000);
291
+ continue;
292
+ }
293
+ const msg = err instanceof Error ? err.message : String(err);
294
+ base.falhas.push({
295
+ slug: d.slug,
296
+ message: status === 413 ? `grande demais para o Core (${msg})` : status === 429 ? `limite de envios do Core (${msg}) — tente de novo em alguns minutos` : msg,
297
+ });
298
+ break;
299
+ }
300
+ }
301
+ }
302
+ if (base.falhas.length) {
303
+ return { ...base, status: 'parcial', message: `${base.enviados.length} enviado(s), ${base.falhas.length} com falha.` };
304
+ }
305
+ return {
306
+ ...base,
307
+ status: 'ok',
308
+ message: dryRun
309
+ ? `Simulação: ${base.enviados.length} doc(s) seriam enviados, ${base.inalterados.length} sem mudança.`
310
+ : `${base.enviados.length} doc(s) enviados, ${base.inalterados.length} sem mudança.`,
311
+ };
312
+ }
313
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../../src/lib/product-docs/sync.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ export type DocFamily = 'vivo' | 'plano' | 'registro';
2
+ export interface DocsTaxonomy {
3
+ protocolVersion: number;
4
+ categories: Record<string, string[]>;
5
+ productOnlyCategories: Record<string, string[]>;
6
+ coreOnlyCategories: string[];
7
+ types: Record<string, DocFamily>;
8
+ statusByFamily: Record<DocFamily, string[]>;
9
+ statusByTypeOverride: Record<string, string[]>;
10
+ audiences: string[];
11
+ owners: string[];
12
+ hiddenDirs: string[];
13
+ }
14
+ /** Bloco §5.2 do protocolo da wiki, v1 (2026-10-03). NÃO editar à mão sem mudar o protocolo. */
15
+ export declare const EMBEDDED_TAXONOMY: DocsTaxonomy;
16
+ /** Categorias válidas num repositório de PRODUTO: as do Core menos as só-do-Core, mais as só-de-produto. */
17
+ export declare function productCategories(t: DocsTaxonomy): Record<string, string[]>;
18
+ /** Status aceitos para um `type` (override por tipo vence a família). */
19
+ export declare function statusesForType(t: DocsTaxonomy, type: string): string[];
20
+ /** Validação mínima do formato EMBUTIDO (categorias como mapa categoria → subcategorias). */
21
+ export declare function isValidTaxonomy(x: unknown): x is DocsTaxonomy;
22
+ /**
23
+ * Converte a taxonomia vinda do Core para o formato da CLI. Aceita os dois:
24
+ * - o do Core (`src/lib/docs-taxonomy.json`, servido por
25
+ * `GET /api/cli/v1/docs/taxonomy`): `categories` é a LISTA de nomes (ordem do
26
+ * portal) e `subcategories` é o mapa categoria → subcategorias, com chaves
27
+ * extras (`subcategoryLabels`, `folders`, `legacyCategories`…) ignoradas;
28
+ * - o embutido (`categories` já como mapa).
29
+ * Devolve null quando o formato não serve — quem chama cai no embutido.
30
+ */
31
+ export declare function normalizeTaxonomy(x: unknown): DocsTaxonomy | null;
32
+ export interface ResolvedTaxonomy {
33
+ taxonomy: DocsTaxonomy;
34
+ source: 'core' | 'embutida';
35
+ /** Preenchido quando a do Core é mais nova que a embutida (atualize a CLI). */
36
+ aviso?: string;
37
+ }
38
+ /**
39
+ * Taxonomia a usar: a do Core quando online (`GET /api/cli/v1/docs/taxonomy`),
40
+ * senão a embutida. Nunca lança — offline, 404, timeout ou formato inválido
41
+ * caem silenciosamente na embutida.
42
+ */
43
+ export declare function resolveTaxonomy(opts?: {
44
+ offline?: boolean;
45
+ timeoutMs?: number;
46
+ }): Promise<ResolvedTaxonomy>;
@@ -0,0 +1,163 @@
1
+ /**
2
+ * Taxonomia dos docs (protocolo v1) — cópia EMBUTIDA na CLI.
3
+ *
4
+ * Fonte única: `src/lib/docs-taxonomy.json` no Core, que por sua vez copia o
5
+ * bloco JSON do §5.2 de `docs/sistema/contrib/PROTOCOLO_WIKI_INTERNA.md`.
6
+ * O teste `product-docs-taxonomy.test.ts` confere que este objeto é IDÊNTICO
7
+ * ao bloco do protocolo (fixture `__tests__/fixtures/docs-taxonomy-protocolo-v1.json`
8
+ * e, quando há um checkout do Core por perto, o próprio markdown).
9
+ *
10
+ * Quando o Core expõe `GET /api/cli/v1/docs/taxonomy`, `resolveTaxonomy()` usa
11
+ * a versão do Core (online) e cai nesta cópia em qualquer falha (offline, 404,
12
+ * formato inesperado). Avisa quando a do Core é mais nova que a embutida.
13
+ */
14
+ import { apiRequest } from '../api-client.js';
15
+ /** Bloco §5.2 do protocolo da wiki, v1 (2026-10-03). NÃO editar à mão sem mudar o protocolo. */
16
+ export const EMBEDDED_TAXONOMY = {
17
+ protocolVersion: 1,
18
+ categories: {
19
+ Plataforma: ['visao-geral', 'decisoes', 'roadmap', 'versionamento', 'modulos', 'superficies-publicas', 'portal-do-cliente'],
20
+ Identidade: ['login-staff', 'mfa', 'oidc', 'contas-de-cliente', 'permissoes', 'chaves-de-api'],
21
+ 'Cobrança': ['stripe', 'assinaturas', 'faturas-e-receita', 'inadimplencia', 'uso-medido', 'precos', 'filiados'],
22
+ Dados: ['firestore', 'bancos-de-produto', 'migracoes', 'backup-e-recuperacao', 'regras-e-indices', 'trilha-de-auditoria'],
23
+ Infraestrutura: ['vm-e-frota', 'agente', 'servicos-na-vm', 'ambientes', 'cloud-functions', 'cloud-run', 'dns-e-certificados', 'gcp-e-contas'],
24
+ Observabilidade: ['logs', 'metricas', 'alertas', 'erros', 'rastreamento', 'incidentes'],
25
+ 'Segurança': ['segredos', 'controle-de-acesso', 'privacidade-e-lgpd', 'vulnerabilidades', 'configuracao-segura'],
26
+ 'Operações': ['deploy-do-core', 'producao', 'custos', 'suporte', 'comunicacao-interna', 'integracoes-externas'],
27
+ 'Produtos SaaS': ['do-zero-a-producao', 'ciclo-de-vida', 'deploy-de-produto', 'api-de-produto', 'credenciais', 'documentacao-de-produto', 'produto-especifico'],
28
+ CLI: ['comandos', 'guias', 'instalacao-e-versoes'],
29
+ SDK: ['namespaces', 'guias', 'versoes-e-migracao'],
30
+ API: ['rest-v1', 'cli-v1', 'openapi', 'webhooks'],
31
+ Bibliotecas: ['libs-internas', 'skills', 'publicacao'],
32
+ Desenvolvimento: ['fluxo-git', 'qualidade-e-testes', 'ambiente-local', 'convencoes', 'interface', 'tours', 'agentes-de-ia'],
33
+ Empresa: ['marca', 'juridico', 'marketing', 'governanca', 'comercial', 'pessoas'],
34
+ 'Documentação': ['indices', 'protocolos', 'inventarios', 'relatorios-automaticos'],
35
+ },
36
+ productOnlyCategories: {
37
+ Produto: ['visao', 'publico-e-proposta', 'roadmap', 'glossario'],
38
+ 'Ajuda ao usuário': ['primeiros-passos', 'tarefas', 'perguntas-frequentes'],
39
+ 'Integrações': ['marketplaces', 'pagamentos', 'fiscal', 'mensageria', 'outras'],
40
+ },
41
+ coreOnlyCategories: ['Produtos SaaS', 'CLI', 'SDK', 'Bibliotecas'],
42
+ types: {
43
+ guia: 'vivo', referencia: 'vivo', arquitetura: 'vivo', adr: 'vivo', runbook: 'vivo',
44
+ norma: 'vivo', indice: 'vivo', tour: 'vivo', juridico: 'vivo', conteudo: 'vivo',
45
+ changelog: 'vivo', plano: 'plano', relatorio: 'registro', incidente: 'registro', ata: 'registro',
46
+ },
47
+ statusByFamily: {
48
+ vivo: ['draft', 'active', 'deprecated', 'superseded', 'archived'],
49
+ plano: ['draft', 'proposed', 'in_progress', 'deferred', 'done', 'abandoned', 'superseded', 'archived'],
50
+ registro: ['draft', 'historical', 'superseded', 'archived'],
51
+ },
52
+ statusByTypeOverride: {
53
+ adr: ['proposed', 'active', 'deprecated', 'superseded', 'archived'],
54
+ },
55
+ audiences: ['staff', 'dev-produto', 'publico'],
56
+ owners: ['dev-core', 'operacoes', 'seguranca', 'produto', 'marca-e-marketing', 'juridico', 'diretoria', 'documentacao'],
57
+ hiddenDirs: ['.git', 'node_modules', '.obsidian', 'tours', '_brand', '_archive', '_assets', '_audit', '_diagrams', '_projetos', '_review', '_inventario', 'reunioes', 'features', 'legal', 'marketing', 'superpowers'],
58
+ };
59
+ /** Categorias válidas num repositório de PRODUTO: as do Core menos as só-do-Core, mais as só-de-produto. */
60
+ export function productCategories(t) {
61
+ const out = {};
62
+ for (const [cat, subs] of Object.entries(t.categories)) {
63
+ if (!t.coreOnlyCategories.includes(cat))
64
+ out[cat] = subs;
65
+ }
66
+ for (const [cat, subs] of Object.entries(t.productOnlyCategories))
67
+ out[cat] = subs;
68
+ return out;
69
+ }
70
+ /** Status aceitos para um `type` (override por tipo vence a família). */
71
+ export function statusesForType(t, type) {
72
+ const override = t.statusByTypeOverride[type];
73
+ if (override)
74
+ return override;
75
+ const fam = t.types[type];
76
+ return fam ? t.statusByFamily[fam] ?? [] : [];
77
+ }
78
+ const isRecordOfArrays = (r) => !!r && typeof r === 'object' && !Array.isArray(r) && Object.values(r).every((v) => Array.isArray(v));
79
+ /** Validação mínima do formato EMBUTIDO (categorias como mapa categoria → subcategorias). */
80
+ export function isValidTaxonomy(x) {
81
+ if (!x || typeof x !== 'object')
82
+ return false;
83
+ const t = x;
84
+ return (typeof t.protocolVersion === 'number' &&
85
+ isRecordOfArrays(t.categories) &&
86
+ isRecordOfArrays(t.productOnlyCategories) &&
87
+ Array.isArray(t.coreOnlyCategories) &&
88
+ !!t.types && typeof t.types === 'object' &&
89
+ isRecordOfArrays(t.statusByFamily) &&
90
+ Array.isArray(t.audiences) &&
91
+ Array.isArray(t.owners));
92
+ }
93
+ /**
94
+ * Converte a taxonomia vinda do Core para o formato da CLI. Aceita os dois:
95
+ * - o do Core (`src/lib/docs-taxonomy.json`, servido por
96
+ * `GET /api/cli/v1/docs/taxonomy`): `categories` é a LISTA de nomes (ordem do
97
+ * portal) e `subcategories` é o mapa categoria → subcategorias, com chaves
98
+ * extras (`subcategoryLabels`, `folders`, `legacyCategories`…) ignoradas;
99
+ * - o embutido (`categories` já como mapa).
100
+ * Devolve null quando o formato não serve — quem chama cai no embutido.
101
+ */
102
+ export function normalizeTaxonomy(x) {
103
+ if (!x || typeof x !== 'object')
104
+ return null;
105
+ const t = x;
106
+ let categories = null;
107
+ if (Array.isArray(t.categories)) {
108
+ if (!isRecordOfArrays(t.subcategories))
109
+ return null;
110
+ const subs = t.subcategories;
111
+ categories = {};
112
+ for (const c of t.categories) {
113
+ if (typeof c !== 'string' || !Array.isArray(subs[c]))
114
+ return null;
115
+ categories[c] = subs[c];
116
+ }
117
+ }
118
+ else if (isRecordOfArrays(t.categories)) {
119
+ categories = t.categories;
120
+ }
121
+ if (!categories)
122
+ return null;
123
+ const candidate = {
124
+ protocolVersion: t.protocolVersion,
125
+ categories,
126
+ productOnlyCategories: t.productOnlyCategories,
127
+ coreOnlyCategories: t.coreOnlyCategories,
128
+ types: t.types,
129
+ statusByFamily: t.statusByFamily,
130
+ statusByTypeOverride: isRecordOfArrays(t.statusByTypeOverride) ? t.statusByTypeOverride : {},
131
+ audiences: t.audiences,
132
+ owners: t.owners,
133
+ hiddenDirs: Array.isArray(t.hiddenDirs) ? t.hiddenDirs : EMBEDDED_TAXONOMY.hiddenDirs,
134
+ };
135
+ return isValidTaxonomy(candidate) ? candidate : null;
136
+ }
137
+ /**
138
+ * Taxonomia a usar: a do Core quando online (`GET /api/cli/v1/docs/taxonomy`),
139
+ * senão a embutida. Nunca lança — offline, 404, timeout ou formato inválido
140
+ * caem silenciosamente na embutida.
141
+ */
142
+ export async function resolveTaxonomy(opts = {}) {
143
+ if (opts.offline || process.env.NEETRU_DOCS_OFFLINE === '1') {
144
+ return { taxonomy: EMBEDDED_TAXONOMY, source: 'embutida' };
145
+ }
146
+ try {
147
+ const res = await apiRequest('/api/cli/v1/docs/taxonomy', { timeoutMs: opts.timeoutMs ?? 3000 });
148
+ const body = res;
149
+ const candidate = body && typeof body === 'object' && 'taxonomy' in body ? body.taxonomy : res;
150
+ const normalized = normalizeTaxonomy(candidate);
151
+ if (!normalized)
152
+ return { taxonomy: EMBEDDED_TAXONOMY, source: 'embutida' };
153
+ const aviso = normalized.protocolVersion > EMBEDDED_TAXONOMY.protocolVersion
154
+ ? `A taxonomia do Core é a versão ${normalized.protocolVersion} e a desta CLI é a ${EMBEDDED_TAXONOMY.protocolVersion}. ` +
155
+ 'Usando a do Core agora; atualize a CLI (npm i -g @neetru/cli) para checar offline com a versão nova.'
156
+ : undefined;
157
+ return { taxonomy: normalized, source: 'core', aviso };
158
+ }
159
+ catch {
160
+ return { taxonomy: EMBEDDED_TAXONOMY, source: 'embutida' };
161
+ }
162
+ }
163
+ //# sourceMappingURL=taxonomy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"taxonomy.js","sourceRoot":"","sources":["../../../src/lib/product-docs/taxonomy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import { THREAT_MODEL_SECTIONS, type Section } from './structure.js';
2
+ export interface DocSpec {
3
+ title: string;
4
+ description: string;
5
+ product: string;
6
+ category: string;
7
+ subcategory: string;
8
+ type: string;
9
+ status: string;
10
+ date: string;
11
+ /** Só na família vivo. */
12
+ updated?: string;
13
+ audience: string;
14
+ owner?: string;
15
+ adr?: number;
16
+ order?: number;
17
+ /** Abertura logo abaixo do H1 (até 3 linhas). */
18
+ lead: string;
19
+ sections: Section[];
20
+ /** Conteúdo extra por seção (vai depois do comentário). */
21
+ extra?: Record<string, string>;
22
+ }
23
+ export declare function renderDoc(spec: DocSpec): string;
24
+ export declare const ADR_EXTRA: Record<string, string>;
25
+ export declare const PLANO_RFC_EXTRA: Record<string, string>;
26
+ export declare const PLANO_SPEC_EXTRA: Record<string, string>;
27
+ export declare const NORMA_POLITICA_EXTRA: Record<string, string>;
28
+ export declare const THREAT_EXTRA: Record<string, string>;
29
+ export { THREAT_MODEL_SECTIONS };
30
+ export declare function renderReadme(name: string): string;
31
+ export declare function renderChangelog(seed: {
32
+ version: string;
33
+ date: string;
34
+ maduro: boolean;
35
+ }): string;
36
+ export interface IndexGroup {
37
+ label: string;
38
+ files: Array<{
39
+ rel: string;
40
+ title: string;
41
+ nomeForaDaRegra?: boolean;
42
+ }>;
43
+ /** Grupo fora da estrutura do protocolo (marcado no índice). */
44
+ foraDoPadrao?: boolean;
45
+ nota?: string;
46
+ }
47
+ export declare function renderIndex(opts: {
48
+ product: string;
49
+ name: string;
50
+ today: string;
51
+ groups: IndexGroup[];
52
+ }): string;
53
+ export declare const FOLDER_LABEL: Record<string, string>;