@semacode/cli 2.3.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +112 -41
  3. package/dist/agentContextPack.js +14 -10
  4. package/dist/agentEntryPoints.d.ts +5 -0
  5. package/dist/agentEntryPoints.js +102 -91
  6. package/dist/angular-consumer-standalone.d.ts +3 -1
  7. package/dist/angular-consumer-standalone.js +12 -8
  8. package/dist/bin.d.ts +6 -0
  9. package/dist/bin.js +130 -0
  10. package/dist/cliArgs.js +4 -4
  11. package/dist/cliControlError.d.ts +12 -0
  12. package/dist/cliControlError.js +47 -0
  13. package/dist/cliGrammar.d.ts +11 -0
  14. package/dist/cliGrammar.js +551 -0
  15. package/dist/cliHelp.d.ts +13 -0
  16. package/dist/cliHelp.js +19 -0
  17. package/dist/cliHelpTexto.d.ts +3 -0
  18. package/dist/cliHelpTexto.js +168 -0
  19. package/dist/cliRuntime.d.ts +2 -0
  20. package/dist/cliRuntime.js +31 -0
  21. package/dist/comandos.js +9 -22
  22. package/dist/contexto.js +5 -5
  23. package/dist/dev/index.d.ts +1 -0
  24. package/dist/dev/index.js +51 -9
  25. package/dist/discovery/catalog.js +3 -3
  26. package/dist/distribuicao/filesystemGlobal.d.ts +63 -0
  27. package/dist/distribuicao/filesystemGlobal.js +701 -0
  28. package/dist/distribuicao/index.d.ts +7 -0
  29. package/dist/distribuicao/index.js +227 -0
  30. package/dist/distribuicao/launcherGlobal.d.ts +53 -0
  31. package/dist/distribuicao/launcherGlobal.js +643 -0
  32. package/dist/distribuicao/launcherWindows.d.ts +28 -0
  33. package/dist/distribuicao/launcherWindows.js +326 -0
  34. package/dist/distribuicao/lockContextGlobal.d.ts +10 -0
  35. package/dist/distribuicao/lockContextGlobal.js +17 -0
  36. package/dist/distribuicao/lockGlobal.d.ts +6 -0
  37. package/dist/distribuicao/lockGlobal.js +520 -0
  38. package/dist/distribuicao/skillGlobal.d.ts +48 -0
  39. package/dist/distribuicao/skillGlobal.js +652 -0
  40. package/dist/distribuicao/skillIntentPolicy.d.ts +21 -0
  41. package/dist/distribuicao/skillIntentPolicy.js +115 -0
  42. package/dist/distribuicao/tipos.d.ts +50 -0
  43. package/dist/distribuicao/tipos.js +10 -0
  44. package/dist/distribuicao/versaoSemantica.d.ts +3 -0
  45. package/dist/distribuicao/versaoSemantica.js +62 -0
  46. package/dist/drift.part01.d.ts +34 -2
  47. package/dist/drift.part01.js +3 -0
  48. package/dist/drift.part04.d.ts +12 -2
  49. package/dist/drift.part04.js +89 -15
  50. package/dist/drift.part05.d.ts +2 -1
  51. package/dist/drift.part05.js +9 -6
  52. package/dist/drift.part06.d.ts +2 -1
  53. package/dist/drift.part06.js +115 -24
  54. package/dist/drift.part07.d.ts +11 -10
  55. package/dist/drift.part07.js +261 -255
  56. package/dist/drift.part08.d.ts +2 -1
  57. package/dist/drift.part08.js +35 -25
  58. package/dist/drift.part11.js +279 -32
  59. package/dist/drift.part12.d.ts +1 -1
  60. package/dist/drift.part12.js +196 -11
  61. package/dist/drift.part13.d.ts +18 -2
  62. package/dist/drift.part13.js +654 -76
  63. package/dist/drift.part14.js +21 -7
  64. package/dist/driftCacheCas.d.ts +43 -0
  65. package/dist/driftCacheCas.js +351 -0
  66. package/dist/driftCacheFilesystem.d.ts +64 -0
  67. package/dist/driftCacheFilesystem.js +313 -0
  68. package/dist/driftCacheModes.d.ts +38 -0
  69. package/dist/driftCacheModes.js +147 -0
  70. package/dist/driftCacheStore.d.ts +80 -0
  71. package/dist/driftCacheStore.js +603 -0
  72. package/dist/driftCatalogo.d.ts +65 -0
  73. package/dist/driftCatalogo.js +516 -0
  74. package/dist/driftEscopo.d.ts +21 -0
  75. package/dist/driftEscopo.js +647 -0
  76. package/dist/driftEscopoReferencias.d.ts +8 -0
  77. package/dist/driftEscopoReferencias.js +612 -0
  78. package/dist/driftOrcamento.d.ts +6 -0
  79. package/dist/driftOrcamento.js +20 -3
  80. package/dist/geracaoCore.js +4 -6
  81. package/dist/iaPrompts.d.ts +3 -3
  82. package/dist/iaPrompts.js +13 -14
  83. package/dist/index.d.ts +4 -1
  84. package/dist/index.js +6 -25
  85. package/dist/index.part01.d.ts +21 -14
  86. package/dist/index.part01.js +20 -165
  87. package/dist/index.part02.js +57 -43
  88. package/dist/index.part03.d.ts +23 -1
  89. package/dist/index.part03.js +83 -8
  90. package/dist/index.part04.d.ts +10 -2
  91. package/dist/index.part04.js +48 -14
  92. package/dist/index.part05.d.ts +1 -1
  93. package/dist/index.part05.js +109 -30
  94. package/dist/index.part06.js +34 -16
  95. package/dist/index.part07.js +31 -27
  96. package/dist/index.part08.d.ts +1 -1
  97. package/dist/index.part08.js +23 -28
  98. package/dist/init/templates.part01.js +393 -393
  99. package/dist/init/templates.part02.js +189 -189
  100. package/dist/initCommand.js +5 -1
  101. package/dist/initTemplatesBackend.js +73 -73
  102. package/dist/initTemplatesBase.js +7 -5
  103. package/dist/initTemplatesFlutter.js +137 -137
  104. package/dist/initTemplatesRuntime.js +350 -350
  105. package/dist/initTemplatesWeb.js +309 -309
  106. package/dist/pipelineConteudo/command.d.ts +1 -0
  107. package/dist/pipelineConteudo/command.js +4 -32
  108. package/dist/pipelineConteudo/help.d.ts +2 -0
  109. package/dist/pipelineConteudo/help.js +33 -0
  110. package/dist/profileAuthorCommand.js +3 -7
  111. package/dist/profileCommand.js +3 -7
  112. package/dist/projeto.d.ts +1 -1
  113. package/dist/projetoCarregar.d.ts +2 -2
  114. package/dist/projetoCarregar.js +69 -28
  115. package/dist/projetoCatalogo.d.ts +8 -0
  116. package/dist/projetoCatalogo.js +164 -0
  117. package/dist/projetoOrigens.d.ts +2 -0
  118. package/dist/projetoOrigens.js +65 -9
  119. package/dist/projetoTipos.d.ts +15 -5
  120. package/dist/resultadoCli.d.ts +20 -0
  121. package/dist/resultadoCli.js +57 -0
  122. package/dist/saidaCli.d.ts +35 -0
  123. package/dist/saidaCli.js +118 -0
  124. package/dist/sistemasInterativos/acceptanceEvidence.d.ts +22 -0
  125. package/dist/sistemasInterativos/acceptanceEvidence.js +345 -0
  126. package/dist/sistemasInterativos/engineObservation.d.ts +12 -0
  127. package/dist/sistemasInterativos/engineObservation.js +438 -0
  128. package/dist/sistemasInterativos/jobOrchestration.d.ts +2 -0
  129. package/dist/sistemasInterativos/jobOrchestration.js +204 -0
  130. package/dist/sistemasInterativos/operationPrimitives.d.ts +21 -0
  131. package/dist/sistemasInterativos/operationPrimitives.js +194 -0
  132. package/dist/sistemasInterativos/operations.d.ts +4 -39
  133. package/dist/sistemasInterativos/operations.js +5 -1164
  134. package/dist/skillCommand.d.ts +5 -0
  135. package/dist/skillCommand.js +88 -0
  136. package/dist/sync/index.js +35 -35
  137. package/docs/README.md +11 -7
  138. package/docs/ai-integration.md +18 -11
  139. package/docs/ai-onboarding.md +81 -62
  140. package/docs/ai-workflow.md +10 -4
  141. package/docs/auth.md +26 -26
  142. package/docs/cli.md +197 -79
  143. package/docs/commands.md +30 -6
  144. package/docs/database.md +15 -15
  145. package/docs/deploy.md +54 -41
  146. package/docs/documentation.md +11 -10
  147. package/docs/drift-cache.md +108 -0
  148. package/docs/env.md +16 -16
  149. package/docs/frontend.md +41 -41
  150. package/docs/getting-started.md +82 -57
  151. package/docs/i18n.md +15 -15
  152. package/docs/repositories.md +60 -43
  153. package/docs/rollback.md +38 -31
  154. package/docs/security.md +54 -32
  155. package/docs/sistemas-interativos.md +27 -27
  156. package/docs/support.md +8 -8
  157. package/docs/testing.md +123 -17
  158. package/docs/vocabulary.md +29 -29
  159. package/exemplos/agendamento.sema +1 -1
  160. package/exemplos/assinatura.sema +1 -1
  161. package/exemplos/auditoria.sema +1 -1
  162. package/exemplos/autenticacao.sema +1 -1
  163. package/exemplos/author_obra_comum.sema +1 -1
  164. package/exemplos/author_tema_sensivel.sema +1 -1
  165. package/exemplos/automacao.sema +1 -1
  166. package/exemplos/cadastro_usuario.sema +1 -1
  167. package/exemplos/calculadora.sema +1 -1
  168. package/exemplos/crud_simples.sema +1 -1
  169. package/exemplos/estoque.sema +1 -1
  170. package/exemplos/exportacao.sema +1 -1
  171. package/exemplos/fila.sema +1 -1
  172. package/exemplos/integracao_externa.sema +1 -1
  173. package/exemplos/multi_tenant.sema +1 -1
  174. package/exemplos/notificacao.sema +1 -1
  175. package/exemplos/operacao_estrategia.sema +132 -132
  176. package/exemplos/operacao_estrategia_discovery.sema +220 -220
  177. package/exemplos/operacao_estrategia_fluxo.sema +114 -114
  178. package/exemplos/operacao_estrategia_gates.sema +106 -106
  179. package/exemplos/operacao_estrategia_quarentena.sema +133 -133
  180. package/exemplos/operacao_estrategia_rollout.sema +124 -124
  181. package/exemplos/pagamento.sema +1 -1
  182. package/exemplos/pagamento_dominio.sema +1 -1
  183. package/exemplos/pedido.sema +1 -1
  184. package/exemplos/permissao.sema +1 -1
  185. package/exemplos/persistencia_vendor_first.sema +1 -1
  186. package/exemplos/profile_conversas.sema +165 -165
  187. package/exemplos/profile_game.sema +1 -1
  188. package/exemplos/profile_legal.sema +1 -1
  189. package/exemplos/profile_ops.sema +1 -1
  190. package/exemplos/profile_research.sema +1 -1
  191. package/exemplos/profile_software.sema +1 -1
  192. package/exemplos/profile_workflow_n8n.sema +1 -1
  193. package/exemplos/relatorio.sema +1 -1
  194. package/exemplos/replica_analitica_erp.sema +1 -1
  195. package/exemplos/testes_embutidos.sema +1 -1
  196. package/exemplos/tratamento_erro.sema +1 -1
  197. package/exemplos/upload_arquivo.sema +1 -1
  198. package/exemplos/webhook.sema +1 -1
  199. package/node_modules/@sema/gerador-cpp/dist/index.js +176 -176
  200. package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
  201. package/node_modules/@sema/gerador-css/dist/index.part02.js +460 -460
  202. package/node_modules/@sema/gerador-dotnet/dist/index.js +169 -169
  203. package/node_modules/@sema/gerador-html/dist/index.js +17 -17
  204. package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
  205. package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
  206. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
  207. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +1 -0
  208. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +1 -0
  209. package/package.json +7 -2
  210. package/scripts/postinstall.mjs +148 -0
  211. package/skills/sema/SKILL.md +199 -0
  212. package/skills/sema/agents/openai.yaml +4 -0
  213. package/node_modules/@sema/gerador-cpp/dist/index.js.map +0 -1
  214. package/node_modules/@sema/gerador-css/dist/index.js.map +0 -1
  215. package/node_modules/@sema/gerador-css/dist/index.part01.js.map +0 -1
  216. package/node_modules/@sema/gerador-css/dist/index.part02.js.map +0 -1
  217. package/node_modules/@sema/gerador-dart/dist/index.js.map +0 -1
  218. package/node_modules/@sema/gerador-dotnet/dist/index.js.map +0 -1
  219. package/node_modules/@sema/gerador-html/dist/index.js.map +0 -1
  220. package/node_modules/@sema/gerador-javascript/dist/index.js.map +0 -1
  221. package/node_modules/@sema/gerador-lua/dist/index.js.map +0 -1
  222. package/node_modules/@sema/gerador-php/dist/index.js.map +0 -1
  223. package/node_modules/@sema/gerador-python/dist/index.js.map +0 -1
  224. package/node_modules/@sema/gerador-python/dist/index.part01.js.map +0 -1
  225. package/node_modules/@sema/gerador-python/dist/index.part02.js.map +0 -1
  226. package/node_modules/@sema/gerador-typescript/dist/index.js.map +0 -1
  227. package/node_modules/@sema/gerador-typescript/dist/index.part01.js.map +0 -1
  228. package/node_modules/@sema/gerador-typescript/dist/index.part02.js.map +0 -1
  229. package/node_modules/@sema/gerador-typescript/dist/index.part03.js.map +0 -1
  230. package/node_modules/@sema/nucleo/dist/ast/tipos.js.map +0 -1
  231. package/node_modules/@sema/nucleo/dist/diagnosticos/index.js.map +0 -1
  232. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js.map +0 -1
  233. package/node_modules/@sema/nucleo/dist/diagnosticos/snippets.js.map +0 -1
  234. package/node_modules/@sema/nucleo/dist/formatador/index.js.map +0 -1
  235. package/node_modules/@sema/nucleo/dist/formatador/index.part01.js.map +0 -1
  236. package/node_modules/@sema/nucleo/dist/formatador/index.part02.js.map +0 -1
  237. package/node_modules/@sema/nucleo/dist/index.js.map +0 -1
  238. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +0 -1
  239. package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js.map +0 -1
  240. package/node_modules/@sema/nucleo/dist/ir/conversor.part02.js.map +0 -1
  241. package/node_modules/@sema/nucleo/dist/ir/conversor.part03.js.map +0 -1
  242. package/node_modules/@sema/nucleo/dist/ir/modelos.js.map +0 -1
  243. package/node_modules/@sema/nucleo/dist/lexer/lexer.js.map +0 -1
  244. package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +0 -1
  245. package/node_modules/@sema/nucleo/dist/parser/parser.declaracoes.js.map +0 -1
  246. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +0 -1
  247. package/node_modules/@sema/nucleo/dist/parser/parser.modulo.js.map +0 -1
  248. package/node_modules/@sema/nucleo/dist/parser/parser.part01.js.map +0 -1
  249. package/node_modules/@sema/nucleo/dist/parser/parser.part02.js.map +0 -1
  250. package/node_modules/@sema/nucleo/dist/parser/parser.part03.js.map +0 -1
  251. package/node_modules/@sema/nucleo/dist/persistencia/contratos.js.map +0 -1
  252. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +0 -1
  253. package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js.map +0 -1
  254. package/node_modules/@sema/nucleo/dist/semantico/analisador.part02.js.map +0 -1
  255. package/node_modules/@sema/nucleo/dist/semantico/analisador.part03.js.map +0 -1
  256. package/node_modules/@sema/nucleo/dist/semantico/analisador.part04.js.map +0 -1
  257. package/node_modules/@sema/nucleo/dist/semantico/analisador.part05.js.map +0 -1
  258. package/node_modules/@sema/nucleo/dist/semantico/analisador.part06.js.map +0 -1
  259. package/node_modules/@sema/nucleo/dist/semantico/analisador.part07.js.map +0 -1
  260. package/node_modules/@sema/nucleo/dist/semantico/analisador.part08.js.map +0 -1
  261. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +0 -1
  262. package/node_modules/@sema/nucleo/dist/semantico/estruturas.part01.js.map +0 -1
  263. package/node_modules/@sema/nucleo/dist/semantico/estruturas.part02.js.map +0 -1
  264. package/node_modules/@sema/nucleo/dist/semantico/orcamentoSemantico.js.map +0 -1
  265. package/node_modules/@sema/nucleo/dist/semantico/seguranca.js.map +0 -1
  266. package/node_modules/@sema/nucleo/dist/util/arquivos.js.map +0 -1
  267. package/node_modules/@sema/padroes/dist/index.js.map +0 -1
