@semacode/cli 2.3.1 → 3.5.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 (281) hide show
  1. package/README.md +265 -217
  2. package/dist/agentContextPack.js +14 -10
  3. package/dist/agentEntryPoints.d.ts +5 -0
  4. package/dist/agentEntryPoints.js +592 -568
  5. package/dist/angular-consumer-standalone.js +1 -1
  6. package/dist/bin.d.ts +6 -0
  7. package/dist/bin.js +130 -0
  8. package/dist/cliArgs.js +4 -4
  9. package/dist/cliControlError.d.ts +12 -0
  10. package/dist/cliControlError.js +47 -0
  11. package/dist/cliGrammar.d.ts +11 -0
  12. package/dist/cliGrammar.js +551 -0
  13. package/dist/cliHelp.d.ts +13 -0
  14. package/dist/cliHelp.js +19 -0
  15. package/dist/cliHelpTexto.d.ts +3 -0
  16. package/dist/cliHelpTexto.js +168 -0
  17. package/dist/cliRuntime.d.ts +2 -0
  18. package/dist/cliRuntime.js +31 -0
  19. package/dist/comandos.js +9 -22
  20. package/dist/contexto.js +5 -5
  21. package/dist/dev/index.d.ts +1 -0
  22. package/dist/dev/index.js +51 -9
  23. package/dist/discovery/catalog.js +3 -3
  24. package/dist/distribuicao/filesystemGlobal.d.ts +63 -0
  25. package/dist/distribuicao/filesystemGlobal.js +701 -0
  26. package/dist/distribuicao/index.d.ts +7 -0
  27. package/dist/distribuicao/index.js +227 -0
  28. package/dist/distribuicao/launcherGlobal.d.ts +53 -0
  29. package/dist/distribuicao/launcherGlobal.js +643 -0
  30. package/dist/distribuicao/launcherWindows.d.ts +28 -0
  31. package/dist/distribuicao/launcherWindows.js +326 -0
  32. package/dist/distribuicao/lockContextGlobal.d.ts +10 -0
  33. package/dist/distribuicao/lockContextGlobal.js +17 -0
  34. package/dist/distribuicao/lockGlobal.d.ts +6 -0
  35. package/dist/distribuicao/lockGlobal.js +520 -0
  36. package/dist/distribuicao/skillGlobal.d.ts +48 -0
  37. package/dist/distribuicao/skillGlobal.js +652 -0
  38. package/dist/distribuicao/skillIntentPolicy.d.ts +21 -0
  39. package/dist/distribuicao/skillIntentPolicy.js +115 -0
  40. package/dist/distribuicao/tipos.d.ts +50 -0
  41. package/dist/distribuicao/tipos.js +10 -0
  42. package/dist/distribuicao/versaoSemantica.d.ts +3 -0
  43. package/dist/distribuicao/versaoSemantica.js +62 -0
  44. package/dist/docs.part01.d.ts +4 -1
  45. package/dist/docs.part01.js +8 -0
  46. package/dist/docs.part02.js +9 -1
  47. package/dist/drift.part01.d.ts +33 -25
  48. package/dist/drift.part01.js +2 -1
  49. package/dist/drift.part04.d.ts +26 -5
  50. package/dist/drift.part04.js +123 -19
  51. package/dist/drift.part05.d.ts +2 -2
  52. package/dist/drift.part05.js +8 -6
  53. package/dist/drift.part06.d.ts +2 -2
  54. package/dist/drift.part06.js +113 -26
  55. package/dist/drift.part07.d.ts +11 -11
  56. package/dist/drift.part07.js +261 -265
  57. package/dist/drift.part08.d.ts +2 -2
  58. package/dist/drift.part08.js +35 -26
  59. package/dist/drift.part09.d.ts +2 -2
  60. package/dist/drift.part09.js +10 -3
  61. package/dist/drift.part11.js +261 -58
  62. package/dist/drift.part12.d.ts +1 -1
  63. package/dist/drift.part12.js +193 -21
  64. package/dist/drift.part13.d.ts +20 -39
  65. package/dist/drift.part13.js +601 -647
  66. package/dist/drift.part14.js +23 -7
  67. package/dist/driftCacheCas.d.ts +43 -0
  68. package/dist/driftCacheCas.js +351 -0
  69. package/dist/driftCacheFilesystem.d.ts +64 -0
  70. package/dist/driftCacheFilesystem.js +313 -0
  71. package/dist/driftCacheModes.d.ts +38 -0
  72. package/dist/driftCacheModes.js +147 -0
  73. package/dist/driftCacheStore.d.ts +80 -0
  74. package/dist/driftCacheStore.js +603 -0
  75. package/dist/driftCatalogo.d.ts +2 -28
  76. package/dist/driftCatalogo.js +143 -284
  77. package/dist/driftEscopo.d.ts +1 -3
  78. package/dist/driftEscopo.js +235 -151
  79. package/dist/driftEscopoReferencias.d.ts +5 -1
  80. package/dist/driftEscopoReferencias.js +375 -28
  81. package/dist/driftOrcamento.d.ts +0 -6
  82. package/dist/driftOrcamento.js +2 -1
  83. package/dist/execucoesExternas.js +19 -5
  84. package/dist/exemplosOficiais.d.ts +2 -1
  85. package/dist/exemplosOficiais.js +9 -3
  86. package/dist/geracaoCore.d.ts +1 -0
  87. package/dist/geracaoCore.js +6 -6
  88. package/dist/iaPrompts.d.ts +3 -3
  89. package/dist/iaPrompts.js +312 -313
  90. package/dist/importador.part01.d.ts +1 -1
  91. package/dist/importador.part06.d.ts +2 -0
  92. package/dist/importador.part06.js +87 -1
  93. package/dist/importador.part09.js +7 -1
  94. package/dist/index.d.ts +4 -1
  95. package/dist/index.js +6 -25
  96. package/dist/index.part01.d.ts +20 -28
  97. package/dist/index.part01.js +16 -237
  98. package/dist/index.part02.js +36 -22
  99. package/dist/index.part03.d.ts +24 -2
  100. package/dist/index.part03.js +83 -19
  101. package/dist/index.part04.d.ts +10 -2
  102. package/dist/index.part04.js +152 -123
  103. package/dist/index.part05.js +80 -78
  104. package/dist/index.part06.js +34 -17
  105. package/dist/index.part07.d.ts +8 -2
  106. package/dist/index.part07.js +153 -7
  107. package/dist/index.part08.d.ts +1 -1
  108. package/dist/index.part08.js +25 -30
  109. package/dist/initCommand.d.ts +1 -0
  110. package/dist/initCommand.js +20 -4
  111. package/dist/initTemplatesBase.js +6 -4
  112. package/dist/pipelineConteudo/command.d.ts +1 -0
  113. package/dist/pipelineConteudo/command.js +9 -2
  114. package/dist/pipelineConteudo/help.d.ts +2 -0
  115. package/dist/pipelineConteudo/help.js +33 -0
  116. package/dist/profileAuthorCommand.js +3 -7
  117. package/dist/profileCommand.js +3 -7
  118. package/dist/projetoCarregar.js +35 -17
  119. package/dist/projetoCatalogo.d.ts +1 -0
  120. package/dist/projetoCatalogo.js +64 -25
  121. package/dist/projetoConfig.js +2 -0
  122. package/dist/projetoLegado.js +18 -0
  123. package/dist/projetoOrigens.d.ts +2 -0
  124. package/dist/projetoOrigens.js +65 -9
  125. package/dist/projetoTipos.d.ts +1 -0
  126. package/dist/resultadoCli.d.ts +20 -0
  127. package/dist/resultadoCli.js +57 -0
  128. package/dist/saidaCli.d.ts +35 -0
  129. package/dist/saidaCli.js +118 -0
  130. package/dist/sistemasInterativos/acceptanceEvidence.d.ts +22 -0
  131. package/dist/sistemasInterativos/acceptanceEvidence.js +345 -0
  132. package/dist/sistemasInterativos/engineObservation.d.ts +12 -0
  133. package/dist/sistemasInterativos/engineObservation.js +438 -0
  134. package/dist/sistemasInterativos/jobOrchestration.d.ts +2 -0
  135. package/dist/sistemasInterativos/jobOrchestration.js +204 -0
  136. package/dist/sistemasInterativos/operationPrimitives.d.ts +21 -0
  137. package/dist/sistemasInterativos/operationPrimitives.js +194 -0
  138. package/dist/sistemasInterativos/operations.d.ts +4 -39
  139. package/dist/sistemasInterativos/operations.js +5 -1164
  140. package/dist/skillCommand.d.ts +5 -0
  141. package/dist/skillCommand.js +88 -0
  142. package/dist/tipos.d.ts +1 -1
  143. package/dist/typescript-http-modelos.d.ts +1 -1
  144. package/dist/typescript-http-rotas.d.ts +1 -0
  145. package/dist/typescript-http-rotas.js +93 -0
  146. package/dist/typescript-http.d.ts +1 -1
  147. package/dist/typescript-http.js +1 -1
  148. package/dist/verificacaoCache.d.ts +25 -0
  149. package/dist/verificacaoCache.js +80 -0
  150. package/docs/README.md +34 -30
  151. package/docs/ai-integration.md +25 -12
  152. package/docs/ai-onboarding.md +37 -18
  153. package/docs/ai-workflow.md +9 -7
  154. package/docs/cli.md +125 -7
  155. package/docs/commands.md +41 -20
  156. package/docs/deploy.md +21 -8
  157. package/docs/descoberta-capacidades.md +106 -106
  158. package/docs/documentation.md +49 -39
  159. package/docs/drift-cache.md +108 -0
  160. package/docs/getting-started.md +43 -18
  161. package/docs/pipeline-conteudo.md +246 -246
  162. package/docs/profiles.md +54 -54
  163. package/docs/repositories.md +19 -2
  164. package/docs/rollback.md +15 -8
  165. package/docs/security.md +25 -3
  166. package/docs/sistemas-interativos.md +379 -374
  167. package/docs/syntax.md +14 -0
  168. package/docs/testing.md +139 -40
  169. package/exemplos/express_crud.sema +139 -0
  170. package/exemplos/fastify_crud.sema +146 -0
  171. package/exemplos/pipeline-conteudo/README.md +44 -44
  172. package/exemplos/pipeline-conteudo/alvos.json +23 -23
  173. package/exemplos/pipeline-conteudo/definicao.json +136 -136
  174. package/exemplos/profile_simulation.sema +211 -211
  175. package/exemplos/sistemas-interativos/README.md +100 -100
  176. package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -5
  177. package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -16
  178. package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -32
  179. package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -93
  180. package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -78
  181. package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -27
  182. package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -79
  183. package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -42
  184. package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -32
  185. package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -23
  186. package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -39
  187. package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -46
  188. package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -39
  189. package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -37
  190. package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -104
  191. package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -27
  192. package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -118
  193. package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -459
  194. package/exemplos/sistemas-interativos/game-2d.json +83 -83
  195. package/exemplos/sistemas-interativos/game-3d-human.json +81 -81
  196. package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -97
  197. package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -94
  198. package/exemplos/sistemas-interativos/game-xr-human.json +80 -80
  199. package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -108
  200. package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -75
  201. package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -58
  202. package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -97
  203. package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -141
  204. package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -112
  205. package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -103
  206. package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -95
  207. package/node_modules/@sema/gerador-cpp/package.json +1 -1
  208. package/node_modules/@sema/gerador-dotnet/package.json +1 -1
  209. package/node_modules/@sema/gerador-lua/dist/index.js +51 -51
  210. package/node_modules/@sema/gerador-php/dist/index.js +113 -113
  211. package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js +37 -38
  212. package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +1 -0
  213. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +1 -0
  214. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +1 -0
  215. package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.d.ts +7 -0
  216. package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js +33 -10
  217. package/package.json +9 -4
  218. package/scripts/postinstall.mjs +148 -0
  219. package/skills/sema/SKILL.md +199 -0
  220. package/skills/sema/agents/openai.yaml +4 -0
  221. package/dist/driftCache.d.ts +0 -49
  222. package/dist/driftCache.js +0 -311
  223. package/dist/driftCacheIncremental.d.ts +0 -98
  224. package/dist/driftCacheIncremental.js +0 -596
  225. package/dist/driftCatalogoPersistente.d.ts +0 -8
  226. package/dist/driftCatalogoPersistente.js +0 -77
  227. package/node_modules/@sema/gerador-cpp/dist/index.js.map +0 -1
  228. package/node_modules/@sema/gerador-css/dist/index.js.map +0 -1
  229. package/node_modules/@sema/gerador-css/dist/index.part01.js.map +0 -1
  230. package/node_modules/@sema/gerador-css/dist/index.part02.js.map +0 -1
  231. package/node_modules/@sema/gerador-dart/dist/index.js.map +0 -1
  232. package/node_modules/@sema/gerador-dotnet/dist/index.js.map +0 -1
  233. package/node_modules/@sema/gerador-html/dist/index.js.map +0 -1
  234. package/node_modules/@sema/gerador-javascript/dist/index.js.map +0 -1
  235. package/node_modules/@sema/gerador-lua/dist/index.js.map +0 -1
  236. package/node_modules/@sema/gerador-php/dist/index.js.map +0 -1
  237. package/node_modules/@sema/gerador-python/dist/index.js.map +0 -1
  238. package/node_modules/@sema/gerador-python/dist/index.part01.js.map +0 -1
  239. package/node_modules/@sema/gerador-python/dist/index.part02.js.map +0 -1
  240. package/node_modules/@sema/gerador-typescript/dist/index.js.map +0 -1
  241. package/node_modules/@sema/gerador-typescript/dist/index.part01.js.map +0 -1
  242. package/node_modules/@sema/gerador-typescript/dist/index.part02.js.map +0 -1
  243. package/node_modules/@sema/gerador-typescript/dist/index.part03.js.map +0 -1
  244. package/node_modules/@sema/nucleo/dist/ast/tipos.js.map +0 -1
  245. package/node_modules/@sema/nucleo/dist/diagnosticos/index.js.map +0 -1
  246. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js.map +0 -1
  247. package/node_modules/@sema/nucleo/dist/diagnosticos/snippets.js.map +0 -1
  248. package/node_modules/@sema/nucleo/dist/formatador/index.js.map +0 -1
  249. package/node_modules/@sema/nucleo/dist/formatador/index.part01.js.map +0 -1
  250. package/node_modules/@sema/nucleo/dist/formatador/index.part02.js.map +0 -1
  251. package/node_modules/@sema/nucleo/dist/index.js.map +0 -1
  252. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +0 -1
  253. package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js.map +0 -1
  254. package/node_modules/@sema/nucleo/dist/ir/conversor.part02.js.map +0 -1
  255. package/node_modules/@sema/nucleo/dist/ir/conversor.part03.js.map +0 -1
  256. package/node_modules/@sema/nucleo/dist/ir/modelos.js.map +0 -1
  257. package/node_modules/@sema/nucleo/dist/lexer/lexer.js.map +0 -1
  258. package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +0 -1
  259. package/node_modules/@sema/nucleo/dist/parser/parser.declaracoes.js.map +0 -1
  260. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +0 -1
  261. package/node_modules/@sema/nucleo/dist/parser/parser.modulo.js.map +0 -1
  262. package/node_modules/@sema/nucleo/dist/parser/parser.part01.js.map +0 -1
  263. package/node_modules/@sema/nucleo/dist/parser/parser.part02.js.map +0 -1
  264. package/node_modules/@sema/nucleo/dist/parser/parser.part03.js.map +0 -1
  265. package/node_modules/@sema/nucleo/dist/persistencia/contratos.js.map +0 -1
  266. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +0 -1
  267. package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js.map +0 -1
  268. package/node_modules/@sema/nucleo/dist/semantico/analisador.part02.js.map +0 -1
  269. package/node_modules/@sema/nucleo/dist/semantico/analisador.part03.js.map +0 -1
  270. package/node_modules/@sema/nucleo/dist/semantico/analisador.part04.js.map +0 -1
  271. package/node_modules/@sema/nucleo/dist/semantico/analisador.part05.js.map +0 -1
  272. package/node_modules/@sema/nucleo/dist/semantico/analisador.part06.js.map +0 -1
  273. package/node_modules/@sema/nucleo/dist/semantico/analisador.part07.js.map +0 -1
  274. package/node_modules/@sema/nucleo/dist/semantico/analisador.part08.js.map +0 -1
  275. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +0 -1
  276. package/node_modules/@sema/nucleo/dist/semantico/estruturas.part01.js.map +0 -1
  277. package/node_modules/@sema/nucleo/dist/semantico/estruturas.part02.js.map +0 -1
  278. package/node_modules/@sema/nucleo/dist/semantico/orcamentoSemantico.js.map +0 -1
  279. package/node_modules/@sema/nucleo/dist/semantico/seguranca.js.map +0 -1
  280. package/node_modules/@sema/nucleo/dist/util/arquivos.js.map +0 -1
  281. package/node_modules/@sema/padroes/dist/index.js.map +0 -1
