@semacode/cli 2.2.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +251 -141
  3. package/dist/agentContext.d.ts +1 -1
  4. package/dist/agentContextPack.js +6 -1
  5. package/dist/agentContextTipos.d.ts +4 -2
  6. package/dist/agentContextTipos.js +7 -0
  7. package/dist/agentEntryPoints.js +551 -499
  8. package/dist/angular-consumer-standalone.d.ts +3 -1
  9. package/dist/angular-consumer-standalone.js +12 -8
  10. package/dist/comandos.js +4 -0
  11. package/dist/discovery/catalog.d.ts +11 -0
  12. package/dist/discovery/catalog.js +521 -0
  13. package/dist/discovery/command.d.ts +11 -0
  14. package/dist/discovery/command.js +226 -0
  15. package/dist/discovery/index.d.ts +5 -0
  16. package/dist/discovery/index.js +8 -0
  17. package/dist/discovery/ranker.d.ts +3 -0
  18. package/dist/discovery/ranker.js +310 -0
  19. package/dist/discovery/redaction.d.ts +2 -0
  20. package/dist/discovery/redaction.js +21 -0
  21. package/dist/discovery/render.d.ts +2 -0
  22. package/dist/discovery/render.js +100 -0
  23. package/dist/discovery/types.d.ts +119 -0
  24. package/dist/discovery/types.js +13 -0
  25. package/dist/drift.part01.d.ts +32 -2
  26. package/dist/drift.part01.js +2 -0
  27. package/dist/drift.part04.d.ts +3 -2
  28. package/dist/drift.part04.js +6 -3
  29. package/dist/drift.part05.d.ts +2 -1
  30. package/dist/drift.part05.js +4 -3
  31. package/dist/drift.part06.d.ts +2 -1
  32. package/dist/drift.part06.js +9 -5
  33. package/dist/drift.part07.d.ts +11 -10
  34. package/dist/drift.part07.js +40 -30
  35. package/dist/drift.part08.d.ts +2 -1
  36. package/dist/drift.part08.js +4 -3
  37. package/dist/drift.part11.js +71 -6
  38. package/dist/drift.part12.js +14 -1
  39. package/dist/drift.part13.d.ts +42 -7
  40. package/dist/drift.part13.js +660 -36
  41. package/dist/driftCache.d.ts +49 -0
  42. package/dist/driftCache.js +311 -0
  43. package/dist/driftCacheIncremental.d.ts +98 -0
  44. package/dist/driftCacheIncremental.js +596 -0
  45. package/dist/driftCatalogo.d.ts +91 -0
  46. package/dist/driftCatalogo.js +657 -0
  47. package/dist/driftCatalogoPersistente.d.ts +8 -0
  48. package/dist/driftCatalogoPersistente.js +77 -0
  49. package/dist/driftEscopo.d.ts +23 -0
  50. package/dist/driftEscopo.js +563 -0
  51. package/dist/driftEscopoReferencias.d.ts +4 -0
  52. package/dist/driftEscopoReferencias.js +265 -0
  53. package/dist/driftOrcamento.d.ts +12 -0
  54. package/dist/driftOrcamento.js +19 -3
  55. package/dist/execucoesExternas.js +5 -19
  56. package/dist/exemplosOficiais.js +29 -8
  57. package/dist/iaPrompts.d.ts +1 -1
  58. package/dist/iaPrompts.js +310 -307
  59. package/dist/index.d.ts +2 -0
  60. package/dist/index.js +23 -5
  61. package/dist/index.part01.d.ts +17 -2
  62. package/dist/index.part01.js +119 -8
  63. package/dist/index.part02.js +21 -21
  64. package/dist/index.part03.d.ts +2 -2
  65. package/dist/index.part03.js +14 -3
  66. package/dist/index.part04.d.ts +2 -2
  67. package/dist/index.part04.js +113 -101
  68. package/dist/index.part05.d.ts +1 -1
  69. package/dist/index.part05.js +99 -22
  70. package/dist/index.part06.js +6 -2
  71. package/dist/index.part07.js +24 -24
  72. package/dist/index.part08.js +1 -1
  73. package/dist/init/templates.part01.js +393 -393
  74. package/dist/init/templates.part02.js +189 -189
  75. package/dist/initTemplatesBackend.js +73 -73
  76. package/dist/initTemplatesBase.js +81 -80
  77. package/dist/initTemplatesFlutter.js +137 -137
  78. package/dist/initTemplatesRuntime.js +350 -350
  79. package/dist/initTemplatesWeb.js +309 -309
  80. package/dist/pipelineConteudo/command.js +1 -36
  81. package/dist/profileArtefatoValidadores.d.ts +3 -2
  82. package/dist/profileArtefatoValidadores.js +81 -0
  83. package/dist/profileAuthorTipos.d.ts +4 -3
  84. package/dist/profileCatalogo.d.ts +5 -5
  85. package/dist/profileCatalogo.js +30 -0
  86. package/dist/profileCommand.d.ts +8 -2
  87. package/dist/profileCommand.js +15 -5
  88. package/dist/profileRegras.d.ts +5 -5
  89. package/dist/profileRegras.js +13 -1
  90. package/dist/profileRulePacks.js +68 -0
  91. package/dist/projeto.d.ts +1 -1
  92. package/dist/projetoCarregar.d.ts +2 -2
  93. package/dist/projetoCarregar.js +47 -24
  94. package/dist/projetoCatalogo.d.ts +7 -0
  95. package/dist/projetoCatalogo.js +125 -0
  96. package/dist/projetoTipos.d.ts +14 -5
  97. package/dist/sistemasInterativos/adapterProtocol.d.ts +3 -0
  98. package/dist/sistemasInterativos/adapterProtocol.js +240 -0
  99. package/dist/sistemasInterativos/advancedCatalog.d.ts +5 -0
  100. package/dist/sistemasInterativos/advancedCatalog.js +442 -0
  101. package/dist/sistemasInterativos/autonomy.d.ts +230 -0
  102. package/dist/sistemasInterativos/autonomy.js +753 -0
  103. package/dist/sistemasInterativos/canonical.d.ts +3 -0
  104. package/dist/sistemasInterativos/canonical.js +43 -0
  105. package/dist/sistemasInterativos/catalog.d.ts +116 -0
  106. package/dist/sistemasInterativos/catalog.js +543 -0
  107. package/dist/sistemasInterativos/command.d.ts +7 -0
  108. package/dist/sistemasInterativos/command.js +311 -0
  109. package/dist/sistemasInterativos/controlRun.d.ts +56 -0
  110. package/dist/sistemasInterativos/controlRun.js +391 -0
  111. package/dist/sistemasInterativos/evidence.d.ts +5 -0
  112. package/dist/sistemasInterativos/evidence.js +306 -0
  113. package/dist/sistemasInterativos/experienceIr.d.ts +12 -0
  114. package/dist/sistemasInterativos/experienceIr.js +895 -0
  115. package/dist/sistemasInterativos/experienceIrSemantics.d.ts +30 -0
  116. package/dist/sistemasInterativos/experienceIrSemantics.js +368 -0
  117. package/dist/sistemasInterativos/experienceIrTypes.d.ts +370 -0
  118. package/dist/sistemasInterativos/experienceIrTypes.js +5 -0
  119. package/dist/sistemasInterativos/extensionCommand.d.ts +391 -0
  120. package/dist/sistemasInterativos/extensionCommand.js +383 -0
  121. package/dist/sistemasInterativos/index.d.ts +19 -0
  122. package/dist/sistemasInterativos/index.js +22 -0
  123. package/dist/sistemasInterativos/operations.d.ts +40 -0
  124. package/dist/sistemasInterativos/operations.js +1167 -0
  125. package/dist/sistemasInterativos/operationsTypes.d.ts +297 -0
  126. package/dist/sistemasInterativos/operationsTypes.js +11 -0
  127. package/dist/sistemasInterativos/planner.d.ts +2 -0
  128. package/dist/sistemasInterativos/planner.js +159 -0
  129. package/dist/sistemasInterativos/portability.d.ts +164 -0
  130. package/dist/sistemasInterativos/portability.js +539 -0
  131. package/dist/sistemasInterativos/render.d.ts +3 -0
  132. package/dist/sistemasInterativos/render.js +179 -0
  133. package/dist/sistemasInterativos/temporal.d.ts +183 -0
  134. package/dist/sistemasInterativos/temporal.js +543 -0
  135. package/dist/sistemasInterativos/types.d.ts +215 -0
  136. package/dist/sistemasInterativos/types.js +4 -0
  137. package/dist/sistemasInterativos/validator.d.ts +2 -0
  138. package/dist/sistemasInterativos/validator.js +305 -0
  139. package/dist/sync/index.js +35 -35
  140. package/docs/README.md +34 -28
  141. package/docs/ai-onboarding.md +62 -62
  142. package/docs/ai-workflow.md +9 -4
  143. package/docs/auth.md +26 -26
  144. package/docs/cli.md +79 -79
  145. package/docs/commands.md +47 -2
  146. package/docs/database.md +15 -15
  147. package/docs/deploy.md +41 -41
  148. package/docs/descoberta-capacidades.md +106 -0
  149. package/docs/documentation.md +39 -39
  150. package/docs/env.md +16 -16
  151. package/docs/frontend.md +41 -41
  152. package/docs/getting-started.md +57 -57
  153. package/docs/i18n.md +15 -15
  154. package/docs/pipeline-conteudo.md +246 -246
  155. package/docs/profiles.md +54 -45
  156. package/docs/repositories.md +43 -43
  157. package/docs/rollback.md +31 -31
  158. package/docs/security.md +32 -32
  159. package/docs/sistemas-interativos.md +376 -0
  160. package/docs/support.md +8 -8
  161. package/docs/testing.md +51 -35
  162. package/docs/vocabulary.md +29 -29
  163. package/exemplos/agendamento.sema +1 -1
  164. package/exemplos/assinatura.sema +1 -1
  165. package/exemplos/auditoria.sema +1 -1
  166. package/exemplos/autenticacao.sema +1 -1
  167. package/exemplos/author_obra_comum.sema +1 -1
  168. package/exemplos/author_tema_sensivel.sema +1 -1
  169. package/exemplos/automacao.sema +1 -1
  170. package/exemplos/cadastro_usuario.sema +1 -1
  171. package/exemplos/calculadora.sema +1 -1
  172. package/exemplos/crud_simples.sema +1 -1
  173. package/exemplos/estoque.sema +1 -1
  174. package/exemplos/exportacao.sema +1 -1
  175. package/exemplos/fila.sema +1 -1
  176. package/exemplos/integracao_externa.sema +1 -1
  177. package/exemplos/multi_tenant.sema +1 -1
  178. package/exemplos/notificacao.sema +1 -1
  179. package/exemplos/operacao_estrategia.sema +132 -132
  180. package/exemplos/operacao_estrategia_discovery.sema +220 -220
  181. package/exemplos/operacao_estrategia_fluxo.sema +114 -114
  182. package/exemplos/operacao_estrategia_gates.sema +106 -106
  183. package/exemplos/operacao_estrategia_quarentena.sema +133 -133
  184. package/exemplos/operacao_estrategia_rollout.sema +124 -124
  185. package/exemplos/pagamento.sema +1 -1
  186. package/exemplos/pagamento_dominio.sema +1 -1
  187. package/exemplos/pedido.sema +1 -1
  188. package/exemplos/permissao.sema +1 -1
  189. package/exemplos/persistencia_vendor_first.sema +1 -1
  190. package/exemplos/pipeline-conteudo/README.md +44 -44
  191. package/exemplos/pipeline-conteudo/alvos.json +23 -23
  192. package/exemplos/pipeline-conteudo/definicao.json +136 -136
  193. package/exemplos/profile_conversas.sema +165 -165
  194. package/exemplos/profile_game.sema +1 -1
  195. package/exemplos/profile_legal.sema +1 -1
  196. package/exemplos/profile_ops.sema +1 -1
  197. package/exemplos/profile_research.sema +1 -1
  198. package/exemplos/profile_simulation.sema +211 -0
  199. package/exemplos/profile_software.sema +1 -1
  200. package/exemplos/profile_workflow_n8n.sema +1 -1
  201. package/exemplos/relatorio.sema +1 -1
  202. package/exemplos/replica_analitica_erp.sema +1 -1
  203. package/exemplos/sistemas-interativos/README.md +100 -0
  204. package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -0
  205. package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -0
  206. package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -0
  207. package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -0
  208. package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -0
  209. package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -0
  210. package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -0
  211. package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -0
  212. package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -0
  213. package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -0
  214. package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -0
  215. package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -0
  216. package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -0
  217. package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -0
  218. package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -0
  219. package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -0
  220. package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -0
  221. package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -0
  222. package/exemplos/sistemas-interativos/game-2d.json +83 -0
  223. package/exemplos/sistemas-interativos/game-3d-human.json +81 -0
  224. package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -0
  225. package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -0
  226. package/exemplos/sistemas-interativos/game-xr-human.json +80 -0
  227. package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -0
  228. package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -0
  229. package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -0
  230. package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -0
  231. package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -0
  232. package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -0
  233. package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -0
  234. package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -0
  235. package/exemplos/testes_embutidos.sema +1 -1
  236. package/exemplos/tratamento_erro.sema +1 -1
  237. package/exemplos/upload_arquivo.sema +1 -1
  238. package/exemplos/webhook.sema +1 -1
  239. package/node_modules/@sema/gerador-cpp/dist/index.js +176 -176
  240. package/node_modules/@sema/gerador-cpp/package.json +1 -1
  241. package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
  242. package/node_modules/@sema/gerador-css/dist/index.part02.js +460 -460
  243. package/node_modules/@sema/gerador-dotnet/dist/index.js +169 -169
  244. package/node_modules/@sema/gerador-dotnet/package.json +1 -1
  245. package/node_modules/@sema/gerador-html/dist/index.js +17 -17
  246. package/node_modules/@sema/gerador-lua/dist/index.js +76 -47
  247. package/node_modules/@sema/gerador-lua/dist/index.js.map +1 -1
  248. package/node_modules/@sema/gerador-php/dist/index.js +113 -113
  249. package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
  250. package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
  251. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
  252. package/package.json +3 -3
