@semacode/cli 2.3.1 → 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 (250) 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 +567 -557
  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/drift.part01.d.ts +26 -24
  45. package/dist/drift.part01.js +2 -1
  46. package/dist/drift.part04.d.ts +12 -3
  47. package/dist/drift.part04.js +88 -17
  48. package/dist/drift.part05.d.ts +2 -2
  49. package/dist/drift.part05.js +8 -6
  50. package/dist/drift.part06.d.ts +2 -2
  51. package/dist/drift.part06.js +113 -26
  52. package/dist/drift.part07.d.ts +11 -11
  53. package/dist/drift.part07.js +261 -265
  54. package/dist/drift.part08.d.ts +2 -2
  55. package/dist/drift.part08.js +35 -26
  56. package/dist/drift.part11.js +238 -56
  57. package/dist/drift.part12.d.ts +1 -1
  58. package/dist/drift.part12.js +193 -21
  59. package/dist/drift.part13.d.ts +20 -39
  60. package/dist/drift.part13.js +601 -647
  61. package/dist/drift.part14.js +21 -7
  62. package/dist/driftCacheCas.d.ts +43 -0
  63. package/dist/driftCacheCas.js +351 -0
  64. package/dist/driftCacheFilesystem.d.ts +64 -0
  65. package/dist/driftCacheFilesystem.js +313 -0
  66. package/dist/driftCacheModes.d.ts +38 -0
  67. package/dist/driftCacheModes.js +147 -0
  68. package/dist/driftCacheStore.d.ts +80 -0
  69. package/dist/driftCacheStore.js +603 -0
  70. package/dist/driftCatalogo.d.ts +2 -28
  71. package/dist/driftCatalogo.js +143 -284
  72. package/dist/driftEscopo.d.ts +1 -3
  73. package/dist/driftEscopo.js +235 -151
  74. package/dist/driftEscopoReferencias.d.ts +5 -1
  75. package/dist/driftEscopoReferencias.js +375 -28
  76. package/dist/driftOrcamento.d.ts +0 -6
  77. package/dist/driftOrcamento.js +2 -1
  78. package/dist/execucoesExternas.js +19 -5
  79. package/dist/geracaoCore.js +4 -6
  80. package/dist/iaPrompts.d.ts +3 -3
  81. package/dist/iaPrompts.js +312 -313
  82. package/dist/index.d.ts +4 -1
  83. package/dist/index.js +6 -25
  84. package/dist/index.part01.d.ts +20 -28
  85. package/dist/index.part01.js +16 -237
  86. package/dist/index.part02.js +36 -22
  87. package/dist/index.part03.d.ts +24 -2
  88. package/dist/index.part03.js +83 -19
  89. package/dist/index.part04.d.ts +10 -2
  90. package/dist/index.part04.js +142 -120
  91. package/dist/index.part05.js +80 -78
  92. package/dist/index.part06.js +34 -17
  93. package/dist/index.part07.js +7 -3
  94. package/dist/index.part08.d.ts +1 -1
  95. package/dist/index.part08.js +22 -27
  96. package/dist/initCommand.js +5 -1
  97. package/dist/initTemplatesBase.js +81 -79
  98. package/dist/pipelineConteudo/command.d.ts +1 -0
  99. package/dist/pipelineConteudo/command.js +9 -2
  100. package/dist/pipelineConteudo/help.d.ts +2 -0
  101. package/dist/pipelineConteudo/help.js +33 -0
  102. package/dist/profileAuthorCommand.js +3 -7
  103. package/dist/profileCommand.js +3 -7
  104. package/dist/projetoCarregar.js +35 -17
  105. package/dist/projetoCatalogo.d.ts +1 -0
  106. package/dist/projetoCatalogo.js +64 -25
  107. package/dist/projetoOrigens.d.ts +2 -0
  108. package/dist/projetoOrigens.js +65 -9
  109. package/dist/projetoTipos.d.ts +1 -0
  110. package/dist/resultadoCli.d.ts +20 -0
  111. package/dist/resultadoCli.js +57 -0
  112. package/dist/saidaCli.d.ts +35 -0
  113. package/dist/saidaCli.js +118 -0
  114. package/dist/sistemasInterativos/acceptanceEvidence.d.ts +22 -0
  115. package/dist/sistemasInterativos/acceptanceEvidence.js +345 -0
  116. package/dist/sistemasInterativos/engineObservation.d.ts +12 -0
  117. package/dist/sistemasInterativos/engineObservation.js +438 -0
  118. package/dist/sistemasInterativos/jobOrchestration.d.ts +2 -0
  119. package/dist/sistemasInterativos/jobOrchestration.js +204 -0
  120. package/dist/sistemasInterativos/operationPrimitives.d.ts +21 -0
  121. package/dist/sistemasInterativos/operationPrimitives.js +194 -0
  122. package/dist/sistemasInterativos/operations.d.ts +4 -39
  123. package/dist/sistemasInterativos/operations.js +5 -1164
  124. package/dist/skillCommand.d.ts +5 -0
  125. package/dist/skillCommand.js +88 -0
  126. package/docs/README.md +34 -30
  127. package/docs/ai-integration.md +25 -12
  128. package/docs/ai-onboarding.md +37 -18
  129. package/docs/ai-workflow.md +9 -7
  130. package/docs/cli.md +125 -7
  131. package/docs/commands.md +41 -20
  132. package/docs/deploy.md +21 -8
  133. package/docs/descoberta-capacidades.md +106 -106
  134. package/docs/documentation.md +49 -39
  135. package/docs/drift-cache.md +108 -0
  136. package/docs/getting-started.md +43 -18
  137. package/docs/pipeline-conteudo.md +246 -246
  138. package/docs/profiles.md +54 -54
  139. package/docs/repositories.md +19 -2
  140. package/docs/rollback.md +15 -8
  141. package/docs/security.md +25 -3
  142. package/docs/sistemas-interativos.md +379 -374
  143. package/docs/testing.md +139 -40
  144. package/exemplos/pipeline-conteudo/README.md +44 -44
  145. package/exemplos/pipeline-conteudo/alvos.json +23 -23
  146. package/exemplos/pipeline-conteudo/definicao.json +136 -136
  147. package/exemplos/profile_simulation.sema +211 -211
  148. package/exemplos/sistemas-interativos/README.md +100 -100
  149. package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -5
  150. package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -16
  151. package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -32
  152. package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -93
  153. package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -78
  154. package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -27
  155. package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -79
  156. package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -42
  157. package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -32
  158. package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -23
  159. package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -39
  160. package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -46
  161. package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -39
  162. package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -37
  163. package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -104
  164. package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -27
  165. package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -118
  166. package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -459
  167. package/exemplos/sistemas-interativos/game-2d.json +83 -83
  168. package/exemplos/sistemas-interativos/game-3d-human.json +81 -81
  169. package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -97
  170. package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -94
  171. package/exemplos/sistemas-interativos/game-xr-human.json +80 -80
  172. package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -108
  173. package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -75
  174. package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -58
  175. package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -97
  176. package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -141
  177. package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -112
  178. package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -103
  179. package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -95
  180. package/node_modules/@sema/gerador-cpp/package.json +1 -1
  181. package/node_modules/@sema/gerador-dotnet/package.json +1 -1
  182. package/node_modules/@sema/gerador-lua/dist/index.js +51 -51
  183. package/node_modules/@sema/gerador-php/dist/index.js +113 -113
  184. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +1 -0
  185. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +1 -0
  186. package/package.json +9 -4
  187. package/scripts/postinstall.mjs +148 -0
  188. package/skills/sema/SKILL.md +199 -0
  189. package/skills/sema/agents/openai.yaml +4 -0
  190. package/dist/driftCache.d.ts +0 -49
  191. package/dist/driftCache.js +0 -311
  192. package/dist/driftCacheIncremental.d.ts +0 -98
  193. package/dist/driftCacheIncremental.js +0 -596
  194. package/dist/driftCatalogoPersistente.d.ts +0 -8
  195. package/dist/driftCatalogoPersistente.js +0 -77
  196. package/node_modules/@sema/gerador-cpp/dist/index.js.map +0 -1
  197. package/node_modules/@sema/gerador-css/dist/index.js.map +0 -1
  198. package/node_modules/@sema/gerador-css/dist/index.part01.js.map +0 -1
  199. package/node_modules/@sema/gerador-css/dist/index.part02.js.map +0 -1
  200. package/node_modules/@sema/gerador-dart/dist/index.js.map +0 -1
  201. package/node_modules/@sema/gerador-dotnet/dist/index.js.map +0 -1
  202. package/node_modules/@sema/gerador-html/dist/index.js.map +0 -1
  203. package/node_modules/@sema/gerador-javascript/dist/index.js.map +0 -1
  204. package/node_modules/@sema/gerador-lua/dist/index.js.map +0 -1
  205. package/node_modules/@sema/gerador-php/dist/index.js.map +0 -1
  206. package/node_modules/@sema/gerador-python/dist/index.js.map +0 -1
  207. package/node_modules/@sema/gerador-python/dist/index.part01.js.map +0 -1
  208. package/node_modules/@sema/gerador-python/dist/index.part02.js.map +0 -1
  209. package/node_modules/@sema/gerador-typescript/dist/index.js.map +0 -1
  210. package/node_modules/@sema/gerador-typescript/dist/index.part01.js.map +0 -1
  211. package/node_modules/@sema/gerador-typescript/dist/index.part02.js.map +0 -1
  212. package/node_modules/@sema/gerador-typescript/dist/index.part03.js.map +0 -1
  213. package/node_modules/@sema/nucleo/dist/ast/tipos.js.map +0 -1
  214. package/node_modules/@sema/nucleo/dist/diagnosticos/index.js.map +0 -1
  215. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js.map +0 -1
  216. package/node_modules/@sema/nucleo/dist/diagnosticos/snippets.js.map +0 -1
  217. package/node_modules/@sema/nucleo/dist/formatador/index.js.map +0 -1
  218. package/node_modules/@sema/nucleo/dist/formatador/index.part01.js.map +0 -1
  219. package/node_modules/@sema/nucleo/dist/formatador/index.part02.js.map +0 -1
  220. package/node_modules/@sema/nucleo/dist/index.js.map +0 -1
  221. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +0 -1
  222. package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js.map +0 -1
  223. package/node_modules/@sema/nucleo/dist/ir/conversor.part02.js.map +0 -1
  224. package/node_modules/@sema/nucleo/dist/ir/conversor.part03.js.map +0 -1
  225. package/node_modules/@sema/nucleo/dist/ir/modelos.js.map +0 -1
  226. package/node_modules/@sema/nucleo/dist/lexer/lexer.js.map +0 -1
  227. package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +0 -1
  228. package/node_modules/@sema/nucleo/dist/parser/parser.declaracoes.js.map +0 -1
  229. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +0 -1
  230. package/node_modules/@sema/nucleo/dist/parser/parser.modulo.js.map +0 -1
  231. package/node_modules/@sema/nucleo/dist/parser/parser.part01.js.map +0 -1
  232. package/node_modules/@sema/nucleo/dist/parser/parser.part02.js.map +0 -1
  233. package/node_modules/@sema/nucleo/dist/parser/parser.part03.js.map +0 -1
  234. package/node_modules/@sema/nucleo/dist/persistencia/contratos.js.map +0 -1
  235. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +0 -1
  236. package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js.map +0 -1
  237. package/node_modules/@sema/nucleo/dist/semantico/analisador.part02.js.map +0 -1
  238. package/node_modules/@sema/nucleo/dist/semantico/analisador.part03.js.map +0 -1
  239. package/node_modules/@sema/nucleo/dist/semantico/analisador.part04.js.map +0 -1
  240. package/node_modules/@sema/nucleo/dist/semantico/analisador.part05.js.map +0 -1
  241. package/node_modules/@sema/nucleo/dist/semantico/analisador.part06.js.map +0 -1
  242. package/node_modules/@sema/nucleo/dist/semantico/analisador.part07.js.map +0 -1
  243. package/node_modules/@sema/nucleo/dist/semantico/analisador.part08.js.map +0 -1
  244. package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +0 -1
  245. package/node_modules/@sema/nucleo/dist/semantico/estruturas.part01.js.map +0 -1
  246. package/node_modules/@sema/nucleo/dist/semantico/estruturas.part02.js.map +0 -1
  247. package/node_modules/@sema/nucleo/dist/semantico/orcamentoSemantico.js.map +0 -1
  248. package/node_modules/@sema/nucleo/dist/semantico/seguranca.js.map +0 -1
  249. package/node_modules/@sema/nucleo/dist/util/arquivos.js.map +0 -1
  250. package/node_modules/@sema/padroes/dist/index.js.map +0 -1
