@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,6 +1,5 @@
1
1
  // SEMA-GOVERNED: sema.governanca_ia_contexto
2
2
  // Descricao: analisa modulos selecionados no drift; consulte contratos/sema/governanca_ia_contexto.sema antes de editar.
3
- import { existsSync } from "node:fs";
4
3
  import path from "node:path";
5
4
  import { escolherArquivoPorVinculo, escolherSimboloPorVinculo } from "./drift.part03.js";
6
5
  import { calcularRiscoOperacional, encontrarAncoraSuperficie } from "./drift.part04.js";
@@ -8,16 +7,29 @@ import { resolverPersistenciaLocalPorTask } from "./drift.part08.js";
8
7
  import { escolherRotasEsperadas, normalizarCaminhoRota, ordenarCandidatos, sugerirCandidatosParaImpl, sugerirCandidatosParaTaskSemImpl } from "./drift.part09.js";
9
8
  import { coletarVinculosIr, extrairRecursosEsperados, resolverRecursoEsperado } from "./drift.part10.js";
10
9
  function escolherArquivoDeclarado(contexto, arquivosConhecidos, valor) {
11
- const resolucaoIndexada = escolherArquivoPorVinculo(arquivosConhecidos, valor);
12
- if (resolucaoIndexada.status !== "nao_encontrado") {
13
- return resolucaoIndexada;
10
+ if (!caminhoEstaDentroDoWorkspace(contexto.baseProjeto, valor)) {
11
+ return { confianca: "baixa", status: "nao_encontrado" };
14
12
  }
15
- const caminhoExplicito = path.resolve(contexto.baseProjeto, valor);
16
- if (existsSync(caminhoExplicito)) {
17
- return { arquivo: caminhoExplicito, confianca: "alta", status: "resolvido" };
13
+ const resolucaoIndexada = escolherArquivoPorVinculo(arquivosConhecidos, valor);
14
+ if (resolucaoIndexada.arquivo
15
+ && !caminhoEstaDentroDoWorkspace(contexto.baseProjeto, resolucaoIndexada.arquivo)) {
16
+ return { confianca: "baixa", status: "nao_encontrado" };
18
17
  }
19
18
  return resolucaoIndexada;
20
19
  }
20
+ function caminhoEstaDentroDoWorkspace(baseProjeto, valor) {
21
+ const relativo = path.relative(path.resolve(baseProjeto), path.resolve(baseProjeto, valor));
22
+ return relativo === "" || (relativo !== ".."
23
+ && !relativo.startsWith(`..${path.sep}`)
24
+ && !path.isAbsolute(relativo));
25
+ }
26
+ function redigirCaminhoDeclaradoExterno(baseProjeto, valor) {
27
+ if (caminhoEstaDentroDoWorkspace(baseProjeto, valor)) {
28
+ return valor;
29
+ }
30
+ const nome = path.basename(path.normalize(valor)) || "arquivo";
31
+ return `[fora_do_workspace]/${nome}`;
32
+ }
21
33
  export function analisarModulosSelecionadosDrift(estado) {
22
34
  const { contexto, mapaImpl, todosSimbolos, mapaRecursos, todosRecursos, todasRotasIndexadas, todosArquivosConhecidos, implsValidos, implsQuebrados, vinculosValidos, vinculosQuebrados, rotasDivergentes, recursosValidos, recursosDivergentes, diagnosticos, tasksResumo, taskPorChave, guardrailsPorTask, resumoVinculosPorTask, arquivosAncoraHerdadosPorTask, } = estado;
23
35
  for (const item of contexto.modulosSelecionados) {
@@ -307,6 +319,7 @@ export function analisarModulosSelecionadosDrift(estado) {
307
319
  registro.simbolo = resolucaoSimbolo.simbolo?.simbolo;
308
320
  }
309
321
  else if (arquivoDeclarado) {
322
+ registro.valor = redigirCaminhoDeclaradoExterno(contexto.baseProjeto, registro.valor);
310
323
  const resolucaoArquivo = escolherArquivoDeclarado(contexto, todosArquivosConhecidos, arquivoDeclarado);
311
324
  registro.status = resolucaoArquivo.status;
312
325
  registro.confianca = resolucaoArquivo.confianca;
@@ -341,6 +354,7 @@ export function analisarModulosSelecionadosDrift(estado) {
341
354
  }
342
355
  }
343
356
  else {
357
+ registro.valor = redigirCaminhoDeclaradoExterno(contexto.baseProjeto, registro.valor);
344
358
  const resolucaoArquivo = escolherArquivoDeclarado(contexto, todosArquivosConhecidos, itemVinculo.vinculo.valor);
345
359
  registro.status = resolucaoArquivo.status;
346
360
  registro.confianca = resolucaoArquivo.confianca;
@@ -0,0 +1,43 @@
1
+ import { type FileHandle } from "node:fs/promises";
2
+ import { type EstadoEntradaCache, type GuardaCadeiaCache, type IdentidadeFilesystem } from "./driftCacheFilesystem.js";
3
+ export type CodigoErroCasCacheDrift = "cache_objeto_corrupto" | "cache_objeto_grande" | "cache_objeto_hardlink" | "cache_objeto_conflitante" | "cache_io_indisponivel";
4
+ export interface LockPublicacaoCache {
5
+ caminho: string;
6
+ handle: FileHandle;
7
+ identidade: IdentidadeFilesystem;
8
+ guarda: GuardaCadeiaCache;
9
+ token: string;
10
+ contendido: boolean;
11
+ }
12
+ export declare class FalhaCasCacheDrift extends Error {
13
+ readonly codigo: CodigoErroCasCacheDrift;
14
+ constructor(codigo: CodigoErroCasCacheDrift);
15
+ }
16
+ export interface OpcoesAdquirirLockPublicacao {
17
+ chave: string;
18
+ pasta: string;
19
+ guardaInicial: GuardaCadeiaCache;
20
+ raiz: string;
21
+ identidadeRaiz: IdentidadeFilesystem;
22
+ }
23
+ export interface OpcoesPublicarObjetoExclusivo {
24
+ temporario: string;
25
+ destino: string;
26
+ guarda: GuardaCadeiaCache;
27
+ identidadeTemporario: IdentidadeFilesystem;
28
+ estadoDestinoSubstituivel: EstadoEntradaCache | null;
29
+ }
30
+ export type ResultadoPublicacaoObjetoExclusivo = {
31
+ estado: "publicado";
32
+ } | {
33
+ estado: "existente";
34
+ } | {
35
+ estado: "conflito";
36
+ };
37
+ export declare function capturarEstadoEntradaGuardado(caminho: string, guarda: GuardaCadeiaCache): Promise<EstadoEntradaCache | null>;
38
+ export declare function removerArquivoGuardadoSeMesmo(caminho: string, identidade: IdentidadeFilesystem, guarda: GuardaCadeiaCache, permitirHardlink?: boolean): Promise<boolean>;
39
+ export declare function publicarObjetoExclusivo(opcoes: OpcoesPublicarObjetoExclusivo): Promise<ResultadoPublicacaoObjetoExclusivo>;
40
+ export declare function adquirirLockPublicacao(opcoes: OpcoesAdquirirLockPublicacao): Promise<LockPublicacaoCache>;
41
+ export declare function confirmarLockPublicacao(lock: LockPublicacaoCache): Promise<void>;
42
+ export declare function liberarLockPublicacao(lock: LockPublicacaoCache): Promise<void>;
43
+ export declare function limparTemporariosOrfaos(chave: string, pasta: string, guarda: GuardaCadeiaCache): Promise<void>;
@@ -0,0 +1,351 @@
1
+ // SEMA-GOVERNED: sema.produto.governanca_ia.drift.cache.store
2
+ // Descrição: serializa publicadores concorrentes por chave e recupera locks/temporários sem substituir vencedor válido.
3
+ import { constants } from "node:fs";
4
+ import { link, lstat, open, readdir, unlink, } from "node:fs/promises";
5
+ import { randomUUID } from "node:crypto";
6
+ import path from "node:path";
7
+ import { performance } from "node:perf_hooks";
8
+ import { setTimeout as esperar } from "node:timers/promises";
9
+ import { aplicarPermissaoArquivo, capturarGuardaCadeia, confirmarGuardaCadeia, erroEhAusencia, estadoEntrada, identidadeArquivoValida, identidadeDe, lerHandleLimitado, lstatOuNull, mesmaIdentidade, mesmoEstadoEntrada, } from "./driftCacheFilesystem.js";
10
+ export class FalhaCasCacheDrift extends Error {
11
+ codigo;
12
+ constructor(codigo) {
13
+ super(codigo);
14
+ this.codigo = codigo;
15
+ this.name = "FalhaCasCacheDrift";
16
+ }
17
+ }
18
+ const SCHEMA_LOCK_CACHE_DRIFT = "sema.drift-cache-lock/v1";
19
+ const TENTATIVAS_LOCK_CACHE_DRIFT = 200;
20
+ const INTERVALO_LOCK_CACHE_DRIFT_MS = 10;
21
+ const TTL_LOCK_CACHE_DRIFT_MS = 30_000;
22
+ const TOKENS_LOCK_ATIVOS = new Set();
23
+ const PROCESSO_INICIADO_EM_CACHE_DRIFT = performance.timeOrigin;
24
+ function processoEstaAtivo(pid) {
25
+ if (!Number.isSafeInteger(pid) || pid <= 0)
26
+ return false;
27
+ try {
28
+ process.kill(pid, 0);
29
+ return true;
30
+ }
31
+ catch (erro) {
32
+ const codigo = erro.code ?? "";
33
+ return !["ESRCH", "EINVAL"].includes(codigo);
34
+ }
35
+ }
36
+ function registroObjeto(valor) {
37
+ return typeof valor === "object" && valor !== null && !Array.isArray(valor);
38
+ }
39
+ function registroLockCache(valor) {
40
+ if (!registroObjeto(valor))
41
+ return false;
42
+ return valor.schema === SCHEMA_LOCK_CACHE_DRIFT
43
+ && Number.isSafeInteger(valor.pid)
44
+ && Number(valor.pid) > 0
45
+ && typeof valor.processoIniciadoEm === "number"
46
+ && Number.isFinite(valor.processoIniciadoEm)
47
+ && valor.processoIniciadoEm > 0
48
+ && typeof valor.token === "string"
49
+ && /^[a-f0-9-]{36}$/u.test(valor.token)
50
+ && typeof valor.criadoEm === "number"
51
+ && Number.isFinite(valor.criadoEm);
52
+ }
53
+ export async function capturarEstadoEntradaGuardado(caminho, guarda) {
54
+ await confirmarGuardaCadeia(guarda);
55
+ const info = await lstatOuNull(caminho);
56
+ await confirmarGuardaCadeia(guarda);
57
+ return info ? estadoEntrada(info) : null;
58
+ }
59
+ async function vincularExclusivo(origem, destino, guarda) {
60
+ await confirmarGuardaCadeia(guarda);
61
+ try {
62
+ await link(origem, destino);
63
+ }
64
+ catch (erro) {
65
+ const codigo = erro.code ?? "";
66
+ if (!["EEXIST", "EPERM"].includes(codigo))
67
+ throw erro;
68
+ await confirmarGuardaCadeia(guarda);
69
+ if (await lstatOuNull(destino))
70
+ return "existente";
71
+ throw erro;
72
+ }
73
+ await confirmarGuardaCadeia(guarda);
74
+ return "vinculado";
75
+ }
76
+ export async function removerArquivoGuardadoSeMesmo(caminho, identidade, guarda, permitirHardlink = false) {
77
+ try {
78
+ await confirmarGuardaCadeia(guarda);
79
+ const info = await lstat(caminho, { bigint: true });
80
+ if (info.isFile()
81
+ && !info.isSymbolicLink()
82
+ && (permitirHardlink || info.nlink === 1n)
83
+ && mesmaIdentidade(identidade, identidadeDe(info))) {
84
+ await confirmarGuardaCadeia(guarda);
85
+ await unlink(caminho);
86
+ await confirmarGuardaCadeia(guarda);
87
+ return true;
88
+ }
89
+ }
90
+ catch (erro) {
91
+ if (erroEhAusencia(erro))
92
+ return true;
93
+ // Limpeza é best effort; nunca seguimos um caminho cuja cadeia mudou.
94
+ }
95
+ return false;
96
+ }
97
+ export async function publicarObjetoExclusivo(opcoes) {
98
+ const identidadeSubstituida = opcoes.estadoDestinoSubstituivel
99
+ ? {
100
+ dev: opcoes.estadoDestinoSubstituivel.dev,
101
+ ino: opcoes.estadoDestinoSubstituivel.ino,
102
+ }
103
+ : null;
104
+ let quarentena = null;
105
+ let destinoCriado = false;
106
+ try {
107
+ await confirmarGuardaCadeia(opcoes.guarda);
108
+ const infoTemporario = await lstat(opcoes.temporario, { bigint: true });
109
+ if (!infoTemporario.isFile()
110
+ || infoTemporario.isSymbolicLink()
111
+ || infoTemporario.nlink !== 1n
112
+ || !mesmaIdentidade(opcoes.identidadeTemporario, identidadeDe(infoTemporario))) {
113
+ throw new FalhaCasCacheDrift("cache_objeto_hardlink");
114
+ }
115
+ if (opcoes.estadoDestinoSubstituivel) {
116
+ if (opcoes.estadoDestinoSubstituivel.tipo !== "arquivo" || !identidadeSubstituida) {
117
+ return { estado: "conflito" };
118
+ }
119
+ const atual = await capturarEstadoEntradaGuardado(opcoes.destino, opcoes.guarda);
120
+ if (!mesmoEstadoEntrada(opcoes.estadoDestinoSubstituivel, atual)) {
121
+ return { estado: "conflito" };
122
+ }
123
+ const digest = path.basename(opcoes.destino, ".json");
124
+ const caminhoQuarentena = path.join(path.dirname(opcoes.destino), `.${digest}.${randomUUID()}.replaced`);
125
+ if (await vincularExclusivo(opcoes.destino, caminhoQuarentena, opcoes.guarda) !== "vinculado") {
126
+ return { estado: "conflito" };
127
+ }
128
+ const [infoQuarentena, infoDestino] = await Promise.all([
129
+ lstat(caminhoQuarentena, { bigint: true }),
130
+ lstat(opcoes.destino, { bigint: true }),
131
+ ]);
132
+ quarentena = { caminho: caminhoQuarentena, identidade: identidadeDe(infoQuarentena) };
133
+ if (!infoQuarentena.isFile()
134
+ || infoQuarentena.isSymbolicLink()
135
+ || !mesmaIdentidade(identidadeSubstituida, identidadeDe(infoQuarentena))
136
+ || !mesmaIdentidade(identidadeSubstituida, identidadeDe(infoDestino))) {
137
+ return { estado: "conflito" };
138
+ }
139
+ const removido = await removerArquivoGuardadoSeMesmo(opcoes.destino, identidadeSubstituida, opcoes.guarda, true);
140
+ if (!removido)
141
+ return { estado: "conflito" };
142
+ }
143
+ const vinculo = await vincularExclusivo(opcoes.temporario, opcoes.destino, opcoes.guarda);
144
+ if (vinculo === "existente")
145
+ return { estado: "existente" };
146
+ destinoCriado = true;
147
+ const [infoDestino, infoTemporarioVinculado] = await Promise.all([
148
+ lstat(opcoes.destino, { bigint: true }),
149
+ lstat(opcoes.temporario, { bigint: true }),
150
+ ]);
151
+ if (!infoDestino.isFile()
152
+ || infoDestino.isSymbolicLink()
153
+ || infoDestino.nlink !== 2n
154
+ || infoTemporarioVinculado.nlink !== 2n
155
+ || !mesmaIdentidade(opcoes.identidadeTemporario, identidadeDe(infoDestino))
156
+ || !mesmaIdentidade(opcoes.identidadeTemporario, identidadeDe(infoTemporarioVinculado))) {
157
+ throw new FalhaCasCacheDrift("cache_objeto_conflitante");
158
+ }
159
+ const temporarioRemovido = await removerArquivoGuardadoSeMesmo(opcoes.temporario, opcoes.identidadeTemporario, opcoes.guarda, true);
160
+ if (!temporarioRemovido)
161
+ throw new FalhaCasCacheDrift("cache_objeto_conflitante");
162
+ const infoFinal = await lstat(opcoes.destino, { bigint: true });
163
+ if (!infoFinal.isFile()
164
+ || infoFinal.isSymbolicLink()
165
+ || infoFinal.nlink !== 1n
166
+ || !mesmaIdentidade(opcoes.identidadeTemporario, identidadeDe(infoFinal))) {
167
+ throw new FalhaCasCacheDrift("cache_objeto_conflitante");
168
+ }
169
+ destinoCriado = false;
170
+ return { estado: "publicado" };
171
+ }
172
+ catch (erro) {
173
+ if (destinoCriado) {
174
+ await removerArquivoGuardadoSeMesmo(opcoes.destino, opcoes.identidadeTemporario, opcoes.guarda, true);
175
+ }
176
+ throw erro;
177
+ }
178
+ finally {
179
+ if (quarentena) {
180
+ await removerArquivoGuardadoSeMesmo(quarentena.caminho, quarentena.identidade, opcoes.guarda, true);
181
+ }
182
+ }
183
+ }
184
+ async function lerLockSeguro(caminho, guarda) {
185
+ await confirmarGuardaCadeia(guarda);
186
+ const infoAntes = await lstatOuNull(caminho);
187
+ if (!infoAntes)
188
+ return null;
189
+ if (!infoAntes.isFile() || infoAntes.isSymbolicLink()) {
190
+ throw new FalhaCasCacheDrift("cache_objeto_corrupto");
191
+ }
192
+ if (infoAntes.nlink !== 1n)
193
+ throw new FalhaCasCacheDrift("cache_objeto_hardlink");
194
+ if (infoAntes.size > 4096n)
195
+ throw new FalhaCasCacheDrift("cache_objeto_grande");
196
+ let handle;
197
+ try {
198
+ handle = await open(caminho, constants.O_RDONLY | (constants.O_NOFOLLOW ?? 0));
199
+ }
200
+ catch (erro) {
201
+ if (erroEhAusencia(erro))
202
+ return null;
203
+ throw erro;
204
+ }
205
+ try {
206
+ await confirmarGuardaCadeia(guarda);
207
+ const infoHandle = await handle.stat({ bigint: true });
208
+ if (!identidadeArquivoValida(caminho, infoAntes, infoHandle)) {
209
+ const atual = await lstatOuNull(caminho);
210
+ if (!atual
211
+ || !mesmaIdentidade(identidadeDe(infoAntes), identidadeDe(atual)))
212
+ return null;
213
+ throw new FalhaCasCacheDrift("cache_objeto_corrupto");
214
+ }
215
+ const bytes = await lerHandleLimitado(handle, 4096);
216
+ const infoHandleFinal = await handle.stat({ bigint: true });
217
+ const infoFinal = await lstatOuNull(caminho);
218
+ await confirmarGuardaCadeia(guarda);
219
+ if (!infoFinal
220
+ || !mesmaIdentidade(identidadeDe(infoAntes), identidadeDe(infoFinal)))
221
+ return null;
222
+ if (bytes.byteLength > 4096
223
+ || !identidadeArquivoValida(caminho, infoFinal, infoHandleFinal)) {
224
+ throw new FalhaCasCacheDrift("cache_objeto_corrupto");
225
+ }
226
+ let valor = null;
227
+ try {
228
+ valor = JSON.parse(bytes.toString("utf8"));
229
+ }
230
+ catch {
231
+ // Lock incompleto só pode ser removido após a janela de segurança.
232
+ }
233
+ return { info: infoFinal, valor };
234
+ }
235
+ finally {
236
+ await handle.close().catch(() => undefined);
237
+ }
238
+ }
239
+ async function removerLockOrfao(caminho, guarda) {
240
+ const leitura = await lerLockSeguro(caminho, guarda);
241
+ if (!leitura)
242
+ return true;
243
+ const lock = registroLockCache(leitura.valor) ? leitura.valor : null;
244
+ const idadeMs = Math.max(0, Date.now() - Number(leitura.info.mtimeMs));
245
+ const pertenceInstanciaAtual = lock?.pid === process.pid
246
+ && lock.processoIniciadoEm === PROCESSO_INICIADO_EM_CACHE_DRIFT;
247
+ const orfao = lock
248
+ ? (!TOKENS_LOCK_ATIVOS.has(lock.token)
249
+ && !pertenceInstanciaAtual
250
+ && (!processoEstaAtivo(lock.pid) || idadeMs >= TTL_LOCK_CACHE_DRIFT_MS))
251
+ : idadeMs >= TTL_LOCK_CACHE_DRIFT_MS;
252
+ if (!orfao)
253
+ return false;
254
+ await removerArquivoGuardadoSeMesmo(caminho, identidadeDe(leitura.info), guarda);
255
+ return await lstatOuNull(caminho) === null;
256
+ }
257
+ export async function adquirirLockPublicacao(opcoes) {
258
+ const caminho = path.join(opcoes.pasta, `.${opcoes.chave.slice("sha256:".length)}.lock`);
259
+ const token = randomUUID();
260
+ let contendido = false;
261
+ let guarda = opcoes.guardaInicial;
262
+ for (let tentativa = 0; tentativa < TENTATIVAS_LOCK_CACHE_DRIFT; tentativa += 1) {
263
+ let handle;
264
+ let identidade;
265
+ try {
266
+ await confirmarGuardaCadeia(guarda);
267
+ handle = await open(caminho, "wx", 0o600);
268
+ await confirmarGuardaCadeia(guarda);
269
+ const [infoHandle, infoCaminho] = await Promise.all([
270
+ handle.stat({ bigint: true }),
271
+ lstat(caminho, { bigint: true }),
272
+ ]);
273
+ if (!identidadeArquivoValida(caminho, infoCaminho, infoHandle)) {
274
+ throw new FalhaCasCacheDrift("cache_objeto_hardlink");
275
+ }
276
+ identidade = identidadeDe(infoHandle);
277
+ await aplicarPermissaoArquivo(handle);
278
+ await confirmarGuardaCadeia(guarda);
279
+ await handle.writeFile(JSON.stringify({
280
+ schema: SCHEMA_LOCK_CACHE_DRIFT,
281
+ pid: process.pid,
282
+ processoIniciadoEm: PROCESSO_INICIADO_EM_CACHE_DRIFT,
283
+ token,
284
+ criadoEm: Date.now(),
285
+ }), "utf8");
286
+ await handle.sync();
287
+ const [infoHandleFinal, infoCaminhoFinal] = await Promise.all([
288
+ handle.stat({ bigint: true }),
289
+ lstat(caminho, { bigint: true }),
290
+ ]);
291
+ if (!identidadeArquivoValida(caminho, infoCaminhoFinal, infoHandleFinal)
292
+ || !mesmaIdentidade(identidade, identidadeDe(infoHandleFinal))) {
293
+ throw new FalhaCasCacheDrift("cache_objeto_corrupto");
294
+ }
295
+ await confirmarGuardaCadeia(guarda);
296
+ TOKENS_LOCK_ATIVOS.add(token);
297
+ return { caminho, handle, identidade, guarda, token, contendido };
298
+ }
299
+ catch (erro) {
300
+ await handle?.close().catch(() => undefined);
301
+ if (identidade)
302
+ await removerArquivoGuardadoSeMesmo(caminho, identidade, guarda);
303
+ if (erro.code !== "EEXIST")
304
+ throw erro;
305
+ contendido = true;
306
+ guarda = await capturarGuardaCadeia(opcoes.raiz, opcoes.identidadeRaiz, opcoes.pasta);
307
+ const removido = await removerLockOrfao(caminho, guarda);
308
+ if (!removido)
309
+ await esperar(INTERVALO_LOCK_CACHE_DRIFT_MS);
310
+ }
311
+ }
312
+ throw new FalhaCasCacheDrift("cache_io_indisponivel");
313
+ }
314
+ export async function confirmarLockPublicacao(lock) {
315
+ await confirmarGuardaCadeia(lock.guarda);
316
+ const [infoHandle, infoCaminho] = await Promise.all([
317
+ lock.handle.stat({ bigint: true }),
318
+ lstat(lock.caminho, { bigint: true }),
319
+ ]);
320
+ if (!identidadeArquivoValida(lock.caminho, infoCaminho, infoHandle)
321
+ || !mesmaIdentidade(lock.identidade, identidadeDe(infoHandle))) {
322
+ throw new FalhaCasCacheDrift("cache_objeto_conflitante");
323
+ }
324
+ await confirmarGuardaCadeia(lock.guarda);
325
+ }
326
+ export async function liberarLockPublicacao(lock) {
327
+ await lock.handle.close().catch(() => undefined);
328
+ try {
329
+ await removerArquivoGuardadoSeMesmo(lock.caminho, lock.identidade, lock.guarda);
330
+ }
331
+ finally {
332
+ TOKENS_LOCK_ATIVOS.delete(lock.token);
333
+ }
334
+ }
335
+ export async function limparTemporariosOrfaos(chave, pasta, guarda) {
336
+ const digest = chave.slice("sha256:".length);
337
+ const padrao = new RegExp(`^\\.${digest}\\.[a-f0-9-]{36}\\.(?:tmp|replaced)$`, "u");
338
+ await confirmarGuardaCadeia(guarda);
339
+ const entradas = await readdir(pasta, { withFileTypes: true });
340
+ await confirmarGuardaCadeia(guarda);
341
+ for (const entrada of entradas) {
342
+ if (entrada.isSymbolicLink() || !padrao.test(entrada.name))
343
+ continue;
344
+ const caminho = path.join(pasta, entrada.name);
345
+ const info = await lstatOuNull(caminho);
346
+ if (info?.isFile() && !info.isSymbolicLink()) {
347
+ await removerArquivoGuardadoSeMesmo(caminho, identidadeDe(info), guarda, true);
348
+ }
349
+ }
350
+ }
351
+ //# sourceMappingURL=driftCacheCas.js.map
@@ -0,0 +1,64 @@
1
+ import { type BigIntStats } from "node:fs";
2
+ import { type FileHandle } from "node:fs/promises";
3
+ export type CodigoErroFilesystemCacheDrift = "cache_root_sobrepoe_workspace" | "cache_root_link" | "cache_root_hardlink" | "cache_root_nao_diretorio" | "cache_root_indisponivel";
4
+ export type OrigemRaizCacheSema = "explicita" | "localappdata" | "windows_fallback" | "macos_cache" | "xdg_cache" | "unix_fallback";
5
+ export interface OpcoesResolverRaizCacheSema {
6
+ plataforma?: NodeJS.Platform;
7
+ ambiente?: Readonly<Record<string, string | undefined>>;
8
+ diretorioUsuario?: string;
9
+ raizCache?: string;
10
+ }
11
+ export type ResolucaoRaizCacheSema = {
12
+ disponivel: true;
13
+ raiz: string;
14
+ origem: OrigemRaizCacheSema;
15
+ } | {
16
+ disponivel: false;
17
+ codigo: "cache_home_invalido" | "cache_root_relativa";
18
+ };
19
+ export interface IdentidadeFilesystem {
20
+ dev: bigint;
21
+ ino: bigint;
22
+ }
23
+ export interface ComponenteGuardadoCache {
24
+ caminho: string;
25
+ identidade: IdentidadeFilesystem;
26
+ }
27
+ export interface GuardaCadeiaCache {
28
+ raiz: string;
29
+ destino: string;
30
+ componentes: readonly ComponenteGuardadoCache[];
31
+ }
32
+ export interface EstadoEntradaCache {
33
+ dev: bigint;
34
+ ino: bigint;
35
+ size: bigint;
36
+ mtimeNs: bigint;
37
+ ctimeNs: bigint;
38
+ nlink: bigint;
39
+ tipo: "arquivo" | "diretorio" | "link" | "outro";
40
+ }
41
+ export declare class FalhaFilesystemCacheDrift extends Error {
42
+ readonly codigo: CodigoErroFilesystemCacheDrift;
43
+ constructor(codigo: CodigoErroFilesystemCacheDrift);
44
+ }
45
+ export declare function resolverRaizCacheSema(opcoes?: OpcoesResolverRaizCacheSema): ResolucaoRaizCacheSema;
46
+ export declare function caminhoContido(base: string, alvo: string): boolean;
47
+ export declare function caminhosSobrepostos(a: string, b: string): boolean;
48
+ export declare function identidadeDe(info: BigIntStats): IdentidadeFilesystem;
49
+ export declare function mesmaIdentidade(a: IdentidadeFilesystem, b: IdentidadeFilesystem): boolean;
50
+ export declare function erroEhAusencia(erro: unknown): boolean;
51
+ export declare function lstatOuNull(caminho: string): Promise<BigIntStats | null>;
52
+ export declare function estadoEntrada(info: BigIntStats): EstadoEntradaCache;
53
+ export declare function mesmoEstadoEntrada(a: EstadoEntradaCache | null, b: EstadoEntradaCache | null): boolean;
54
+ export declare function capturarGuardaCadeia(raiz: string, identidadeRaiz: IdentidadeFilesystem, destino: string): Promise<GuardaCadeiaCache>;
55
+ export declare function confirmarGuardaCadeia(guarda: GuardaCadeiaCache): Promise<void>;
56
+ export declare function aplicarPermissaoArquivo(handle: FileHandle): Promise<void>;
57
+ export declare function lerHandleLimitado(handle: FileHandle, limiteBytes: number): Promise<Buffer>;
58
+ export declare function validarComponentesExistentesSemLink(alvo: string): Promise<void>;
59
+ export declare function prepararRaizCache(caminho: string): Promise<{
60
+ real: string;
61
+ identidade: IdentidadeFilesystem;
62
+ }>;
63
+ export declare function garantirSubdiretorioSeguro(raiz: string, identidadeRaiz: IdentidadeFilesystem, destino: string): Promise<GuardaCadeiaCache>;
64
+ export declare function identidadeArquivoValida(caminho: string, infoCaminho: BigIntStats, infoHandle: BigIntStats): boolean;