@@ -509,54 +509,54 @@ function gerarTask(task, contexto) {
509
509
  const erros = Object.entries(task.errors)
510
510
  .map(([codigo, mensagem]) => ` [${literalString(codigo)}] = ${literalString(mensagem)},`)
511
511
  .join("\n");
512
- return `// SEMA-TASK: ${escaparComentario(task.nome)}
513
- public sealed record class ${nomeEntrada}
514
- {
515
- ${gerarPropriedades(task.input, contexto)}
516
- }
517
-
518
- public sealed record class ${nomeSaida}
519
- {
520
- ${gerarPropriedades(task.output, contexto)}
521
- }
522
-
523
- public static class ${nome}Contract
524
- {
525
- public static IReadOnlyList<string> Rules { get; } = ${regras};
526
- public static IReadOnlyList<string> Guarantees { get; } = ${garantias};
527
- public static IReadOnlyList<string> Effects { get; } = ${efeitos};
528
- public static IReadOnlyDictionary<string, string> Errors { get; } = new Dictionary<string, string>
529
- {
530
- ${erros}
531
- };
532
-
533
- public static void Validate(${nomeEntrada} input)
534
- {
535
- ArgumentNullException.ThrowIfNull(input);
536
- ${gerarValidacoes(task, contexto)}
537
- }
538
-
539
- public static ${nomeSaida} Execute(${nomeEntrada} input, string? expectedErrorCode = null)
540
- {
541
- Validate(input);
542
- if (!string.IsNullOrWhiteSpace(expectedErrorCode))
543
- {
544
- var message = Errors.TryGetValue(expectedErrorCode, out var declaredMessage)
545
- ? declaredMessage
546
- : "Erro esperado pelo caso Sema.";
547
- throw new SemaContractException(expectedErrorCode, message);
548
- }
549
-
550
- var output = ${gerarInicializadorSaida(task, contexto)};
551
- VerifyGuarantees(output);
552
- return output;
553
- }
554
-
555
- public static void VerifyGuarantees(${nomeSaida} output)
556
- {
557
- ArgumentNullException.ThrowIfNull(output);
558
- ${gerarVerificacaoGarantias(task, contexto)}
559
- }
512
+ return `// SEMA-TASK: ${escaparComentario(task.nome)}
513
+ public sealed record class ${nomeEntrada}
514
+ {
515
+ ${gerarPropriedades(task.input, contexto)}
516
+ }
517
+
518
+ public sealed record class ${nomeSaida}
519
+ {
520
+ ${gerarPropriedades(task.output, contexto)}
521
+ }
522
+
523
+ public static class ${nome}Contract
524
+ {
525
+ public static IReadOnlyList<string> Rules { get; } = ${regras};
526
+ public static IReadOnlyList<string> Guarantees { get; } = ${garantias};
527
+ public static IReadOnlyList<string> Effects { get; } = ${efeitos};
528
+ public static IReadOnlyDictionary<string, string> Errors { get; } = new Dictionary<string, string>
529
+ {
530
+ ${erros}
531
+ };
532
+
533
+ public static void Validate(${nomeEntrada} input)
534
+ {
535
+ ArgumentNullException.ThrowIfNull(input);
536
+ ${gerarValidacoes(task, contexto)}
537
+ }
538
+
539
+ public static ${nomeSaida} Execute(${nomeEntrada} input, string? expectedErrorCode = null)
540
+ {
541
+ Validate(input);
542
+ if (!string.IsNullOrWhiteSpace(expectedErrorCode))
543
+ {
544
+ var message = Errors.TryGetValue(expectedErrorCode, out var declaredMessage)
545
+ ? declaredMessage
546
+ : "Erro esperado pelo caso Sema.";
547
+ throw new SemaContractException(expectedErrorCode, message);
548
+ }
549
+
550
+ var output = ${gerarInicializadorSaida(task, contexto)};
551
+ VerifyGuarantees(output);
552
+ return output;
553
+ }
554
+
555
+ public static void VerifyGuarantees(${nomeSaida} output)
556
+ {
557
+ ArgumentNullException.ThrowIfNull(output);
558
+ ${gerarVerificacaoGarantias(task, contexto)}
559
+ }
560
560
  }`;
561
561
  }
562
562
  function removerAspas(valor) {
@@ -636,27 +636,27 @@ function gerarMetodoTeste(task, caso, indice, contexto) {
636
636
  .join(", ");
637
637
  const assercoesEsperadas = gerarAssercoesEsperadas(task, caso, contexto);
638
638
  const corpo = erro
639
- ? ` try
640
- {
641
- ${nomeTask}.Execute(input, ${literalString(erro)});
642
- throw new InvalidOperationException(${literalString(`O caso ${caso.nome} deveria falhar.`)});
643
- }
644
- catch (SemaContractException exception) when (exception.Code == ${literalString(erro)})
645
- {
646
- // Erro declarado e observado conforme o contrato.
639
+ ? ` try
640
+ {
641
+ ${nomeTask}.Execute(input, ${literalString(erro)});
642
+ throw new InvalidOperationException(${literalString(`O caso ${caso.nome} deveria falhar.`)});
643
+ }
644
+ catch (SemaContractException exception) when (exception.Code == ${literalString(erro)})
645
+ {
646
+ // Erro declarado e observado conforme o contrato.
647
647
  }`
648
- : ` var output = ${nomeTask}.Execute(input);
649
- SemaAssert.NotNull(output, ${literalString(`O caso ${caso.nome} não retornou saída.`)});
650
- ${nomeTask}.VerifyGuarantees(output);
648
+ : ` var output = ${nomeTask}.Execute(input);
649
+ SemaAssert.NotNull(output, ${literalString(`O caso ${caso.nome} não retornou saída.`)});
650
+ ${nomeTask}.VerifyGuarantees(output);
651
651
  ${assercoesEsperadas || " // O caso não declarou campos de saída verificáveis."}`;
652
652
  return {
653
653
  nome,
654
- codigo: ` // SEMA-TEST: ${escaparComentario(task.nome)} :: ${escaparComentario(caso.nome)}
655
- private static void ${nome}()
656
- {
657
- // SEMA-EXPECT: ${escaparComentario(detalhesEsperados || "sucesso")}
658
- var input = ${entrada};
659
- ${corpo}
654
+ codigo: ` // SEMA-TEST: ${escaparComentario(task.nome)} :: ${escaparComentario(caso.nome)}
655
+ private static void ${nome}()
656
+ {
657
+ // SEMA-EXPECT: ${escaparComentario(detalhesEsperados || "sucesso")}
658
+ var input = ${entrada};
659
+ ${corpo}
660
660
  }`,
661
661
  };
662
662
  }
@@ -671,30 +671,30 @@ function gerarCodigoFonte(modulo, contexto) {
671
671
  const flows = modulo.flows.map((item) => `// SEMA-FLOW: ${escaparComentario(item.nome)} tasks=${escaparComentario(item.tasksReferenciadas.join(", ") || "nenhuma")}`).join("\n");
672
672
  const routes = modulo.routes.map((item) => `// SEMA-ROUTE: ${escaparComentario(item.nome)} metodo=${escaparComentario(item.metodo ?? "nao_definido")} caminho=${escaparComentario(item.caminho ?? "nao_definido")} task=${escaparComentario(item.task ?? "nao_definida")}`).join("\n");
673
673
  const states = modulo.states.map((item) => `// SEMA-STATE: ${escaparComentario(item.nome ?? "anonimo")} campos=${item.campos.length} invariantes=${item.invariantes.length} transicoes=${item.transicoes.length}`).join("\n");
674
- return `${gerarCabecalhoCSharp(modulo, "código C# gerado a partir do IR Sema, incluindo modelos, regras, garantias e metadados operacionais.")}using System;
675
- using System.Collections.Generic;
676
- using System.Globalization;
677
- using System.Linq;
678
-
679
- namespace ${namespace};
680
-
681
- public class SemaContractException : Exception
682
- {
683
- public SemaContractException(string code, string message) : base(message) => Code = code;
684
- public string Code { get; }
685
- }
686
-
687
- public sealed class SemaValidationException : SemaContractException
688
- {
689
- public SemaValidationException(string rule) : base("regra_invalida", $"Regra Sema violada: {rule}") { }
690
- }
691
-
692
- public sealed class SemaGuaranteeException : SemaContractException
693
- {
694
- public SemaGuaranteeException(string guarantee) : base("garantia_violada", $"Garantia Sema violada: {guarantee}") { }
695
- }
696
-
697
- ${interops ? `${interops}\n\n` : ""}${externos ? `${externos}\n\n` : ""}${enums ? `${enums}\n\n` : ""}${tipos ? `${tipos}\n\n` : ""}${entidades ? `${entidades}\n\n` : ""}${tasks}${states ? `\n\n${states}` : ""}${flows ? `\n${flows}` : ""}${routes ? `\n${routes}` : ""}
674
+ return `${gerarCabecalhoCSharp(modulo, "código C# gerado a partir do IR Sema, incluindo modelos, regras, garantias e metadados operacionais.")}using System;
675
+ using System.Collections.Generic;
676
+ using System.Globalization;
677
+ using System.Linq;
678
+
679
+ namespace ${namespace};
680
+
681
+ public class SemaContractException : Exception
682
+ {
683
+ public SemaContractException(string code, string message) : base(message) => Code = code;
684
+ public string Code { get; }
685
+ }
686
+
687
+ public sealed class SemaValidationException : SemaContractException
688
+ {
689
+ public SemaValidationException(string rule) : base("regra_invalida", $"Regra Sema violada: {rule}") { }
690
+ }
691
+
692
+ public sealed class SemaGuaranteeException : SemaContractException
693
+ {
694
+ public SemaGuaranteeException(string guarantee) : base("garantia_violada", $"Garantia Sema violada: {guarantee}") { }
695
+ }
696
+
697
+ ${interops ? `${interops}\n\n` : ""}${externos ? `${externos}\n\n` : ""}${enums ? `${enums}\n\n` : ""}${tipos ? `${tipos}\n\n` : ""}${entidades ? `${entidades}\n\n` : ""}${tasks}${states ? `\n\n${states}` : ""}${flows ? `\n${flows}` : ""}${routes ? `\n${routes}` : ""}
698
698
  `;
699
699
  }
700
700
  function gerarCodigoTestes(modulo, contexto) {
@@ -703,96 +703,96 @@ function gerarCodigoTestes(modulo, contexto) {
703
703
  if (metodos.length === 0) {
704
704
  metodos.push({
705
705
  nome: "TestEstruturaGerada",
706
- codigo: ` // SEMA-TEST: estrutura gerada :: módulo sem casos declarados
707
- private static void TestEstruturaGerada()
708
- {
709
- SemaAssert.True(true, "A estrutura .NET gerada deve ser executavel.");
706
+ codigo: ` // SEMA-TEST: estrutura gerada :: módulo sem casos declarados
707
+ private static void TestEstruturaGerada()
708
+ {
709
+ SemaAssert.True(true, "A estrutura .NET gerada deve ser executavel.");
710
710
  }`,
711
711
  });
712
712
  }
