@semacode/cli 1.5.30 → 1.5.32

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 (176) hide show
  1. package/AGENTS.md +294 -0
  2. package/AGENT_CONTEXT_PACK.json +164 -0
  3. package/LICENSE +22 -0
  4. package/README.md +85 -144
  5. package/SEMA_BRIEF.curto.txt +11 -0
  6. package/SEMA_BRIEF.md +616 -0
  7. package/SEMA_BRIEF.micro.txt +9 -0
  8. package/SEMA_INDEX.json +9393 -0
  9. package/dist/billing/index.d.ts +46 -0
  10. package/dist/billing/index.js +143 -0
  11. package/dist/billing/index.js.map +1 -0
  12. package/dist/comandos.js +33 -0
  13. package/dist/comandos.js.map +1 -1
  14. package/dist/controleComercialSupabase.d.ts +7 -0
  15. package/dist/controleComercialSupabase.js +6 -0
  16. package/dist/controleComercialSupabase.js.map +1 -0
  17. package/dist/controleComercialSupabaseAdmin.d.ts +7 -0
  18. package/dist/controleComercialSupabaseAdmin.js +138 -0
  19. package/dist/controleComercialSupabaseAdmin.js.map +1 -0
  20. package/dist/controleComercialSupabaseCadastro.d.ts +4 -0
  21. package/dist/controleComercialSupabaseCadastro.js +85 -0
  22. package/dist/controleComercialSupabaseCadastro.js.map +1 -0
  23. package/dist/controleComercialSupabaseConstantes.d.ts +28 -0
  24. package/dist/controleComercialSupabaseConstantes.js +44 -0
  25. package/dist/controleComercialSupabaseConstantes.js.map +1 -0
  26. package/dist/controleComercialSupabaseConsumo.d.ts +2 -0
  27. package/dist/controleComercialSupabaseConsumo.js +77 -0
  28. package/dist/controleComercialSupabaseConsumo.js.map +1 -0
  29. package/dist/controleComercialSupabaseConta.d.ts +11 -0
  30. package/dist/controleComercialSupabaseConta.js +157 -0
  31. package/dist/controleComercialSupabaseConta.js.map +1 -0
  32. package/dist/controleComercialSupabaseProfiles.d.ts +4 -0
  33. package/dist/controleComercialSupabaseProfiles.js +55 -0
  34. package/dist/controleComercialSupabaseProfiles.js.map +1 -0
  35. package/dist/controleComercialSupabaseTipos.d.ts +3 -0
  36. package/dist/controleComercialSupabaseTipos.js +2 -0
  37. package/dist/controleComercialSupabaseTipos.js.map +1 -0
  38. package/dist/controleComercialSupabaseTiposAdmin.d.ts +152 -0
  39. package/dist/controleComercialSupabaseTiposAdmin.js +2 -0
  40. package/dist/controleComercialSupabaseTiposAdmin.js.map +1 -0
  41. package/dist/controleComercialSupabaseTiposBase.d.ts +169 -0
  42. package/dist/controleComercialSupabaseTiposBase.js +2 -0
  43. package/dist/controleComercialSupabaseTiposBase.js.map +1 -0
  44. package/dist/controleComercialSupabaseTiposConta.d.ts +220 -0
  45. package/dist/controleComercialSupabaseTiposConta.js +2 -0
  46. package/dist/controleComercialSupabaseTiposConta.js.map +1 -0
  47. package/dist/dev/index.d.ts +18 -0
  48. package/dist/dev/index.js +143 -0
  49. package/dist/dev/index.js.map +1 -0
  50. package/dist/index.js +222 -46
  51. package/dist/index.js.map +1 -1
  52. package/dist/init/index.d.ts +23 -0
  53. package/dist/init/index.js +112 -0
  54. package/dist/init/index.js.map +1 -0
  55. package/dist/init/templates.d.ts +11 -0
  56. package/dist/init/templates.js +660 -0
  57. package/dist/init/templates.js.map +1 -0
  58. package/dist/runnerValidacaoRemota.d.ts +9 -0
  59. package/dist/runnerValidacaoRemota.js +9 -0
  60. package/dist/runnerValidacaoRemota.js.map +1 -0
  61. package/dist/runnerValidacaoRemotaBateria.d.ts +10 -0
  62. package/dist/runnerValidacaoRemotaBateria.js +115 -0
  63. package/dist/runnerValidacaoRemotaBateria.js.map +1 -0
  64. package/dist/runnerValidacaoRemotaCli.d.ts +4 -0
  65. package/dist/runnerValidacaoRemotaCli.js +86 -0
  66. package/dist/runnerValidacaoRemotaCli.js.map +1 -0
  67. package/dist/runnerValidacaoRemotaComandos.d.ts +7 -0
  68. package/dist/runnerValidacaoRemotaComandos.js +123 -0
  69. package/dist/runnerValidacaoRemotaComandos.js.map +1 -0
  70. package/dist/runnerValidacaoRemotaEscopo.d.ts +4 -0
  71. package/dist/runnerValidacaoRemotaEscopo.js +79 -0
  72. package/dist/runnerValidacaoRemotaEscopo.js.map +1 -0
  73. package/dist/runnerValidacaoRemotaExecucao.d.ts +2 -0
  74. package/dist/runnerValidacaoRemotaExecucao.js +102 -0
  75. package/dist/runnerValidacaoRemotaExecucao.js.map +1 -0
  76. package/dist/runnerValidacaoRemotaRelatorio.d.ts +3 -0
  77. package/dist/runnerValidacaoRemotaRelatorio.js +93 -0
  78. package/dist/runnerValidacaoRemotaRelatorio.js.map +1 -0
  79. package/dist/runnerValidacaoRemotaServidor.d.ts +3 -0
  80. package/dist/runnerValidacaoRemotaServidor.js +157 -0
  81. package/dist/runnerValidacaoRemotaServidor.js.map +1 -0
  82. package/dist/runnerValidacaoRemotaSnapshot.d.ts +10 -0
  83. package/dist/runnerValidacaoRemotaSnapshot.js +217 -0
  84. package/dist/runnerValidacaoRemotaSnapshot.js.map +1 -0
  85. package/dist/runnerValidacaoRemotaTipos.d.ts +158 -0
  86. package/dist/runnerValidacaoRemotaTipos.js +35 -0
  87. package/dist/runnerValidacaoRemotaTipos.js.map +1 -0
  88. package/dist/runnerValidacaoRemotaUtil.d.ts +3 -0
  89. package/dist/runnerValidacaoRemotaUtil.js +18 -0
  90. package/dist/runnerValidacaoRemotaUtil.js.map +1 -0
  91. package/dist/runnerValidacaoRemotaWorkspace.d.ts +2 -0
  92. package/dist/runnerValidacaoRemotaWorkspace.js +110 -0
  93. package/dist/runnerValidacaoRemotaWorkspace.js.map +1 -0
  94. package/dist/sync/index.d.ts +24 -0
  95. package/dist/sync/index.js +174 -0
  96. package/dist/sync/index.js.map +1 -0
  97. package/docs/AGENT_STARTER.md +109 -0
  98. package/docs/api.md +82 -0
  99. package/docs/cli.md +93 -0
  100. package/docs/como-ensinar-a-sema-para-ia.md +30 -0
  101. package/docs/deploy.md +45 -0
  102. package/docs/documentacao.md +88 -0
  103. package/docs/env.md +115 -0
  104. package/docs/extensao-vscode.md +42 -0
  105. package/docs/fluxo-pratico-ia-sema.md +187 -0
  106. package/docs/instalacao-e-primeiro-uso.md +48 -0
  107. package/docs/integracao-com-ia.md +24 -0
  108. package/docs/mcp.md +48 -0
  109. package/docs/pagamento-ponta-a-ponta.md +171 -0
  110. package/docs/persistencia-vendor-first.md +151 -0
  111. package/docs/prompt-base-ia-sema.md +111 -0
  112. package/docs/repositories.md +69 -0
  113. package/docs/rollback.md +24 -0
  114. package/docs/seguranca.md +126 -0
  115. package/docs/sintaxe.md +218 -0
  116. package/exemplos/profile_conversas.sema +165 -0
  117. package/llms-full.txt +35 -0
  118. package/llms.txt +18 -0
  119. package/node_modules/@sema/gerador-css/package.json +7 -14
  120. package/node_modules/@sema/gerador-dart/package.json +7 -14
  121. package/node_modules/@sema/gerador-html/package.json +7 -14
  122. package/node_modules/@sema/gerador-javascript/package.json +7 -14
  123. package/node_modules/@sema/gerador-lua/package.json +7 -14
  124. package/node_modules/@sema/gerador-python/package.json +7 -14
  125. package/node_modules/@sema/gerador-typescript/package.json +7 -14
  126. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.d.ts +22 -0
  127. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +97 -0
  128. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js.map +1 -0
  129. package/node_modules/@sema/nucleo/dist/index.d.ts +1 -0
  130. package/node_modules/@sema/nucleo/dist/index.js +1 -0
  131. package/node_modules/@sema/nucleo/dist/index.js.map +1 -1
  132. package/node_modules/@sema/nucleo/package.json +7 -10
  133. package/node_modules/@sema/padroes/package.json +7 -10
  134. package/package.json +75 -74
  135. package/exemplos/.prepack-generated +0 -1
  136. package/node_modules/@sema/gerador-css/src/index.ts +0 -605
  137. package/node_modules/@sema/gerador-css/tsconfig.json +0 -13
  138. package/node_modules/@sema/gerador-css/tsconfig.tsbuildinfo +0 -1
  139. package/node_modules/@sema/gerador-dart/src/index.ts +0 -52
  140. package/node_modules/@sema/gerador-dart/tsconfig.json +0 -13
  141. package/node_modules/@sema/gerador-dart/tsconfig.tsbuildinfo +0 -1
  142. package/node_modules/@sema/gerador-html/src/index.ts +0 -185
  143. package/node_modules/@sema/gerador-html/tsconfig.json +0 -13
  144. package/node_modules/@sema/gerador-html/tsconfig.tsbuildinfo +0 -1
  145. package/node_modules/@sema/gerador-javascript/src/index.ts +0 -461
  146. package/node_modules/@sema/gerador-javascript/tsconfig.json +0 -13
  147. package/node_modules/@sema/gerador-javascript/tsconfig.tsbuildinfo +0 -1
  148. package/node_modules/@sema/gerador-lua/src/index.ts +0 -359
  149. package/node_modules/@sema/gerador-lua/tsconfig.json +0 -13
  150. package/node_modules/@sema/gerador-lua/tsconfig.tsbuildinfo +0 -1
  151. package/node_modules/@sema/gerador-python/src/index.ts +0 -850
  152. package/node_modules/@sema/gerador-python/tsconfig.json +0 -13
  153. package/node_modules/@sema/gerador-python/tsconfig.tsbuildinfo +0 -1
  154. package/node_modules/@sema/gerador-typescript/src/index.ts +0 -876
  155. package/node_modules/@sema/gerador-typescript/tsconfig.json +0 -13
  156. package/node_modules/@sema/gerador-typescript/tsconfig.tsbuildinfo +0 -1
  157. package/node_modules/@sema/nucleo/src/ast/tipos.ts +0 -207
  158. package/node_modules/@sema/nucleo/src/diagnosticos/index.ts +0 -43
  159. package/node_modules/@sema/nucleo/src/formatador/index.ts +0 -530
  160. package/node_modules/@sema/nucleo/src/index.ts +0 -183
  161. package/node_modules/@sema/nucleo/src/ir/conversor.ts +0 -1037
  162. package/node_modules/@sema/nucleo/src/ir/modelos.ts +0 -403
  163. package/node_modules/@sema/nucleo/src/lexer/lexer.ts +0 -166
  164. package/node_modules/@sema/nucleo/src/lexer/tokens.ts +0 -79
  165. package/node_modules/@sema/nucleo/src/parser/gramatica.ebnf +0 -41
  166. package/node_modules/@sema/nucleo/src/parser/parser.ts +0 -936
  167. package/node_modules/@sema/nucleo/src/persistencia/contratos.ts +0 -379
  168. package/node_modules/@sema/nucleo/src/semantico/analisador.ts +0 -3126
  169. package/node_modules/@sema/nucleo/src/semantico/estruturas.ts +0 -665
  170. package/node_modules/@sema/nucleo/src/semantico/seguranca.ts +0 -362
  171. package/node_modules/@sema/nucleo/src/util/arquivos.ts +0 -28
  172. package/node_modules/@sema/nucleo/tsconfig.json +0 -9
  173. package/node_modules/@sema/nucleo/tsconfig.tsbuildinfo +0 -1
  174. package/node_modules/@sema/padroes/src/index.ts +0 -382
  175. package/node_modules/@sema/padroes/tsconfig.json +0 -9
  176. package/node_modules/@sema/padroes/tsconfig.tsbuildinfo +0 -1
