@semacode/cli 1.5.17 → 1.5.19

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 (111) hide show
  1. package/AGENTS.md +268 -260
  2. package/LICENSE +22 -22
  3. package/README.md +93 -61
  4. package/SEMA_BRIEF.curto.txt +8 -6
  5. package/SEMA_BRIEF.md +71 -22
  6. package/SEMA_BRIEF.micro.txt +7 -5
  7. package/SEMA_INDEX.json +931 -193
  8. package/dist/controleComercialSupabase.d.ts +326 -0
  9. package/dist/controleComercialSupabase.js +310 -0
  10. package/dist/controleComercialSupabase.js.map +1 -0
  11. package/dist/docs.js +48 -20
  12. package/dist/docs.js.map +1 -1
  13. package/dist/drift.d.ts +5 -3
  14. package/dist/drift.js +119 -116
  15. package/dist/drift.js.map +1 -1
  16. package/dist/importador.d.ts +1 -1
  17. package/dist/importador.js +1 -200
  18. package/dist/importador.js.map +1 -1
  19. package/dist/index.js +1924 -493
  20. package/dist/index.js.map +1 -1
  21. package/dist/mcpRemoto.d.ts +32 -0
  22. package/dist/mcpRemoto.js +61 -0
  23. package/dist/mcpRemoto.js.map +1 -0
  24. package/dist/projeto.js +3 -21
  25. package/dist/projeto.js.map +1 -1
  26. package/dist/tipos.d.ts +1 -1
  27. package/docs/AGENT_STARTER.md +109 -102
  28. package/docs/cli.md +89 -33
  29. package/docs/como-ensinar-a-sema-para-ia.md +42 -36
  30. package/docs/deploy.md +231 -43
  31. package/docs/documentacao.md +61 -36
  32. package/docs/env.md +63 -14
  33. package/docs/extensao-vscode.md +12 -4
  34. package/docs/fluxo-pratico-ia-sema.md +45 -35
  35. package/docs/instalacao-e-primeiro-uso.md +52 -30
  36. package/docs/integracao-com-ia.md +44 -35
  37. package/docs/mcp.md +270 -31
  38. package/docs/pagamento-ponta-a-ponta.md +40 -24
  39. package/docs/persistencia-vendor-first.md +11 -5
  40. package/docs/prompt-base-ia-sema.md +18 -11
  41. package/docs/rollback.md +17 -15
  42. package/docs/sintaxe.md +37 -229
  43. package/exemplos/agendamento.sema +105 -106
  44. package/exemplos/assinatura.sema +133 -136
  45. package/exemplos/auditoria.sema +89 -88
  46. package/exemplos/autenticacao.sema +125 -125
  47. package/exemplos/author_obra_comum.sema +294 -0
  48. package/exemplos/author_tema_sensivel.sema +264 -0
  49. package/exemplos/automacao.sema +107 -107
  50. package/exemplos/cadastro_usuario.sema +54 -54
  51. package/exemplos/calculadora.sema +78 -78
  52. package/exemplos/crud_simples.sema +89 -89
  53. package/exemplos/estoque.sema +127 -126
  54. package/exemplos/exportacao.sema +94 -94
  55. package/exemplos/fila.sema +130 -131
  56. package/exemplos/integracao_externa.sema +94 -94
  57. package/exemplos/multi_tenant.sema +140 -140
  58. package/exemplos/notificacao.sema +149 -98
  59. package/exemplos/operacao_estrategia.sema +633 -402
  60. package/exemplos/pagamento.sema +434 -222
  61. package/exemplos/pagamento_dominio.sema +35 -35
  62. package/exemplos/pedido.sema +255 -119
  63. package/exemplos/permissao.sema +121 -121
  64. package/exemplos/persistencia_vendor_first.sema +86 -86
  65. package/exemplos/profile_game.sema +114 -0
  66. package/exemplos/profile_legal.sema +105 -0
  67. package/exemplos/profile_ops.sema +110 -0
  68. package/exemplos/profile_research.sema +104 -0
  69. package/exemplos/profile_software.sema +123 -0
  70. package/exemplos/profile_workflow_n8n.sema +99 -0
  71. package/exemplos/relatorio.sema +93 -93
  72. package/exemplos/replica_analitica_erp.sema +160 -0
  73. package/exemplos/testes_embutidos.sema +45 -45
  74. package/exemplos/tratamento_erro.sema +157 -157
  75. package/exemplos/upload_arquivo.sema +93 -93
  76. package/exemplos/webhook.sema +94 -96
  77. package/llms-full.txt +34 -34
  78. package/llms.txt +17 -17
  79. package/node_modules/@sema/gerador-css/dist/index.js +563 -563
  80. package/node_modules/@sema/gerador-css/package.json +1 -1
  81. package/node_modules/@sema/gerador-dart/package.json +1 -1
  82. package/node_modules/@sema/gerador-html/dist/index.js +90 -90
  83. package/node_modules/@sema/gerador-html/package.json +1 -1
  84. package/node_modules/@sema/gerador-javascript/dist/index.js +92 -92
  85. package/node_modules/@sema/gerador-javascript/package.json +1 -1
  86. package/node_modules/@sema/gerador-lua/dist/index.js +53 -53
  87. package/node_modules/@sema/gerador-lua/package.json +1 -1
  88. package/node_modules/@sema/gerador-python/dist/index.js +122 -96
  89. package/node_modules/@sema/gerador-python/dist/index.js.map +1 -1
  90. package/node_modules/@sema/gerador-python/package.json +1 -1
  91. package/node_modules/@sema/gerador-typescript/dist/index.js +153 -153
  92. package/node_modules/@sema/gerador-typescript/package.json +1 -1
  93. package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +2 -4
  94. package/node_modules/@sema/nucleo/dist/formatador/index.js +26 -46
  95. package/node_modules/@sema/nucleo/dist/formatador/index.js.map +1 -1
  96. package/node_modules/@sema/nucleo/dist/ir/conversor.js +9 -204
  97. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
  98. package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -35
  99. package/node_modules/@sema/nucleo/dist/lexer/tokens.js +0 -21
  100. package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +1 -1
  101. package/node_modules/@sema/nucleo/dist/parser/parser.js +0 -40
  102. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
  103. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +6 -5
  104. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +76 -307
  105. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
  106. package/node_modules/@sema/nucleo/dist/semantico/estruturas.d.ts +2 -0
  107. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js +32 -2
  108. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +1 -1
  109. package/node_modules/@sema/nucleo/package.json +1 -1
  110. package/node_modules/@sema/padroes/package.json +1 -1
  111. package/package.json +15 -15