@@ -0,0 +1,647 @@
1
+ // SEMA-GOVERNED: sema.produto.governanca_ia.drift
2
+ // Descricao: planeja o conjunto fisico minimo que pode ser indexado antes de qualquer caminhada de drift.
3
+ import { lstat, realpath } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { filtrarCaminhosEscopoReal, resolverDiretoriosCodigoEscopoReal, } from "./drift.part02.js";
6
+ import { candidatosReferenciaLocalDrift, extrairReferenciasLocaisDrift, raizesCodigoLogicasDrift, } from "./driftEscopoReferencias.js";
7
+ export { extrairReferenciasLocaisDrift } from "./driftEscopoReferencias.js";
8
+ const CONCORRENCIA_SONDAGENS_DRIFT = 16;
9
+ const CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT = 8;
10
+ const EXTENSAO_POR_ORIGEM = {
11
+ ts: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
12
+ js: [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"],
13
+ py: [".py"],
14
+ dart: [".dart"],
15
+ lua: [".lua"],
16
+ cs: [".cs"],
17
+ java: [".java"],
18
+ go: [".go"],
19
+ rust: [".rs"],
20
+ cpp: [".cpp", ".cc", ".cxx", ".hpp", ".h"],
21
+ php: [".php"],
22
+ };
23
+ const EXTENSOES_CODIGO_PLANEJADO = new Set([
24
+ ...Object.values(EXTENSAO_POR_ORIGEM).flat(),
25
+ ".sql", ".psql", ".ddl", ".prisma",
26
+ ]);
27
+ function chaveCaminho(caminho) {
28
+ const absoluto = path.normalize(path.resolve(caminho));
29
+ return process.platform === "win32" ? absoluto.toLowerCase() : absoluto;
30
+ }
31
+ function caminhoEstaDentro(raiz, alvo) {
32
+ const relativo = path.relative(path.resolve(raiz), path.resolve(alvo));
33
+ return relativo === "" || (relativo !== ".."
34
+ && !relativo.startsWith(`..${path.sep}`)
35
+ && !path.isAbsolute(relativo));
36
+ }
37
+ function identidadesArquivoIguais(a, b) {
38
+ return a.isFile()
39
+ && b.isFile()
40
+ && !a.isSymbolicLink()
41
+ && !b.isSymbolicLink()
42
+ && a.dev === b.dev
43
+ && a.ino === b.ino
44
+ && a.size === b.size
45
+ && a.mtimeNs === b.mtimeNs
46
+ && a.ctimeNs === b.ctimeNs;
47
+ }
48
+ async function mapearComLimite(itens, limite, executar) {
49
+ if (itens.length === 0) {
50
+ return [];
51
+ }
52
+ const resultados = new Array(itens.length);
53
+ let proximoIndice = 0;
54
+ const trabalhador = async () => {
55
+ for (;;) {
56
+ const indice = proximoIndice;
57
+ proximoIndice += 1;
58
+ if (indice >= itens.length) {
59
+ return;
60
+ }
61
+ resultados[indice] = await executar(itens[indice]);
62
+ }
63
+ };
64
+ await Promise.all(Array.from({ length: Math.min(Math.max(1, limite), itens.length) }, () => trabalhador()));
65
+ return resultados;
66
+ }
67
+ async function arquivoRegularContido(caminho, raizReal) {
68
+ try {
69
+ const informacaoAntes = await lstat(caminho, { bigint: true });
70
+ if (!informacaoAntes.isFile() || informacaoAntes.isSymbolicLink()) {
71
+ return false;
72
+ }
73
+ const caminhoReal = await realpath(caminho);
74
+ const informacaoDepois = await lstat(caminho, { bigint: true });
75
+ return caminhoEstaDentro(raizReal, caminhoReal)
76
+ && identidadesArquivoIguais(informacaoAntes, informacaoDepois);
77
+ }
78
+ catch {
79
+ return false;
80
+ }
81
+ }
82
+ async function sondarArquivosRegularesContidos(caminhos, raizReal) {
83
+ const unicos = [...new Map(caminhos.map((caminho) => [chaveCaminho(caminho), caminho])).entries()];
84
+ const resultados = await mapearComLimite(unicos, CONCORRENCIA_SONDAGENS_DRIFT, async ([chave, caminho]) => [chave, await arquivoRegularContido(caminho, raizReal)]);
85
+ return new Map(resultados);
86
+ }
87
+ function vinculosModulo(ir) {
88
+ return [
89
+ ...ir.vinculos,
90
+ ...ir.tasks.flatMap((task) => task.vinculos),
91
+ ...ir.flows.flatMap((flow) => flow.vinculos),
92
+ ...ir.routes.flatMap((route) => route.vinculos),
93
+ ...ir.superficies.flatMap((superficie) => superficie.vinculos),
94
+ ];
95
+ }
96
+ function implementacoesModulo(ir) {
97
+ return [
98
+ ...ir.tasks.flatMap((task) => task.implementacoesExternas),
99
+ ...ir.superficies.flatMap((superficie) => superficie.implementacoesExternas),
100
+ ];
101
+ }
102
+ function moduloExigeAncoraCodigo(ir) {
103
+ return ir.tasks.length > 0
104
+ || ir.routes.length > 0
105
+ || ir.superficies.length > 0
106
+ || implementacoesModulo(ir).length > 0
107
+ || vinculosModulo(ir).some((vinculo) => Boolean(vinculo.arquivo || vinculo.tipo === "arquivo"));
108
+ }
109
+ function resolverArquivoWorkspace(baseProjeto, valor) {
110
+ const absoluto = path.isAbsolute(valor)
111
+ ? path.resolve(valor)
112
+ : path.resolve(baseProjeto, valor);
113
+ return caminhoEstaDentro(baseProjeto, absoluto) ? absoluto : undefined;
114
+ }
115
+ function descreverArquivoForaWorkspace(valor) {
116
+ const nome = path.basename(path.normalize(valor)) || "alvo";
117
+ return `[fora_do_workspace]/${nome}`;
118
+ }
119
+ function variantesSegmentoDiretorio(segmento) {
120
+ const camel = segmento.replace(/_([a-z0-9])/gi, (_ocorrencia, caractere) => caractere.toUpperCase());
121
+ return [...new Set([
122
+ segmento,
123
+ segmento.includes("_") ? segmento.replace(/_/g, "-") : undefined,
124
+ segmento.includes("_") && camel !== segmento ? camel : undefined,
125
+ /(?:^|_)id$/i.test(segmento) ? `[${segmento}]` : undefined,
126
+ /(?:^|_)id$/i.test(segmento) && camel !== segmento ? `[${camel}]` : undefined,
127
+ ].filter((item) => Boolean(item)))];
128
+ }
129
+ function adicionarCandidatoPreservandoForma(candidatos, baseProjeto, caminho) {
130
+ const absoluto = path.resolve(caminho);
131
+ if (!caminhoEstaDentro(baseProjeto, absoluto)) {
132
+ return;
133
+ }
134
+ const chave = chaveCaminho(absoluto);
135
+ if (!candidatos.has(chave)) {
136
+ candidatos.set(chave, absoluto);
137
+ }
138
+ }
139
+ function variantesNomeArquivo(segmento) {
140
+ const pascal = segmento
141
+ .split(/[_-]+/)
142
+ .filter(Boolean)
143
+ .map((parte) => `${parte[0]?.toUpperCase() ?? ""}${parte.slice(1)}`)
144
+ .join("");
145
+ return [...new Set([
146
+ segmento,
147
+ segmento.includes("_") ? segmento.replace(/_/g, "-") : undefined,
148
+ segmento.includes("_") ? segmento.replace(/_/g, ".") : undefined,
149
+ pascal && pascal !== segmento ? pascal : undefined,
150
+ ].filter((item) => Boolean(item)))];
151
+ }
152
+ function resolverDiretoriosCodigoPlanejados(contexto, irs, configuracao) {
153
+ const raizesModulo = irs.flatMap((ir) => {
154
+ const primeiroSegmento = ir.nome.split(".").map((item) => item.trim()).find(Boolean);
155
+ return primeiroSegmento
156
+ ? variantesNomeArquivo(primeiroSegmento).map((segmento) => path.resolve(contexto.baseProjeto, segmento))
157
+ : [];
158
+ });
159
+ const candidatos = [...resolverDiretoriosCodigoEscopoReal(contexto, configuracao), ...raizesModulo];
160
+ return [...new Map(filtrarCaminhosEscopoReal(candidatos, contexto, configuracao)
161
+ .map((diretorio) => [chaveCaminho(diretorio), diretorio])).values()];
162
+ }
163
+ function variantesCaminhoSegmentos(segmentos) {
164
+ let variantes = [[]];
165
+ for (const segmento of segmentos) {
166
+ const opcoes = variantesSegmentoDiretorio(segmento);
167
+ variantes = variantes.flatMap((prefixo) => opcoes.map((opcao) => [...prefixo, opcao]));
168
+ }
169
+ return variantes.slice(0, 16);
170
+ }
171
+ function candidatosArquivoImpl(contexto, impl, diretoriosCodigo = contexto.diretoriosCodigo) {
172
+ const grupos = [];
173
+ if (impl.origemArquivo) {
174
+ const declarado = resolverArquivoWorkspace(contexto.baseProjeto, impl.origemArquivo);
175
+ if (declarado) {
176
+ grupos.push([declarado]);
177
+ }
178
+ }
179
+ const partes = impl.caminho.split(".").map((parte) => parte.trim()).filter(Boolean);
180
+ if (partes.length < 2) {
181
+ return grupos;
182
+ }
183
+ const bases = [...new Map([contexto.baseProjeto, ...diretoriosCodigo]
184
+ .map((base) => [chaveCaminho(base), base])).values()];
185
+ const extensoes = EXTENSAO_POR_ORIGEM[impl.origem] ?? [];
186
+ for (const removerCauda of [1, 2]) {
187
+ const candidatos = new Map();
188
+ const adicionar = (caminho) => {
189
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
190
+ };
191
+ const segmentosOriginais = partes.slice(0, Math.max(1, partes.length - removerCauda));
192
+ for (const base of bases) {
193
+ const nomeBase = path.basename(base).toLowerCase();
194
+ const segmentos = segmentosOriginais[0]?.toLowerCase() === nomeBase
195
+ ? segmentosOriginais.slice(1)
196
+ : segmentosOriginais;
197
+ if (segmentos.length === 0) {
198
+ continue;
199
+ }
200
+ for (const diretorios of variantesCaminhoSegmentos(segmentos.slice(0, -1))) {
201
+ for (const nomeArquivo of variantesNomeArquivo(segmentos.at(-1))) {
202
+ for (const extensao of extensoes) {
203
+ adicionar(path.join(base, ...diretorios, `${nomeArquivo}${extensao}`));
204
+ }
205
+ }
206
+ }
207
+ for (const caminhoDiretorio of variantesCaminhoSegmentos(segmentos)) {
208
+ for (const extensao of extensoes) {
209
+ adicionar(path.join(base, ...caminhoDiretorio, `index${extensao}`));
210
+ }
211
+ }
212
+ }
213
+ if (candidatos.size > 0) {
214
+ grupos.push([...candidatos.values()]);
215
+ }
216
+ }
217
+ return grupos;
218
+ }
219
+ function candidatosConsumerDeterministicos(contexto, irs, termosEscopo, diretoriosCodigo) {
220
+ const segmentos = new Set();
221
+ for (const termo of termosEscopo) {
222
+ segmentos.add(termo);
223
+ segmentos.add(termo.replace(/_/g, "-"));
224
+ }
225
+ for (const ir of irs) {
226
+ for (const rota of ir.routes) {
227
+ for (const segmento of (rota.caminho ?? "").split("/").filter((item) => item && !item.startsWith(":"))) {
228
+ segmentos.add(segmento);
229
+ }
230
+ }
231
+ }
232
+ const candidatos = new Map();
233
+ const extensoes = [".ts", ".tsx", ".js", ".jsx"];
234
+ for (const raiz of diretoriosCodigo) {
235
+ for (const segmento of segmentos) {
236
+ for (const extensao of extensoes) {
237
+ for (const relativo of [
238
+ ["src", "app", segmento, `page${extensao}`],
239
+ ["app", segmento, `page${extensao}`],
240
+ ["src", "pages", `${segmento}${extensao}`],
241
+ ["pages", `${segmento}${extensao}`],
242
+ ]) {
243
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, path.resolve(raiz, ...relativo));
244
+ }
245
+ }
246
+ }
247
+ }
248
+ return [...candidatos.values()];
249
+ }
250
+ function candidatosRotasDeterministicos(contexto, irs, diretoriosCodigo) {
251
+ const candidatos = new Map();
252
+ const extensoes = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py"];
253
+ const segmentos = new Set();
254
+ for (const ir of irs) {
255
+ for (const rota of ir.routes) {
256
+ for (const segmento of (rota.caminho ?? "").split("/").filter((item) => item && !item.startsWith(":") && !item.startsWith("{"))) {
257
+ segmentos.add(segmento);
258
+ }
259
+ }
260
+ }
261
+ for (const raiz of diretoriosCodigo) {
262
+ for (const segmento of segmentos) {
263
+ const nomes = variantesNomeArquivo(segmento);
264
+ for (const nome of nomes) {
265
+ for (const extensao of extensoes) {
266
+ for (const relativo of [
267
+ [segmento, `${nome}.controller${extensao}`],
268
+ [`${nome}.controller${extensao}`],
269
+ ["controllers", `${nome}.controller${extensao}`],
270
+ ["routes", `${nome}${extensao}`],
271
+ ]) {
272
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, path.resolve(raiz, ...relativo));
273
+ }
274
+ }
275
+ }
276
+ }
277
+ }
278
+ return [...candidatos.values()];
279
+ }
280
+ function candidatosConvencionaisEscopo(contexto, irs, diretoriosCodigo) {
281
+ const candidatos = new Map();
282
+ const adicionar = (caminho) => {
283
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
284
+ };
285
+ const origens = new Set(irs.flatMap((ir) => implementacoesModulo(ir).map((impl) => impl.origem)));
286
+ const possuiRotas = irs.some((ir) => ir.routes.length > 0);
287
+ const possuiPersistencia = irs.some((ir) => ir.databases.length > 0
288
+ || ir.tasks.some((task) => task.effects.some((efeito) => /\b(?:db|database|persist|storage)\b/i.test(efeito))));
289
+ const bases = diretoriosCodigo;
290
+ if (possuiRotas && origens.has("rust")) {
291
+ for (const base of bases) {
292
+ adicionar(path.join(base, "main.rs"));
293
+ adicionar(path.join(base, "src", "main.rs"));
294
+ adicionar(path.join(base, "lib.rs"));
295
+ adicionar(path.join(base, "src", "lib.rs"));
296
+ }
297
+ }
298
+ if (possuiPersistencia) {
299
+ for (const base of bases) {
300
+ adicionar(path.join(base, "schema.sql"));
301
+ adicionar(path.join(base, "schema.prisma"));
302
+ adicionar(path.join(base, "db", "schema.sql"));
303
+ adicionar(path.join(base, "prisma", "schema.prisma"));
304
+ }
305
+ }
306
+ return [...candidatos.values()];
307
+ }
308
+ function escolherDiretoriosLogicos(contexto, arquivos, diretoriosCodigo = contexto.diretoriosCodigo) {
309
+ const candidatos = [...new Map(diretoriosCodigo
310
+ .map((diretorio) => path.resolve(diretorio))
311
+ .map((diretorio) => [chaveCaminho(diretorio), diretorio])).values()]
312
+ .sort((a, b) => b.length - a.length || a.localeCompare(b, "pt-BR"));
313
+ const escolhidos = new Map();
314
+ for (const arquivo of arquivos) {
315
+ if (!EXTENSOES_CODIGO_PLANEJADO.has(path.extname(arquivo).toLowerCase())) {
316
+ continue;
317
+ }
318
+ const raiz = candidatos.find((diretorio) => caminhoEstaDentro(diretorio, arquivo));
319
+ const raizEfetiva = raiz ?? path.dirname(arquivo);
320
+ escolhidos.set(chaveCaminho(raizEfetiva), raizEfetiva);
321
+ }
322
+ return [...escolhidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
323
+ }
324
+ export async function planejarEscopoDrift(contexto, configuracao) {
325
+ if (configuracao.escopo === "projeto") {
326
+ const diretorios = resolverDiretoriosCodigoEscopoReal(contexto, configuracao);
327
+ return {
328
+ escopo: configuracao.escopo,
329
+ estrategia: "projeto",
330
+ arquivos: [],
331
+ arquivosDeclarados: [],
332
+ arquivosInferidos: [],
333
+ arquivosAusentes: [],
334
+ diretorios,
335
+ modulos: contexto.modulosSelecionados
336
+ .map((modulo) => modulo.resultado.ir?.nome)
337
+ .filter((nome) => Boolean(nome)),
338
+ cobertura: "completa",
339
+ bloqueios: [],
340
+ dependencias: {},
341
+ };
342
+ }
343
+ const modulosFonte = configuracao.escopo === "arquivo"
344
+ ? contexto.modulosSelecionados
345
+ : contexto.modulosCarregados;
346
+ const irs = modulosFonte
347
+ .map((modulo) => modulo.resultado.ir)
348
+ .filter((ir) => Boolean(ir));
349
+ const declarados = new Map();
350
+ const ausentes = new Map();
351
+ const inferidos = new Map();
352
+ const bloqueiosPlano = new Set();
353
+ const raizReal = await realpath(contexto.baseProjeto);
354
+ const diretoriosCodigoPermitidos = resolverDiretoriosCodigoPlanejados(contexto, irs, configuracao);
355
+ const vinculosPlanejados = irs.flatMap((ir) => vinculosModulo(ir))
356
+ .map((vinculo) => vinculo.arquivo ?? (vinculo.tipo === "arquivo" ? vinculo.valor : undefined))
357
+ .filter((valor) => Boolean(valor))
358
+ .map((valor) => ({
359
+ valor,
360
+ absoluto: resolverArquivoWorkspace(contexto.baseProjeto, valor),
361
+ }));
362
+ const implementacoesPlanejadas = irs
363
+ .flatMap((ir) => implementacoesModulo(ir))
364
+ .map((impl) => candidatosArquivoImpl(contexto, impl, diretoriosCodigoPermitidos));
365
+ const resultadoSondagens = await sondarArquivosRegularesContidos([
366
+ ...vinculosPlanejados.flatMap((vinculo) => vinculo.absoluto ? [vinculo.absoluto] : []),
367
+ ...implementacoesPlanejadas.flat(2),
368
+ ], raizReal);
369
+ const arquivoExiste = (arquivo) => resultadoSondagens.get(chaveCaminho(arquivo)) === true;
370
+ for (const vinculo of vinculosPlanejados) {
371
+ if (!vinculo.absoluto) {
372
+ const descricaoSegura = descreverArquivoForaWorkspace(vinculo.valor);
373
+ ausentes.set(`fora:${descricaoSegura}`, descricaoSegura);
374
+ continue;
375
+ }
376
+ if (arquivoExiste(vinculo.absoluto)) {
377
+ declarados.set(chaveCaminho(vinculo.absoluto), vinculo.absoluto);
378
+ }
379
+ else {
380
+ ausentes.set(chaveCaminho(vinculo.absoluto), vinculo.absoluto);
381
+ }
382
+ }
383
+ const raizesDeclaradasCodigo = escolherDiretoriosLogicos(contexto, [...declarados.values()]);
384
+ for (const gruposCandidatos of implementacoesPlanejadas) {
385
+ const grupoResolvido = gruposCandidatos.find((grupo) => grupo.some(arquivoExiste));
386
+ let encontrados = grupoResolvido?.filter(arquivoExiste) ?? [];
387
+ const encontradosDeclarados = encontrados.filter((candidato) => declarados.has(chaveCaminho(candidato)));
388
+ if (encontradosDeclarados.length > 0) {
389
+ encontrados = encontradosDeclarados;
390
+ }
391
+ else if (raizesDeclaradasCodigo.length > 0) {
392
+ const proximosDeDeclarados = encontrados.filter((candidato) => raizesDeclaradasCodigo.some((raiz) => caminhoEstaDentro(raiz, candidato)));
393
+ if (proximosDeDeclarados.length > 0) {
394
+ encontrados = proximosDeDeclarados;
395
+ }
396
+ }
397
+ if (encontrados.length > 1) {
398
+ bloqueiosPlano.add("escopo_estreito_ambiguo");
399
+ continue;
400
+ }
401
+ for (const candidato of encontrados) {
402
+ const chave = chaveCaminho(candidato);
403
+ if (!declarados.has(chave) && !inferidos.has(chave)) {
404
+ inferidos.set(chave, candidato);
405
+ }
406
+ }
407
+ const primeiroCandidato = gruposCandidatos[0]?.[0];
408
+ if (encontrados.length === 0 && primeiroCandidato) {
409
+ ausentes.set(chaveCaminho(primeiroCandidato), primeiroCandidato);
410
+ }
411
+ }
412
+ const raizesAncoradas = escolherDiretoriosLogicos(contexto, [...declarados.values(), ...inferidos.values()]);
413
+ if (raizesAncoradas.length > 0) {
414
+ const candidatosDeterministicos = [
415
+ ...candidatosConsumerDeterministicos(contexto, irs, configuracao.termosEscopo, raizesAncoradas),
416
+ ...candidatosRotasDeterministicos(contexto, irs, raizesAncoradas),
417
+ ...candidatosConvencionaisEscopo(contexto, irs, raizesAncoradas),
418
+ ];
419
+ const sondagensDeterministicas = await sondarArquivosRegularesContidos(candidatosDeterministicos, raizReal);
420
+ for (const candidato of candidatosDeterministicos) {
421
+ if (sondagensDeterministicas.get(chaveCaminho(candidato)) !== true) {
422
+ continue;
423
+ }
424
+ const chave = chaveCaminho(candidato);
425
+ if (!declarados.has(chave) && !inferidos.has(chave)) {
426
+ inferidos.set(chave, candidato);
427
+ }
428
+ }
429
+ }
430
+ const arquivosMesclados = new Map(declarados);
431
+ for (const [chave, arquivo] of inferidos) {
432
+ if (!arquivosMesclados.has(chave)) {
433
+ arquivosMesclados.set(chave, arquivo);
434
+ }
435
+ }
436
+ const arquivos = [...arquivosMesclados.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
437
+ const arquivosAusentes = [...ausentes.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
438
+ const exigeAncoraCodigo = irs.some(moduloExigeAncoraCodigo);
439
+ if (arquivos.length === 0
440
+ && exigeAncoraCodigo
441
+ && !bloqueiosPlano.has("escopo_estreito_ambiguo")) {
442
+ bloqueiosPlano.add("escopo_estreito_sem_vinculos");
443
+ }
444
+ const bloqueios = [...bloqueiosPlano].sort((a, b) => a.localeCompare(b, "pt-BR"));
445
+ return {
446
+ escopo: configuracao.escopo,
447
+ estrategia: "arquivos_vinculados",
448
+ arquivos,
449
+ arquivosDeclarados: [...declarados.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
450
+ arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
451
+ arquivosAusentes,
452
+ diretorios: escolherDiretoriosLogicos(contexto, arquivos),
453
+ modulos: irs.map((ir) => ir.nome),
454
+ cobertura: arquivosAusentes.length === 0 && bloqueios.length === 0 ? "completa" : "parcial",
455
+ bloqueios,
456
+ dependencias: {},
457
+ };
458
+ }
459
+ async function construirConfinamentoDependencias(contexto) {
460
+ const raizWorkspaceReal = await realpath(contexto.baseProjeto);
461
+ const logicas = raizesCodigoLogicasDrift(contexto);
462
+ const reaisPossiveis = await mapearComLimite(logicas, CONCORRENCIA_SONDAGENS_DRIFT, async (raiz) => {
463
+ try {
464
+ const raizReal = await realpath(raiz);
465
+ return caminhoEstaDentro(raizWorkspaceReal, raizReal) ? raizReal : undefined;
466
+ }
467
+ catch {
468
+ return undefined;
469
+ }
470
+ });
471
+ const raizesCodigoReais = [...new Map(reaisPossiveis
472
+ .filter((raiz) => Boolean(raiz))
473
+ .map((raiz) => [chaveCaminho(raiz), raiz])).values()];
474
+ return {
475
+ raizWorkspaceReal,
476
+ raizesCodigoLogicas: logicas,
477
+ raizesCodigoReais,
478
+ };
479
+ }
480
+ async function arquivoRegularConfinadoDependencias(caminho, confinamento) {
481
+ const absoluto = path.resolve(caminho);
482
+ if (!confinamento.raizesCodigoLogicas.some((raiz) => caminhoEstaDentro(raiz, absoluto))) {
483
+ return false;
484
+ }
485
+ try {
486
+ const informacaoAntes = await lstat(absoluto, { bigint: true });
487
+ if (!informacaoAntes.isFile() || informacaoAntes.isSymbolicLink()) {
488
+ return false;
489
+ }
490
+ const caminhoReal = await realpath(absoluto);
491
+ const informacaoDepois = await lstat(absoluto, { bigint: true });
492
+ return caminhoEstaDentro(confinamento.raizWorkspaceReal, caminhoReal)
493
+ && confinamento.raizesCodigoReais.some((raiz) => caminhoEstaDentro(raiz, caminhoReal))
494
+ && identidadesArquivoIguais(informacaoAntes, informacaoDepois);
495
+ }
496
+ catch {
497
+ return false;
498
+ }
499
+ }
500
+ function candidatoAusenteSeguro(contexto, candidatos, referencia) {
501
+ const seguro = candidatos.find((candidato) => caminhoEstaDentro(contexto.baseProjeto, candidato));
502
+ return seguro ?? referencia;
503
+ }
504
+ function referenciaPythonEhLocalObrigatoria(referencia) {
505
+ return referencia.startsWith("python:.");
506
+ }
507
+ async function resolverReferenciasLocais(contexto, arquivoOrigem, referencias, confinamento) {
508
+ const resultados = await mapearComLimite(referencias, CONCORRENCIA_SONDAGENS_DRIFT, async (referencia) => {
509
+ const candidatos = candidatosReferenciaLocalDrift(contexto, arquivoOrigem, referencia);
510
+ for (const candidato of candidatos) {
511
+ if (await arquivoRegularConfinadoDependencias(candidato, confinamento)) {
512
+ return { referencia, resolvida: candidato };
513
+ }
514
+ }
515
+ const ehPython = referencia.startsWith("python:");
516
+ return {
517
+ referencia,
518
+ ausente: !ehPython || referenciaPythonEhLocalObrigatoria(referencia)
519
+ ? candidatoAusenteSeguro(contexto, candidatos, referencia)
520
+ : undefined,
521
+ };
522
+ });
523
+ const modulosPythonResolvidos = resultados
524
+ .filter((item) => item.resolvida && item.referencia.startsWith("python:"))
525
+ .map((item) => item.referencia.slice("python:".length));
526
+ const dependenciasPythonMarcadas = resultados.map((item) => {
527
+ if (item.resolvida || !item.referencia.startsWith("python:")) {
528
+ return item;
529
+ }
530
+ const modulo = item.referencia.slice("python:".length);
531
+ const prefixoLocalResolvido = modulosPythonResolvidos.some((prefixo) => prefixo !== modulo && modulo.startsWith(`${prefixo}.`));
532
+ if (!referenciaPythonEhLocalObrigatoria(item.referencia) && !prefixoLocalResolvido) {
533
+ return item;
534
+ }
535
+ const candidatos = candidatosReferenciaLocalDrift(contexto, arquivoOrigem, item.referencia);
536
+ return {
537
+ referencia: item.referencia,
538
+ ausente: candidatoAusenteSeguro(contexto, candidatos, item.referencia),
539
+ };
540
+ });
541
+ const modulosPythonAusentes = dependenciasPythonMarcadas
542
+ .filter((item) => item.ausente && item.referencia.startsWith("python:"))
543
+ .map((item) => item.referencia.slice("python:".length));
544
+ return dependenciasPythonMarcadas.map((item) => {
545
+ if (!item.ausente || !item.referencia.startsWith("python:")) {
546
+ return item;
547
+ }
548
+ const modulo = item.referencia.slice("python:".length);
549
+ const possuiPaiAusente = modulosPythonAusentes.some((prefixo) => prefixo !== modulo && modulo.startsWith(`${prefixo}.`));
550
+ return possuiPaiAusente ? { referencia: item.referencia } : item;
551
+ });
552
+ }
553
+ export async function expandirDependenciasPlanoDrift(contexto, plano, catalogo) {
554
+ if (plano.estrategia !== "arquivos_vinculados" || plano.arquivos.length === 0) {
555
+ return plano;
556
+ }
557
+ const arquivos = new Map(plano.arquivos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
558
+ const inferidos = new Map(plano.arquivosInferidos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
559
+ const ausentes = new Map(plano.arquivosAusentes.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
560
+ const visitados = new Set();
561
+ const fila = [...plano.arquivos];
562
+ const confinamento = await construirConfinamentoDependencias(contexto);
563
+ const dependencias = new Map(Object.entries(plano.dependencias).map(([arquivo, itens]) => [arquivo, new Set(itens)]));
564
+ while (fila.length > 0) {
565
+ const lote = fila.splice(0).filter((arquivo) => {
566
+ const chave = chaveCaminho(arquivo);
567
+ if (visitados.has(chave)) {
568
+ return false;
569
+ }
570
+ visitados.add(chave);
571
+ return true;
572
+ });
573
+ const resultadosLote = await mapearComLimite(lote, CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT, async (arquivo) => {
574
+ try {
575
+ const referencias = extrairReferenciasLocaisDrift(await catalogo.lerTexto(arquivo), { contexto, arquivoOrigem: arquivo });
576
+ return {
577
+ arquivo,
578
+ referencias: await resolverReferenciasLocais(contexto, arquivo, referencias, confinamento),
579
+ };
580
+ }
581
+ catch {
582
+ return {
583
+ arquivo,
584
+ referencias: [],
585
+ leituraFalhou: true,
586
+ };
587
+ }
588
+ });
589
+ const candidatosParaIncluir = new Map();
590
+ for (const resultado of resultadosLote) {
591
+ if (resultado.leituraFalhou) {
592
+ ausentes.set(chaveCaminho(resultado.arquivo), resultado.arquivo);
593
+ }
594
+ for (const referencia of resultado.referencias) {
595
+ if (referencia.ausente) {
596
+ ausentes.set(chaveCaminho(referencia.ausente), referencia.ausente);
597
+ }
598
+ if (referencia.resolvida && !catalogo.contem(referencia.resolvida)) {
599
+ candidatosParaIncluir.set(chaveCaminho(referencia.resolvida), referencia.resolvida);
600
+ }
601
+ }
602
+ }
603
+ await catalogo.incluir([...candidatosParaIncluir.values()]);
604
+ const novos = new Map();
605
+ for (const resultado of resultadosLote) {
606
+ const lista = dependencias.get(resultado.arquivo) ?? new Set();
607
+ for (const referencia of resultado.referencias) {
608
+ if (!referencia.resolvida) {
609
+ continue;
610
+ }
611
+ if (!catalogo.contem(referencia.resolvida)) {
612
+ ausentes.set(chaveCaminho(referencia.resolvida), referencia.resolvida);
613
+ continue;
614
+ }
615
+ lista.add(referencia.resolvida);
616
+ const chave = chaveCaminho(referencia.resolvida);
617
+ if (!arquivos.has(chave)) {
618
+ novos.set(chave, referencia.resolvida);
619
+ }
620
+ }
621
+ if (lista.size > 0) {
622
+ dependencias.set(resultado.arquivo, lista);
623
+ }
624
+ }
625
+ const novosOrdenados = [...novos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
626
+ for (const candidato of novosOrdenados) {
627
+ const chave = chaveCaminho(candidato);
628
+ arquivos.set(chave, candidato);
629
+ inferidos.set(chave, candidato);
630
+ fila.push(candidato);
631
+ }
632
+ }
633
+ const arquivosExpandidos = [...arquivos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
634
+ const arquivosAusentes = [...ausentes.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
635
+ return {
636
+ ...plano,
637
+ arquivos: arquivosExpandidos,
638
+ arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
639
+ arquivosAusentes,
640
+ diretorios: escolherDiretoriosLogicos(contexto, arquivosExpandidos),
641
+ cobertura: arquivosAusentes.length === 0 && plano.bloqueios.length === 0 ? "completa" : "parcial",
642
+ dependencias: Object.fromEntries([...dependencias.entries()]
643
+ .sort(([a], [b]) => a.localeCompare(b, "pt-BR"))
644
+ .map(([arquivo, itens]) => [arquivo, [...itens].sort((a, b) => a.localeCompare(b, "pt-BR"))])),
645
+ };
646
+ }
647
+ //# sourceMappingURL=driftEscopo.js.map
@@ -0,0 +1,8 @@
1
+ import type { ContextoProjetoCarregado } from "./projeto.js";
2
+ export interface OpcoesExtracaoReferenciasDrift {
3
+ contexto?: ContextoProjetoCarregado;
4
+ arquivoOrigem?: string;
5
+ }
6
+ export declare function extrairReferenciasLocaisDrift(codigo: string, opcoes?: OpcoesExtracaoReferenciasDrift): string[];
7
+ export declare function raizesCodigoLogicasDrift(contexto: ContextoProjetoCarregado): string[];
8
+ export declare function candidatosReferenciaLocalDrift(contexto: ContextoProjetoCarregado, arquivoOrigem: string, referencia: string): string[];