713
713
  const registros = metodos.map((metodo) => ` (${literalString(metodo.nome)}, ${metodo.nome}),`).join("\n");
714
- return `${gerarCabecalhoCSharp(modulo, "runner de testes .NET gerado sem framework ou pacote NuGet externo.")}using System;
715
- using System.Collections.Generic;
716
- using System.Globalization;
717
- using ${namespace};
718
-
719
- internal static class SemaAssert
720
- {
721
- public static void True(bool condition, string message)
722
- {
723
- if (!condition) throw new InvalidOperationException(message);
724
- }
725
-
726
- public static void NotNull(object? value, string message) => True(value is not null, message);
727
-
728
- public static void Equal<T>(T expected, T actual, string message)
729
- {
730
- if (!EqualityComparer<T>.Default.Equals(expected, actual))
731
- {
732
- throw new InvalidOperationException($"{message} Esperado={expected}; Atual={actual}.");
733
- }
734
- }
735
- }
736
-
737
- internal static class Program
738
- {
739
- private static int Main()
740
- {
741
- var tests = new (string Name, Action Run)[]
742
- {
743
- ${registros}
744
- };
745
-
746
- foreach (var test in tests)
747
- {
748
- Console.WriteLine($"test {test.Name}");
749
- test.Run();
750
- }
751
-
752
- Console.WriteLine($"ok {tests.Length} testes");
753
- return 0;
754
- }
755
-
756
- ${metodos.map((metodo) => metodo.codigo).join("\n\n")}
757
- }
714
+ return `${gerarCabecalhoCSharp(modulo, "runner de testes .NET gerado sem framework ou pacote NuGet externo.")}using System;
715
+ using System.Collections.Generic;
716
+ using System.Globalization;
717
+ using ${namespace};
718
+
719
+ internal static class SemaAssert
720
+ {
721
+ public static void True(bool condition, string message)
722
+ {
723
+ if (!condition) throw new InvalidOperationException(message);
724
+ }
725
+
726
+ public static void NotNull(object? value, string message) => True(value is not null, message);
727
+
728
+ public static void Equal<T>(T expected, T actual, string message)
729
+ {
730
+ if (!EqualityComparer<T>.Default.Equals(expected, actual))
731
+ {
732
+ throw new InvalidOperationException($"{message} Esperado={expected}; Atual={actual}.");
733
+ }
734
+ }
735
+ }
736
+
737
+ internal static class Program
738
+ {
739
+ private static int Main()
740
+ {
741
+ var tests = new (string Name, Action Run)[]
742
+ {
743
+ ${registros}
744
+ };
745
+
746
+ foreach (var test in tests)
747
+ {
748
+ Console.WriteLine($"test {test.Name}");
749
+ test.Run();
750
+ }
751
+
752
+ Console.WriteLine($"ok {tests.Length} testes");
753
+ return 0;
754
+ }
755
+
756
+ ${metodos.map((metodo) => metodo.codigo).join("\n\n")}
757
+ }
758
758
  `;
759
759
  }
760
760
  function gerarProjetoFonte(modulo, base, assemblyName) {
761
- return `${gerarCabecalhoProjeto(modulo, "biblioteca .NET gerada sem dependências NuGet externas.")}
762
- <Project Sdk="Microsoft.NET.Sdk">
763
- <PropertyGroup>
764
- <TargetFramework>net8.0</TargetFramework>
765
- <ImplicitUsings>enable</ImplicitUsings>
766
- <Nullable>enable</Nullable>
767
- <LangVersion>latest</LangVersion>
768
- <AssemblyName>${assemblyName}</AssemblyName>
769
- <RootNamespace>${assemblyName}</RootNamespace>
770
- <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
771
- </PropertyGroup>
772
- <ItemGroup>
773
- <Compile Include="${base}.cs" />
774
- </ItemGroup>
775
- </Project>
761
+ return `${gerarCabecalhoProjeto(modulo, "biblioteca .NET gerada sem dependências NuGet externas.")}
762
+ <Project Sdk="Microsoft.NET.Sdk">
763
+ <PropertyGroup>
764
+ <TargetFramework>net8.0</TargetFramework>
765
+ <ImplicitUsings>enable</ImplicitUsings>
766
+ <Nullable>enable</Nullable>
767
+ <LangVersion>latest</LangVersion>
768
+ <AssemblyName>${assemblyName}</AssemblyName>
769
+ <RootNamespace>${assemblyName}</RootNamespace>
770
+ <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
771
+ </PropertyGroup>
772
+ <ItemGroup>
773
+ <Compile Include="${base}.cs" />
774
+ </ItemGroup>
775
+ </Project>
776
776
  `;
