@semacode/cli 2.3.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 (177) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +251 -228
  3. package/dist/agentEntryPoints.js +551 -550
  4. package/dist/angular-consumer-standalone.d.ts +3 -1
  5. package/dist/angular-consumer-standalone.js +12 -8
  6. package/dist/drift.part01.d.ts +32 -2
  7. package/dist/drift.part01.js +2 -0
  8. package/dist/drift.part04.d.ts +3 -2
  9. package/dist/drift.part04.js +6 -3
  10. package/dist/drift.part05.d.ts +2 -1
  11. package/dist/drift.part05.js +4 -3
  12. package/dist/drift.part06.d.ts +2 -1
  13. package/dist/drift.part06.js +9 -5
  14. package/dist/drift.part07.d.ts +11 -10
  15. package/dist/drift.part07.js +40 -30
  16. package/dist/drift.part08.d.ts +2 -1
  17. package/dist/drift.part08.js +4 -3
  18. package/dist/drift.part11.js +71 -6
  19. package/dist/drift.part12.js +14 -1
  20. package/dist/drift.part13.d.ts +42 -7
  21. package/dist/drift.part13.js +660 -36
  22. package/dist/driftCache.d.ts +49 -0
  23. package/dist/driftCache.js +311 -0
  24. package/dist/driftCacheIncremental.d.ts +98 -0
  25. package/dist/driftCacheIncremental.js +596 -0
  26. package/dist/driftCatalogo.d.ts +91 -0
  27. package/dist/driftCatalogo.js +657 -0
  28. package/dist/driftCatalogoPersistente.d.ts +8 -0
  29. package/dist/driftCatalogoPersistente.js +77 -0
  30. package/dist/driftEscopo.d.ts +23 -0
  31. package/dist/driftEscopo.js +563 -0
  32. package/dist/driftEscopoReferencias.d.ts +4 -0
  33. package/dist/driftEscopoReferencias.js +265 -0
  34. package/dist/driftOrcamento.d.ts +12 -0
  35. package/dist/driftOrcamento.js +19 -3
  36. package/dist/execucoesExternas.js +5 -19
  37. package/dist/iaPrompts.js +310 -310
  38. package/dist/index.part01.d.ts +16 -1
  39. package/dist/index.part01.js +80 -4
  40. package/dist/index.part02.js +21 -21
  41. package/dist/index.part03.d.ts +2 -2
  42. package/dist/index.part03.js +14 -3
  43. package/dist/index.part04.d.ts +2 -2
  44. package/dist/index.part04.js +113 -101
  45. package/dist/index.part05.d.ts +1 -1
  46. package/dist/index.part05.js +99 -22
  47. package/dist/index.part06.js +3 -2
  48. package/dist/index.part07.js +24 -24
  49. package/dist/index.part08.js +1 -1
  50. package/dist/init/templates.part01.js +393 -393
  51. package/dist/init/templates.part02.js +189 -189
  52. package/dist/initTemplatesBackend.js +73 -73
  53. package/dist/initTemplatesBase.js +81 -81
  54. package/dist/initTemplatesFlutter.js +137 -137
  55. package/dist/initTemplatesRuntime.js +350 -350
  56. package/dist/initTemplatesWeb.js +309 -309
  57. package/dist/pipelineConteudo/command.js +1 -36
  58. package/dist/projeto.d.ts +1 -1
  59. package/dist/projetoCarregar.d.ts +2 -2
  60. package/dist/projetoCarregar.js +47 -24
  61. package/dist/projetoCatalogo.d.ts +7 -0
  62. package/dist/projetoCatalogo.js +125 -0
  63. package/dist/projetoTipos.d.ts +14 -5
  64. package/dist/sync/index.js +35 -35
  65. package/docs/README.md +34 -34
  66. package/docs/ai-integration.md +1 -7
  67. package/docs/ai-onboarding.md +62 -62
  68. package/docs/ai-workflow.md +4 -0
  69. package/docs/auth.md +26 -26
  70. package/docs/cli.md +79 -79
  71. package/docs/commands.md +16 -13
  72. package/docs/database.md +15 -15
  73. package/docs/deploy.md +41 -41
  74. package/docs/descoberta-capacidades.md +106 -106
  75. package/docs/documentation.md +37 -46
  76. package/docs/env.md +16 -16
  77. package/docs/frontend.md +41 -41
  78. package/docs/getting-started.md +57 -57
  79. package/docs/i18n.md +15 -15
  80. package/docs/pipeline-conteudo.md +246 -246
  81. package/docs/profiles.md +54 -54
  82. package/docs/repositories.md +43 -43
  83. package/docs/rollback.md +31 -31
  84. package/docs/security.md +32 -32
  85. package/docs/sistemas-interativos.md +373 -378
  86. package/docs/support.md +8 -8
  87. package/docs/testing.md +51 -44
  88. package/docs/vocabulary.md +29 -29
  89. package/exemplos/agendamento.sema +1 -1
  90. package/exemplos/assinatura.sema +1 -1
  91. package/exemplos/auditoria.sema +1 -1
  92. package/exemplos/autenticacao.sema +1 -1
  93. package/exemplos/author_obra_comum.sema +1 -1
  94. package/exemplos/author_tema_sensivel.sema +1 -1
  95. package/exemplos/automacao.sema +1 -1
  96. package/exemplos/cadastro_usuario.sema +1 -1
  97. package/exemplos/calculadora.sema +1 -1
  98. package/exemplos/crud_simples.sema +1 -1
  99. package/exemplos/estoque.sema +1 -1
  100. package/exemplos/exportacao.sema +1 -1
  101. package/exemplos/fila.sema +1 -1
  102. package/exemplos/integracao_externa.sema +1 -1
  103. package/exemplos/multi_tenant.sema +1 -1
  104. package/exemplos/notificacao.sema +1 -1
  105. package/exemplos/operacao_estrategia.sema +132 -132
  106. package/exemplos/operacao_estrategia_discovery.sema +220 -220
  107. package/exemplos/operacao_estrategia_fluxo.sema +114 -114
  108. package/exemplos/operacao_estrategia_gates.sema +106 -106
  109. package/exemplos/operacao_estrategia_quarentena.sema +133 -133
  110. package/exemplos/operacao_estrategia_rollout.sema +124 -124
  111. package/exemplos/pagamento.sema +1 -1
  112. package/exemplos/pagamento_dominio.sema +1 -1
  113. package/exemplos/pedido.sema +1 -1
  114. package/exemplos/permissao.sema +1 -1
  115. package/exemplos/persistencia_vendor_first.sema +1 -1
  116. package/exemplos/pipeline-conteudo/README.md +44 -44
  117. package/exemplos/pipeline-conteudo/alvos.json +23 -23
  118. package/exemplos/pipeline-conteudo/definicao.json +136 -136
  119. package/exemplos/profile_conversas.sema +165 -165
  120. package/exemplos/profile_game.sema +1 -1
  121. package/exemplos/profile_legal.sema +1 -1
  122. package/exemplos/profile_ops.sema +1 -1
  123. package/exemplos/profile_research.sema +1 -1
  124. package/exemplos/profile_simulation.sema +211 -211
  125. package/exemplos/profile_software.sema +1 -1
  126. package/exemplos/profile_workflow_n8n.sema +1 -1
  127. package/exemplos/relatorio.sema +1 -1
  128. package/exemplos/replica_analitica_erp.sema +1 -1
  129. package/exemplos/sistemas-interativos/README.md +100 -100
  130. package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -5
  131. package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -16
  132. package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -32
  133. package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -93
  134. package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -78
  135. package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -27
  136. package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -79
  137. package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -42
  138. package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -32
  139. package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -23
  140. package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -39
  141. package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -46
  142. package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -39
  143. package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -37
  144. package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -104
  145. package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -27
  146. package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -118
  147. package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -459
  148. package/exemplos/sistemas-interativos/game-2d.json +83 -83
  149. package/exemplos/sistemas-interativos/game-3d-human.json +81 -81
  150. package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -97
  151. package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -94
  152. package/exemplos/sistemas-interativos/game-xr-human.json +80 -80
  153. package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -108
  154. package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -75
  155. package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -58
  156. package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -97
  157. package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -141
  158. package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -112
  159. package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -103
  160. package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -95
  161. package/exemplos/testes_embutidos.sema +1 -1
  162. package/exemplos/tratamento_erro.sema +1 -1
  163. package/exemplos/upload_arquivo.sema +1 -1
  164. package/exemplos/webhook.sema +1 -1
  165. package/node_modules/@sema/gerador-cpp/dist/index.js +176 -176
  166. package/node_modules/@sema/gerador-cpp/package.json +1 -1
  167. package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
  168. package/node_modules/@sema/gerador-css/dist/index.part02.js +460 -460
  169. package/node_modules/@sema/gerador-dotnet/dist/index.js +169 -169
  170. package/node_modules/@sema/gerador-dotnet/package.json +1 -1
  171. package/node_modules/@sema/gerador-html/dist/index.js +17 -17
  172. package/node_modules/@sema/gerador-lua/dist/index.js +51 -51
  173. package/node_modules/@sema/gerador-php/dist/index.js +113 -113
  174. package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
  175. package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
  176. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
  177. 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,32 +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