@@ -2,18 +2,13 @@
2
2
  // Descricao: planeja o conjunto fisico minimo que pode ser indexado antes de qualquer caminhada de drift.
3
3
  import { lstat, realpath } from "node:fs/promises";
4
4
  import path from "node:path";
5
- import { resolverDiretoriosCodigoEscopoReal } from "./drift.part02.js";
5
+ import { filtrarCaminhosEscopoReal, resolverDiretoriosCodigoEscopoReal, } from "./drift.part02.js";
6
6
  import { candidatosReferenciaLocalDrift, extrairReferenciasLocaisDrift, raizesCodigoLogicasDrift, } from "./driftEscopoReferencias.js";
7
7
  export { extrairReferenciasLocaisDrift } from "./driftEscopoReferencias.js";
8
8
  const CONCORRENCIA_SONDAGENS_DRIFT = 16;
9
9
  const CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT = 8;
10
10
  const EXTENSAO_POR_ORIGEM = {
11
- // O indexador TypeScript tambem cobre JavaScript legado. Essa compatibilidade
12
- // e necessaria para contratos antigos que usam `ts:` para simbolos browser-side.
13
11
  ts: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
14
- // O resolvedor semantico trata JS/TS como a mesma familia. O planejamento
15
- // precisa sondar a mesma familia para nao descartar uma implementacao `js:`
16
- // escrita fisicamente em TypeScript antes de o resolvedor poder avalia-la.
17
12
  js: [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"],
18
13
  py: [".py"],
19
14
  dart: [".dart"],
@@ -25,6 +20,10 @@ const EXTENSAO_POR_ORIGEM = {
25
20
  cpp: [".cpp", ".cc", ".cxx", ".hpp", ".h"],
26
21
  php: [".php"],
27
22
  };
23
+ const EXTENSOES_CODIGO_PLANEJADO = new Set([
24
+ ...Object.values(EXTENSAO_POR_ORIGEM).flat(),
25
+ ".sql", ".psql", ".ddl", ".prisma",
26
+ ]);
28
27
  function chaveCaminho(caminho) {
29
28
  const absoluto = path.normalize(path.resolve(caminho));
30
29
  return process.platform === "win32" ? absoluto.toLowerCase() : absoluto;
@@ -35,6 +34,17 @@ function caminhoEstaDentro(raiz, alvo) {
35
34
  && !relativo.startsWith(`..${path.sep}`)
36
35
  && !path.isAbsolute(relativo));
37
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
+ }
38
48
  async function mapearComLimite(itens, limite, executar) {
39
49
  if (itens.length === 0) {
40
50
  return [];
@@ -56,12 +66,14 @@ async function mapearComLimite(itens, limite, executar) {
56
66
  }
57
67
  async function arquivoRegularContido(caminho, raizReal) {
58
68
  try {
59
- const informacao = await lstat(caminho);
60
- if (!informacao.isFile() || informacao.isSymbolicLink()) {
69
+ const informacaoAntes = await lstat(caminho, { bigint: true });
70
+ if (!informacaoAntes.isFile() || informacaoAntes.isSymbolicLink()) {
61
71
  return false;
62
72
  }
63
73
  const caminhoReal = await realpath(caminho);
64
- return caminhoEstaDentro(raizReal, caminhoReal);
74
+ const informacaoDepois = await lstat(caminho, { bigint: true });
75
+ return caminhoEstaDentro(raizReal, caminhoReal)
76
+ && identidadesArquivoIguais(informacaoAntes, informacaoDepois);
65
77
  }
66
78
  catch {
67
79
  return false;
@@ -87,17 +99,29 @@ function implementacoesModulo(ir) {
87
99
  ...ir.superficies.flatMap((superficie) => superficie.implementacoesExternas),
88
100
  ];
89
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
+ }
90
109
  function resolverArquivoWorkspace(baseProjeto, valor) {
91
110
  const absoluto = path.isAbsolute(valor)
92
111
  ? path.resolve(valor)
93
112
  : path.resolve(baseProjeto, valor);
94
113
  return caminhoEstaDentro(baseProjeto, absoluto) ? absoluto : undefined;
95
114
  }
115
+ function descreverArquivoForaWorkspace(valor) {
116
+ const nome = path.basename(path.normalize(valor)) || "alvo";
117
+ return `[fora_do_workspace]/${nome}`;
118
+ }
96
119
  function variantesSegmentoDiretorio(segmento) {
97
120
  const camel = segmento.replace(/_([a-z0-9])/gi, (_ocorrencia, caractere) => caractere.toUpperCase());
98
121
  return [...new Set([
99
122
  segmento,
100
123
  segmento.includes("_") ? segmento.replace(/_/g, "-") : undefined,
124
+ segmento.includes("_") && camel !== segmento ? camel : undefined,
101
125
  /(?:^|_)id$/i.test(segmento) ? `[${segmento}]` : undefined,
102
126
  /(?:^|_)id$/i.test(segmento) && camel !== segmento ? `[${camel}]` : undefined,
103
127
  ].filter((item) => Boolean(item)))];
@@ -125,6 +149,17 @@ function variantesNomeArquivo(segmento) {
125
149
  pascal && pascal !== segmento ? pascal : undefined,
126
150
  ].filter((item) => Boolean(item)))];
127
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
+ }
128
163
  function variantesCaminhoSegmentos(segmentos) {
129
164
  let variantes = [[]];
130
165
  for (const segmento of segmentos) {
@@ -133,24 +168,26 @@ function variantesCaminhoSegmentos(segmentos) {
133
168
  }
134
169
  return variantes.slice(0, 16);
135
170
  }
136
- function candidatosArquivoImpl(contexto, impl) {
137
- const candidatos = new Map();
138
- const adicionar = (caminho) => {
139
- adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
140
- };
171
+ function candidatosArquivoImpl(contexto, impl, diretoriosCodigo = contexto.diretoriosCodigo) {
172
+ const grupos = [];
141
173
  if (impl.origemArquivo) {
142
174
  const declarado = resolverArquivoWorkspace(contexto.baseProjeto, impl.origemArquivo);
143
175
  if (declarado) {
144
- adicionar(declarado);
176
+ grupos.push([declarado]);
145
177
  }
146
178
  }
147
179
  const partes = impl.caminho.split(".").map((parte) => parte.trim()).filter(Boolean);
148
180
  if (partes.length < 2) {
149
- return [...candidatos.values()];
181
+ return grupos;
150
182
  }
151
- const bases = [contexto.baseProjeto, ...contexto.diretoriosCodigo];
183
+ const bases = [...new Map([contexto.baseProjeto, ...diretoriosCodigo]
184
+ .map((base) => [chaveCaminho(base), base])).values()];
152
185
  const extensoes = EXTENSAO_POR_ORIGEM[impl.origem] ?? [];
153
186
  for (const removerCauda of [1, 2]) {
187
+ const candidatos = new Map();
188
+ const adicionar = (caminho) => {
189
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
190
+ };
154
191
  const segmentosOriginais = partes.slice(0, Math.max(1, partes.length - removerCauda));
155
192
  for (const base of bases) {
156
193
  const nomeBase = path.basename(base).toLowerCase();
@@ -173,10 +210,13 @@ function candidatosArquivoImpl(contexto, impl) {
173
210
  }
174
211
  }
175
212
  }
213
+ if (candidatos.size > 0) {
214
+ grupos.push([...candidatos.values()]);
215
+ }
176
216
  }
177
- return [...candidatos.values()];
217
+ return grupos;
178
218
  }
179
- function candidatosConsumerDeterministicos(contexto, irs, termosEscopo) {
219
+ function candidatosConsumerDeterministicos(contexto, irs, termosEscopo, diretoriosCodigo) {
180
220
  const segmentos = new Set();
181
221
  for (const termo of termosEscopo) {
182
222
  segmentos.add(termo);
@@ -191,7 +231,7 @@ function candidatosConsumerDeterministicos(contexto, irs, termosEscopo) {
191
231
  }
192
232
  const candidatos = new Map();
193
233
  const extensoes = [".ts", ".tsx", ".js", ".jsx"];
194
- for (const raiz of contexto.diretoriosCodigo) {
234
+ for (const raiz of diretoriosCodigo) {
195
235
  for (const segmento of segmentos) {
196
236
  for (const extensao of extensoes) {
197
237
  for (const relativo of [
@@ -200,15 +240,14 @@ function candidatosConsumerDeterministicos(contexto, irs, termosEscopo) {
200
240
  ["src", "pages", `${segmento}${extensao}`],
201
241
  ["pages", `${segmento}${extensao}`],
202
242
  ]) {
203
- const absoluto = path.resolve(raiz, ...relativo);
204
- adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, absoluto);
243
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, path.resolve(raiz, ...relativo));
205
244
  }
206
245
  }
207
246
  }
208
247
  }
209
248
  return [...candidatos.values()];
210
249
  }
211
- function candidatosRotasDeterministicos(contexto, irs) {
250
+ function candidatosRotasDeterministicos(contexto, irs, diretoriosCodigo) {
212
251
  const candidatos = new Map();
213
252
  const extensoes = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py"];
214
253
  const segmentos = new Set();
@@ -219,7 +258,7 @@ function candidatosRotasDeterministicos(contexto, irs) {
219
258
  }
220
259
  }
221
260
  }
222
- for (const raiz of contexto.diretoriosCodigo) {
261
+ for (const raiz of diretoriosCodigo) {
223
262
  for (const segmento of segmentos) {
224
263
  const nomes = variantesNomeArquivo(segmento);
225
264
  for (const nome of nomes) {
@@ -238,7 +277,7 @@ function candidatosRotasDeterministicos(contexto, irs) {
238
277
  }
239
278
  return [...candidatos.values()];
240
279
  }
241
- function candidatosConvencionaisEscopo(contexto, irs) {
280
+ function candidatosConvencionaisEscopo(contexto, irs, diretoriosCodigo) {
242
281
  const candidatos = new Map();
243
282
  const adicionar = (caminho) => {
244
283
  adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
@@ -247,7 +286,7 @@ function candidatosConvencionaisEscopo(contexto, irs) {
247
286
  const possuiRotas = irs.some((ir) => ir.routes.length > 0);
248
287
  const possuiPersistencia = irs.some((ir) => ir.databases.length > 0
249
288
  || ir.tasks.some((task) => task.effects.some((efeito) => /\b(?:db|database|persist|storage)\b/i.test(efeito))));
250
- const bases = [contexto.baseProjeto, ...contexto.diretoriosCodigo];
289
+ const bases = diretoriosCodigo;
251
290
  if (possuiRotas && origens.has("rust")) {
252
291
  for (const base of bases) {
253
292
  adicionar(path.join(base, "main.rs"));
@@ -266,19 +305,21 @@ function candidatosConvencionaisEscopo(contexto, irs) {
266
305
  }
267
306
  return [...candidatos.values()];
268
307
  }
269
- function escolherDiretoriosLogicos(contexto, arquivos) {
270
- const candidatos = [...new Map(contexto.diretoriosCodigo
308
+ function escolherDiretoriosLogicos(contexto, arquivos, diretoriosCodigo = contexto.diretoriosCodigo) {
309
+ const candidatos = [...new Map(diretoriosCodigo
271
310
  .map((diretorio) => path.resolve(diretorio))
272
311
  .map((diretorio) => [chaveCaminho(diretorio), diretorio])).values()]
273
312
  .sort((a, b) => b.length - a.length || a.localeCompare(b, "pt-BR"));
274
313
  const escolhidos = new Map();
275
314
  for (const arquivo of arquivos) {
276
- const raiz = candidatos.find((diretorio) => caminhoEstaDentro(diretorio, arquivo))
277
- ?? path.dirname(arquivo);
278
- escolhidos.set(chaveCaminho(raiz), raiz);
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);
279
321
  }
280
- return [...escolhidos.values()]
281
- .sort((a, b) => a.localeCompare(b, "pt-BR"));
322
+ return [...escolhidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
282
323
  }
283
324
  export async function planejarEscopoDrift(contexto, configuracao) {
284
325
  if (configuracao.escopo === "projeto") {
@@ -308,7 +349,9 @@ export async function planejarEscopoDrift(contexto, configuracao) {
308
349
  const declarados = new Map();
309
350
  const ausentes = new Map();
310
351
  const inferidos = new Map();
352
+ const bloqueiosPlano = new Set();
311
353
  const raizReal = await realpath(contexto.baseProjeto);
354
+ const diretoriosCodigoPermitidos = resolverDiretoriosCodigoPlanejados(contexto, irs, configuracao);
312
355
  const vinculosPlanejados = irs.flatMap((ir) => vinculosModulo(ir))
313
356
  .map((vinculo) => vinculo.arquivo ?? (vinculo.tipo === "arquivo" ? vinculo.valor : undefined))
314
357
  .filter((valor) => Boolean(valor))
@@ -318,49 +361,70 @@ export async function planejarEscopoDrift(contexto, configuracao) {
318
361
  }));
319
362
  const implementacoesPlanejadas = irs
320
363
  .flatMap((ir) => implementacoesModulo(ir))
321
- .map((impl) => candidatosArquivoImpl(contexto, impl));
322
- const candidatosDeterministicos = [
323
- ...candidatosConsumerDeterministicos(contexto, irs, configuracao.termosEscopo),
324
- ...candidatosRotasDeterministicos(contexto, irs),
325
- ...candidatosConvencionaisEscopo(contexto, irs),
326
- ];
364
+ .map((impl) => candidatosArquivoImpl(contexto, impl, diretoriosCodigoPermitidos));
327
365
  const resultadoSondagens = await sondarArquivosRegularesContidos([
328
366
  ...vinculosPlanejados.flatMap((vinculo) => vinculo.absoluto ? [vinculo.absoluto] : []),
329
- ...implementacoesPlanejadas.flat(),
330
- ...candidatosDeterministicos,
367
+ ...implementacoesPlanejadas.flat(2),
331
368
  ], raizReal);
332
369
  const arquivoExiste = (arquivo) => resultadoSondagens.get(chaveCaminho(arquivo)) === true;
333
370
  for (const vinculo of vinculosPlanejados) {
334
371
  if (!vinculo.absoluto) {
335
- ausentes.set(`fora:${vinculo.valor}`, vinculo.valor);
372
+ const descricaoSegura = descreverArquivoForaWorkspace(vinculo.valor);
373
+ ausentes.set(`fora:${descricaoSegura}`, descricaoSegura);
336
374
  continue;
337
375
  }
338
376
  if (arquivoExiste(vinculo.absoluto)) {
339
- const chave = chaveCaminho(vinculo.absoluto);
340
- if (!declarados.has(chave)) {
341
- declarados.set(chave, vinculo.absoluto);
342
- }
377
+ declarados.set(chaveCaminho(vinculo.absoluto), vinculo.absoluto);
343
378
  }
344
379
  else {
345
380
  ausentes.set(chaveCaminho(vinculo.absoluto), vinculo.absoluto);
346
381
  }
347
382
  }
348
- for (const candidatos of implementacoesPlanejadas) {
349
- const encontrados = candidatos.filter(arquivoExiste);
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
+ }
350
401
  for (const candidato of encontrados) {
351
402
  const chave = chaveCaminho(candidato);
352
403
  if (!declarados.has(chave) && !inferidos.has(chave)) {
353
404
  inferidos.set(chave, candidato);
354
405
  }
355
406
  }
356
- if (encontrados.length === 0 && candidatos[0]) {
357
- ausentes.set(chaveCaminho(candidatos[0]), candidatos[0]);
407
+ const primeiroCandidato = gruposCandidatos[0]?.[0];
408
+ if (encontrados.length === 0 && primeiroCandidato) {
409
+ ausentes.set(chaveCaminho(primeiroCandidato), primeiroCandidato);
358
410
  }
359
411
  }
360
- for (const candidato of candidatosDeterministicos.filter(arquivoExiste)) {
361
- const chave = chaveCaminho(candidato);
362
- if (!declarados.has(chave) && !inferidos.has(chave)) {
363
- inferidos.set(chave, candidato);
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
+ }
364
428
  }
365
429
  }
366
430
  const arquivosMesclados = new Map(declarados);
@@ -369,13 +433,15 @@ export async function planejarEscopoDrift(contexto, configuracao) {
369
433
  arquivosMesclados.set(chave, arquivo);
370
434
  }
371
435
  }
372
- const arquivos = [...arquivosMesclados.values()]
373
- .sort((a, b) => a.localeCompare(b, "pt-BR"));
374
- const arquivosAusentes = [...ausentes.values()]
375
- .sort((a, b) => a.localeCompare(b, "pt-BR"));
376
- const bloqueios = arquivos.length === 0
377
- ? ["escopo_estreito_sem_vinculos"]
378
- : [];
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"));
379
445
  return {
380
446
  escopo: configuracao.escopo,
381
447
  estrategia: "arquivos_vinculados",
@@ -417,43 +483,86 @@ async function arquivoRegularConfinadoDependencias(caminho, confinamento) {
417
483
  return false;
418
484
  }
419
485
  try {
420
- const informacao = await lstat(absoluto);
421
- if (!informacao.isFile() || informacao.isSymbolicLink()) {
486
+ const informacaoAntes = await lstat(absoluto, { bigint: true });
487
+ if (!informacaoAntes.isFile() || informacaoAntes.isSymbolicLink()) {
422
488
  return false;
423
489
  }
424
490
  const caminhoReal = await realpath(absoluto);
491
+ const informacaoDepois = await lstat(absoluto, { bigint: true });
425
492
  return caminhoEstaDentro(confinamento.raizWorkspaceReal, caminhoReal)
426
- && confinamento.raizesCodigoReais.some((raiz) => caminhoEstaDentro(raiz, caminhoReal));
493
+ && confinamento.raizesCodigoReais.some((raiz) => caminhoEstaDentro(raiz, caminhoReal))
494
+ && identidadesArquivoIguais(informacaoAntes, informacaoDepois);
427
495
  }
428
496
  catch {
429
497
  return false;
430
498
  }
431
499
  }
432
- async function resolverReferenciaLocalExistente(contexto, arquivoOrigem, referencia, confinamento, catalogados) {
433
- for (const candidatoBruto of candidatosReferenciaLocalDrift(contexto, arquivoOrigem, referencia)) {
434
- const candidato = catalogados?.get(chaveCaminho(candidatoBruto)) ?? candidatoBruto;
435
- if (catalogados && !catalogados.has(chaveCaminho(candidatoBruto))) {
436
- continue;
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
+ }
437
514
  }
438
- if (await arquivoRegularConfinadoDependencias(candidato, confinamento)) {
439
- return candidato;
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;
440
529
  }
441
- }
442
- return undefined;
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
+ });
443
552
  }
444
- export async function expandirDependenciasPlanoDrift(contexto, plano, catalogo, cache) {
553
+ export async function expandirDependenciasPlanoDrift(contexto, plano, catalogo) {
445
554
  if (plano.estrategia !== "arquivos_vinculados" || plano.arquivos.length === 0) {
446
555
  return plano;
447
556
  }
448
557
  const arquivos = new Map(plano.arquivos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
449
558
  const inferidos = new Map(plano.arquivosInferidos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
559
+ const ausentes = new Map(plano.arquivosAusentes.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
450
560
  const visitados = new Set();
451
561
  const fila = [...plano.arquivos];
452
562
  const confinamento = await construirConfinamentoDependencias(contexto);
453
563
  const dependencias = new Map(Object.entries(plano.dependencias).map(([arquivo, itens]) => [arquivo, new Set(itens)]));
454
564
  while (fila.length > 0) {
455
- const lote = fila.splice(0)
456
- .filter((arquivo) => {
565
+ const lote = fila.splice(0).filter((arquivo) => {
457
566
  const chave = chaveCaminho(arquivo);
458
567
  if (visitados.has(chave)) {
459
568
  return false;
@@ -462,102 +571,77 @@ export async function expandirDependenciasPlanoDrift(contexto, plano, catalogo,
462
571
  return true;
463
572
  });
464
573
  const resultadosLote = await mapearComLimite(lote, CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT, async (arquivo) => {
465
- let referencias;
466
574
  try {
467
- if (cache) {
468
- const estado = await cache.resolverArquivo({
469
- arquivo,
470
- analise: "dependencias-v4",
471
- ler: () => catalogo.ler(arquivo),
472
- extrair: (conteudo) => extrairReferenciasLocaisDrift(conteudo.texto),
473
- validar: (valor) => Array.isArray(valor) && valor.every((item) => typeof item === "string"),
474
- });
475
- referencias = estado.valor;
476
- }
477
- else {
478
- referencias = extrairReferenciasLocaisDrift(await catalogo.lerTexto(arquivo));
479
- }
575
+ const referencias = extrairReferenciasLocaisDrift(await catalogo.lerTexto(arquivo), { contexto, arquivoOrigem: arquivo });
576
+ return {
577
+ arquivo,
578
+ referencias: await resolverReferenciasLocais(contexto, arquivo, referencias, confinamento),
579
+ };
480
580
  }
481
581
  catch {
482
- return { arquivo, resolvidas: [] };
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);
483
593
  }
484
- const resolvidas = new Map();
485
- for (const referencia of referencias) {
486
- const candidato = await resolverReferenciaLocalExistente(contexto, arquivo, referencia, confinamento);
487
- if (candidato) {
488
- resolvidas.set(chaveCaminho(candidato), candidato);
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);
489
600
  }
490
601
  }
491
- return { arquivo, resolvidas: [...resolvidas.values()] };
492
- });
602
+ }
603
+ await catalogo.incluir([...candidatosParaIncluir.values()]);
493
604
  const novos = new Map();
494
- for (const { arquivo, resolvidas } of resultadosLote) {
495
- if (resolvidas.length > 0) {
496
- const lista = dependencias.get(arquivo) ?? new Set();
497
- for (const candidato of resolvidas) {
498
- lista.add(candidato);
499
- const chave = chaveCaminho(candidato);
500
- if (!arquivos.has(chave)) {
501
- novos.set(chave, candidato);
502
- }
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);
503
619
  }
504
- dependencias.set(arquivo, lista);
505
620
  }
506
- }
507
- if (novos.size > 0) {
508
- const novosOrdenados = [...novos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
509
- await catalogo.incluir(novosOrdenados);
510
- for (const candidato of novosOrdenados) {
511
- const chave = chaveCaminho(candidato);
512
- arquivos.set(chave, candidato);
513
- inferidos.set(chave, candidato);
514
- fila.push(candidato);
621
+ if (lista.size > 0) {
622
+ dependencias.set(resultado.arquivo, lista);
515
623
  }
516
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
+ }
517
632
  }
518
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"));
519
635
  return {
520
636
  ...plano,
521
637
  arquivos: arquivosExpandidos,
522
638
  arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
639
+ arquivosAusentes,
523
640
  diretorios: escolherDiretoriosLogicos(contexto, arquivosExpandidos),
641
+ cobertura: arquivosAusentes.length === 0 && plano.bloqueios.length === 0 ? "completa" : "parcial",
524
642
  dependencias: Object.fromEntries([...dependencias.entries()]
525
643
  .sort(([a], [b]) => a.localeCompare(b, "pt-BR"))
526
644
  .map(([arquivo, itens]) => [arquivo, [...itens].sort((a, b) => a.localeCompare(b, "pt-BR"))])),
527
645
  };
528
646
  }
529
- export async function mapearDependenciasCatalogadasDrift(contexto, catalogo, cache, arquivos = catalogo.arquivosCatalogados()) {
530
- const confinamento = await construirConfinamentoDependencias(contexto);
531
- const catalogados = new Map(catalogo.arquivosCatalogados().map((arquivo) => [chaveCaminho(arquivo), arquivo]));
532
- const arquivosOrdenados = [...arquivos].sort((a, b) => a.localeCompare(b, "pt-BR"));
533
- const resultados = await mapearComLimite(arquivosOrdenados, CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT, async (arquivo) => {
534
- let referencias;
535
- try {
536
- const estado = await cache.resolverArquivo({
537
- arquivo,
538
- analise: "dependencias-v4",
539
- ler: () => catalogo.ler(arquivo),
540
- extrair: (conteudo) => extrairReferenciasLocaisDrift(conteudo.texto),
541
- validar: (valor) => Array.isArray(valor) && valor.every((item) => typeof item === "string"),
542
- });
543
- referencias = estado.valor;
544
- }
545
- catch {
546
- return undefined;
547
- }
548
- const resolvidas = new Map();
549
- for (const referencia of referencias) {
550
- const existente = await resolverReferenciaLocalExistente(contexto, arquivo, referencia, confinamento, catalogados);
551
- if (existente) {
552
- resolvidas.set(chaveCaminho(existente), existente);
553
- }
554
- }
555
- return [
556
- arquivo,
557
- [...resolvidas.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
558
- ];
559
- });
560
- const dependencias = new Map(resultados.filter((item) => Boolean(item)));
561
- return Object.fromEntries([...dependencias.entries()].sort(([a], [b]) => a.localeCompare(b, "pt-BR")));
562
- }
563
647
  //# sourceMappingURL=driftEscopo.js.map
@@ -1,4 +1,8 @@
1
1
  import type { ContextoProjetoCarregado } from "./projeto.js";
2
- export declare function extrairReferenciasLocaisDrift(codigo: string): string[];
2
+ export interface OpcoesExtracaoReferenciasDrift {
3
+ contexto?: ContextoProjetoCarregado;
4
+ arquivoOrigem?: string;
5
+ }
6
+ export declare function extrairReferenciasLocaisDrift(codigo: string, opcoes?: OpcoesExtracaoReferenciasDrift): string[];
3
7
  export declare function raizesCodigoLogicasDrift(contexto: ContextoProjetoCarregado): string[];
4
8
  export declare function candidatosReferenciaLocalDrift(contexto: ContextoProjetoCarregado, arquivoOrigem: string, referencia: string): string[];