@@ -1,1037 +0,0 @@
1
- import type { BlocoCasoTesteAst, BlocoGenericoAst, CampoAst, ModuloAst } from "../ast/tipos.js";
2
- import type { Diagnostico } from "../diagnosticos/index.js";
3
- import {
4
- localizarCampoPersistencia,
5
- matrizCompatibilidadePersistencia,
6
- nomeTipoRecursoPersistencia,
7
- normalizarConsistenciaPersistencia,
8
- normalizarDurabilidadePersistencia,
9
- normalizarEngineBanco,
10
- normalizarModeloConsultaPersistencia,
11
- normalizarModeloTransacaoPersistencia,
12
- parsearBooleanoPersistencia,
13
- TIPOS_RECURSO_PERSISTENCIA,
14
- type TipoRecursoPersistencia,
15
- } from "../persistencia/contratos.js";
16
- import type { ContextoSemantico, ErroSemanticoTask } from "../semantico/analisador.js";
17
- import {
18
- contratoDadosTemSensivel,
19
- extrairContratoAudit,
20
- extrairContratoAuth,
21
- extrairContratoAuthz,
22
- extrairContratoDados,
23
- extrairContratoForbidden,
24
- extrairContratoSegredos,
25
- efeitoEhPrivilegiado,
26
- } from "../semantico/seguranca.js";
27
- import { parsearEfeitoSemantico, parsearEtapaFlow, parsearExpressaoSemantica, parsearTransicaoEstado } from "../semantico/estruturas.js";
28
- import type {
29
- IrBlocoDeclarativo,
30
- IrCampo,
31
- IrCasoTeste,
32
- IrAudit,
33
- IrAuth,
34
- IrAuthz,
35
- IrDados,
36
- IrEntity,
37
- IrErroOperacional,
38
- IrExecucao,
39
- IrForbidden,
40
- IrFlow,
41
- IrImplementacaoTask,
42
- IrBancoDados,
43
- IrCompatibilidadePersistencia,
44
- IrModulo,
45
- IrRecursoPersistencia,
46
- IrResumoAgente,
47
- IrRoute,
48
- IrRoutePublica,
49
- IrSegredos,
50
- IrState,
51
- IrSuperficie,
52
- IrTask,
53
- IrType,
54
- IrVinculo,
55
- NivelConfiancaSemantica,
56
- NivelRiscoSemantico,
57
- PerfilCompatibilidade,
58
- TipoSuperficieIr,
59
- } from "./modelos.js";
60
-
61
- const TIPOS_PRIMITIVOS = new Set([
62
- "Texto",
63
- "Numero",
64
- "Inteiro",
65
- "Decimal",
66
- "Booleano",
67
- "Data",
68
- "DataHora",
69
- "Timestamp",
70
- "Id",
71
- "Email",
72
- "Url",
73
- "Json",
74
- "Objeto",
75
- "Vazio",
76
- ]);
77
-
78
- function encontrarSubBloco(bloco: BlocoGenericoAst, palavraChave: string): BlocoGenericoAst | undefined {
79
- return bloco.blocos.find((subbloco): subbloco is BlocoGenericoAst => subbloco.tipo === "bloco_generico" && subbloco.palavraChave === palavraChave);
80
- }
81
-
82
- function localizarCampo(bloco: BlocoGenericoAst | undefined, ...nomes: string[]): CampoAst | undefined {
83
- return bloco?.campos.find((campo) => nomes.includes(campo.nome));
84
- }
85
-
86
- function valorCampoCompleto(campo?: CampoAst): string | undefined {
87
- if (!campo) {
88
- return undefined;
89
- }
90
- return [campo.valor, ...campo.modificadores].join(" ").trim() || undefined;
91
- }
92
-
93
- function normalizarTipoDeclarado(tipo: string): string {
94
- return tipo
95
- .replace(/\s*([<>\[\](),|?])\s*/g, "$1")
96
- .replace(/\s+/g, "")
97
- .trim();
98
- }
99
-
100
- function dividirNoNivelRaiz(texto: string, separador: string): string[] {
101
- const partes: string[] = [];
102
- let profundidadeAngular = 0;
103
- let profundidadeColchete = 0;
104
- let inicio = 0;
105
-
106
- for (let indice = 0; indice < texto.length; indice += 1) {
107
- const caractere = texto[indice]!;
108
- if (caractere === "<") {
109
- profundidadeAngular += 1;
110
- continue;
111
- }
112
- if (caractere === ">") {
113
- profundidadeAngular = Math.max(0, profundidadeAngular - 1);
114
- continue;
115
- }
116
- if (caractere === "[") {
117
- profundidadeColchete += 1;
118
- continue;
119
- }
120
- if (caractere === "]") {
121
- profundidadeColchete = Math.max(0, profundidadeColchete - 1);
122
- continue;
123
- }
124
- if (profundidadeAngular === 0 && profundidadeColchete === 0 && texto.startsWith(separador, indice)) {
125
- partes.push(texto.slice(inicio, indice));
126
- inicio = indice + separador.length;
127
- indice += separador.length - 1;
128
- }
129
- }
130
-
131
- partes.push(texto.slice(inicio));
132
- return partes.map((parte) => parte.trim()).filter(Boolean);
133
- }
134
-
135
- function analisarCampoTipo(tipo: string, modificadores: string[]): Omit<IrCampo, "nome"> {
136
- const tipoOriginal = normalizarTipoDeclarado(tipo);
137
- const modificadoresNormalizados = modificadores.map((item) => item.trim()).filter(Boolean);
138
- const refinamentos = modificadoresNormalizados.filter((item) => !["required", "optional", "opcional"].includes(item));
139
- const opcionalPorModificador = modificadoresNormalizados.includes("optional") || modificadoresNormalizados.includes("opcional");
140
-
141
- let tipoBase = tipoOriginal;
142
- let cardinalidade: IrCampo["cardinalidade"] = "unitario";
143
- let tiposAlternativos: string[] = [];
144
- let tipoItem: string | undefined;
145
- let chaveMapa: string | undefined;
146
- let valorMapa: string | undefined;
147
- let opcional = opcionalPorModificador;
148
-
149
- if (tipoBase.endsWith("?")) {
150
- opcional = true;
151
- tipoBase = tipoBase.slice(0, -1);
152
- }
153
-
154
- if (/^Opcional<.+>$/.test(tipoBase)) {
155
- opcional = true;
156
- tipoBase = tipoBase.slice("Opcional<".length, -1);
157
- }
158
-
159
- const uniao = dividirNoNivelRaiz(tipoBase, "|");
160
- if (uniao.length > 1) {
161
- cardinalidade = "uniao";
162
- tiposAlternativos = uniao.map(normalizarTipoDeclarado);
163
- tipoBase = tiposAlternativos[0] ?? tipoBase;
164
- } else if (/^Lista<.+>$/.test(tipoBase)) {
165
- cardinalidade = "lista";
166
- tipoItem = tipoBase.slice("Lista<".length, -1).trim();
167
- tipoBase = tipoItem;
168
- } else if (/^Mapa<.+>$/.test(tipoBase)) {
169
- cardinalidade = "mapa";
170
- const partesMapa = dividirNoNivelRaiz(tipoBase.slice("Mapa<".length, -1), ",");
171
- chaveMapa = partesMapa[0];
172
- valorMapa = partesMapa[1];
173
- tipoBase = valorMapa ?? tipoBase;
174
- }
175
-
176
- return {
177
- tipo: tipoOriginal,
178
- modificadores: modificadoresNormalizados,
179
- tipoOriginal,
180
- tipoBase,
181
- cardinalidade,
182
- opcional,
183
- tiposAlternativos,
184
- tipoItem,
185
- chaveMapa,
186
- valorMapa,
187
- refinamentos,
188
- };
189
- }
190
-
191
- function converterCampo(campo: CampoAst): IrCampo {
192
- return {
193
- nome: campo.nome,
194
- ...analisarCampoTipo(campo.valor, campo.modificadores),
195
- };
196
- }
197
-
198
- function converterCampos(bloco?: BlocoGenericoAst): IrCampo[] {
199
- if (!bloco) {
200
- return [];
201
- }
202
- return bloco.campos.map(converterCampo);
203
- }
204
-
205
- function converterBloco(bloco?: BlocoGenericoAst): IrBlocoDeclarativo {
206
- return {
207
- campos: converterCampos(bloco),
208
- linhas: bloco?.linhas.map((linha) => linha.conteudo) ?? [],
209
- blocos: (bloco?.blocos ?? [])
210
- .filter((subbloco): subbloco is BlocoGenericoAst => subbloco.tipo === "bloco_generico")
211
- .map((subbloco) => ({
212
- nome: subbloco.nome ?? subbloco.palavraChave,
213
- conteudo: converterBloco(subbloco),
214
- })),
215
- };
216
- }
217
-
218
- function converterCaso(caso: BlocoCasoTesteAst): IrCasoTeste {
219
- return {
220
- nome: caso.nome,
221
- given: converterBloco(caso.given),
222
- when: caso.when ? converterBloco(caso.when) : undefined,
223
- expect: converterBloco(caso.expect),
224
- error: caso.error ? converterBloco(caso.error) : undefined,
225
- };
226
- }
227
-
228
- function coletarLinhasPersistencia(bloco: BlocoGenericoAst | undefined, nome: string): string[] {
229
- if (!bloco) {
230
- return [];
231
- }
232
- return encontrarSubBloco(bloco, nome)?.linhas.map((linha) => linha.conteudo) ?? [];
233
- }
234
-
235
- function resolverTipoRecursoPersistencia(bloco: BlocoGenericoAst): TipoRecursoPersistencia | undefined {
236
- const explicito = valorCampoCompleto(localizarCampoPersistencia(bloco, "resource_kind"));
237
- if (explicito && TIPOS_RECURSO_PERSISTENCIA.has(explicito as TipoRecursoPersistencia)) {
238
- return explicito as TipoRecursoPersistencia;
239
- }
240
- return nomeTipoRecursoPersistencia(bloco);
241
- }
242
-
243
- function converterCompatibilidadePersistencia(
244
- compatibilidades: ReturnType<typeof matrizCompatibilidadePersistencia>,
245
- ): IrCompatibilidadePersistencia[] {
246
- return compatibilidades.map((item) => ({ ...item }));
247
- }
248
-
249
- function converterRecursoPersistencia(recurso: BlocoGenericoAst): IrRecursoPersistencia | undefined {
250
- const resourceKind = resolverTipoRecursoPersistencia(recurso);
251
- if (!resourceKind) {
252
- return undefined;
253
- }
254
-
255
- const mode = valorCampoCompleto(localizarCampoPersistencia(recurso, "mode"));
256
- const isolation = valorCampoCompleto(localizarCampoPersistencia(recurso, "isolation"));
257
-
258
- return {
259
- nome: recurso.nome ?? resourceKind,
260
- resourceKind,
261
- entity: valorCampoCompleto(localizarCampoPersistencia(recurso, "entity")),
262
- collection: valorCampoCompleto(localizarCampoPersistencia(recurso, "collection")),
263
- table: valorCampoCompleto(localizarCampoPersistencia(recurso, "table")),
264
- consistency: normalizarConsistenciaPersistencia(valorCampoCompleto(localizarCampoPersistencia(recurso, "consistency")))
265
- ?? valorCampoCompleto(localizarCampoPersistencia(recurso, "consistency")),
266
- durability: normalizarDurabilidadePersistencia(valorCampoCompleto(localizarCampoPersistencia(recurso, "durability")))
267
- ?? valorCampoCompleto(localizarCampoPersistencia(recurso, "durability")),
268
- transactionModel: normalizarModeloTransacaoPersistencia(valorCampoCompleto(localizarCampoPersistencia(recurso, "transaction_model")))
269
- ?? valorCampoCompleto(localizarCampoPersistencia(recurso, "transaction_model")),
270
- queryModel: normalizarModeloConsultaPersistencia(valorCampoCompleto(localizarCampoPersistencia(recurso, "query_model")))
271
- ?? valorCampoCompleto(localizarCampoPersistencia(recurso, "query_model")),
272
- mode,
273
- isolation,
274
- strategy: valorCampoCompleto(localizarCampoPersistencia(recurso, "strategy")),
275
- ttl: valorCampoCompleto(localizarCampoPersistencia(recurso, "ttl")),
276
- retention: valorCampoCompleto(localizarCampoPersistencia(recurso, "retention")),
277
- path: valorCampoCompleto(localizarCampoPersistencia(recurso, "path")),
278
- from: valorCampoCompleto(localizarCampoPersistencia(recurso, "from")),
279
- to: valorCampoCompleto(localizarCampoPersistencia(recurso, "to")),
280
- surface: valorCampoCompleto(localizarCampoPersistencia(recurso, "surface")),
281
- adapter: valorCampoCompleto(localizarCampoPersistencia(recurso, "adapter")),
282
- portavel: parsearBooleanoPersistencia(valorCampoCompleto(localizarCampoPersistencia(recurso, "portavel"))),
283
- capabilities: coletarLinhasPersistencia(recurso, "capabilities"),
284
- operations: coletarLinhasPersistencia(recurso, "operations"),
285
- indexing: coletarLinhasPersistencia(recurso, "indexing"),
286
- guarantees: coletarLinhasPersistencia(recurso, "guarantees"),
287
- diagnostics: coletarLinhasPersistencia(recurso, "diagnostics"),
288
- risks: coletarLinhasPersistencia(recurso, "risks"),
289
- fields: converterCampos(recurso),
290
- lines: recurso.linhas.map((linha) => linha.conteudo),
291
- block: converterBloco(recurso),
292
- compatibilidade: converterCompatibilidadePersistencia(matrizCompatibilidadePersistencia(resourceKind, { mode, isolation })),
293
- };
294
- }
295
-
296
- function converterDatabase(database: BlocoGenericoAst): IrBancoDados {
297
- return {
298
- nome: database.nome ?? "database",
299
- engine: normalizarEngineBanco(valorCampoCompleto(localizarCampoPersistencia(database, "engine"))),
300
- schema: valorCampoCompleto(localizarCampoPersistencia(database, "schema")),
301
- database: valorCampoCompleto(localizarCampoPersistencia(database, "database")),
302
- consistency: normalizarConsistenciaPersistencia(valorCampoCompleto(localizarCampoPersistencia(database, "consistency")))
303
- ?? valorCampoCompleto(localizarCampoPersistencia(database, "consistency")),
304
- durability: normalizarDurabilidadePersistencia(valorCampoCompleto(localizarCampoPersistencia(database, "durability")))
305
- ?? valorCampoCompleto(localizarCampoPersistencia(database, "durability")),
306
- transactionModel: normalizarModeloTransacaoPersistencia(valorCampoCompleto(localizarCampoPersistencia(database, "transaction_model")))
307
- ?? valorCampoCompleto(localizarCampoPersistencia(database, "transaction_model")),
308
- queryModel: normalizarModeloConsultaPersistencia(valorCampoCompleto(localizarCampoPersistencia(database, "query_model")))
309
- ?? valorCampoCompleto(localizarCampoPersistencia(database, "query_model")),
310
- portavel: parsearBooleanoPersistencia(valorCampoCompleto(localizarCampoPersistencia(database, "portavel"))),
311
- adapter: valorCampoCompleto(localizarCampoPersistencia(database, "adapter")),
312
- capabilities: coletarLinhasPersistencia(database, "capabilities"),
313
- operations: coletarLinhasPersistencia(database, "operations"),
314
- indexing: coletarLinhasPersistencia(database, "indexing"),
315
- guarantees: coletarLinhasPersistencia(database, "guarantees"),
316
- diagnostics: coletarLinhasPersistencia(database, "diagnostics"),
317
- risks: coletarLinhasPersistencia(database, "risks"),
318
- fields: converterCampos(database),
319
- lines: database.linhas.map((linha) => linha.conteudo),
320
- block: converterBloco(database),
321
- resources: database.blocos
322
- .filter((bloco): bloco is BlocoGenericoAst => bloco.tipo === "bloco_generico")
323
- .map(converterRecursoPersistencia)
324
- .filter((item): item is IrRecursoPersistencia => Boolean(item)),
325
- };
326
- }
327
-
328
- function converterImplementacoes(bloco?: BlocoGenericoAst): IrImplementacaoTask[] {
329
- const implementacoes: IrImplementacaoTask[] = [];
330
- for (const campo of bloco?.campos ?? []) {
331
- const origem = campo.nome.toLowerCase();
332
- if (origem === "ts" || origem === "typescript") {
333
- implementacoes.push({ origem: "ts", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
334
- continue;
335
- }
336
- if (origem === "py" || origem === "python") {
337
- implementacoes.push({ origem: "py", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
338
- continue;
339
- }
340
- if (origem === "dart") {
341
- implementacoes.push({ origem: "dart", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
342
- continue;
343
- }
344
- if (origem === "lua") {
345
- implementacoes.push({ origem: "lua", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
346
- continue;
347
- }
348
- if (origem === "cs" || origem === "csharp" || origem === "dotnet") {
349
- implementacoes.push({ origem: "cs", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
350
- continue;
351
- }
352
- if (origem === "java") {
353
- implementacoes.push({ origem: "java", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
354
- continue;
355
- }
356
- if (origem === "go" || origem === "golang") {
357
- implementacoes.push({ origem: "go", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
358
- continue;
359
- }
360
- if (origem === "rust" || origem === "rs") {
361
- implementacoes.push({ origem: "rust", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
362
- continue;
363
- }
364
- if (origem === "cpp" || origem === "cxx" || origem === "cc" || origem === "c++") {
365
- implementacoes.push({ origem: "cpp", caminho: campo.valor, resolucaoImpl: campo.valor, statusImpl: "nao_verificado" });
366
- }
367
- }
368
- return implementacoes;
369
- }
370
-
371
- function converterVinculos(bloco?: BlocoGenericoAst): IrVinculo[] {
372
- if (!bloco) {
373
- return [];
374
- }
375
-
376
- const campos = bloco.campos.map((campo) => {
377
- const valor = valorCampoCompleto(campo) ?? "";
378
- return {
379
- tipo: campo.nome,
380
- valor,
381
- arquivo: campo.nome === "arquivo" ? valor : undefined,
382
- simbolo: campo.nome === "simbolo" ? valor : undefined,
383
- recurso: ["recurso", "tabela", "fila", "cache", "storage"].includes(campo.nome) ? valor : undefined,
384
- superficie: ["superficie", "rota", "worker", "cron", "webhook", "evento", "policy", "fila", "cache", "storage"].includes(campo.nome) ? valor : undefined,
385
- statusResolucao: "nao_verificado" as const,
386
- };
387
- });
388
-
389
- const linhas = bloco.linhas.map((linha) => {
390
- const [tipo, ...resto] = linha.conteudo.split(/\s+/);
391
- const valor = resto.join(" ").trim();
392
- return {
393
- tipo: tipo ?? "desconhecido",
394
- valor,
395
- statusResolucao: "nao_verificado" as const,
396
- };
397
- }).filter((item) => item.valor);
398
-
399
- const subblocos = bloco.blocos
400
- .filter((item): item is BlocoGenericoAst => item.tipo === "bloco_generico")
401
- .map((item) => ({
402
- tipo: item.palavraChave === "desconhecido" ? (item.nome ?? "desconhecido") : item.palavraChave,
403
- valor: item.nome ?? item.palavraChave,
404
- arquivo: valorCampoCompleto(localizarCampo(item, "arquivo")),
405
- simbolo: valorCampoCompleto(localizarCampo(item, "simbolo")),
406
- recurso: valorCampoCompleto(localizarCampo(item, "recurso", "tabela", "fila", "cache", "storage")),
407
- superficie: valorCampoCompleto(localizarCampo(item, "superficie", "rota", "worker", "cron", "webhook", "evento")),
408
- statusResolucao: "nao_verificado" as const,
409
- }));
410
-
411
- return [...campos, ...linhas, ...subblocos];
412
- }
413
-
414
- function converterExecucao(bloco?: BlocoGenericoAst): IrExecucao {
415
- const idempotencia = valorCampoCompleto(localizarCampo(bloco, "idempotencia"));
416
- const criticidadeOperacional = valorCampoCompleto(localizarCampo(bloco, "criticidade_operacional"));
417
-
418
- return {
419
- idempotencia: idempotencia === "verdadeiro" || idempotencia === "true",
420
- timeout: valorCampoCompleto(localizarCampo(bloco, "timeout")) ?? "padrao",
421
- retry: valorCampoCompleto(localizarCampo(bloco, "retry")) ?? "nenhum",
422
- compensacao: valorCampoCompleto(localizarCampo(bloco, "compensacao")) ?? "nenhuma",
423
- criticidadeOperacional: (
424
- criticidadeOperacional === "baixa"
425
- || criticidadeOperacional === "alta"
426
- || criticidadeOperacional === "critica"
427
- ) ? criticidadeOperacional : "media",
428
- explicita: Boolean(bloco),
429
- };
430
- }
431
-
432
- function converterAuth(bloco?: BlocoGenericoAst): IrAuth {
433
- return extrairContratoAuth(bloco);
434
- }
435
-
436
- function converterAuthz(bloco?: BlocoGenericoAst): IrAuthz {
437
- return extrairContratoAuthz(bloco);
438
- }
439
-
440
- function converterDados(bloco?: BlocoGenericoAst): IrDados {
441
- return extrairContratoDados(bloco);
442
- }
443
-
444
- function converterAudit(bloco?: BlocoGenericoAst): IrAudit {
445
- return extrairContratoAudit(bloco);
446
- }
447
-
448
- function converterSegredos(bloco?: BlocoGenericoAst): IrSegredos {
449
- return extrairContratoSegredos(bloco);
450
- }
451
-
452
- function converterForbidden(bloco?: BlocoGenericoAst): IrForbidden {
453
- return extrairContratoForbidden(bloco);
454
- }
455
-
456
- function converterErrosTask(bloco?: BlocoGenericoAst, fallback?: ErroSemanticoTask[]): IrErroOperacional[] {
457
- const erros = new Map<string, IrErroOperacional>();
458
-
459
- for (const campo of bloco?.campos ?? []) {
460
- erros.set(campo.nome, {
461
- codigo: campo.nome,
462
- mensagem: valorCampoCompleto(campo) ?? "",
463
- });
464
- }
465
-
466
- for (const subbloco of bloco?.blocos ?? []) {
467
- if (subbloco.tipo !== "bloco_generico") {
468
- continue;
469
- }
470
- const codigo = subbloco.nome ?? subbloco.palavraChave;
471
- if (!codigo || codigo === "desconhecido") {
472
- continue;
473
- }
474
- erros.set(codigo, {
475
- codigo,
476
- mensagem: valorCampoCompleto(localizarCampo(subbloco, "mensagem")) ?? `Erro estruturado "${codigo}".`,
477
- categoria: valorCampoCompleto(localizarCampo(subbloco, "categoria")),
478
- recuperabilidade: valorCampoCompleto(localizarCampo(subbloco, "recuperabilidade")),
479
- acaoChamador: valorCampoCompleto(localizarCampo(subbloco, "acao_chamador")),
480
- impactaEstado: valorCampoCompleto(localizarCampo(subbloco, "impacta_estado")) === "verdadeiro",
481
- requerCompensacao: valorCampoCompleto(localizarCampo(subbloco, "requer_compensacao")) === "verdadeiro",
482
- });
483
- }
484
-
485
- for (const erro of fallback ?? []) {
486
- if (!erros.has(erro.codigo)) {
487
- erros.set(erro.codigo, {
488
- codigo: erro.codigo,
489
- mensagem: erro.mensagem,
490
- categoria: erro.categoria,
491
- recuperabilidade: erro.recuperabilidade,
492
- acaoChamador: erro.acaoChamador,
493
- impactaEstado: erro.impactaEstado,
494
- requerCompensacao: erro.requerCompensacao,
495
- });
496
- }
497
- }
498
-
499
- return [...erros.values()];
500
- }
501
-
502
- function extrairPerfil(bloco?: BlocoGenericoAst, padrao: PerfilCompatibilidade = "interno"): PerfilCompatibilidade {
503
- const perfil = valorCampoCompleto(localizarCampo(bloco, "perfil", "compatibilidade"))?.toLowerCase();
504
- if (
505
- perfil === "publico"
506
- || perfil === "interno"
507
- || perfil === "experimental"
508
- || perfil === "legado"
509
- || perfil === "deprecado"
510
- ) {
511
- return perfil;
512
- }
513
- return padrao;
514
- }
515
-
516
- function tipoNaoPrimitivo(campo: IrCampo): string | undefined {
517
- if (!TIPOS_PRIMITIVOS.has(campo.tipoBase)) {
518
- return campo.tipoBase;
519
- }
520
- if (campo.tipoItem && !TIPOS_PRIMITIVOS.has(campo.tipoItem)) {
521
- return campo.tipoItem;
522
- }
523
- if (campo.valorMapa && !TIPOS_PRIMITIVOS.has(campo.valorMapa)) {
524
- return campo.valorMapa;
525
- }
526
- return undefined;
527
- }
528
-
529
- function deduplicarTexto(valores: string[]): string[] {
530
- return [...new Set(valores.filter(Boolean))].sort((a, b) => a.localeCompare(b, "pt-BR"));
531
- }
532
-
533
- function resumirAgente(params: {
534
- input?: IrCampo[];
535
- output?: IrCampo[];
536
- efeitos?: Array<{ categoria: string; alvo: string; criticidade?: string }>;
537
- vinculos?: IrVinculo[];
538
- execucao?: IrExecucao;
539
- auth?: IrAuth;
540
- authz?: IrAuthz;
541
- dados?: IrDados;
542
- audit?: IrAudit;
543
- segredos?: IrSegredos;
544
- forbidden?: IrForbidden;
545
- superficiePublica?: string;
546
- }): IrResumoAgente {
547
- const entidadesAfetadas = deduplicarTexto([
548
- ...(params.input ?? []).map(tipoNaoPrimitivo).filter((item): item is string => Boolean(item)),
549
- ...(params.output ?? []).map(tipoNaoPrimitivo).filter((item): item is string => Boolean(item)),
550
- ...(params.efeitos ?? []).map((efeito) => efeito.alvo),
551
- ]);
552
-
553
- const mutacoesPrevistas = deduplicarTexto(
554
- (params.efeitos ?? []).map((efeito) => `${efeito.categoria}:${efeito.alvo}`),
555
- );
556
-
557
- const riscos = new Set<string>();
558
- if ((params.efeitos ?? []).some((efeito) => efeito.categoria === "persistencia")) {
559
- riscos.add("altera_persistencia");
560
- }
561
- if ((params.efeitos ?? []).some((efeito) => efeitoEhPrivilegiado(efeito))) {
562
- riscos.add("efeito_privilegiado");
563
- }
564
- if ((params.efeitos ?? []).some((efeito) => efeito.criticidade === "alta" || efeito.criticidade === "critica")) {
565
- riscos.add("efeito_critico");
566
- }
567
- if (params.execucao?.criticidadeOperacional === "alta" || params.execucao?.criticidadeOperacional === "critica") {
568
- riscos.add("execucao_critica");
569
- }
570
- if (contratoDadosTemSensivel(params.dados)) {
571
- riscos.add("dados_sensiveis");
572
- }
573
- if (params.segredos?.itens.length) {
574
- riscos.add("segredo_operacional");
575
- }
576
- if ((params.vinculos ?? []).length === 0) {
577
- riscos.add("vinculo_fraco");
578
- }
579
-
580
- const checks = new Set<string>();
581
- checks.add("rodar sema validar --json");
582
- if ((params.output ?? []).length > 0) {
583
- checks.add("verificar guarantees");
584
- }
585
- if ((params.vinculos ?? []).length > 0) {
586
- checks.add("rodar sema drift --json");
587
- }
588
- if (params.auth?.explicita || params.authz?.explicita) {
589
- checks.add("revisar auth e authz");
590
- }
591
- if (params.dados?.explicita) {
592
- checks.add("validar classificacao de dados");
593
- }
594
- if (params.audit?.explicita) {
595
- checks.add("validar trilha de auditoria");
596
- }
597
- if (params.forbidden?.explicita) {
598
- checks.add("confirmar proibicoes operacionais");
599
- }
600
- if (params.superficiePublica) {
601
- checks.add("validar superficie publica impactada");
602
- }
603
-
604
- return {
605
- riscos: [...riscos],
606
- checks: [...checks],
607
- entidadesAfetadas,
608
- superficiesPublicas: params.superficiePublica ? [params.superficiePublica] : [],
609
- mutacoesPrevistas,
610
- };
611
- }
612
-
613
- function recomporCaminho(campo?: CampoAst): string | undefined {
614
- const valor = valorCampoCompleto(campo);
615
- return valor?.replace(/\s*\/\s*/g, "/").trim();
616
- }
617
-
618
- function ehUseInterop(
619
- use: ModuloAst["uses"][number],
620
- ): use is ModuloAst["uses"][number] & { origem: "ts" | "py" | "dart" | "lua" | "cs" | "java" | "go" | "rust" | "cpp" } {
621
- return use.origem !== "sema";
622
- }
623
-
624
- function converterErroPublico(erro: IrErroOperacional, origemTask?: string) {
625
- return {
626
- nome: erro.codigo,
627
- codigo: erro.codigo,
628
- mensagem: erro.mensagem,
629
- categoria: erro.categoria,
630
- recuperabilidade: erro.recuperabilidade,
631
- acaoChamador: erro.acaoChamador,
632
- impactaEstado: erro.impactaEstado,
633
- requerCompensacao: erro.requerCompensacao,
634
- origemTask,
635
- };
636
- }
637
-
638
- function calcularConfiancaPublica(route: IrRoute): NivelConfiancaSemantica {
639
- if (route.task && route.vinculos.length > 0) {
640
- return "alta";
641
- }
642
- if (route.task || route.vinculos.length > 0) {
643
- return "media";
644
- }
645
- return "baixa";
646
- }
647
-
648
- function calcularRiscoPublico(route: IrRoute): NivelRiscoSemantico {
649
- if (
650
- !route.auth.explicita
651
- || contratoDadosTemSensivel(route.dados)
652
- || route.efeitosPublicos.some((efeito) => efeitoEhPrivilegiado(efeito) || efeito.categoria === "persistencia" || efeito.criticidade === "critica")
653
- ) {
654
- return "alto";
655
- }
656
- if (route.efeitosPublicos.length > 0 || route.errosPublicos.length > 0) {
657
- return "medio";
658
- }
659
- return "baixo";
660
- }
661
-
662
- function converterSuperficie(
663
- tipo: TipoSuperficieIr,
664
- superficie: BlocoGenericoAst,
665
- ): IrSuperficie {
666
- const input = converterCampos(encontrarSubBloco(superficie, "input"));
667
- const output = converterCampos(encontrarSubBloco(superficie, "output"));
668
- const effects = (encontrarSubBloco(superficie, "effects")?.linhas ?? [])
669
- .map((linha) => parsearEfeitoSemantico(linha.conteudo))
670
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha));
671
- const vinculos = converterVinculos(encontrarSubBloco(superficie, "vinculos"));
672
- const execucao = converterExecucao(encontrarSubBloco(superficie, "execucao"));
673
- const auth = converterAuth(encontrarSubBloco(superficie, "auth"));
674
- const authz = converterAuthz(encontrarSubBloco(superficie, "authz"));
675
- const dados = converterDados(encontrarSubBloco(superficie, "dados"));
676
- const audit = converterAudit(encontrarSubBloco(superficie, "audit"));
677
- const segredos = converterSegredos(encontrarSubBloco(superficie, "segredos"));
678
- const forbidden = converterForbidden(encontrarSubBloco(superficie, "forbidden"));
679
- const task = valorCampoCompleto(localizarCampo(superficie, "task", "tarefa"));
680
- const perfilCompatibilidade = extrairPerfil(superficie, tipo === "webhook" ? "publico" : "interno");
681
- const resumoAgente = resumirAgente({
682
- input,
683
- output,
684
- efeitos: effects,
685
- vinculos,
686
- execucao,
687
- auth,
688
- authz,
689
- dados,
690
- audit,
691
- segredos,
692
- forbidden,
693
- superficiePublica: perfilCompatibilidade === "publico" ? `${tipo}:${superficie.nome ?? tipo}` : undefined,
694
- });
695
-
696
- return {
697
- tipo,
698
- nome: superficie.nome ?? tipo,
699
- campos: converterCampos(superficie),
700
- linhas: superficie.linhas.map((linha) => linha.conteudo),
701
- task: task || undefined,
702
- input,
703
- output,
704
- effects,
705
- implementacoesExternas: converterImplementacoes(encontrarSubBloco(superficie, "impl")),
706
- vinculos,
707
- execucao,
708
- auth,
709
- authz,
710
- dados,
711
- audit,
712
- segredos,
713
- forbidden,
714
- perfilCompatibilidade,
715
- resumoAgente,
716
- };
717
- }
718
-
719
- export function converterParaIr(modulo: ModuloAst, diagnosticos: Diagnostico[], contexto?: ContextoSemantico): IrModulo {
720
- const perfilModulo = extrairPerfil(modulo.vinculos, modulo.routes.length > 0 || modulo.webhooks.length > 0 ? "publico" : "interno");
721
-
722
- const types: IrType[] = modulo.types.map((type) => ({
723
- nome: type.nome,
724
- definicao: converterBloco(encontrarSubBloco(type.corpo, "fields") ?? type.corpo),
725
- invariantes: (encontrarSubBloco(type.corpo, "invariants")?.linhas ?? [])
726
- .map((linha) => parsearExpressaoSemantica(linha.conteudo))
727
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
728
- }));
729
-
730
- const entities: IrEntity[] = modulo.entities.map((entity) => ({
731
- nome: entity.nome,
732
- campos: converterCampos(encontrarSubBloco(entity.corpo, "fields")),
733
- invariantes: (encontrarSubBloco(entity.corpo, "invariants")?.linhas ?? [])
734
- .map((linha) => parsearExpressaoSemantica(linha.conteudo))
735
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
736
- }));
737
-
738
- const tarefasSemanticas = contexto?.tarefasDetalhadas ?? new Map();
739
- const tasks: IrTask[] = modulo.tasks.map((task) => {
740
- const input = converterCampos(task.input);
741
- const output = converterCampos(task.output);
742
- const effects = (task.effects?.linhas ?? [])
743
- .map((linha) => parsearEfeitoSemantico(linha.conteudo))
744
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha));
745
- const vinculos = converterVinculos(task.vinculos);
746
- const execucao = converterExecucao(task.execucao);
747
- const auth = converterAuth(encontrarSubBloco(task.corpo, "auth"));
748
- const authz = converterAuthz(encontrarSubBloco(task.corpo, "authz"));
749
- const dados = converterDados(encontrarSubBloco(task.corpo, "dados"));
750
- const audit = converterAudit(encontrarSubBloco(task.corpo, "audit"));
751
- const segredos = converterSegredos(encontrarSubBloco(task.corpo, "segredos"));
752
- const forbidden = converterForbidden(encontrarSubBloco(task.corpo, "forbidden"));
753
- const errosDetalhados = converterErrosTask(task.error, tarefasSemanticas.get(task.nome)?.errors);
754
- const perfilCompatibilidade = extrairPerfil(task.corpo, "interno");
755
- const resumoAgente = resumirAgente({
756
- input,
757
- output,
758
- efeitos: effects,
759
- vinculos,
760
- execucao,
761
- auth,
762
- authz,
763
- dados,
764
- audit,
765
- segredos,
766
- forbidden,
767
- });
768
-
769
- return {
770
- nome: task.nome,
771
- input,
772
- output,
773
- rules: task.rules?.linhas.map((linha) => linha.conteudo) ?? [],
774
- regrasEstruturadas: (task.rules?.linhas ?? [])
775
- .map((linha) => parsearExpressaoSemantica(linha.conteudo))
776
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
777
- effects: task.effects?.linhas.map((linha) => linha.conteudo) ?? [],
778
- efeitosEstruturados: effects,
779
- implementacoesExternas: converterImplementacoes(task.impl),
780
- vinculos,
781
- execucao,
782
- auth,
783
- authz,
784
- dados,
785
- audit,
786
- segredos,
787
- forbidden,
788
- guarantees: task.guarantees?.linhas.map((linha) => linha.conteudo) ?? [],
789
- garantiasEstruturadas: (task.guarantees?.linhas ?? [])
790
- .map((linha) => parsearExpressaoSemantica(linha.conteudo))
791
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
792
- errors: Object.fromEntries(errosDetalhados.map((erro) => [erro.codigo, erro.mensagem])),
793
- errosDetalhados,
794
- perfilCompatibilidade,
795
- stateContract: task.state ? {
796
- nomeEstado: task.state.nome ?? task.state.campos.find((campo) => campo.nome === "state" || campo.nome === "estado")?.valor,
797
- campos: converterCampos(task.state),
798
- linhas: task.state.linhas.map((linha) => linha.conteudo),
799
- transicoes: (encontrarSubBloco(task.state, "transitions")?.linhas ?? task.state.linhas)
800
- .map((linha) => parsearTransicaoEstado(linha.conteudo))
801
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
802
- } : undefined,
803
- resumoAgente,
804
- tests: (task.tests?.blocos.filter((bloco): bloco is BlocoCasoTesteAst => bloco.tipo === "caso_teste") ?? []).map(converterCaso),
805
- };
806
- });
807
-
808
- const tarefasPorNome = new Map(tasks.map((task) => [task.nome, task] as const));
809
-
810
- const flows: IrFlow[] = modulo.flows.map((flow) => {
811
- const campos = converterCampos(flow.corpo);
812
- const effects = (encontrarSubBloco(flow.corpo, "effects")?.linhas ?? [])
813
- .map((linha) => parsearEfeitoSemantico(linha.conteudo))
814
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha));
815
- const vinculos = converterVinculos(flow.vinculos);
816
- const perfilCompatibilidade = extrairPerfil(flow.corpo, "interno");
817
- return {
818
- nome: flow.nome,
819
- campos,
820
- linhas: flow.corpo.linhas.map((linha) => linha.conteudo),
821
- tasksReferenciadas: flow.corpo.campos
822
- .filter((campo) => campo.nome === "task" || campo.nome === "tarefa")
823
- .map((campo) => campo.valor),
824
- etapasEstruturadas: flow.corpo.linhas
825
- .map((linha) => parsearEtapaFlow(linha.conteudo))
826
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
827
- effects: (encontrarSubBloco(flow.corpo, "effects")?.linhas ?? []).map((linha) => linha.conteudo),
828
- efeitosEstruturados: effects,
829
- vinculos,
830
- perfilCompatibilidade,
831
- resumoAgente: resumirAgente({
832
- input: campos,
833
- efeitos: effects,
834
- vinculos,
835
- }),
836
- };
837
- });
838
-
839
- const routes: IrRoute[] = modulo.routes.map((route) => ({
840
- nome: route.nome,
841
- campos: converterCampos(route.corpo),
842
- linhas: route.corpo.linhas.map((linha) => linha.conteudo),
843
- metodo: route.corpo.campos.find((campo) => campo.nome === "metodo")?.valor,
844
- caminho: recomporCaminho(route.corpo.campos.find((campo) => campo.nome === "caminho")),
845
- task: route.corpo.campos.find((campo) => campo.nome === "task" || campo.nome === "tarefa")?.valor,
846
- inputPublico: [],
847
- outputPublico: [],
848
- errosPublicos: [],
849
- efeitosPublicos: [],
850
- vinculos: converterVinculos(route.vinculos),
851
- auth: converterAuth(encontrarSubBloco(route.corpo, "auth")),
852
- authz: converterAuthz(encontrarSubBloco(route.corpo, "authz")),
853
- dados: converterDados(encontrarSubBloco(route.corpo, "dados")),
854
- audit: converterAudit(encontrarSubBloco(route.corpo, "audit")),
855
- segredos: converterSegredos(encontrarSubBloco(route.corpo, "segredos")),
856
- forbidden: converterForbidden(encontrarSubBloco(route.corpo, "forbidden")),
857
- perfilCompatibilidade: extrairPerfil(route.corpo, "publico"),
858
- garantiasPublicasMinimas: [],
859
- resumoAgente: {
860
- riscos: [],
861
- checks: [],
862
- entidadesAfetadas: [],
863
- superficiesPublicas: [],
864
- mutacoesPrevistas: [],
865
- },
866
- publico: {
867
- metodo: undefined,
868
- caminho: undefined,
869
- task: undefined,
870
- input: [],
871
- output: [],
872
- errors: [],
873
- effects: [],
874
- garantiasMinimas: [],
875
- },
876
- })).map((route) => {
877
- const routeAst = modulo.routes.find((item) => item.nome === route.nome)!;
878
- const tarefaAssociada = route.task ? tarefasPorNome.get(route.task) : undefined;
879
- const tarefaSemantica = route.task ? tarefasSemanticas.get(route.task) : undefined;
880
- const inputPublicoDeclarado = converterCampos(encontrarSubBloco(routeAst.corpo, "input"));
881
- const outputPublicoDeclarado = converterCampos(encontrarSubBloco(routeAst.corpo, "output"));
882
- const errosDeclarados = converterErrosTask(encontrarSubBloco(routeAst.corpo, "error"), tarefaSemantica?.errors);
883
- const efeitosPublicosDeclarados = (encontrarSubBloco(routeAst.corpo, "effects")?.linhas ?? [])
884
- .map((linha) => parsearEfeitoSemantico(linha.conteudo))
885
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha));
886
- const inputPublicoResolvido = inputPublicoDeclarado.length > 0
887
- ? inputPublicoDeclarado
888
- : (tarefaAssociada?.input ?? tarefaSemantica?.input?.map((campo: { nome: string; tipo: string; modificadores: string[] }) => ({
889
- nome: campo.nome,
890
- tipo: campo.tipo,
891
- modificadores: campo.modificadores,
892
- tipoOriginal: campo.tipo,
893
- tipoBase: campo.tipo,
894
- cardinalidade: "unitario" as const,
895
- opcional: false,
896
- tiposAlternativos: [],
897
- refinamentos: [],
898
- })) ?? []);
899
- const outputPublicoResolvido = outputPublicoDeclarado.length > 0
900
- ? outputPublicoDeclarado
901
- : (tarefaAssociada?.output ?? tarefaSemantica?.output?.map((campo: { nome: string; tipo: string; modificadores: string[] }) => ({
902
- nome: campo.nome,
903
- tipo: campo.tipo,
904
- modificadores: campo.modificadores,
905
- tipoOriginal: campo.tipo,
906
- tipoBase: campo.tipo,
907
- cardinalidade: "unitario" as const,
908
- opcional: false,
909
- tiposAlternativos: [],
910
- refinamentos: [],
911
- })) ?? []);
912
- const errosPublicosResolvidos = errosDeclarados.length > 0
913
- ? errosDeclarados.map((erro) => converterErroPublico(erro, route.task))
914
- : (tarefaAssociada?.errosDetalhados ?? (tarefaSemantica?.errors ?? []).map((erro: { codigo: string; mensagem: string }) => ({ codigo: erro.codigo, mensagem: erro.mensagem }))).map((erro: IrErroOperacional) =>
915
- converterErroPublico(erro, route.task));
916
- const garantiasPublicasMinimas = (tarefaAssociada?.guarantees ?? tarefaSemantica?.guarantees ?? []).filter((garantia: string) => {
917
- const referencia = garantia.trim().split(/\s+/)[0] ?? "";
918
- return outputPublicoResolvido.some((campo: IrCampo) => campo.nome === referencia || garantia.includes(`${campo.nome}.`));
919
- });
920
-
921
- const routeResolvida: IrRoute = {
922
- ...route,
923
- inputPublico: inputPublicoResolvido,
924
- outputPublico: outputPublicoResolvido,
925
- errosPublicos: errosPublicosResolvidos,
926
- efeitosPublicos: efeitosPublicosDeclarados,
927
- garantiasPublicasMinimas,
928
- resumoAgente: resumirAgente({
929
- input: inputPublicoResolvido,
930
- output: outputPublicoResolvido,
931
- efeitos: efeitosPublicosDeclarados,
932
- vinculos: route.vinculos,
933
- auth: route.auth,
934
- authz: route.authz,
935
- dados: route.dados,
936
- audit: route.audit,
937
- segredos: route.segredos,
938
- forbidden: route.forbidden,
939
- superficiePublica: `${route.metodo ?? "?"} ${route.caminho ?? "?"}`,
940
- }),
941
- publico: {
942
- metodo: route.metodo,
943
- caminho: route.caminho,
944
- task: route.task,
945
- input: inputPublicoResolvido,
946
- output: outputPublicoResolvido,
947
- errors: errosPublicosResolvidos,
948
- effects: efeitosPublicosDeclarados,
949
- garantiasMinimas: garantiasPublicasMinimas,
950
- confiancaContrato: "media",
951
- riscoRegressao: "medio",
952
- divergenciasPublicas: [],
953
- },
954
- };
955
-
956
- routeResolvida.publico.confiancaContrato = calcularConfiancaPublica(routeResolvida);
957
- routeResolvida.publico.riscoRegressao = calcularRiscoPublico(routeResolvida);
958
- return routeResolvida;
959
- });
960
-
961
- const superficies: IrSuperficie[] = [
962
- ...modulo.workers.map((item) => converterSuperficie("worker", item)),
963
- ...modulo.eventos.map((item) => converterSuperficie("evento", item)),
964
- ...modulo.filas.map((item) => converterSuperficie("fila", item)),
965
- ...modulo.crons.map((item) => converterSuperficie("cron", item)),
966
- ...modulo.webhooks.map((item) => converterSuperficie("webhook", item)),
967
- ...modulo.caches.map((item) => converterSuperficie("cache", item)),
968
- ...modulo.storages.map((item) => converterSuperficie("storage", item)),
969
- ...modulo.policies.map((item) => converterSuperficie("policy", item)),
970
- ];
971
-
972
- const states: IrState[] = modulo.states.map((state) => ({
973
- nome: state.nome,
974
- campos: converterCampos(encontrarSubBloco(state.corpo, "fields") ?? state.corpo),
975
- linhas: state.corpo.linhas.map((linha) => linha.conteudo),
976
- invariantes: (encontrarSubBloco(state.corpo, "invariants")?.linhas ?? [])
977
- .map((linha) => parsearExpressaoSemantica(linha.conteudo))
978
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
979
- transicoes: (encontrarSubBloco(state.corpo, "transitions")?.linhas ?? [])
980
- .map((linha) => parsearTransicaoEstado(linha.conteudo))
981
- .filter((linha): linha is NonNullable<typeof linha> => Boolean(linha)),
982
- }));
983
-
984
- const databases = modulo.databases.map(converterDatabase);
985
-
986
- const resumoAgenteModulo = resumirAgente({
987
- input: [],
988
- output: [],
989
- efeitos: [
990
- ...tasks.flatMap((task) => task.efeitosEstruturados),
991
- ...routes.flatMap((route) => route.efeitosPublicos),
992
- ...superficies.flatMap((superficie) => superficie.effects),
993
- ],
994
- vinculos: [
995
- ...converterVinculos(modulo.vinculos),
996
- ...tasks.flatMap((task) => task.vinculos),
997
- ...routes.flatMap((route) => route.vinculos),
998
- ...superficies.flatMap((superficie) => superficie.vinculos),
999
- ],
1000
- });
1001
-
1002
- return {
1003
- nome: modulo.nome,
1004
- uses: contexto?.modulosImportados.length
1005
- ? [...contexto.modulosImportados]
1006
- : modulo.uses.filter((use) => use.origem === "sema").map((use) => use.caminho),
1007
- imports: modulo.uses.map((use) => ({
1008
- origem: use.origem,
1009
- caminho: use.caminho,
1010
- externo: use.origem !== "sema",
1011
- })),
1012
- interoperabilidades: contexto?.interoperabilidades.map((interop) => ({ ...interop })) ?? modulo.uses
1013
- .filter(ehUseInterop)
1014
- .map((use) => ({ origem: use.origem, caminho: use.caminho })),
1015
- vinculos: converterVinculos(modulo.vinculos),
1016
- perfilCompatibilidade: perfilModulo,
1017
- types,
1018
- entities,
1019
- enums: modulo.enums.map((enumeracao) => ({ nome: enumeracao.nome, valores: enumeracao.valores })),
1020
- tasks,
1021
- flows,
1022
- routes,
1023
- superficies,
1024
- states,
1025
- databases,
1026
- resumoAgente: {
1027
- ...resumoAgenteModulo,
1028
- superficiesPublicas: deduplicarTexto([
1029
- ...routes.map((route) => `${route.metodo ?? "?"} ${route.caminho ?? route.nome}`),
1030
- ...superficies
1031
- .filter((superficie) => superficie.perfilCompatibilidade === "publico")
1032
- .map((superficie) => `${superficie.tipo}:${superficie.nome}`),
1033
- ]),
1034
- },
1035
- diagnosticos,
1036
- };
1037
- }