305
  const falhaSemSaida = caso.expect.campos.some((campo) => campo.nome === "sucesso" && campo.tipo === "falso")
306
306
  && caso.expect.campos.every((campo) => campo.nome === "sucesso")
307
307
  && caso.expect.linhas.length === 0
308
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
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
315
315
  end`;
316
316
  });
317
317
  const lista = testes.map(({ task, caso, indice }) => `{ nome = ${JSON.stringify(caso.nome)}, fn = test_${normalizarNomeParaSimbolo(task.nome)}_${indice + 1} }`).join(",\n ");
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)}))()
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)}))()
321
321
 
322
322
  ${funcoes.join("\n\n")}
323
323
 
@@ -376,20 +376,20 @@ function gerarFuncoesTask(task) {
376
376
  : valorPadraoLua(campo);
377
377
  return ` ${campo.nome} = ${valor},`;
378
378
  }).join("\n");
379
- return ` if igual_profundo(entrada, ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}) then
380
- return {
381
- ${saida}
382
- }
379
+ return ` if igual_profundo(entrada, ${converterBlocoTesteParaLua(caso.given, tiposDeclarados)}) then
380
+ return {
381
+ ${saida}
382
+ }
383
383
  end`;
384
384
  })
385
385
  .join("\n");
386
- return `${gerarMetadadosTask(task)}
386
+ return `${gerarMetadadosTask(task)}
387
387
 