777
777
  }
778
778
  function gerarProjetoTestes(modulo, base, assemblyName) {
779
- return `${gerarCabecalhoProjeto(modulo, "executavel de testes .NET autocontido, sem xUnit, MSTest, NUnit ou outro pacote NuGet.")}
780
- <Project Sdk="Microsoft.NET.Sdk">
781
- <PropertyGroup>
782
- <OutputType>Exe</OutputType>
783
- <TargetFramework>net8.0</TargetFramework>
784
- <ImplicitUsings>enable</ImplicitUsings>
785
- <Nullable>enable</Nullable>
786
- <LangVersion>latest</LangVersion>
787
- <AssemblyName>${assemblyName}.Tests</AssemblyName>
788
- <RootNamespace>${assemblyName}.Tests</RootNamespace>
789
- <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
790
- </PropertyGroup>
791
- <ItemGroup>
792
- <Compile Include="${base}.Tests.cs" />
793
- <ProjectReference Include="${base}.csproj" />
794
- </ItemGroup>
795
- </Project>
779
+ return `${gerarCabecalhoProjeto(modulo, "executavel de testes .NET autocontido, sem xUnit, MSTest, NUnit ou outro pacote NuGet.")}
780
+ <Project Sdk="Microsoft.NET.Sdk">
781
+ <PropertyGroup>
782
+ <OutputType>Exe</OutputType>
783
+ <TargetFramework>net8.0</TargetFramework>
784
+ <ImplicitUsings>enable</ImplicitUsings>
785
+ <Nullable>enable</Nullable>
786
+ <LangVersion>latest</LangVersion>
787
+ <AssemblyName>${assemblyName}.Tests</AssemblyName>
788
+ <RootNamespace>${assemblyName}.Tests</RootNamespace>
789
+ <EnableDefaultCompileItems>false</EnableDefaultCompileItems>
790
+ </PropertyGroup>
791
+ <ItemGroup>
792
+ <Compile Include="${base}.Tests.cs" />
793
+ <ProjectReference Include="${base}.csproj" />
794
+ </ItemGroup>
795
+ </Project>
796
796
  `;
797
797
  }
798
798
  export function gerarDotNet(modulo) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema/gerador-dotnet",
3
- "version": "2.1.0",
3
+ "version": "2.3.1",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts"
@@ -112,7 +112,7 @@ ${etapas || ' <li>Nenhuma etapa estruturada.</li>'}
112
112
  </section>`;
113
113
  }