@@ -1,242 +1,432 @@
1
- // SEMA-GOVERNED: sema.produto.governanca_ia.drift
2
- // Descricao: planeja antes de catalogar e indexa unidades incrementais com uma unica leitura fisica por arquivo.
3
- import pacoteCli from "../package.json" with { type: "json" };
1
+ // SEMA-GOVERNED: sema.produto.governanca_ia.drift, sema.produto.governanca_ia.drift.cache.store
2
+ // Descrição: planeja o escopo físico, cataloga uma vez e reutiliza extrações validadas sem escrever no workspace.
4
3
  import path from "node:path";
5
- import { performance } from "node:perf_hooks";
6
4
  import ts from "typescript";
7
- import { resolverDiretoriosIgnoradosAtivos } from "./drift.part01.js";
8
- import { EXTENSOES_ARQUIVOS_RASTREAVEIS_DRIFT, indexarArquivosRastreaveis } from "./drift.part04.js";
5
+ import pacoteCli from "../package.json" with { type: "json" };
6
+ import { resolverDiretoriosIgnoradosAtivos, } from "./drift.part01.js";
7
+ import { EXTENSOES_ARQUIVOS_RASTREAVEIS_DRIFT, chaveCaminhoCanonicoDrift, } from "./drift.part04.js";
9
8
  import { indexarTypeScript } from "./drift.part06.js";
10
9
  import { indexarCpp, indexarDart, indexarDotnet, indexarGo, indexarJava, indexarLua, indexarPersistenciaDeclarativa, indexarPhp, indexarPython, indexarRust, } from "./drift.part07.js";
11
10
  import { indexarPersistenciaDetalhada } from "./drift.part08.js";