388
388
  ${garantias}
389
389
 
390
- function M.executar_${simbolo}(entrada)
391
- entrada = entrada or {}
392
- ${cenariosErro ? `${cenariosErro}\n` : ""}${cenariosFalhaEstruturada ? `${cenariosFalhaEstruturada}\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}
393
393
  verificar_garantias_${simbolo}(saida)
394
394
  return saida
395
395
  end`;
@@ -405,39 +405,39 @@ export function gerarLua(modulo) {
405
405
  const tasks = modulo.tasks.map((task) => gerarFuncoesTask(task)).join("\n\n");
406
406
  const flows = modulo.flows.map((flow) => `-- Flow ${flow.nome}: etapas=${flow.etapasEstruturadas.length} tasks=${flow.tasksReferenciadas.join(", ") || "nenhuma"}`).join("\n");
407
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");
408
- const codigo = `${gerarCabecalhoSemaLua(modulo)}
409
- ${interops ? `${interops}\n` : ""}${tiposExternos ? `${tiposExternos}\n\n` : ""}local M = {}
408
+ const codigo = `${gerarCabecalhoSemaLua(modulo)}
409
+ ${interops ? `${interops}\n` : ""}${tiposExternos ? `${tiposExternos}\n\n` : ""}local M = {}
410
410
 
411
- local function contem(lista, valor)
411
+ local function contem(lista, valor)
412
412
  for _, item in ipairs(lista) do
413
413
  if item == valor then
414
414
  return true
415
415
  end
416
416
  end
417
417
  return false
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}` : ""}
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}` : ""}
441
441
 
442
442
  return M
443
443
  `;