114
114
  function gerarRoute(route) {
115
- return ` <section class="sema-route" data-route="${route.nome}">
115
+ return ` <section class="sema-route" data-route="${route.nome}">
116
116
  <h3>Route: ${route.nome}</h3>
117
117
  <div class="sema-route-detalhe">
118
118
  <span class="sema-route-metodo">${route.metodo ?? "POST"}</span>
@@ -124,13 +124,13 @@ function gerarRoute(route) {
124
124
  </section>`;
125
125
  }
126
126
  function gerarCabecalhoSemaHtml(modulo) {
127
- return `<!--
128
- SEMA-GOVERNED
129
- Módulo de origem: ${escaparHtml(modulo.nome)}
130
- Consulte o contrato .sema aplicável antes de editar este arquivo.
131
- Rastreabilidade: outros contratos .sema podem governar este mesmo arquivo via vinculos.
132
- Para IA fraca/média/forte: chame Sema, rode docs-impacto e drift antes de alterar código.
133
- Descrição: página HTML gerada para humanos e IAs entenderem rapidamente a intenção do contrato.
127
+ return `<!--
128
+ SEMA-GOVERNED
129
+ Módulo de origem: ${escaparHtml(modulo.nome)}
130
+ Consulte o contrato .sema aplicável antes de editar este arquivo.
131
+ Rastreabilidade: outros contratos .sema podem governar este mesmo arquivo via vinculos.
132
+ Para IA fraca/média/forte: chame Sema, rode docs-impacto e drift antes de alterar código.
133
+ Descrição: página HTML gerada para humanos e IAs entenderem rapidamente a intenção do contrato.
134
134
  -->`;
135
135
  }
136
136
  export function gerarHtml(modulo) {
@@ -142,15 +142,15 @@ export function gerarHtml(modulo) {
142
142
  const tasks = modulo.tasks.map(gerarFormularioTask).join("\n\n");
143
143
  const flows = modulo.flows.map(gerarFlow).join("\n\n");
144
144
  const routes = modulo.routes.map(gerarRoute).join("\n\n");
145
- const html = `<!DOCTYPE html>
146
- ${gerarCabecalhoSemaHtml(modulo)}
147
- <html lang="pt-BR">
148
- <head>
149
- <meta charset="UTF-8">
150
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
151
- <meta name="description" content="Contrato Sema: ${escaparHtml(modulo.nome)}">
152
- <meta name="sema-governed" content="true">
153
- <meta name="sema-module" content="${escaparHtml(modulo.nome)}">
145
+ const html = `<!DOCTYPE html>
146
+ ${gerarCabecalhoSemaHtml(modulo)}
147
+ <html lang="pt-BR">
148
+ <head>
149
+ <meta charset="UTF-8">
150
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
151
+ <meta name="description" content="Contrato Sema: ${escaparHtml(modulo.nome)}">
152
+ <meta name="sema-governed" content="true">
153
+ <meta name="sema-module" content="${escaparHtml(modulo.nome)}">
154
154
  <title>${escaparHtml(titulo)} — Sema</title>
155
155
  <link rel="stylesheet" href="${nomeBase}.css">
156
156
  </head>
@@ -292,28 +292,32 @@ function gerarTestesLua(modulo, arquivoModulo) {
292
292
  const tiposDeclarados = gerarTabelaTiposDeclarados(task);
293
293
  const tipoErro = caso.error?.campos.find((campo) => campo.nome === "tipo")?.tipo ?? caso.error?.campos[0]?.tipo;
294
294
  if (tipoErro) {
295
- return `local function ${nomeTeste}()
296
- local entrada = ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}
297
- local ok, erro = pcall(function()
298
- modulo.executar_${normalizarNomeParaSimbolo(task.nome)}(entrada)
299
- end)
300
- if ok or not string.find(tostring(erro), ${JSON.stringify(tipoErro)}, 1, true) then
301
- error("Caso ${caso.nome} nao produziu o erro esperado ${tipoErro}.")
302
- end
295
+ return `local function ${nomeTeste}()
296
+ local entrada = ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}
297
+ local ok, erro = pcall(function()
298
+ modulo.executar_${normalizarNomeParaSimbolo(task.nome)}(entrada)
299
+ end)
300
+ if ok or not string.find(tostring(erro), ${JSON.stringify(tipoErro)}, 1, true) then
301
+ error("Caso ${caso.nome} nao produziu o erro esperado ${tipoErro}.")
302
+ end
303
303
  end`;
304
304
  }
305
- return `local function ${nomeTeste}()
306
- local entrada = ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}
307
- local saida = modulo.executar_${normalizarNomeParaSimbolo(task.nome)}(entrada)
308
- if ${caso.expect.campos.some((campo) => campo.nome === "sucesso" && campo.tipo === "falso") ? "saida ~= nil" : "saida == nil"} then
309
- error("Caso ${caso.nome} nao respeitou expectativa basica de execucao.")
310
- end
305
+ const falhaSemSaida = caso.expect.campos.some((campo) => campo.nome === "sucesso" && campo.tipo === "falso")
306
+ && caso.expect.campos.every((campo) => campo.nome === "sucesso")
307
+ && caso.expect.linhas.length === 0
308
+ && caso.expect.blocos.length === 0;
309
+ return `local function ${nomeTeste}()
310
+ local entrada = ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}
311
+ local saida = modulo.executar_${normalizarNomeParaSimbolo(task.nome)}(entrada)
312
+ if ${falhaSemSaida ? "saida ~= nil" : "saida == nil"} then
313
+ error("Caso ${caso.nome} nao respeitou expectativa basica de execucao.")
314
+ end
311
315
  end`;
312
316
  });
313
317
  const lista = testes.map(({ task, caso, indice }) => `{ nome = ${JSON.stringify(caso.nome)}, fn = test_${normalizarNomeParaSimbolo(task.nome)}_${indice + 1} }`).join(",\n ");
314
- return `${gerarCabecalhoSemaLua(modulo, "teste")}local origem = debug.getinfo(1, "S").source:sub(2)
315
- local base = origem:match("^(.*[/\\\\])") or "./"
316
- local modulo = assert(loadfile(base .. ${JSON.stringify(nomeArquivo)}))()
318
+ return `${gerarCabecalhoSemaLua(modulo, "teste")}local origem = debug.getinfo(1, "S").source:sub(2)
319
+ local base = origem:match("^(.*[/\\\\])") or "./"
320
+ local modulo = assert(loadfile(base .. ${JSON.stringify(nomeArquivo)}))()
317
321
 
318
322
  ${funcoes.join("\n\n")}
319
323
 
@@ -346,6 +350,7 @@ function gerarFuncoesTask(task) {
346
350
  const garantias = gerarGarantias(task);
347
351
  const preparacaoSaida = gerarPreparacaoSaida(task);
348
352
  const tiposDeclarados = gerarTabelaTiposDeclarados(task);
353
+ const camposSaida = new Map(task.output.map((campo) => [campo.nome, campo]));
349
354
  const cenariosErro = task.tests
350
355
  .map((caso) => ({
351
356
  caso,
@@ -354,13 +359,37 @@ function gerarFuncoesTask(task) {
354
359
  .filter((item) => Boolean(item.tipoErro))
355
360
  .map(({ caso, tipoErro }) => ` if igual_profundo(entrada, ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}) then error(${JSON.stringify(tipoErro)}) end`)
356
361
  .join("\n");
357
- return `${gerarMetadadosTask(task)}
362
+ const cenariosFalhaEstruturada = task.tests
363
+ .filter((caso) => caso.expect.campos.some((campo) => campo.nome === "sucesso" && campo.tipo === "falso"))
364
+ .map((caso) => ({
365
+ caso,
366
+ expectativas: new Map(caso.expect.campos
367
+ .filter((campo) => camposSaida.has(campo.nome))
368
+ .map((campo) => [campo.nome, campo])),
369
+ }))
370
+ .filter(({ expectativas }) => expectativas.size > 0)
371
+ .map(({ caso, expectativas }) => {
372
+ const saida = task.output.map((campo) => {
373
+ const esperado = expectativas.get(campo.nome);
374
+ const valor = esperado
375
+ ? formatarLiteralTesteLua(esperado.tipo, campo.tipo)
376
+ : valorPadraoLua(campo);
377
+ return ` ${campo.nome} = ${valor},`;
378
+ }).join("\n");
379
+ return ` if igual_profundo(entrada, ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}) then
380
+ return {
381
+ ${saida}
382
+ }
383
+ end`;
384
+ })
385
+ .join("\n");
386
+ return `${gerarMetadadosTask(task)}
358
387
 
359
388
  ${garantias}
360
389
 
361
- function M.executar_${simbolo}(entrada)
362
- entrada = entrada or {}
363
- ${cenariosErro ? `${cenariosErro}\n` : ""}${validacoes ? `${validacoes}\n` : ""}${preparacaoSaida}
390
+ function M.executar_${simbolo}(entrada)
391
+ entrada = entrada or {}
392
+ ${cenariosErro ? `${cenariosErro}\n` : ""}${cenariosFalhaEstruturada ? `${cenariosFalhaEstruturada}\n` : ""}${validacoes ? `${validacoes}\n` : ""}${preparacaoSaida}
364
393
  verificar_garantias_${simbolo}(saida)
365
394
  return saida
366
395
  end`;
@@ -376,39 +405,39 @@ export function gerarLua(modulo) {
376
405
  const tasks = modulo.tasks.map((task) => gerarFuncoesTask(task)).join("\n\n");
377
406
  const flows = modulo.flows.map((flow) => `-- Flow ${flow.nome}: etapas=${flow.etapasEstruturadas.length} tasks=${flow.tasksReferenciadas.join(", ") || "nenhuma"}`).join("\n");
378
407
  const routes = modulo.routes.map((route) => `-- Route ${route.nome}: metodo=${route.metodo ?? "nao_definido"} caminho=${route.caminho ?? "nao_definido"} task=${route.task ?? "nao_definida"}`).join("\n");
379
- const codigo = `${gerarCabecalhoSemaLua(modulo)}
380
- ${interops ? `${interops}\n` : ""}${tiposExternos ? `${tiposExternos}\n\n` : ""}local M = {}
408
+ const codigo = `${gerarCabecalhoSemaLua(modulo)}
409
+ ${interops ? `${interops}\n` : ""}${tiposExternos ? `${tiposExternos}\n\n` : ""}local M = {}
381
410
 
382
- local function contem(lista, valor)
411
+ local function contem(lista, valor)
383
412
  for _, item in ipairs(lista) do
384
413
  if item == valor then
385
414
  return true
386
415
  end
387
416
  end
388
417
  return false
389
- end
390
-
391
- local function igual_profundo(esquerda, direita)
392
- if esquerda == direita then
393
- return true
394
- end
395
- if type(esquerda) ~= "table" or type(direita) ~= "table" then
396
- return false
397
- end
398
- for chave, valor in pairs(esquerda) do
399
- if not igual_profundo(valor, direita[chave]) then
400
- return false
401
- end
402
- end
403
- for chave, _ in pairs(direita) do
404
- if esquerda[chave] == nil then
405
- return false
406
- end
407
- end
408
- return true
409
- end
410
-
411
- ${tipos ? `${tipos}\n\n` : ""}${entidades ? `${entidades}\n\n` : ""}${enums ? `${enums}\n\n` : ""}${tasks}${flows ? `\n\n${flows}` : ""}${routes ? `\n${routes}` : ""}
418
+ end
419
+
420
+ local function igual_profundo(esquerda, direita)
421
+ if esquerda == direita then
422
+ return true
423
+ end
424
+ if type(esquerda) ~= "table" or type(direita) ~= "table" then
425
+ return false
426
+ end
427
+ for chave, valor in pairs(esquerda) do
428
+ if not igual_profundo(valor, direita[chave]) then
429
+ return false
430
+ end
431
+ end
432
+ for chave, _ in pairs(direita) do
433
+ if esquerda[chave] == nil then
434
+ return false
435
+ end
436
+ end
437
+ return true
438
+ end
439
+
440
+ ${tipos ? `${tipos}\n\n` : ""}${entidades ? `${entidades}\n\n` : ""}${enums ? `${enums}\n\n` : ""}${tasks}${flows ? `\n\n${flows}` : ""}${routes ? `\n${routes}` : ""}
412
441
 
413
442
  return M
414
443
  `;