12
- import { construirMapaRecursos } from "./drift.part10.js";
13
- import { emitirDiagnosticosArquivosOrcamento, workspaceExigeCabecalhoCodigoGovernado, } from "./driftOrcamento.js";
14
- import { criarCatalogoPersistenteDrift } from "./driftCatalogoPersistente.js";
15
- import { CacheIncrementalDrift, FILE_INDEX_SCHEMA, } from "./driftCacheIncremental.js";
16
- import { expandirDependenciasPlanoDrift, extrairReferenciasLocaisDrift, mapearDependenciasCatalogadasDrift, planejarEscopoDrift, } from "./driftEscopo.js";
17
- const EXTENSOES_ANALISE_DRIFT = new Set([
18
- ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
19
- ".py", ".dart", ".lua", ".cs", ".java", ".go", ".rs", ".php",
20
- ".cpp", ".cc", ".cxx", ".hpp", ".h",
21
- ".sql", ".psql", ".ddl", ".prisma",
22
- ]);
23
- const EXTENSOES_TYPESCRIPT_DRIFT = new Set([
24
- ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs",
25
- ]);
26
- const EXTENSOES_DEPENDENCIA_TYPESCRIPT_DRIFT = new Set([
27
- ...EXTENSOES_TYPESCRIPT_DRIFT,
28
- ".html", ".htm", ".css",
29
- ]);
30
- function chaveCaminho(caminho) {
31
- const absoluto = path.normalize(path.resolve(caminho));
32
- return process.platform === "win32" ? absoluto.toLowerCase() : absoluto;
33
- }
34
- function chaveRelativa(caminho) {
35
- const normalizado = caminho.replace(/\\/g, "/");
36
- return process.platform === "win32" ? normalizado.toLowerCase() : normalizado;
37
- }
38
- function paraJsonCache(valor) {
39
- return JSON.parse(JSON.stringify(valor));
40
- }
41
- function registroObjeto(valor) {
42
- return typeof valor === "object" && valor !== null && !Array.isArray(valor);
43
- }
44
- function textoNaoVazio(valor) {
45
- return typeof valor === "string" && valor.length > 0;
46
- }
47
- function pertenceAoConjunto(valor, conjunto) {
48
- return typeof valor === "string" && conjunto.has(valor);
49
- }
50
- function inteiroNaoNegativo(valor) {
51
- return typeof valor === "number" && Number.isSafeInteger(valor) && valor >= 0;
52
- }
53
- const ORIGENS_SIMBOLO_DRIFT = new Set([
54
- "ts", "js", "py", "dart", "lua", "cs", "java", "go", "rust", "cpp", "php", "sql",
55
- ]);
56
- const ORIGENS_ROTA_DRIFT = new Set([
57
- "nestjs", "fastapi", "flask", "nextjs", "nextjs-consumer", "react-vite-consumer",
58
- "angular-consumer", "flutter-consumer", "firebase", "dotnet", "java", "go", "rust", "php",
59
- ]);
60
- const ORIGENS_RECURSO_DRIFT = new Set([
61
- "firebase", "postgres", "mysql", "sqlite", "mongodb", "redis", "arquivo",
62
- ]);
63
- const TIPOS_RECURSO_DRIFT = new Set([
64
- "colecao", "arquivo_local", "table", "view", "query", "transaction", "index", "constraint",
65
- "relationship", "collection", "document", "keyspace", "stream", "lock", "retention", "replication",
66
- ]);
67
- const CATEGORIAS_PERSISTENCIA_DRIFT = new Set([
68
- "relacional", "documental", "chave_valor", "local_arquivo", "desconhecida",
69
- ]);
70
- const TIPOS_DIAGNOSTICO_ORCAMENTO = new Set([
71
- "contrato_monolitico", "codigo_monolitico", "codigo_governado_sem_cabecalho",
72
- ]);
73
- function simboloResolvidoValido(valor) {
74
- return registroObjeto(valor)
75
- && pertenceAoConjunto(valor.origem, ORIGENS_SIMBOLO_DRIFT)
76
- && textoNaoVazio(valor.caminho)
77
- && textoNaoVazio(valor.arquivo)
78
- && textoNaoVazio(valor.simbolo);
79
- }
80
- function rotaResolvidaValida(valor) {
81
- return registroObjeto(valor)
82
- && pertenceAoConjunto(valor.origem, ORIGENS_ROTA_DRIFT)
83
- && textoNaoVazio(valor.metodo)
84
- && textoNaoVazio(valor.caminho)
85
- && textoNaoVazio(valor.arquivo)
86
- && textoNaoVazio(valor.simbolo);
87
- }
88
- function recursoResolvidoValido(valor) {
89
- return registroObjeto(valor)
90
- && pertenceAoConjunto(valor.origem, ORIGENS_RECURSO_DRIFT)
91
- && textoNaoVazio(valor.nome)
92
- && textoNaoVazio(valor.arquivo)
93
- && (valor.simbolo === undefined || textoNaoVazio(valor.simbolo))
94
- && pertenceAoConjunto(valor.tipo, TIPOS_RECURSO_DRIFT);
95
- }
96
- function consumerSurfaceValida(valor) {
97
- return registroObjeto(valor)
98
- && textoNaoVazio(valor.rota)
99
- && textoNaoVazio(valor.arquivo)
100
- && textoNaoVazio(valor.tipoArquivo);
101
- }
102
- function colunaPersistenciaValida(valor) {
103
- return registroObjeto(valor)
104
- && pertenceAoConjunto(valor.origem, ORIGENS_RECURSO_DRIFT)
105
- && pertenceAoConjunto(valor.categoriaPersistencia, CATEGORIAS_PERSISTENCIA_DRIFT)
106
- && textoNaoVazio(valor.recurso)
107
- && textoNaoVazio(valor.coluna)
108
- && textoNaoVazio(valor.arquivo);
109
- }
110
- function repositorioPersistenciaValido(valor) {
111
- return registroObjeto(valor)
112
- && pertenceAoConjunto(valor.origem, ORIGENS_RECURSO_DRIFT)
113
- && pertenceAoConjunto(valor.categoriaPersistencia, CATEGORIAS_PERSISTENCIA_DRIFT)
114
- && textoNaoVazio(valor.recurso)
115
- && textoNaoVazio(valor.arquivo);
116
- }
117
- function diagnosticoOrcamentoValido(valor) {
118
- return registroObjeto(valor)
119
- && pertenceAoConjunto(valor.tipo, TIPOS_DIAGNOSTICO_ORCAMENTO)
120
- && textoNaoVazio(valor.arquivo)
121
- && inteiroNaoNegativo(valor.linhas)
122
- && (valor.severidade === "aviso" || valor.severidade === "erro")
123
- && typeof valor.bloqueia === "boolean"
124
- && textoNaoVazio(valor.mensagem)
125
- && inteiroNaoNegativo(valor.limite_aviso_linhas)
126
- && inteiroNaoNegativo(valor.limite_bloqueio_linhas);
127
- }
128
- function listaValida(valor, validar) {
129
- return Array.isArray(valor) && valor.every(validar);
130
- }
131
- function indiceLinguagemValido(valor) {
132
- return registroObjeto(valor)
133
- && listaValida(valor.simbolos, simboloResolvidoValido)
134
- && listaValida(valor.rotas, rotaResolvidaValida)
135
- && listaValida(valor.recursos, recursoResolvidoValido)
136
- && Array.isArray(valor.consumerSurfaces)
137
- && valor.consumerSurfaces.every(consumerSurfaceValida);
138
- }
139
- function validarIndicesSerializaveis(valor) {
140
- if (!registroObjeto(valor) || !registroObjeto(valor.detalhesPersistencia)) {
141
- return false;
142
- }
143
- const detalhes = valor.detalhesPersistencia;
144
- return listaValida(detalhes.colunas, colunaPersistenciaValida)
145
- && listaValida(detalhes.repositorios, repositorioPersistenciaValido)
146
- && Array.isArray(valor.arquivosOrcamentoAvaliados)
147
- && valor.arquivosOrcamentoAvaliados.every(textoNaoVazio)
148
- && listaValida(valor.diagnosticosOrcamento, diagnosticoOrcamentoValido)
149
- && indiceLinguagemValido(valor.indexDart)
150
- && indiceLinguagemValido(valor.indexTs)
151
- && listaValida(valor.todasRotasIndexadas, rotaResolvidaValida)
152
- && Array.isArray(valor.todosArquivosConhecidos)
153
- && valor.todosArquivosConhecidos.every(textoNaoVazio)
154
- && listaValida(valor.todosRecursos, recursoResolvidoValido)
155
- && listaValida(valor.todosSimbolos, simboloResolvidoValido);
156
- }
157
- function indicesPermanecemNoCatalogo(valor, catalogo) {
158
- const registros = [
159
- ...valor.detalhesPersistencia.colunas,
160
- ...valor.detalhesPersistencia.repositorios,
161
- ...valor.indexDart.simbolos,
162
- ...valor.indexDart.rotas,
163
- ...valor.indexDart.recursos,
164
- ...valor.indexDart.consumerSurfaces,
165
- ...valor.indexTs.simbolos,
166
- ...valor.indexTs.rotas,
167
- ...valor.indexTs.recursos,
168
- ...valor.indexTs.consumerSurfaces,
169
- ...valor.todasRotasIndexadas,
170
- ...valor.todosRecursos,
171
- ...valor.todosSimbolos,
172
- ];
173
- return registros.every((item) => catalogo.contem(item.arquivo))
174
- && valor.todosArquivosConhecidos.every((arquivo) => catalogo.contem(arquivo))
175
- && valor.arquivosOrcamentoAvaliados.every((arquivo) => catalogo.contem(path.resolve(catalogo.baseDiretorio, arquivo)))
176
- && valor.diagnosticosOrcamento.every((item) => catalogo.contem(path.resolve(catalogo.baseDiretorio, item.arquivo)));
177
- }
178
- function reconstruirIndices(serializaveis, planoEscopo, cache, catalogo, leitorArquivosPlanejados) {
179
- const mapaImpl = new Map(serializaveis.todosSimbolos
180
- .filter((item) => item.origem !== "sql")
181
- .map((item) => [item.caminho, item]));
11
+ import { coletarVinculosIr, construirMapaRecursos } from "./drift.part10.js";
12
+ import { criarCatalogoDrift, } from "./driftCatalogo.js";
13
+ import { expandirDependenciasPlanoDrift, planejarEscopoDrift, } from "./driftEscopo.js";
14
+ import { criarStoreCacheDrift, digestJsonCanonicoCacheDrift, } from "./driftCacheStore.js";
15
+ const SCHEMA_PAYLOAD_INDICES_CACHE_DRIFT = "sema.drift-index-payload/v4";
16
+ const SCHEMA_IDENTIDADE_INDICES_CACHE_DRIFT = "sema.drift-index-identity/v3";
17
+ const SCHEMA_ESTADO_CACHE_DRIFT = "sema.drift-cache/v3";
18
+ const EXTRATOR_INDICES_CACHE_DRIFT = "drift-index-v4-2026-08-16";
19
+ const CHAVES_INDICES_CACHE_DRIFT = [
20
+ "indexTs", "indexPy", "indexDart", "indexDotnet", "indexJava", "indexGo",
21
+ "indexRust", "indexLua", "indexCpp", "indexPhp", "indexPersistencia",
22
+ ];
23
+ const ORIGENS_SIMBOLO_POR_INDICE = {
24
+ indexTs: ["ts", "js"],
25
+ indexPy: ["py"],
26
+ indexDart: ["dart"],
27
+ indexDotnet: ["cs"],
28
+ indexJava: ["java"],
29
+ indexGo: ["go"],
30
+ indexRust: ["rust"],
31
+ indexLua: ["lua"],
32
+ indexCpp: ["cpp"],
33
+ indexPhp: ["php"],
34
+ indexPersistencia: ["sql"],
35
+ };
36
+ const EXTENSOES_POR_INDICE = {
37
+ indexTs: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
38
+ indexPy: [".py"],
39
+ indexDart: [".dart"],
40
+ indexDotnet: [".cs"],
41
+ indexJava: [".java"],
42
+ indexGo: [".go"],
43
+ indexRust: [".rs"],
44
+ indexLua: [".lua"],
45
+ indexCpp: [".cpp", ".cc", ".cxx", ".hpp", ".h"],
46
+ indexPhp: [".php"],
47
+ indexPersistencia: [
48
+ ".sql", ".psql", ".ddl", ".prisma", ".ts", ".tsx", ".js", ".jsx",
49
+ ".mjs", ".cjs", ".py", ".dart", ".lua", ".cs", ".java", ".go",
50
+ ".rs", ".cpp", ".cc", ".cxx", ".hpp", ".h", ".php",
51
+ ],
52
+ };
53
+ const METRICAS_CATALOGO_VAZIO = {
54
+ diretoriosVisitados: 0,
55
+ arquivosCatalogados: 0,
56
+ leiturasConteudo: 0,
57
+ bytesLidos: 0,
58
+ acertosMemoriaConteudo: 0,
59
+ origem: "plano_explicito",
60
+ };
61
+ const LEITOR_VAZIO = {
62
+ contem: () => false,
63
+ lerTexto: async (caminho) => {
64
+ throw new Error(`Arquivo fora do plano explicito do drift: ${caminho}`);
65
+ },
66
+ };
67
+ function estadoCacheInicial(modo, origem, avisos) {
182
68
  return {
183
- ...serializaveis,
184
- mapaImpl,
185
- mapaRecursos: construirMapaRecursos(serializaveis.todosRecursos),
186
- planoEscopo,
187
- cache,
188
- catalogo,
189
- leitorArquivosPlanejados,
69
+ modo,
70
+ origem,
71
+ schema: SCHEMA_ESTADO_CACHE_DRIFT,
72
+ metricas: {
73
+ hits: 0,
74
+ misses: 0,
75
+ corruptos: 0,
76
+ gravacoes: 0,
77
+ errosGravacao: 0,
78
+ },
79
+ avisos,
190
80
  };
191
81
  }
192
- function indicesVazios() {
82
+ function indicesVazios(planoEscopo, modoCache, avisosModoCache) {
193
83
  return {
194
- arquivosOrcamentoAvaliados: [],
195
84
  detalhesPersistencia: { colunas: [], repositorios: [] },
196
- diagnosticosOrcamento: [],
197
85
  indexDart: { simbolos: [], rotas: [], recursos: [], consumerSurfaces: [] },
198
86
  indexTs: { simbolos: [], rotas: [], recursos: [], consumerSurfaces: [] },
87
+ mapaImpl: new Map(),
88
+ mapaRecursos: new Map(),
199
89
  todasRotasIndexadas: [],
200
90
  todosArquivosConhecidos: [],
201
91
  todosRecursos: [],
202
92
  todosSimbolos: [],
93
+ planoEscopo,
94
+ cache: estadoCacheInicial(modoCache, "nao_aplicavel", avisosModoCache),
95
+ catalogo: { ...METRICAS_CATALOGO_VAZIO },
96
+ leitorArquivosPlanejados: LEITOR_VAZIO,
203
97
  };
204
98
  }
205
- function deduplicar(itens, chave) {
206
- return [...new Map(itens.map((item) => [chave(item), item])).values()];
99
+ function coletarArquivosFisicosDeclarados(contexto) {
100
+ const arquivos = new Set();
101
+ for (const modulo of contexto.modulosSelecionados) {
102
+ const ir = modulo.resultado.ir;
103
+ if (!ir) {
104
+ continue;
105
+ }
106
+ for (const { vinculo } of coletarVinculosIr(ir)) {
107
+ const arquivo = vinculo.arquivo ?? (vinculo.tipo === "arquivo" ? vinculo.valor : undefined);
108
+ if (arquivo) {
109
+ arquivos.add(arquivo);
110
+ }
111
+ }
112
+ }
113
+ return [...arquivos].sort((a, b) => a.localeCompare(b, "pt-BR"));
114
+ }
115
+ function caminhoContidoCache(baseProjeto, arquivo) {
116
+ const relativo = path.relative(path.resolve(baseProjeto), path.resolve(arquivo));
117
+ return relativo === "" || (relativo !== ".."
118
+ && !relativo.startsWith(`..${path.sep}`)
119
+ && !path.isAbsolute(relativo));
207
120
  }
208
- function filtrarAoCatalogo(itens, catalogo) {
209
- return itens.filter((item) => catalogo.contem(item.arquivo));
121
+ function resolverArquivoCache(baseProjeto, arquivo) {
122
+ if (!path.isAbsolute(arquivo) && arquivo.includes(":")) {
123
+ throw new Error("cache_indice_arquivo_fora_workspace");
124
+ }
125
+ const absoluto = path.isAbsolute(arquivo)
126
+ ? path.resolve(arquivo)
127
+ : path.resolve(baseProjeto, arquivo);
128
+ if (!caminhoContidoCache(baseProjeto, absoluto)) {
129
+ throw new Error("cache_indice_arquivo_fora_workspace");
130
+ }
131
+ return absoluto;
210
132
  }
211
- function sanitizarIndices(indices, catalogo) {
212
- const diagnosticosOrcamento = indices.diagnosticosOrcamento.filter((item) => catalogo.contem(path.resolve(catalogo.baseDiretorio, item.arquivo)));
133
+ function caminhoRelativoSeguroCache(baseProjeto, arquivo) {
134
+ const relativo = path.relative(path.resolve(baseProjeto), resolverArquivoCache(baseProjeto, arquivo)).replace(/\\/g, "/");
135
+ if (!caminhoRelativoValidoCache(relativo)) {
136
+ throw new Error("cache_indice_arquivo_fora_workspace");
137
+ }
138
+ return relativo;
139
+ }
140
+ function caminhoRelativoValidoCache(valor) {
141
+ return typeof valor === "string"
142
+ && valor.length > 0
143
+ && valor !== "."
144
+ && valor !== ".."
145
+ && !valor.startsWith("../")
146
+ && !valor.includes("\\")
147
+ && !valor.includes(":")
148
+ && !valor.includes("\0")
149
+ && !path.posix.isAbsolute(valor)
150
+ && valor.split("/").every((segmento) => segmento.length > 0 && segmento !== "." && segmento !== "..");
151
+ }
152
+ function resolverCaminhoRelativoCache(baseProjeto, relativo) {
153
+ if (!caminhoRelativoValidoCache(relativo)) {
154
+ throw new Error("cache_indice_arquivo_fora_workspace");
155
+ }
156
+ const absoluto = path.resolve(baseProjeto, ...relativo.split("/"));
157
+ if (!caminhoContidoCache(baseProjeto, absoluto)) {
158
+ throw new Error("cache_indice_arquivo_fora_workspace");
159
+ }
160
+ return absoluto;
161
+ }
162
+ function registroJson(valor) {
163
+ return typeof valor === "object" && valor !== null && !Array.isArray(valor);
164
+ }
165
+ function textoNaoVazio(valor) {
166
+ return typeof valor === "string" && valor.length > 0;
167
+ }
168
+ function normalizarJsonCache(valor) {
169
+ return JSON.parse(JSON.stringify(valor));
170
+ }
171
+ function serializarSimboloCache(baseProjeto, registro) {
213
172
  return {
214
- arquivosOrcamentoAvaliados: indices.arquivosOrcamentoAvaliados.filter((arquivo) => catalogo.contem(path.resolve(catalogo.baseDiretorio, arquivo))),
215
- detalhesPersistencia: {
216
- colunas: filtrarAoCatalogo(indices.detalhesPersistencia.colunas, catalogo),
217
- repositorios: filtrarAoCatalogo(indices.detalhesPersistencia.repositorios, catalogo),
218
- },
219
- diagnosticosOrcamento,
220
- indexDart: {
221
- simbolos: filtrarAoCatalogo(indices.indexDart.simbolos, catalogo),
222
- rotas: filtrarAoCatalogo(indices.indexDart.rotas, catalogo),
223
- recursos: filtrarAoCatalogo(indices.indexDart.recursos, catalogo),
224
- consumerSurfaces: filtrarAoCatalogo(indices.indexDart.consumerSurfaces, catalogo),
225
- },
226
- indexTs: {
227
- simbolos: filtrarAoCatalogo(indices.indexTs.simbolos, catalogo),
228
- rotas: filtrarAoCatalogo(indices.indexTs.rotas, catalogo),
229
- recursos: filtrarAoCatalogo(indices.indexTs.recursos, catalogo),
230
- consumerSurfaces: filtrarAoCatalogo(indices.indexTs.consumerSurfaces, catalogo),
231
- },
232
- todasRotasIndexadas: filtrarAoCatalogo(indices.todasRotasIndexadas, catalogo),
233
- todosArquivosConhecidos: indices.todosArquivosConhecidos.filter((arquivo) => catalogo.contem(arquivo)),
234
- todosRecursos: filtrarAoCatalogo(indices.todosRecursos, catalogo),
235
- todosSimbolos: filtrarAoCatalogo(indices.todosSimbolos, catalogo),
173
+ origem: registro.origem,
174
+ caminho: registro.caminho,
175
+ arquivo: caminhoRelativoSeguroCache(baseProjeto, registro.arquivo),
176
+ simbolo: registro.simbolo,
177
+ };
178
+ }
179
+ function serializarRotaCache(baseProjeto, registro) {
180
+ return {
181
+ origem: registro.origem,
182
+ metodo: registro.metodo,
183
+ caminho: registro.caminho,
184
+ arquivo: caminhoRelativoSeguroCache(baseProjeto, registro.arquivo),
185
+ simbolo: registro.simbolo,
236
186
  };
237
187
  }
238
- async function calcularIndices(diretorios, catalogo, exigirCabecalhoCodigoGovernado) {
239
- const [indexTs, indexPy, indexDart, indexDotnet, indexJava, indexGo, indexRust, indexLua, indexPhp, indexPersistencia, detalhesPersistencia, indexCpp, arquivosRastreaveis,] = await Promise.all([
188
+ function serializarRecursoCache(baseProjeto, registro) {
189
+ const serializado = {
190
+ origem: registro.origem,
191
+ nome: registro.nome,
192
+ arquivo: caminhoRelativoSeguroCache(baseProjeto, registro.arquivo),
193
+ tipo: registro.tipo,
194
+ };
195
+ if (registro.simbolo !== undefined) {
196
+ serializado.simbolo = registro.simbolo;
197
+ }
198
+ return serializado;
199
+ }
200
+ function serializarConsumerSurfaceCache(baseProjeto, registro) {
201
+ return {
202
+ rota: registro.rota,
203
+ arquivo: caminhoRelativoSeguroCache(baseProjeto, registro.arquivo),
204
+ tipoArquivo: registro.tipoArquivo,
205
+ };
206
+ }
207
+ function serializarColunaPersistenciaCache(baseProjeto, registro) {
208
+ return {
209
+ origem: registro.origem,
210
+ categoriaPersistencia: registro.categoriaPersistencia,
211
+ recurso: registro.recurso,
212
+ coluna: registro.coluna,
213
+ arquivo: caminhoRelativoSeguroCache(baseProjeto, registro.arquivo),
214
+ };
215
+ }
216
+ function serializarRepositorioPersistenciaCache(baseProjeto, registro) {
217
+ return {
218
+ origem: registro.origem,
219
+ categoriaPersistencia: registro.categoriaPersistencia,
220
+ recurso: registro.recurso,
221
+ arquivo: caminhoRelativoSeguroCache(baseProjeto, registro.arquivo),
222
+ };
223
+ }
224
+ function serializarIndiceCache(baseProjeto, indice) {
225
+ return {
226
+ simbolos: indice.simbolos.map((item) => serializarSimboloCache(baseProjeto, item)),
227
+ rotas: indice.rotas.map((item) => serializarRotaCache(baseProjeto, item)),
228
+ recursos: indice.recursos.map((item) => serializarRecursoCache(baseProjeto, item)),
229
+ consumerSurfaces: indice.consumerSurfaces
230
+ .map((item) => serializarConsumerSurfaceCache(baseProjeto, item)),
231
+ };
232
+ }
233
+ function derivarIntegridadePayloadCache(indices, detalhesPersistencia) {
234
+ const agregar = (campo) => CHAVES_INDICES_CACHE_DRIFT
235
+ .flatMap((chave) => {
236
+ const indice = indices[chave];
237
+ return indice[campo];
238
+ });
239
+ return {
240
+ simbolosDigest: digestJsonCanonicoCacheDrift(agregar("simbolos")),
241
+ rotasDigest: digestJsonCanonicoCacheDrift(agregar("rotas")),
242
+ recursosDigest: digestJsonCanonicoCacheDrift(agregar("recursos")),
243
+ consumerSurfacesDigest: digestJsonCanonicoCacheDrift(agregar("consumerSurfaces")),
244
+ persistenciaDigest: digestJsonCanonicoCacheDrift(detalhesPersistencia),
245
+ };
246
+ }
247
+ function serializarIndicesCache(baseProjeto, extracoes) {
248
+ const indices = Object.fromEntries(CHAVES_INDICES_CACHE_DRIFT.map((chave) => [
249
+ chave,
250
+ serializarIndiceCache(baseProjeto, extracoes.indices[chave]),
251
+ ]));
252
+ const detalhesPersistencia = {
253
+ colunas: extracoes.detalhesPersistencia.colunas
254
+ .map((item) => serializarColunaPersistenciaCache(baseProjeto, item)),
255
+ repositorios: extracoes.detalhesPersistencia.repositorios
256
+ .map((item) => serializarRepositorioPersistenciaCache(baseProjeto, item)),
257
+ };
258
+ return normalizarJsonCache({
259
+ schema: SCHEMA_PAYLOAD_INDICES_CACHE_DRIFT,
260
+ detalhesPersistencia,
261
+ indices,
262
+ integridadeDerivada: derivarIntegridadePayloadCache(indices, detalhesPersistencia),
263
+ });
264
+ }
265
+ function possuiCamposExatos(valor, obrigatorios, opcionais = []) {
266
+ const permitidos = new Set([...obrigatorios, ...opcionais]);
267
+ return obrigatorios.every((campo) => Object.prototype.hasOwnProperty.call(valor, campo))
268
+ && Object.keys(valor).every((campo) => permitidos.has(campo));
269
+ }
270
+ function validarRegistroArquivoCache(valor, camposTexto, camposOpcionais = []) {
271
+ return registroJson(valor)
272
+ && possuiCamposExatos(valor, ["arquivo", ...camposTexto], camposOpcionais)
273
+ && caminhoRelativoValidoCache(valor.arquivo)
274
+ && camposTexto.every((campo) => textoNaoVazio(valor[campo]))
275
+ && camposOpcionais.every((campo) => valor[campo] === undefined || textoNaoVazio(valor[campo]));
276
+ }
277
+ function validarListaRegistrosCache(valor, camposTexto, camposOpcionais = []) {
278
+ return Array.isArray(valor)
279
+ && valor.every((item) => validarRegistroArquivoCache(item, camposTexto, camposOpcionais));
280
+ }
281
+ function arquivoCompativelComIndiceCache(chave, arquivo) {
282
+ const extensao = path.posix.extname(arquivo).toLowerCase();
283
+ return EXTENSOES_POR_INDICE[chave].includes(extensao);
284
+ }
285
+ function validarIndiceLinguagemCache(valor, chave) {
286
+ if (!(registroJson(valor)
287
+ && possuiCamposExatos(valor, ["simbolos", "rotas", "recursos", "consumerSurfaces"])
288
+ && validarListaRegistrosCache(valor.simbolos, ["origem", "caminho", "simbolo"])
289
+ && validarListaRegistrosCache(valor.rotas, ["origem", "metodo", "caminho", "simbolo"])
290
+ && validarListaRegistrosCache(valor.recursos, ["origem", "nome", "tipo"], ["simbolo"])
291
+ && validarListaRegistrosCache(valor.consumerSurfaces, ["rota", "tipoArquivo"]))) {
292
+ return false;
293
+ }
294
+ const registros = [valor.simbolos, valor.rotas, valor.recursos, valor.consumerSurfaces]
295
+ .flat();
296
+ if (!registros.every((item) => arquivoCompativelComIndiceCache(chave, item.arquivo)))
297
+ return false;
298
+ if (!valor.simbolos
299
+ .every((item) => ORIGENS_SIMBOLO_POR_INDICE[chave].includes(item.origem)))
300
+ return false;
301
+ if (["indexLua", "indexCpp", "indexPersistencia"].includes(chave)
302
+ && (valor.rotas.length > 0 || valor.consumerSurfaces.length > 0))
303
+ return false;
304
+ if (!["indexTs", "indexDart"].includes(chave) && valor.consumerSurfaces.length > 0)
305
+ return false;
306
+ const caminhosRotas = new Set(valor.rotas
307
+ .map((rota) => rota.caminho));
308
+ return valor.consumerSurfaces
309
+ .every((surface) => caminhosRotas.has(surface.rota));
310
+ }
311
+ function validarPayloadIndicesCache(valor) {
312
+ if (!registroJson(valor)
313
+ || !possuiCamposExatos(valor, [
314
+ "schema",
315
+ "detalhesPersistencia",
316
+ "indices",
317
+ "integridadeDerivada",
318
+ ])
319
+ || valor.schema !== SCHEMA_PAYLOAD_INDICES_CACHE_DRIFT
320
+ || !registroJson(valor.detalhesPersistencia)
321
+ || !possuiCamposExatos(valor.detalhesPersistencia, ["colunas", "repositorios"])
322
+ || !registroJson(valor.indices)
323
+ || !possuiCamposExatos(valor.indices, CHAVES_INDICES_CACHE_DRIFT)
324
+ || !CHAVES_INDICES_CACHE_DRIFT.every((chave) => validarIndiceLinguagemCache(valor.indices[chave], chave))
325
+ || !registroJson(valor.integridadeDerivada)
326
+ || !possuiCamposExatos(valor.integridadeDerivada, [
327
+ "simbolosDigest",
328
+ "rotasDigest",
329
+ "recursosDigest",
330
+ "consumerSurfacesDigest",
331
+ "persistenciaDigest",
332
+ ])) {
333
+ return false;
334
+ }
335
+ const estruturaValida = validarListaRegistrosCache(valor.detalhesPersistencia.colunas, ["origem", "categoriaPersistencia", "recurso", "coluna"]) && validarListaRegistrosCache(valor.detalhesPersistencia.repositorios, ["origem", "categoriaPersistencia", "recurso"]);
336
+ if (!estruturaValida)
337
+ return false;
338
+ const integridadeEsperada = derivarIntegridadePayloadCache(valor.indices, valor.detalhesPersistencia);
339
+ return Object.entries(integridadeEsperada).every(([campo, esperado]) => (valor.integridadeDerivada[campo] === esperado));
340
+ }
341
+ function restaurarRegistroArquivoCache(baseProjeto, catalogo, registro) {
342
+ const arquivo = resolverCaminhoRelativoCache(baseProjeto, registro.arquivo);
343
+ if (!catalogo.contem(arquivo)) {
344
+ throw new Error("cache_indice_arquivo_fora_catalogo");
345
+ }
346
+ return { ...registro, arquivo };
347
+ }
348
+ function restaurarIndicesCache(baseProjeto, catalogo, payload) {
349
+ if (!validarPayloadIndicesCache(payload))
350
+ return null;
351
+ const restaurar = (valor) => valor.map((item) => restaurarRegistroArquivoCache(baseProjeto, catalogo, item));
352
+ try {
353
+ const detalhes = payload.detalhesPersistencia;
354
+ const indicesPayload = payload.indices;
355
+ const indices = Object.fromEntries(CHAVES_INDICES_CACHE_DRIFT.map((chave) => {
356
+ const indice = indicesPayload[chave];
357
+ return [chave, {
358
+ simbolos: restaurar(indice.simbolos),
359
+ rotas: restaurar(indice.rotas),
360
+ recursos: restaurar(indice.recursos),
361
+ consumerSurfaces: restaurar(indice.consumerSurfaces),
362
+ }];
363
+ }));
364
+ return derivarIndicesExtraidos({
365
+ detalhesPersistencia: {
366
+ colunas: restaurar(detalhes.colunas),
367
+ repositorios: restaurar(detalhes.repositorios),
368
+ },
369
+ indices,
370
+ }, catalogo);
371
+ }
372
+ catch {
373
+ return null;
374
+ }
375
+ }
376
+ function criarMapaImplDrift(todosSimbolos, arquivosPrioritarios) {
377
+ const prioritarios = new Set(arquivosPrioritarios.map(chaveCaminhoCanonicoDrift));
378
+ const mapaImpl = new Map();
379
+ for (const simbolo of todosSimbolos.filter((item) => item.origem !== "sql")) {
380
+ const existente = mapaImpl.get(simbolo.caminho);
381
+ if (!existente) {
382
+ mapaImpl.set(simbolo.caminho, simbolo);
383
+ continue;
384
+ }
385
+ const prioridadeExistente = prioritarios.has(chaveCaminhoCanonicoDrift(existente.arquivo));
386
+ const prioridadeNova = prioritarios.has(chaveCaminhoCanonicoDrift(simbolo.arquivo));
387
+ if ((prioridadeNova && !prioridadeExistente)
388
+ || (prioridadeNova === prioridadeExistente
389
+ && simbolo.arquivo.localeCompare(existente.arquivo, "pt-BR") < 0)) {
390
+ mapaImpl.set(simbolo.caminho, simbolo);
391
+ }
392
+ }
393
+ return mapaImpl;
394
+ }
395
+ function montarIndicesPreparados(extraidos, arquivosPrioritarios, planoEscopo, cache, catalogo) {
396
+ return {
397
+ ...extraidos,
398
+ mapaImpl: criarMapaImplDrift(extraidos.todosSimbolos, arquivosPrioritarios),
399
+ mapaRecursos: construirMapaRecursos(extraidos.todosRecursos),
400
+ planoEscopo,
401
+ cache,
402
+ catalogo: catalogo.metricas(),
403
+ leitorArquivosPlanejados: catalogo,
404
+ };
405
+ }
406
+ function derivarIndicesExtraidos(extracoes, catalogo) {
407
+ const agregar = (campo) => CHAVES_INDICES_CACHE_DRIFT
408
+ .flatMap((chave) => extracoes.indices[chave][campo]);
409
+ const todosSimbolos = agregar("simbolos");
410
+ const todasRotasIndexadas = agregar("rotas");
411
+ const todosRecursos = agregar("recursos");
412
+ const todosArquivosConhecidos = [...new Set([
413
+ ...catalogo.arquivosCatalogados(),
414
+ ...todosSimbolos.map((item) => item.arquivo),
415
+ ...todasRotasIndexadas.map((item) => item.arquivo),
416
+ ...todosRecursos.map((item) => item.arquivo),
417
+ ])].sort((a, b) => a.localeCompare(b, "pt-BR"));
418
+ return {
419
+ detalhesPersistencia: extracoes.detalhesPersistencia,
420
+ indexDart: extracoes.indices.indexDart,
421
+ indexTs: extracoes.indices.indexTs,
422
+ todasRotasIndexadas,
423
+ todosArquivosConhecidos,
424
+ todosRecursos,
425
+ todosSimbolos,
426
+ };
427
+ }
428
+ async function calcularIndices(diretorios, catalogo) {
429
+ const [indexTs, indexPy, indexDart, indexDotnet, indexJava, indexGo, indexRust, indexLua, indexPhp, indexPersistencia, detalhesPersistencia, indexCpp,] = await Promise.all([
240
430
  indexarTypeScript(diretorios, catalogo),
241
431
  indexarPython(diretorios, catalogo),
242
432
  indexarDart(diretorios, catalogo),
@@ -249,467 +439,231 @@ async function calcularIndices(diretorios, catalogo, exigirCabecalhoCodigoGovern
249
439
  indexarPersistenciaDeclarativa(diretorios, catalogo),
250
440
  indexarPersistenciaDetalhada(diretorios, catalogo),
251
441
  indexarCpp(diretorios, catalogo),
252
- indexarArquivosRastreaveis(diretorios, catalogo),
253
442
  ]);
254
- const todosSimbolos = [
255
- ...indexTs.simbolos,
256
- ...indexPy.simbolos,
257
- ...indexDart.simbolos,
258
- ...indexDotnet.simbolos,
259
- ...indexJava.simbolos,
260
- ...indexGo.simbolos,
261
- ...indexRust.simbolos,
262
- ...indexLua.simbolos,
263
- ...indexCpp.simbolos,
264
- ...indexPhp.simbolos,
265
- ...indexPersistencia.simbolos,
266
- ];
267
- const todosRecursos = [
268
- ...indexTs.recursos,
269
- ...indexPy.recursos,
270
- ...indexDart.recursos,
271
- ...indexDotnet.recursos,
272
- ...indexJava.recursos,
273
- ...indexGo.recursos,
274
- ...indexRust.recursos,
275
- ...indexLua.recursos,
276
- ...indexCpp.recursos,
277
- ...indexPhp.recursos,
278
- ...indexPersistencia.recursos,
279
- ];
280
- const todasRotasIndexadas = [
281
- ...indexTs.rotas,
282
- ...indexPy.rotas,
283
- ...indexDart.rotas,
284
- ...indexDotnet.rotas,
285
- ...indexJava.rotas,
286
- ...indexGo.rotas,
287
- ...indexRust.rotas,
288
- ...indexPhp.rotas,
289
- ];
290
- const todosArquivosConhecidos = [...new Set([
291
- ...arquivosRastreaveis,
292
- ...todosSimbolos.map((item) => item.arquivo),
293
- ...todasRotasIndexadas.map((item) => item.arquivo),
294
- ...todosRecursos.map((item) => item.arquivo),
295
- ])].sort((a, b) => a.localeCompare(b, "pt-BR"));
296
- const diagnosticosOrcamento = await emitirDiagnosticosArquivosOrcamento({
297
- arquivos: catalogo.arquivosCatalogados(),
298
- baseProjeto: catalogo.baseDiretorio,
299
- exigirCabecalhoCodigoGovernado,
300
- leitorArquivos: catalogo,
301
- });
302
- return sanitizarIndices(paraJsonCache({
303
- arquivosOrcamentoAvaliados: catalogo.arquivosCatalogados()
304
- .map((arquivo) => pathRelativo(catalogo.baseDiretorio, arquivo)),
443
+ const extracoes = {
305
444
  detalhesPersistencia,
306
- diagnosticosOrcamento,
307
- indexDart,
308
- indexTs,
309
- todasRotasIndexadas,
310
- todosArquivosConhecidos,
311
- todosRecursos,
312
- todosSimbolos,
313
- }), catalogo);
314
- }
315
- function mesclarIndices(resumos, todosArquivosCatalogados) {
316
- const simbolos = deduplicar(resumos.flatMap((item) => item.todosSimbolos), (item) => item.caminho);
317
- const rotas = deduplicar(resumos.flatMap((item) => item.todasRotasIndexadas), (item) => `${item.origem}:${item.metodo}:${item.caminho}:${item.arquivo}:${item.simbolo}`);
318
- const recursos = deduplicar(resumos.flatMap((item) => item.todosRecursos), (item) => `${item.origem}:${item.tipo}:${item.nome}:${item.arquivo}:${item.simbolo ?? ""}`);
319
- const simbolosTs = deduplicar(resumos.flatMap((item) => item.indexTs.simbolos), (item) => item.caminho);
320
- const rotasTs = deduplicar(resumos.flatMap((item) => item.indexTs.rotas), (item) => `${item.origem}:${item.metodo}:${item.caminho}:${item.arquivo}:${item.simbolo}`);
321
- const recursosTs = deduplicar(resumos.flatMap((item) => item.indexTs.recursos), (item) => `${item.origem}:${item.tipo}:${item.nome}:${item.arquivo}:${item.simbolo ?? ""}`);
322
- const surfacesTs = deduplicar(resumos.flatMap((item) => item.indexTs.consumerSurfaces), (item) => `${item.rota}:${item.arquivo}:${item.tipoArquivo}`);
323
- const simbolosDart = deduplicar(resumos.flatMap((item) => item.indexDart.simbolos), (item) => item.caminho);
324
- const rotasDart = deduplicar(resumos.flatMap((item) => item.indexDart.rotas), (item) => `${item.origem}:${item.metodo}:${item.caminho}:${item.arquivo}:${item.simbolo}`);
325
- const recursosDart = deduplicar(resumos.flatMap((item) => item.indexDart.recursos), (item) => `${item.origem}:${item.tipo}:${item.nome}:${item.arquivo}:${item.simbolo ?? ""}`);
326
- const surfacesDart = deduplicar(resumos.flatMap((item) => item.indexDart.consumerSurfaces), (item) => `${item.rota}:${item.arquivo}:${item.tipoArquivo}`);
327
- const colunas = deduplicar(resumos.flatMap((item) => item.detalhesPersistencia.colunas), (item) => `${item.origem}:${item.recurso}:${item.coluna}:${item.arquivo}`);
328
- const repositorios = deduplicar(resumos.flatMap((item) => item.detalhesPersistencia.repositorios), (item) => `${item.origem}:${item.recurso}:${item.arquivo}`);
329
- const diagnosticosOrcamento = deduplicar(resumos.flatMap((item) => item.diagnosticosOrcamento), (item) => `${item.tipo}:${item.arquivo}:${item.severidade}:${item.mensagem}`);
330
- return paraJsonCache({
331
- arquivosOrcamentoAvaliados: [...new Set(resumos.flatMap((item) => item.arquivosOrcamentoAvaliados))].sort((a, b) => a.localeCompare(b, "pt-BR")),
332
- detalhesPersistencia: { colunas, repositorios },
333
- diagnosticosOrcamento,
334
- indexDart: {
335
- simbolos: simbolosDart,
336
- rotas: rotasDart,
337
- recursos: recursosDart,
338
- consumerSurfaces: surfacesDart,
339
- },
340
- indexTs: {
341
- simbolos: simbolosTs,
342
- rotas: rotasTs,
343
- recursos: recursosTs,
344
- consumerSurfaces: surfacesTs,
445
+ indices: {
446
+ indexTs,
447
+ indexPy: { ...indexPy, consumerSurfaces: [] },
448
+ indexDart,
449
+ indexDotnet: { ...indexDotnet, consumerSurfaces: [] },
450
+ indexJava: { ...indexJava, consumerSurfaces: [] },
451
+ indexGo: { ...indexGo, consumerSurfaces: [] },
452
+ indexRust: { ...indexRust, consumerSurfaces: [] },
453
+ indexLua: { ...indexLua, rotas: [], consumerSurfaces: [] },
454
+ indexCpp: { ...indexCpp, rotas: [], consumerSurfaces: [] },
455
+ indexPhp: { ...indexPhp, consumerSurfaces: [] },
456
+ indexPersistencia: { ...indexPersistencia, rotas: [], consumerSurfaces: [] },
345
457
  },
346
- todasRotasIndexadas: rotas,
347
- todosArquivosConhecidos: [...new Set(todosArquivosCatalogados)].sort((a, b) => a.localeCompare(b, "pt-BR")),
348
- todosRecursos: recursos,
349
- todosSimbolos: simbolos,
458
+ };
459
+ return [extracoes, derivarIndicesExtraidos(extracoes, catalogo)];
460
+ }
461
+ function relativoIdentidade(baseProjeto, alvo) {
462
+ const absoluto = resolverArquivoCache(baseProjeto, alvo);
463
+ const relativo = path.relative(path.resolve(baseProjeto), absoluto).replace(/\\/g, "/");
464
+ if (relativo === "")
465
+ return ".";
466
+ if (relativo === ".."
467
+ || relativo.startsWith("../")
468
+ || relativo.includes(":")
469
+ || relativo.includes("\0")
470
+ || path.posix.isAbsolute(relativo)) {
471
+ throw new Error("cache_identidade_fora_workspace");
472
+ }
473
+ return relativo;
474
+ }
475
+ function digestValorCache(valor) {
476
+ return digestJsonCanonicoCacheDrift(normalizarJsonCache(valor));
477
+ }
478
+ function representarPlanoCache(contexto, configuracao, plano) {
479
+ const relativo = (alvo) => relativoIdentidade(contexto.baseProjeto, alvo);
480
+ const ordenar = (itens) => [...new Set(itens.map(relativo))]
481
+ .sort((a, b) => a.localeCompare(b, "pt-BR"));
482
+ const dependencias = Object.entries(plano.dependencias)
483
+ .map(([arquivo, destinos]) => [
484
+ relativo(arquivo),
485
+ ordenar(destinos),
486
+ ])
487
+ .sort(([a], [b]) => a.localeCompare(b, "pt-BR"));
488
+ return normalizarJsonCache({
489
+ escopo: configuracao.escopo,
490
+ estrategia: plano.estrategia,
491
+ cobertura: plano.cobertura,
492
+ termos: [...configuracao.termosEscopo].sort((a, b) => a.localeCompare(b, "pt-BR")),
493
+ modulos: [...plano.modulos].sort((a, b) => a.localeCompare(b, "pt-BR")),
494
+ arquivos: ordenar(plano.arquivos),
495
+ arquivosDeclarados: ordenar(plano.arquivosDeclarados),
496
+ arquivosInferidos: ordenar(plano.arquivosInferidos),
497
+ arquivosAusentes: ordenar(plano.arquivosAusentes),
498
+ diretorios: ordenar(plano.diretorios),
499
+ diretoriosCodigo: ordenar(contexto.diretoriosCodigo),
500
+ ignorarWorktrees: configuracao.ignorarWorktrees,
501
+ ignorarConsumidoresLaterais: configuracao.ignorarConsumidoresLaterais,
502
+ dependencias,
350
503
  });
351
504
  }
352
- class CatalogoFiltradoDrift {
353
- origem;
354
- baseDiretorio;
355
- raizes;
356
- permitidos;
357
- constructor(origem, arquivos) {
358
- this.origem = origem;
359
- this.baseDiretorio = origem.baseDiretorio;
360
- this.raizes = origem.raizes;
361
- this.permitidos = new Set(arquivos.map(chaveCaminho));
362
- }
363
- listar(extensoesOuFiltro = [], raizes) {
364
- const arquivos = Array.isArray(extensoesOuFiltro)
365
- ? this.origem.listar(extensoesOuFiltro, raizes)
366
- : this.origem.listar(extensoesOuFiltro);
367
- return arquivos.filter((arquivo) => this.permitidos.has(chaveCaminho(arquivo)));
368
- }
369
- listarEntradas(filtro = {}) {
370
- return this.origem.listarEntradas(filtro)
371
- .filter((arquivo) => this.permitidos.has(chaveCaminho(arquivo.caminho)));
372
- }
373
- listarPorExtensoes(extensoes, raiz) {
374
- return this.listarEntradas({ extensoes, raiz }).map((arquivo) => arquivo.caminho);
375
- }
376
- listarPorRaiz(raiz, extensoes) {
377
- return this.listarEntradas({ raiz, extensoes }).map((arquivo) => arquivo.caminho);
378
- }
379
- arquivosCatalogados() {
380
- return this.listar();
381
- }
382
- async incluir(arquivos) {
383
- const fora = arquivos.find((arquivo) => !this.permitidos.has(chaveCaminho(arquivo)));
384
- if (fora) {
385
- throw new Error(`Arquivo fora da unidade incremental do drift: ${fora}`);
386
- }
387
- }
388
- contem(caminho) {
389
- return this.permitidos.has(chaveCaminho(caminho)) && this.origem.contem(caminho);
390
- }
391
- ler(caminho) {
392
- return this.contem(caminho)
393
- ? this.origem.ler(caminho)
394
- : Promise.reject(new Error(`Arquivo fora da unidade incremental do drift: ${caminho}`));
395
- }
396
- async lerTexto(caminho) {
397
- return (await this.ler(caminho)).texto;
398
- }
399
- async digest(caminho) {
400
- return (await this.ler(caminho)).digest;
401
- }
402
- fingerprint(caminhos) {
403
- const selecionados = (caminhos ?? this.arquivosCatalogados())
404
- .filter((arquivo) => this.contem(arquivo));
405
- return this.origem.fingerprint(selecionados);
505
+ async function criarChaveIndicesCache(contexto, configuracao, plano, catalogo, store, arquivosExplicitos) {
506
+ const candidatos = new Map();
507
+ const adicionarCandidato = (arquivo) => {
508
+ const absoluto = resolverArquivoCache(contexto.baseProjeto, arquivo);
509
+ candidatos.set(chaveCaminhoCanonicoDrift(absoluto), absoluto);
510
+ };
511
+ for (const entrada of catalogo.listarEntradas().filter((item) => configuracao.escopo === "projeto" || item.explicito)) {
512
+ adicionarCandidato(entrada.caminho);
406
513
  }
407
- obterFingerprint(caminhos) {
408
- return this.fingerprint(caminhos);
514
+ for (const arquivo of [
515
+ ...arquivosExplicitos,
516
+ ...plano.arquivos,
517
+ ...plano.arquivosDeclarados,
518
+ ...plano.arquivosInferidos,
519
+ ...plano.arquivosAusentes,
520
+ ]) {
521
+ adicionarCandidato(arquivo);
409
522
  }
410
- emitir(tipo, arquivo) {
411
- if (tipo === "ast.create") {
412
- this.origem.emitir(tipo, arquivo);
523
+ const membros = await Promise.all([...candidatos.values()].map(async (arquivo) => {
524
+ const relativo = caminhoRelativoSeguroCache(contexto.baseProjeto, arquivo);
525
+ if (!catalogo.contem(arquivo)) {
526
+ return { arquivo: relativo, estado: "ausente" };
413
527
  }
414
- }
415
- metricas() {
416
- return this.origem.metricas();
417
- }
418
- snapshot() {
419
- const snapshot = this.origem.snapshot();
420
528
  return {
421
- ...snapshot,
422
- arquivos: snapshot.arquivos.filter((arquivo) => this.permitidos.has(chaveCaminho(path.resolve(this.baseDiretorio, arquivo.caminho)))),
529
+ arquivo: relativo,
530
+ estado: "presente",
531
+ digest: await catalogo.digest(arquivo),
423
532
  };
424
- }
533
+ }));
534
+ membros.sort((a, b) => a.arquivo.localeCompare(b.arquivo, "pt-BR"));
535
+ const contratos = contexto.modulosSelecionados
536
+ .map((modulo) => ({
537
+ arquivo: caminhoRelativoSeguroCache(contexto.baseProjeto, modulo.caminho),
538
+ modulo: modulo.resultado.ir ?? null,
539
+ diagnosticos: modulo.resultado.diagnosticos,
540
+ }))
541
+ .sort((a, b) => a.arquivo.localeCompare(b.arquivo, "pt-BR"));
542
+ return digestJsonCanonicoCacheDrift({
543
+ schema: SCHEMA_IDENTIDADE_INDICES_CACHE_DRIFT,
544
+ cliVersion: pacoteCli.version,
545
+ typescriptVersion: ts.version,
546
+ extrator: EXTRATOR_INDICES_CACHE_DRIFT,
547
+ workspaceId: store.workspaceId,
548
+ gitHead: store.gitHead,
549
+ planoDigest: digestValorCache(representarPlanoCache(contexto, configuracao, plano)),
550
+ contratosDigest: digestValorCache(contratos),
551
+ configuracaoDigest: digestValorCache(contexto.configCarregada?.config ?? null),
552
+ membros,
553
+ });
425
554
  }
426
- function extrairPerfilAgrupamentoTypeScript(arquivo, codigo) {
427
- const relacao = arquivo.replace(/\\/g, "/");
428
- const motivos = new Set();
429
- if (/(?:^|\n)\s*export\s+(?:type\s+)?(?:\*|\{[\s\S]{0,4000}?\})\s+from\s*["'`][^"'`]+["'`]/mu.test(codigo)) {
430
- motivos.add("reexportacao");
431
- }
432
- if (/(?:^|\/)(?:app\.)?(?:routes?|router|routing)(?:\.[^/]*)?\.(?:ts|tsx|js|jsx|mjs|cjs)$/iu.test(relacao)
433
- || /\b(?:createBrowserRouter|useRoutes|loadChildren|loadComponent)\s*[:(]/u.test(codigo)
434
- || /\bRouterModule\.(?:forRoot|forChild)\s*\(/u.test(codigo)
435
- || /<Routes?\b/u.test(codigo)) {
436
- motivos.add("roteamento_consumer");
437
- }
438
- if (/(?:^|\/)(?:src\/)?(?:app\/)?app\.component\.(?:ts|js)$/iu.test(relacao)) {
439
- motivos.add("angular_standalone_raiz");
440
- }
555
+ function adaptarEventoStoreCache(observador) {
556
+ if (!observador)
557
+ return undefined;
558
+ return (evento) => {
559
+ const tipo = evento.tipo === "cache.read.hit"
560
+ ? "cache.hit"
561
+ : evento.tipo === "cache.read.miss"
562
+ ? "cache.miss"
563
+ : evento.tipo === "cache.read.corrupt"
564
+ ? "cache.corrupt"
565
+ : evento.tipo === "cache.write.published" || evento.tipo === "cache.write.reused"
566
+ ? "cache.write"
567
+ : evento.tipo === "cache.store.unavailable" || evento.tipo === "cache.write.error"
568
+ ? "cache.unavailable"
569
+ : null;
570
+ if (!tipo)
571
+ return;
572
+ try {
573
+ observador({
574
+ tipo,
575
+ ...(evento.caminhoVirtual ? { caminho: evento.caminhoVirtual } : {}),
576
+ ...(evento.chave ? { chave: evento.chave } : {}),
577
+ ...(evento.codigo ? { motivo: evento.codigo } : {}),
578
+ });
579
+ }
580
+ catch {
581
+ // Observabilidade não altera o resultado funcional do drift.
582
+ }
583
+ };
584
+ }
585
+ function estadoCacheDoStore(modo, origem, avisos, store) {
586
+ const metricas = store.metricas();
441
587
  return {
442
- acoplarDependencias: motivos.size > 0,
443
- motivos: [...motivos].sort((a, b) => a.localeCompare(b, "pt-BR")),
588
+ modo,
589
+ origem,
590
+ schema: SCHEMA_ESTADO_CACHE_DRIFT,
591
+ ...(store.workspaceId ? { workspaceId: store.workspaceId } : {}),
592
+ metricas: {
593
+ hits: metricas.hits,
594
+ misses: metricas.misses,
595
+ corruptos: metricas.corruptos,
596
+ gravacoes: metricas.publicacoes,
597
+ errosGravacao: metricas.erros,
598
+ },
599
+ avisos,
444
600
  };
445
601
  }
446
- function perfilAgrupamentoTypeScriptValido(valor) {
447
- return registroObjeto(valor)
448
- && typeof valor.acoplarDependencias === "boolean"
449
- && Array.isArray(valor.motivos)
450
- && valor.motivos.every(textoNaoVazio);
451
- }
452
- function construirGruposIncrementais(arquivos, dependencias, perfisTypeScript) {
453
- const porChave = new Map(arquivos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
454
- const analisaveis = arquivos.filter((arquivo) => EXTENSOES_ANALISE_DRIFT.has(path.extname(arquivo).toLowerCase()));
455
- const typescript = analisaveis.filter((arquivo) => EXTENSOES_TYPESCRIPT_DRIFT.has(path.extname(arquivo).toLowerCase()));
456
- const dependenciasPorChave = new Map();
457
- for (const arquivo of typescript) {
458
- const destinos = (dependencias[arquivo] ?? [])
459
- .map((dependencia) => porChave.get(chaveCaminho(dependencia)))
460
- .filter((dependencia) => Boolean(dependencia))
461
- .filter((dependencia) => EXTENSOES_DEPENDENCIA_TYPESCRIPT_DRIFT.has(path.extname(dependencia).toLowerCase()));
462
- dependenciasPorChave.set(chaveCaminho(arquivo), destinos);
602
+ async function resolverIndicesComCache(contexto, configuracaoEscopo, planoEscopo, catalogo, arquivosPrioritarios, arquivosExplicitos, modoCache, avisosModoCache, observador) {
603
+ const store = await criarStoreCacheDrift({
604
+ baseProjeto: contexto.baseProjeto,
605
+ observador: adaptarEventoStoreCache(observador),
606
+ });
607
+ if (!store.disponivel) {
608
+ const [, extraidos] = await calcularIndices(planoEscopo.diretorios, catalogo);
609
+ return montarIndicesPreparados(extraidos, arquivosPrioritarios, planoEscopo, estadoCacheDoStore(modoCache, "indisponivel", avisosModoCache, store), catalogo);
463
610
  }
464
- const pai = new Map();
465
- const encontrar = (chave) => {
466
- const atual = pai.get(chave) ?? chave;
467
- if (atual === chave) {
468
- pai.set(chave, chave);
469
- return chave;
470
- }
471
- const raiz = encontrar(atual);
472
- pai.set(chave, raiz);
473
- return raiz;
474
- };
475
- const unir = (a, b) => {
476
- const raizA = encontrar(a);
477
- const raizB = encontrar(b);
478
- if (raizA !== raizB) {
479
- pai.set(raizB, raizA.localeCompare(raizB, "en") <= 0 ? raizA : raizB);
480
- pai.set(raizA, raizA.localeCompare(raizB, "en") <= 0 ? raizA : raizB);
481
- }
611
+ let chave;
612
+ try {
613
+ chave = await criarChaveIndicesCache(contexto, configuracaoEscopo, planoEscopo, catalogo, store, arquivosExplicitos);
614
+ }
615
+ catch {
616
+ const [, extraidos] = await calcularIndices(planoEscopo.diretorios, catalogo);
617
+ return montarIndicesPreparados(extraidos, arquivosPrioritarios, planoEscopo, estadoCacheDoStore(modoCache, "indisponivel", avisosModoCache, store), catalogo);
618
+ }
619
+ const validarPayloadAplicavel = (valor) => {
620
+ if (!validarPayloadIndicesCache(valor))
621
+ return false;
622
+ return restaurarIndicesCache(contexto.baseProjeto, catalogo, valor) !== null;
482
623
  };
483
- for (const semente of typescript) {
484
- if (!perfisTypeScript.get(chaveCaminho(semente))?.acoplarDependencias) {
485
- continue;
486
- }
487
- const chaveSemente = chaveCaminho(semente);
488
- const fila = [chaveSemente];
489
- const fechamento = new Set();
490
- while (fila.length > 0) {
491
- const atual = fila.shift();
492
- if (fechamento.has(atual)) {
493
- continue;
624
+ if (modoCache === "cache") {
625
+ const leitura = await store.ler(chave, validarPayloadAplicavel);
626
+ if (leitura.estado === "hit") {
627
+ const restaurados = restaurarIndicesCache(contexto.baseProjeto, catalogo, leitura.valor);
628
+ if (restaurados) {
629
+ return montarIndicesPreparados(restaurados, arquivosPrioritarios, planoEscopo, estadoCacheDoStore(modoCache, "cache", avisosModoCache, store), catalogo);
494
630
  }
495
- fechamento.add(atual);
496
- for (const dependencia of dependenciasPorChave.get(atual) ?? []) {
497
- const chaveDependencia = chaveCaminho(dependencia);
498
- if (!fechamento.has(chaveDependencia)) {
499
- fila.push(chaveDependencia);
500
- }
501
- }
502
- }
503
- for (const membro of fechamento) {
504
- unir(chaveSemente, membro);
505
631
  }
506
632
  }
507
- const gruposPorRaiz = new Map();
508
- const usados = new Set();
509
- for (const arquivo of arquivos) {
510
- const chave = chaveCaminho(arquivo);
511
- if (!pai.has(chave)) {
512
- continue;
513
- }
514
- usados.add(chave);
515
- const raiz = encontrar(chave);
516
- const grupo = gruposPorRaiz.get(raiz) ?? [];
517
- grupo.push(arquivo);
518
- gruposPorRaiz.set(raiz, grupo);
633
+ const [extracoes, extraidos] = await calcularIndices(planoEscopo.diretorios, catalogo);
634
+ try {
635
+ const payload = serializarIndicesCache(contexto.baseProjeto, extracoes);
636
+ await store.publicar(chave, payload, validarPayloadAplicavel);
519
637
  }
520
- const grupos = [...gruposPorRaiz.values()]
521
- .map((grupo) => grupo.sort((a, b) => a.localeCompare(b, "pt-BR")));
522
- for (const arquivo of analisaveis.sort((a, b) => a.localeCompare(b, "pt-BR"))) {
523
- const chave = chaveCaminho(arquivo);
524
- if (!usados.has(chave)) {
525
- usados.add(chave);
526
- grupos.push([arquivo]);
527
- }
638
+ catch {
639
+ // Cache é aceleração descartável; a extração recém-calculada continua autoritativa.
528
640
  }
529
- return grupos
530
- .filter((grupo) => grupo.length > 0)
531
- .sort((a, b) => a[0].localeCompare(b[0], "pt-BR"));
532
- }
533
- async function mapearComLimite(itens, limite, executar) {
534
- const resultados = new Array(itens.length);
535
- let proximo = 0;
536
- const trabalhador = async () => {
537
- for (;;) {
538
- const indice = proximo;
539
- proximo += 1;
540
- if (indice >= itens.length) {
541
- return;
542
- }
543
- resultados[indice] = await executar(itens[indice]);
544
- }
545
- };
546
- await Promise.all(Array.from({ length: Math.min(limite, itens.length) }, trabalhador));
547
- return resultados;
548
- }
549
- function pathRelativo(baseProjeto, alvo) {
550
- const relativo = path.relative(baseProjeto, alvo).replace(/\\/g, "/");
551
- return relativo || ".";
552
- }
553
- function criarIdentidadeCache(contexto, configuracaoEscopo, plano, exigirCabecalhoCodigoGovernado) {
554
- const ordenarCaminhos = (caminhos) => [...new Set(caminhos.map((caminho) => path.normalize(path.resolve(caminho))))].sort((a, b) => a.localeCompare(b, "pt-BR"));
555
- const representarDiretorios = (diretorios) => {
556
- const fisicos = ordenarCaminhos(diretorios);
557
- return {
558
- fisicos,
559
- semanticos: fisicos.map((diretorio) => pathRelativo(contexto.baseProjeto, diretorio)),
560
- };
561
- };
562
- return paraJsonCache({
563
- cliVersion: pacoteCli.version,
564
- typescriptVersion: ts.version,
565
- fileIndexSchema: FILE_INDEX_SCHEMA,
566
- extractorBuild: "drift-file-index-v4-2026-07-21",
567
- escopo: {
568
- solicitado: configuracaoEscopo.escopo,
569
- estrategia: plano.estrategia,
570
- cobertura: plano.cobertura,
571
- termos: [...configuracaoEscopo.termosEscopo].sort((a, b) => a.localeCompare(b, "pt-BR")),
572
- modulos: [...plano.modulos].sort((a, b) => a.localeCompare(b, "pt-BR")),
573
- arquivosFisicos: ordenarCaminhos(plano.arquivos),
574
- arquivosSemanticos: plano.arquivos
575
- .map((arquivo) => pathRelativo(contexto.baseProjeto, arquivo))
576
- .sort((a, b) => a.localeCompare(b, "pt-BR")),
577
- },
578
- diretoriosPlano: representarDiretorios(plano.diretorios),
579
- diretoriosContexto: representarDiretorios(contexto.diretoriosCodigo),
580
- exigirCabecalhoCodigoGovernado,
581
- ignorarWorktrees: configuracaoEscopo.ignorarWorktrees,
582
- ignorarConsumidoresLaterais: configuracaoEscopo.ignorarConsumidoresLaterais,
583
- fontesLegado: contexto.fontesLegado,
584
- configuracao: contexto.configCarregada?.config ?? null,
585
- });
641
+ return montarIndicesPreparados(extraidos, arquivosPrioritarios, planoEscopo, estadoCacheDoStore(modoCache, "calculado", avisosModoCache, store), catalogo);
586
642
  }
587
643
  export async function prepararIndicesDrift(contexto, configuracaoEscopo, opcoes = {}) {
588
- const inicioTotal = performance.now();
644
+ const modoCache = opcoes.modoCache ?? "none";
645
+ const avisosModoCache = opcoes.avisosModoCache ?? [];
589
646
  let planoEscopo = await planejarEscopoDrift(contexto, configuracaoEscopo);
590
- const fimPlanejamento = performance.now();
591
- const politicaCache = opcoes.politicaCache ?? "auto";
592
647
  if (planoEscopo.bloqueios.length > 0) {
593
- return reconstruirIndices(indicesVazios(), planoEscopo, {
594
- politica: politicaCache,
595
- origem: "nao_aplicavel",
596
- fasesMs: {
597
- planejamento: Number((fimPlanejamento - inicioTotal).toFixed(3)),
598
- catalogacao: 0,
599
- dependencias: 0,
600
- assinaturas: 0,
601
- indexacao: 0,
602
- total: Number((performance.now() - inicioTotal).toFixed(3)),
603
- },
604
- }, {
605
- diretoriosVisitados: 0,
606
- arquivosCatalogados: 0,
607
- leiturasConteudo: 0,
608
- bytesLidos: 0,
609
- acertosMemoriaConteudo: 0,
610
- origem: "plano_explicito",
611
- diretoriosValidadosCache: 0,
612
- });
648
+ return indicesVazios(planoEscopo, modoCache, avisosModoCache);
613
649
  }
614
- const exigirCabecalhoCodigoGovernado = await workspaceExigeCabecalhoCodigoGovernado(contexto.baseProjeto, contexto.configCarregada?.config.modoEstrito === true);
615
- const identidadeCache = criarIdentidadeCache(contexto, configuracaoEscopo, planoEscopo, exigirCabecalhoCodigoGovernado);
616
- const cache = new CacheIncrementalDrift({
617
- baseProjeto: contexto.baseProjeto,
618
- politica: politicaCache,
619
- identidade: identidadeCache,
620
- observador: opcoes.observador,
621
- });
622
- const catalogo = await criarCatalogoPersistenteDrift({
650
+ const arquivosExplicitos = planoEscopo.estrategia === "arquivos_vinculados"
651
+ ? planoEscopo.arquivos
652
+ : coletarArquivosFisicosDeclarados(contexto);
653
+ const catalogo = await criarCatalogoDrift({
623
654
  baseDiretorio: contexto.baseProjeto,
624
- arquivos: planoEscopo.estrategia === "arquivos_vinculados" ? planoEscopo.arquivos : [],
655
+ arquivos: arquivosExplicitos,
625
656
  raizes: planoEscopo.estrategia === "projeto" ? planoEscopo.diretorios : [],
626
657
  extensoes: EXTENSOES_ARQUIVOS_RASTREAVEIS_DRIFT,
627
- diretoriosIgnorados: resolverDiretoriosIgnoradosAtivos({
628
- escopo: configuracaoEscopo.escopo,
629
- ignorarWorktrees: configuracaoEscopo.ignorarWorktrees,
630
- ignorarConsumidoresLaterais: configuracaoEscopo.ignorarConsumidoresLaterais,
631
- }),
658
+ diretoriosIgnorados: resolverDiretoriosIgnoradosAtivos(configuracaoEscopo),
632
659
  observador: opcoes.observador,
633
- }, { politica: politicaCache, identidade: identidadeCache });
634
- const fimCatalogacao = performance.now();
635
- try {
636
- planoEscopo = await expandirDependenciasPlanoDrift(contexto, planoEscopo, catalogo, cache);
637
- if (planoEscopo.estrategia === "projeto") {
638
- const arquivosTypeScript = catalogo.arquivosCatalogados()
639
- .filter((arquivo) => EXTENSOES_TYPESCRIPT_DRIFT.has(path.extname(arquivo).toLowerCase()));
640
- planoEscopo.dependencias = await mapearDependenciasCatalogadasDrift(contexto, catalogo, cache, arquivosTypeScript);
641
- }
642
- const fimDependencias = performance.now();
643
- const membrosUnicos = catalogo.arquivosCatalogados()
644
- .filter((arquivo) => {
645
- const extensao = path.extname(arquivo).toLowerCase();
646
- return EXTENSOES_ANALISE_DRIFT.has(extensao)
647
- || EXTENSOES_DEPENDENCIA_TYPESCRIPT_DRIFT.has(extensao);
648
- });
649
- const estados = await mapearComLimite(membrosUnicos, 8, async (arquivo) => cache.resolverArquivo({
650
- arquivo,
651
- analise: "dependencias-v4",
652
- ler: () => catalogo.ler(arquivo),
653
- extrair: (conteudo) => extrairReferenciasLocaisDrift(conteudo.texto),
654
- validar: (valor) => Array.isArray(valor) && valor.every((item) => typeof item === "string"),
655
- }));
656
- const arquivosTypeScript = membrosUnicos
657
- .filter((arquivo) => EXTENSOES_TYPESCRIPT_DRIFT.has(path.extname(arquivo).toLowerCase()));
658
- const perfis = await mapearComLimite(arquivosTypeScript, 8, async (arquivo) => cache.resolverArquivo({
659
- arquivo,
660
- analise: "agrupamento-semantico-ts-v1",
661
- ler: () => catalogo.ler(arquivo),
662
- extrair: (conteudo) => extrairPerfilAgrupamentoTypeScript(arquivo, conteudo.texto),
663
- validar: perfilAgrupamentoTypeScriptValido,
664
- }));
665
- const perfisPorArquivo = new Map(perfis.map((perfil) => [
666
- chaveCaminho(path.resolve(contexto.baseProjeto, perfil.caminho)),
667
- perfil.valor,
668
- ]));
669
- const grupos = construirGruposIncrementais(catalogo.arquivosCatalogados(), planoEscopo.dependencias, perfisPorArquivo);
670
- const estadoPorArquivo = new Map(estados.map((estado) => [chaveRelativa(estado.caminho), estado]));
671
- const fimAssinaturas = performance.now();
672
- const resultadosGrupos = await mapearComLimite(grupos, 8, async (grupo) => {
673
- const membros = grupo.map((arquivo) => {
674
- const estado = estadoPorArquivo.get(chaveRelativa(pathRelativo(contexto.baseProjeto, arquivo)));
675
- if (!estado) {
676
- throw new Error(`estado_cache_arquivo_ausente:${arquivo}`);
677
- }
678
- return { caminho: arquivo, contentHash: estado.contentHash };
679
- });
680
- const catalogoGrupo = new CatalogoFiltradoDrift(catalogo, grupo);
681
- return cache.resolverGrupo({
682
- membros,
683
- calcular: () => calcularIndices(planoEscopo.diretorios, catalogoGrupo, exigirCabecalhoCodigoGovernado),
684
- validar: (valor) => (validarIndicesSerializaveis(valor)
685
- && indicesPermanecemNoCatalogo(valor, catalogoGrupo)),
686
- });
687
- });
688
- await cache.finalizar();
689
- const fimIndexacao = performance.now();
690
- const serializaveis = mesclarIndices(resultadosGrupos.map((resultado) => resultado.valor), catalogo.arquivosCatalogados());
691
- const metricasIncrementais = cache.metricas();
692
- const origem = resultadosGrupos.length > 0
693
- && resultadosGrupos.every((resultado) => resultado.origem === "cache")
694
- ? "cache"
695
- : "calculado";
696
- return reconstruirIndices(serializaveis, planoEscopo, {
697
- politica: politicaCache,
698
- origem,
699
- chave: cache.identidadeDigest,
700
- incremental: metricasIncrementais,
701
- fasesMs: {
702
- planejamento: Number((fimPlanejamento - inicioTotal).toFixed(3)),
703
- catalogacao: Number((fimCatalogacao - fimPlanejamento).toFixed(3)),
704
- dependencias: Number((fimDependencias - fimCatalogacao).toFixed(3)),
705
- assinaturas: Number((fimAssinaturas - fimDependencias).toFixed(3)),
706
- indexacao: Number((fimIndexacao - fimAssinaturas).toFixed(3)),
707
- total: Number((fimIndexacao - inicioTotal).toFixed(3)),
708
- },
709
- }, catalogo.metricas(), catalogo);
710
- }
711
- finally {
712
- await cache.finalizar();
660
+ });
661
+ const arquivosPrioritarios = [...planoEscopo.arquivos];
662
+ planoEscopo = await expandirDependenciasPlanoDrift(contexto, planoEscopo, catalogo);
663
+ if (modoCache === "none") {
664
+ const [, extraidos] = await calcularIndices(planoEscopo.diretorios, catalogo);
665
+ return montarIndicesPreparados(extraidos, arquivosPrioritarios, planoEscopo, estadoCacheInicial(modoCache, "calculado", avisosModoCache), catalogo);
713
666
  }
667
+ return resolverIndicesComCache(contexto, configuracaoEscopo, planoEscopo, catalogo, arquivosPrioritarios, arquivosExplicitos, modoCache, avisosModoCache, opcoes.observador);
714
668
  }
715
669
  //# sourceMappingURL=drift.part13.js.map