package/dist/drift.js CHANGED
@@ -6,8 +6,6 @@ import { extrairSimbolosCpp } from "./cpp-symbols.js";
6
6
  import { extrairRotasDotnet, extrairSimbolosDotnet } from "./dotnet-http.js";
7
7
  import { extrairRotasGo, extrairSimbolosGo } from "./go-http.js";
8
8
  import { extrairRotasJava, extrairSimbolosJava } from "./java-http.js";
9
- import { extrairSimbolosLua } from "./lua-symbols.js";
10
- import { extrairRotasPhp, extrairSimbolosPhp } from "./php-symbols.js";
11
9
  import { contarIndentacaoPython, extrairRotasFlaskDecoradas, normalizarCaminhoFlask } from "./python-http.js";
12
10
  import { extrairRotasRust, extrairSimbolosRust } from "./rust-http.js";
13
11
  import { extrairRotasTypeScriptHttp } from "./typescript-http.js";
@@ -51,9 +49,11 @@ const TERMOS_ESCopo_IGNORADOS = new Set([
51
49
  "api",
52
50
  "app",
53
51
  "apps",
52
+ "antes",
54
53
  "base",
55
54
  "codigo",
56
55
  "config",
56
+ "contra",
57
57
  "controller",
58
58
  "controllers",
59
59
  "data",
@@ -62,16 +62,19 @@ const TERMOS_ESCopo_IGNORADOS = new Set([
62
62
  "int",
63
63
  "module",
64
64
  "modulo",
65
+ "para",
65
66
  "publico",
66
67
  "route",
67
68
  "routes",
68
69
  "schema",
70
+ "sem",
69
71
  "sema",
70
72
  "service",
71
73
  "services",
72
74
  "src",
73
75
  "task",
74
76
  "tasks",
77
+ "testes",
75
78
  "tests",
76
79
  "ui",
77
80
  "web",
@@ -203,11 +206,11 @@ function resolverRaizesExplicitasConfiguradas(contexto) {
203
206
  ...origensDeclaradas.map((origem) => path.resolve(configCarregada.baseDiretorio, origem)),
204
207
  ])].sort((a, b) => a.localeCompare(b, "pt-BR"));
205
208
  }
206
- function resolverRaizesIgnoradasPermitidas(contexto, segmentosIgnorados) {
209
+ function resolverRaizesIgnoradasPermitidas(contexto, segmentosIgnorados, incluirRaizesConfiguradas = false) {
207
210
  return [...new Set([
208
211
  path.resolve(contexto.baseProjeto),
209
212
  resolverRaizEscopoReal(contexto),
210
- ...resolverRaizesExplicitasConfiguradas(contexto),
213
+ ...(incluirRaizesConfiguradas ? resolverRaizesExplicitasConfiguradas(contexto) : []),
211
214
  ])]
212
215
  .filter((raiz) => caminhoTemSegmentoIgnorado(raiz, segmentosIgnorados))
213
216
  .sort((a, b) => a.localeCompare(b, "pt-BR"));
@@ -222,8 +225,12 @@ function caminhoIgnoradoForaDoEscopoReal(caminhoArquivo, segmentosIgnorados, rai
222
225
  return !raizesPermitidas.some((raiz) => caminhoEstaDentroDe(raiz, caminhoArquivo));
223
226
  }
224
227
  function filtrarCaminhosEscopoReal(caminhos, contexto, configuracao) {
225
- const raizesWorktreePermitidas = resolverRaizesIgnoradasPermitidas(contexto, DIRETORIOS_WORKTREE);
226
- const raizesConsumidorPermitidas = resolverRaizesIgnoradasPermitidas(contexto, DIRETORIOS_CONSUMIDOR_LATERAL);
228
+ const escopoJaEstaEmWorktree = caminhoTemSegmentoIgnorado(contexto.baseProjeto, DIRETORIOS_WORKTREE)
229
+ || caminhoTemSegmentoIgnorado(resolverRaizEscopoReal(contexto), DIRETORIOS_WORKTREE);
230
+ const escopoJaEstaEmConsumer = caminhoTemSegmentoIgnorado(contexto.baseProjeto, DIRETORIOS_CONSUMIDOR_LATERAL)
231
+ || caminhoTemSegmentoIgnorado(resolverRaizEscopoReal(contexto), DIRETORIOS_CONSUMIDOR_LATERAL);
232
+ const raizesWorktreePermitidas = resolverRaizesIgnoradasPermitidas(contexto, DIRETORIOS_WORKTREE, escopoJaEstaEmWorktree);
233
+ const raizesConsumidorPermitidas = resolverRaizesIgnoradasPermitidas(contexto, DIRETORIOS_CONSUMIDOR_LATERAL, escopoJaEstaEmConsumer);
227
234
  return caminhos.filter((caminho) => {
228
235
  if (configuracao.ignorarWorktrees && caminhoIgnoradoForaDoEscopoReal(caminho, DIRETORIOS_WORKTREE, raizesWorktreePermitidas)) {
229
236
  return false;
@@ -339,6 +346,11 @@ function pontuarProximidadeRotaConsumer(rota, rotasAncora) {
339
346
  }
340
347
  return scoreMaximo;
341
348
  }
349
+ function caminhoConsumerParaTextoEscopo(contexto, arquivo) {
350
+ return path.isAbsolute(arquivo)
351
+ ? path.relative(contexto.baseProjeto, arquivo)
352
+ : arquivo;
353
+ }
342
354
  function filtrarConsumerSurfacesPorEscopo(consumerSurfaces, consumerBridges, contexto, configuracao, relevancia) {
343
355
  const raizesWorktreePermitidas = resolverRaizesIgnoradasPermitidas(contexto, DIRETORIOS_WORKTREE);
344
356
  const raizesConsumidorPermitidas = resolverRaizesIgnoradasPermitidas(contexto, DIRETORIOS_CONSUMIDOR_LATERAL);
@@ -352,13 +364,20 @@ function filtrarConsumerSurfacesPorEscopo(consumerSurfaces, consumerBridges, con
352
364
  && caminhoIgnoradoForaDoEscopoReal(surface.arquivo, DIRETORIOS_CONSUMIDOR_LATERAL, raizesConsumidorPermitidas)) {
353
365
  return false;
354
366
  }
367
+ if (!configuracao.ignorarConsumidoresLaterais) {
368
+ return true;
369
+ }
355
370
  if (configuracao.escopo === "projeto") {
356
371
  return true;
357
372
  }
358
- const score = pontuarTextoEscopo(`${surface.rota} ${surface.arquivo} ${surface.tipoArquivo}`, configuracao.termosEscopo)
359
- + pontuarProximidadeArquivoConsumer(surface.arquivo, relevancia?.arquivosAncora ?? [])
360
- + pontuarProximidadeRotaConsumer(surface.rota, relevancia?.rotasAncora ?? []);
361
- return score >= limiar;
373
+ const arquivoTexto = caminhoConsumerParaTextoEscopo(contexto, surface.arquivo);
374
+ const scoreTexto = pontuarTextoEscopo(`${surface.rota} ${arquivoTexto} ${surface.tipoArquivo}`, configuracao.termosEscopo);
375
+ const scoreRota = pontuarProximidadeRotaConsumer(surface.rota, relevancia?.rotasAncora ?? []);
376
+ if (scoreTexto === 0 && scoreRota === 0) {
377
+ return false;
378
+ }
379
+ const scoreArquivo = pontuarProximidadeArquivoConsumer(surface.arquivo, relevancia?.arquivosAncora ?? []);
380
+ return scoreTexto + scoreArquivo + scoreRota >= limiar;
362
381
  };
363
382
  const manterBridge = (bridge) => {
364
383
  if (configuracao.ignorarWorktrees
@@ -369,12 +388,19 @@ function filtrarConsumerSurfacesPorEscopo(consumerSurfaces, consumerBridges, con
369
388
  && caminhoIgnoradoForaDoEscopoReal(bridge.arquivo, DIRETORIOS_CONSUMIDOR_LATERAL, raizesConsumidorPermitidas)) {
370
389
  return false;
371
390
  }
391
+ if (!configuracao.ignorarConsumidoresLaterais) {
392
+ return true;
393
+ }
372
394
  if (configuracao.escopo === "projeto") {
373
395
  return true;
374
396
  }
375
- const score = pontuarTextoEscopo(`${bridge.caminho} ${bridge.arquivo} ${bridge.simbolo}`, configuracao.termosEscopo)
376
- + pontuarProximidadeArquivoConsumer(bridge.arquivo, relevancia?.arquivosAncora ?? []);
377
- return score >= limiar;
397
+ const arquivoTexto = caminhoConsumerParaTextoEscopo(contexto, bridge.arquivo);
398
+ const scoreTexto = pontuarTextoEscopo(`${bridge.caminho} ${arquivoTexto} ${bridge.simbolo}`, configuracao.termosEscopo);
399
+ if (scoreTexto === 0) {
400
+ return false;
401
+ }
402
+ const scoreArquivo = pontuarProximidadeArquivoConsumer(bridge.arquivo, relevancia?.arquivosAncora ?? []);
403
+ return scoreTexto + scoreArquivo >= limiar;
378
404
  };
379
405
  return {
380
406
  consumerSurfaces: consumerSurfaces.filter(manterSurface),
@@ -629,6 +655,51 @@ function extrairRecursosSql(arquivo, codigo) {
629
655
  }
630
656
  return [...recursos.values()];
631
657
  }
658
+ function limparIdentificadorSql(valor) {
659
+ const limpo = valor.trim();
660
+ if ((limpo.startsWith("\"") && limpo.endsWith("\""))
661
+ || (limpo.startsWith("`") && limpo.endsWith("`"))
662
+ || (limpo.startsWith("[") && limpo.endsWith("]"))) {
663
+ return limpo.slice(1, -1).replace(/""/g, "\"").trim();
664
+ }
665
+ return limpo;
666
+ }
667
+ function normalizarNomeSqlDeclarativo(valor) {
668
+ return valor
669
+ .split(/\s*\.\s*/g)
670
+ .map(limparIdentificadorSql)
671
+ .filter(Boolean)
672
+ .join(".");
673
+ }
674
+ function registrarSimboloSqlDeclarativo(simbolos, arquivo, nomeSql) {
675
+ const caminho = normalizarNomeSqlDeclarativo(nomeSql);
676
+ if (!caminho) {
677
+ return;
678
+ }
679
+ const ultimoSegmento = caminho.split(".").filter(Boolean).at(-1);
680
+ for (const simbolo of [caminho, ultimoSegmento].filter((item) => Boolean(item))) {
681
+ if (!simbolos.has(simbolo)) {
682
+ simbolos.set(simbolo, {
683
+ origem: "sql",
684
+ caminho: simbolo,
685
+ arquivo,
686
+ simbolo,
687
+ });
688
+ }
689
+ }
690
+ }
691
+ function extrairSimbolosSqlDeclarativos(arquivo, codigo) {
692
+ if (!/\.(?:sql|psql|ddl)$/i.test(arquivo)) {
693
+ return [];
694
+ }
695
+ const simbolos = new Map();
696
+ const padraoIdentificadorSql = /(?:"[^"]+"|`[^`]+`|\[[^\]]+\]|[A-Za-z_][\w$]*)/;
697
+ const padraoObjetoSql = new RegExp(`\\bcreate\\s+(?:or\\s+replace\\s+)?(?:function|procedure)\\s+(${padraoIdentificadorSql.source}(?:\\s*\\.\\s*${padraoIdentificadorSql.source})?)\\s*\\(`, "gi");
698
+ for (const match of codigo.matchAll(padraoObjetoSql)) {
699
+ registrarSimboloSqlDeclarativo(simbolos, arquivo, match[1] ?? "");
700
+ }
701
+ return [...simbolos.values()];
702
+ }
632
703
  function extrairRecursosMongoDb(arquivo, codigo) {
633
704
  const recursos = new Map();
634
705
  const contextoMongo = /\b(?:mongodb|mongoose|mongoclient|objectid)\b/i.test(codigo)
@@ -691,7 +762,7 @@ function extrairRecursosArquivoLocal(arquivo, codigo) {
691
762
  const nomeBase = path.basename(literal, path.extname(literal));
692
763
  registrarRecursoDrift(recursos, "arquivo", "arquivo_local", nomeBase, arquivo);
693
764
  }
694
- const nomeArquivo = path.basename(arquivo).replace(/\.(?:ts|tsx|js|jsx|mjs|cjs|py|dart|lua|cs|java|go|rs|cpp|cc|cxx|hpp|h)$/i, "");
765
+ const nomeArquivo = path.basename(arquivo).replace(/\.(?:ts|tsx|js|jsx|mjs|cjs|py|dart|cs|java|go|rs|cpp|cc|cxx|hpp|h)$/i, "");
695
766
  const nomeStore = nomeArquivo
696
767
  .replace(/(?:[_.-]?(?:repository|repositories|repo|store|storage|persistencia|persistence))$/i, "")
697
768
  .trim();
@@ -766,9 +837,17 @@ function escolherSimboloPorVinculo(simbolos, mapaImpl, valor) {
766
837
  if (exato) {
767
838
  return { simbolo: exato, confianca: "alta", status: "resolvido" };
768
839
  }
840
+ const valorNormalizado = valor.toLowerCase();
841
+ const exatoIndexado = simbolos.find((simbolo) => simbolo.caminho.toLowerCase() === valorNormalizado
842
+ || simbolo.simbolo.toLowerCase() === valorNormalizado);
843
+ if (exatoIndexado) {
844
+ return { simbolo: exatoIndexado, confianca: "alta", status: "resolvido" };
845
+ }
769
846
  const ultimoSegmento = valor.split(".").at(-1)?.toLowerCase();
770
- const aproximado = simbolos.find((simbolo) => simbolo.caminho.toLowerCase() === valor.toLowerCase()
771
- || simbolo.simbolo.toLowerCase() === ultimoSegmento
847
+ if (!ultimoSegmento) {
848
+ return { confianca: "baixa", status: "nao_encontrado" };
849
+ }
850
+ const aproximado = simbolos.find((simbolo) => simbolo.simbolo.toLowerCase() === ultimoSegmento
772
851
  || simbolo.caminho.toLowerCase().endsWith(`.${ultimoSegmento}`));
773
852
  if (aproximado) {
774
853
  return { simbolo: aproximado, confianca: "media", status: "parcial" };
@@ -1042,15 +1121,19 @@ async function listarArquivosRecursivos(diretorio, extensoes) {
1042
1121
  }
1043
1122
  return encontrados.sort((a, b) => a.localeCompare(b, "pt-BR"));
1044
1123
  }
1045
- const EXTENSOES_ARQUIVOS_CODIGO_DRIFT = [
1124
+ const EXTENSOES_ARQUIVOS_RASTREAVEIS_DRIFT = [
1046
1125
  ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
1047
- ".py", ".dart", ".lua", ".php", ".cs", ".java", ".go", ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h",
1048
- ".sql", ".psql", ".ddl", ".prisma", ".json",
1126
+ ".py", ".dart", ".cs", ".java", ".go", ".rs",
1127
+ ".cpp", ".cc", ".cxx", ".hpp", ".h",
1128
+ ".sql", ".psql", ".ddl", ".prisma",
1129
+ ".md", ".mdx", ".txt", ".json", ".jsonl",
1130
+ ".yml", ".yaml", ".toml", ".xml", ".html", ".htm", ".css",
1131
+ ".Caddyfile", ".caddyfile",
1049
1132
  ];
1050
- async function indexarArquivosCodigo(diretorios) {
1133
+ async function indexarArquivosRastreaveis(diretorios) {
1051
1134
  const arquivos = new Set();
1052
1135
  for (const diretorio of diretorios) {
1053
- for (const arquivo of await listarArquivosRecursivos(diretorio, EXTENSOES_ARQUIVOS_CODIGO_DRIFT)) {
1136
+ for (const arquivo of await listarArquivosRecursivos(diretorio, EXTENSOES_ARQUIVOS_RASTREAVEIS_DRIFT)) {
1054
1137
  arquivos.add(arquivo);
1055
1138
  }
1056
1139
  }
@@ -1894,57 +1977,6 @@ async function indexarDart(diretorios) {
1894
1977
  || a.arquivo.localeCompare(b.arquivo, "pt-BR")),
1895
1978
  };
1896
1979
  }
1897
- async function indexarLua(diretorios) {
1898
- const simbolos = new Map();
1899
- const recursos = new Map();
1900
- for (const diretorio of diretorios) {
1901
- const arquivos = (await listarArquivosRecursivos(diretorio, [".lua"]))
1902
- .filter((arquivo) => !/(^|[\\/])tests?([\\/]|$)|(?:^|[\\/])spec([\\/]|$)|(?:_spec|_test)\.lua$/i.test(arquivo));
1903
- for (const arquivo of arquivos) {
1904
- const codigo = await readFile(arquivo, "utf8");
1905
- const basesSimbolicas = caminhosSimbolicos(diretorio, arquivo);
1906
- for (const recurso of extrairRecursosPersistenciaCodigoVivo(arquivo, codigo)) {
1907
- registrarRecursoDrift(recursos, recurso.origem, recurso.tipo, recurso.nome, recurso.arquivo, recurso.simbolo);
1908
- }
1909
- for (const simbolo of extrairSimbolosLua(codigo)) {
1910
- registrarSimboloGenerico(simbolos, "lua", basesSimbolicas, arquivo, simbolo.simbolo);
1911
- }
1912
- }
1913
- }
1914
- return {
1915
- simbolos: [...simbolos.values()],
1916
- recursos: [...recursos.values()],
1917
- };
1918
- }
1919
- async function indexarPhp(diretorios) {
1920
- const simbolos = new Map();
1921
- const rotas = [];
1922
- const recursos = new Map();
1923
- for (const diretorio of diretorios) {
1924
- const arquivos = (await listarArquivosRecursivos(diretorio, [".php"]))
1925
- .filter((arquivo) => !/(^|[\\/])tests?([\\/]|$)|(?:^|[\\/])spec([\\/]|$)|(?:Test|Spec)\.php$/i.test(arquivo));
1926
- for (const arquivo of arquivos) {
1927
- const codigo = await readFile(arquivo, "utf8");
1928
- const basesSimbolicas = caminhosSimbolicos(diretorio, arquivo);
1929
- for (const recurso of extrairRecursosPersistenciaCodigoVivo(arquivo, codigo)) {
1930
- registrarRecursoDrift(recursos, recurso.origem, recurso.tipo, recurso.nome, recurso.arquivo, recurso.simbolo);
1931
- }
1932
- for (const simbolo of extrairSimbolosPhp(codigo)) {
1933
- registrarSimboloPhp(simbolos, basesSimbolicas, arquivo, simbolo.simbolo);
1934
- }
1935
- for (const rota of extrairRotasPhp(codigo)) {
1936
- rotas.push({
1937
- origem: "php",
1938
- metodo: rota.metodo,
1939
- caminho: rota.caminho,
1940
- arquivo,
1941
- simbolo: rota.simbolo,
1942
- });
1943
- }
1944
- }
1945
- }
1946
- return { simbolos: [...simbolos.values()], rotas, recursos: [...recursos.values()] };
1947
- }
1948
1980
  function registrarSimboloGenerico(simbolos, origem, basesSimbolicas, arquivo, simbolo) {
1949
1981
  for (const baseSimbolica of basesSimbolicas) {
1950
1982
  const caminho = `${baseSimbolica}.${simbolo}`;
@@ -1968,30 +2000,6 @@ function registrarSimboloGenerico(simbolos, origem, basesSimbolicas, arquivo, si
1968
2000
  }
1969
2001
  }
1970
2002
  }
1971
- function registrarSimboloPhp(simbolos, basesSimbolicas, arquivo, simbolo) {
1972
- registrarSimboloGenerico(simbolos, "php", basesSimbolicas, arquivo, simbolo);
1973
- const partes = simbolo.split(".").filter(Boolean);
1974
- const aliases = new Set([simbolo]);
1975
- const ultimo = partes.at(-1);
1976
- const penultimo = partes.at(-2);
1977
- if (ultimo) {
1978
- aliases.add(ultimo);
1979
- }
1980
- if (penultimo && ultimo) {
1981
- aliases.add(`${penultimo}.${ultimo}`);
1982
- }
1983
- for (const alias of aliases) {
1984
- if (!alias || simbolos.has(alias)) {
1985
- continue;
1986
- }
1987
- simbolos.set(alias, {
1988
- origem: "php",
1989
- caminho: alias,
1990
- arquivo,
1991
- simbolo,
1992
- });
1993
- }
1994
- }
1995
2003
  async function indexarDotnet(diretorios) {
1996
2004
  const simbolos = new Map();
1997
2005
  const rotas = [];
@@ -2130,11 +2138,12 @@ async function indexarCpp(diretorios) {
2130
2138
  }
2131
2139
  async function indexarPersistenciaDeclarativa(diretorios) {
2132
2140
  const recursos = new Map();
2141
+ const simbolos = new Map();
2133
2142
  for (const diretorio of diretorios) {
2134
2143
  const arquivos = await listarArquivosRecursivos(diretorio, [
2135
2144
  ".sql", ".psql", ".ddl", ".prisma",
2136
2145
  ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
2137
- ".py", ".dart", ".lua", ".php", ".cs", ".java", ".go", ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h",
2146
+ ".py", ".dart", ".cs", ".java", ".go", ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h",
2138
2147
  ]);
2139
2148
  for (const arquivo of arquivos) {
2140
2149
  const codigo = await readFile(arquivo, "utf8");
@@ -2144,9 +2153,12 @@ async function indexarPersistenciaDeclarativa(diretorios) {
2144
2153
  for (const recurso of extracoes) {
2145
2154
  registrarRecursoDrift(recursos, recurso.origem, recurso.tipo, recurso.nome, recurso.arquivo, recurso.simbolo);
2146
2155
  }
2156
+ for (const simbolo of extrairSimbolosSqlDeclarativos(arquivo, codigo)) {
2157
+ simbolos.set(`${simbolo.caminho}:${simbolo.arquivo}`, simbolo);
2158
+ }
2147
2159
  }
2148
2160
  }
2149
- return { recursos: [...recursos.values()] };
2161
+ return { recursos: [...recursos.values()], simbolos: [...simbolos.values()] };
2150
2162
  }
2151
2163
  function normalizarOrigemParaEngine(origem) {
2152
2164
  return origem && origem !== "firebase" && origem !== "arquivo" ? origem : undefined;
@@ -2338,7 +2350,7 @@ async function indexarPersistenciaDetalhada(diretorios) {
2338
2350
  for (const diretorio of diretorios) {
2339
2351
  const arquivos = await listarArquivosRecursivos(diretorio, [
2340
2352
  ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
2341
- ".py", ".dart", ".lua", ".cs", ".java", ".go", ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h",
2353
+ ".py", ".dart", ".cs", ".java", ".go", ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h",
2342
2354
  ".sql", ".psql", ".ddl", ".prisma",
2343
2355
  ]);
2344
2356
  for (const arquivo of arquivos) {
@@ -2571,7 +2583,7 @@ function extrairFontesHttpTypeScript(fontesLegado) {
2571
2583
  return fontesLegado.filter((fonte) => fonte === "nestjs" || fonte === "nextjs" || fonte === "firebase");
2572
2584
  }
2573
2585
  function extrairFontesHttpBackend(fontesLegado) {
2574
- return fontesLegado.filter((fonte) => fonte === "php" || fonte === "dotnet" || fonte === "java" || fonte === "go" || fonte === "rust");
2586
+ return fontesLegado.filter((fonte) => fonte === "dotnet" || fonte === "java" || fonte === "go" || fonte === "rust");
2575
2587
  }
2576
2588
  function ultimoSegmentoSimbolico(caminho) {
2577
2589
  const partes = caminho.split(".").filter(Boolean);
@@ -2630,6 +2642,9 @@ function pontuarCandidatoDeclarado(candidato, origem, caminhoDeclarado) {
2630
2642
  return undefined;
2631
2643
  }
2632
2644
  function pontuarCandidatoPorTask(candidato, task) {
2645
+ if (candidato.origem === "sql") {
2646
+ return undefined;
2647
+ }
2633
2648
  const taskNormalizada = paraIdentificadorModulo(task);
2634
2649
  const simboloNormalizado = paraIdentificadorModulo(candidato.simbolo.replace(/\./g, "_"));
2635
2650
  const caminhoNormalizado = paraIdentificadorModulo(candidato.caminho.replace(/\./g, "_"));
@@ -2717,10 +2732,6 @@ function escolherRotasEsperadas(task, fontesLegado) {
2717
2732
  }
2718
2733
  return ["fastapi", "flask"];
2719
2734
  }
2720
- const implPhp = task.implementacoesExternas.find((impl) => impl.origem === "php");
2721
- if (implPhp) {
2722
- return fontesBackend.includes("php") ? ["php"] : ["php"];
2723
- }
2724
2735
  const implCs = task.implementacoesExternas.find((impl) => impl.origem === "cs");
2725
2736
  if (implCs) {
2726
2737
  return fontesBackend.includes("dotnet") ? ["dotnet"] : ["dotnet"];
@@ -2925,12 +2936,9 @@ export async function analisarDriftLegado(contexto, opcoes) {
2925
2936
  diretoriosIgnoradosAtivos = resolverDiretoriosIgnoradosAtivos(opcoesResolvidas);
2926
2937
  try {
2927
2938
  const diretoriosCodigoAtivos = resolverDiretoriosCodigoEscopoReal(contexto, configuracaoEscopo);
2928
- const arquivosCodigo = await indexarArquivosCodigo(diretoriosCodigoAtivos);
2929
2939
  const indexTs = await indexarTypeScript(diretoriosCodigoAtivos);
2930
2940
  const indexPy = await indexarPython(diretoriosCodigoAtivos);
2931
2941
  const indexDart = await indexarDart(diretoriosCodigoAtivos);
2932
- const indexLua = await indexarLua(diretoriosCodigoAtivos);
2933
- const indexPhp = await indexarPhp(diretoriosCodigoAtivos);
2934
2942
  const indexDotnet = await indexarDotnet(diretoriosCodigoAtivos);
2935
2943
  const indexJava = await indexarJava(diretoriosCodigoAtivos);
2936
2944
  const indexGo = await indexarGo(diretoriosCodigoAtivos);
@@ -2938,24 +2946,22 @@ export async function analisarDriftLegado(contexto, opcoes) {
2938
2946
  const indexPersistencia = await indexarPersistenciaDeclarativa(diretoriosCodigoAtivos);
2939
2947
  const detalhesPersistencia = await indexarPersistenciaDetalhada(diretoriosCodigoAtivos);
2940
2948
  const indexCpp = await indexarCpp(diretoriosCodigoAtivos);
2949
+ const arquivosRastreaveis = await indexarArquivosRastreaveis(diretoriosCodigoAtivos);
2941
2950
  const todosSimbolos = [
2942
2951
  ...indexTs.simbolos,
2943
2952
  ...indexPy.simbolos,
2944
2953
  ...indexDart.simbolos,
2945
- ...indexLua.simbolos,
2946
- ...indexPhp.simbolos,
2947
2954
  ...indexDotnet.simbolos,
2948
2955
  ...indexJava.simbolos,
2949
2956
  ...indexGo.simbolos,
2950
2957
  ...indexRust.simbolos,
2951
2958
  ...indexCpp.simbolos,
2959
+ ...indexPersistencia.simbolos,
2952
2960
  ];
2953
2961
  const mapaImpl = new Map([
2954
2962
  ...indexTs.simbolos.map((item) => [item.caminho, item]),
2955
2963
  ...indexPy.simbolos.map((item) => [item.caminho, item]),
2956
2964
  ...indexDart.simbolos.map((item) => [item.caminho, item]),
2957
- ...indexLua.simbolos.map((item) => [item.caminho, item]),
2958
- ...indexPhp.simbolos.map((item) => [item.caminho, item]),
2959
2965
  ...indexDotnet.simbolos.map((item) => [item.caminho, item]),
2960
2966
  ...indexJava.simbolos.map((item) => [item.caminho, item]),
2961
2967
  ...indexGo.simbolos.map((item) => [item.caminho, item]),
@@ -2966,8 +2972,6 @@ export async function analisarDriftLegado(contexto, opcoes) {
2966
2972
  ...indexTs.recursos,
2967
2973
  ...indexPy.recursos,
2968
2974
  ...indexDart.recursos,
2969
- ...indexLua.recursos,
2970
- ...indexPhp.recursos,
2971
2975
  ...indexDotnet.recursos,
2972
2976
  ...indexJava.recursos,
2973
2977
  ...indexGo.recursos,
@@ -2980,14 +2984,13 @@ export async function analisarDriftLegado(contexto, opcoes) {
2980
2984
  ...indexTs.rotas,
2981
2985
  ...indexPy.rotas,
2982
2986
  ...indexDart.rotas,
2983
- ...indexPhp.rotas,
2984
2987
  ...indexDotnet.rotas,
2985
2988
  ...indexJava.rotas,
2986
2989
  ...indexGo.rotas,
2987
2990
  ...indexRust.rotas,
2988
2991
  ];
2989
2992
  const todosArquivosConhecidos = [...new Set([
2990
- ...arquivosCodigo,
2993
+ ...arquivosRastreaveis,
2991
2994
  ...todosSimbolos.map((item) => item.arquivo),
2992
2995
  ...todasRotasIndexadas.map((item) => item.arquivo),
2993
2996
  ...todosRecursos.map((item) => item.arquivo),
@@ -3614,7 +3617,7 @@ export async function analisarDriftLegado(contexto, opcoes) {
3614
3617
  const EXTENSOES_BUSCA_IMPACTO = [
3615
3618
  ".sema",
3616
3619
  ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
3617
- ".py", ".dart", ".lua", ".php", ".cs", ".java", ".go", ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h",
3620
+ ".py", ".dart", ".cs", ".java", ".go", ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h",
3618
3621
  ".sql", ".psql", ".ddl", ".prisma", ".json",
3619
3622
  ];
3620
3623
  function construirVariantesSemanticas(valor) {