@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.
- package/README.md +265 -217
- package/dist/agentContextPack.js +14 -10
- package/dist/agentEntryPoints.d.ts +5 -0
- package/dist/agentEntryPoints.js +567 -557
- package/dist/angular-consumer-standalone.js +1 -1
- package/dist/bin.d.ts +6 -0
- package/dist/bin.js +130 -0
- package/dist/cliArgs.js +4 -4
- package/dist/cliControlError.d.ts +12 -0
- package/dist/cliControlError.js +47 -0
- package/dist/cliGrammar.d.ts +11 -0
- package/dist/cliGrammar.js +551 -0
- package/dist/cliHelp.d.ts +13 -0
- package/dist/cliHelp.js +19 -0
- package/dist/cliHelpTexto.d.ts +3 -0
- package/dist/cliHelpTexto.js +168 -0
- package/dist/cliRuntime.d.ts +2 -0
- package/dist/cliRuntime.js +31 -0
- package/dist/comandos.js +9 -22
- package/dist/contexto.js +5 -5
- package/dist/dev/index.d.ts +1 -0
- package/dist/dev/index.js +51 -9
- package/dist/discovery/catalog.js +3 -3
- package/dist/distribuicao/filesystemGlobal.d.ts +63 -0
- package/dist/distribuicao/filesystemGlobal.js +701 -0
- package/dist/distribuicao/index.d.ts +7 -0
- package/dist/distribuicao/index.js +227 -0
- package/dist/distribuicao/launcherGlobal.d.ts +53 -0
- package/dist/distribuicao/launcherGlobal.js +643 -0
- package/dist/distribuicao/launcherWindows.d.ts +28 -0
- package/dist/distribuicao/launcherWindows.js +326 -0
- package/dist/distribuicao/lockContextGlobal.d.ts +10 -0
- package/dist/distribuicao/lockContextGlobal.js +17 -0
- package/dist/distribuicao/lockGlobal.d.ts +6 -0
- package/dist/distribuicao/lockGlobal.js +520 -0
- package/dist/distribuicao/skillGlobal.d.ts +48 -0
- package/dist/distribuicao/skillGlobal.js +652 -0
- package/dist/distribuicao/skillIntentPolicy.d.ts +21 -0
- package/dist/distribuicao/skillIntentPolicy.js +115 -0
- package/dist/distribuicao/tipos.d.ts +50 -0
- package/dist/distribuicao/tipos.js +10 -0
- package/dist/distribuicao/versaoSemantica.d.ts +3 -0
- package/dist/distribuicao/versaoSemantica.js +62 -0
- package/dist/drift.part01.d.ts +26 -24
- package/dist/drift.part01.js +2 -1
- package/dist/drift.part04.d.ts +12 -3
- package/dist/drift.part04.js +88 -17
- package/dist/drift.part05.d.ts +2 -2
- package/dist/drift.part05.js +8 -6
- package/dist/drift.part06.d.ts +2 -2
- package/dist/drift.part06.js +113 -26
- package/dist/drift.part07.d.ts +11 -11
- package/dist/drift.part07.js +261 -265
- package/dist/drift.part08.d.ts +2 -2
- package/dist/drift.part08.js +35 -26
- package/dist/drift.part11.js +238 -56
- package/dist/drift.part12.d.ts +1 -1
- package/dist/drift.part12.js +193 -21
- package/dist/drift.part13.d.ts +20 -39
- package/dist/drift.part13.js +601 -647
- package/dist/drift.part14.js +21 -7
- package/dist/driftCacheCas.d.ts +43 -0
- package/dist/driftCacheCas.js +351 -0
- package/dist/driftCacheFilesystem.d.ts +64 -0
- package/dist/driftCacheFilesystem.js +313 -0
- package/dist/driftCacheModes.d.ts +38 -0
- package/dist/driftCacheModes.js +147 -0
- package/dist/driftCacheStore.d.ts +80 -0
- package/dist/driftCacheStore.js +603 -0
- package/dist/driftCatalogo.d.ts +2 -28
- package/dist/driftCatalogo.js +143 -284
- package/dist/driftEscopo.d.ts +1 -3
- package/dist/driftEscopo.js +235 -151
- package/dist/driftEscopoReferencias.d.ts +5 -1
- package/dist/driftEscopoReferencias.js +375 -28
- package/dist/driftOrcamento.d.ts +0 -6
- package/dist/driftOrcamento.js +2 -1
- package/dist/execucoesExternas.js +19 -5
- package/dist/geracaoCore.js +4 -6
- package/dist/iaPrompts.d.ts +3 -3
- package/dist/iaPrompts.js +312 -313
- package/dist/index.d.ts +4 -1
- package/dist/index.js +6 -25
- package/dist/index.part01.d.ts +20 -28
- package/dist/index.part01.js +16 -237
- package/dist/index.part02.js +36 -22
- package/dist/index.part03.d.ts +24 -2
- package/dist/index.part03.js +83 -19
- package/dist/index.part04.d.ts +10 -2
- package/dist/index.part04.js +142 -120
- package/dist/index.part05.js +80 -78
- package/dist/index.part06.js +34 -17
- package/dist/index.part07.js +7 -3
- package/dist/index.part08.d.ts +1 -1
- package/dist/index.part08.js +22 -27
- package/dist/initCommand.js +5 -1
- package/dist/initTemplatesBase.js +81 -79
- package/dist/pipelineConteudo/command.d.ts +1 -0
- package/dist/pipelineConteudo/command.js +9 -2
- package/dist/pipelineConteudo/help.d.ts +2 -0
- package/dist/pipelineConteudo/help.js +33 -0
- package/dist/profileAuthorCommand.js +3 -7
- package/dist/profileCommand.js +3 -7
- package/dist/projetoCarregar.js +35 -17
- package/dist/projetoCatalogo.d.ts +1 -0
- package/dist/projetoCatalogo.js +64 -25
- package/dist/projetoOrigens.d.ts +2 -0
- package/dist/projetoOrigens.js +65 -9
- package/dist/projetoTipos.d.ts +1 -0
- package/dist/resultadoCli.d.ts +20 -0
- package/dist/resultadoCli.js +57 -0
- package/dist/saidaCli.d.ts +35 -0
- package/dist/saidaCli.js +118 -0
- package/dist/sistemasInterativos/acceptanceEvidence.d.ts +22 -0
- package/dist/sistemasInterativos/acceptanceEvidence.js +345 -0
- package/dist/sistemasInterativos/engineObservation.d.ts +12 -0
- package/dist/sistemasInterativos/engineObservation.js +438 -0
- package/dist/sistemasInterativos/jobOrchestration.d.ts +2 -0
- package/dist/sistemasInterativos/jobOrchestration.js +204 -0
- package/dist/sistemasInterativos/operationPrimitives.d.ts +21 -0
- package/dist/sistemasInterativos/operationPrimitives.js +194 -0
- package/dist/sistemasInterativos/operations.d.ts +4 -39
- package/dist/sistemasInterativos/operations.js +5 -1164
- package/dist/skillCommand.d.ts +5 -0
- package/dist/skillCommand.js +88 -0
- package/docs/README.md +34 -30
- package/docs/ai-integration.md +25 -12
- package/docs/ai-onboarding.md +37 -18
- package/docs/ai-workflow.md +9 -7
- package/docs/cli.md +125 -7
- package/docs/commands.md +41 -20
- package/docs/deploy.md +21 -8
- package/docs/descoberta-capacidades.md +106 -106
- package/docs/documentation.md +49 -39
- package/docs/drift-cache.md +108 -0
- package/docs/getting-started.md +43 -18
- package/docs/pipeline-conteudo.md +246 -246
- package/docs/profiles.md +54 -54
- package/docs/repositories.md +19 -2
- package/docs/rollback.md +15 -8
- package/docs/security.md +25 -3
- package/docs/sistemas-interativos.md +379 -374
- package/docs/testing.md +139 -40
- package/exemplos/pipeline-conteudo/README.md +44 -44
- package/exemplos/pipeline-conteudo/alvos.json +23 -23
- package/exemplos/pipeline-conteudo/definicao.json +136 -136
- package/exemplos/profile_simulation.sema +211 -211
- package/exemplos/sistemas-interativos/README.md +100 -100
- package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -5
- package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -16
- package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -32
- package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -93
- package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -78
- package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -27
- package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -79
- package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -42
- package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -32
- package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -23
- package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -39
- package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -46
- package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -39
- package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -37
- package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -104
- package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -27
- package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -118
- package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -459
- package/exemplos/sistemas-interativos/game-2d.json +83 -83
- package/exemplos/sistemas-interativos/game-3d-human.json +81 -81
- package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -97
- package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -94
- package/exemplos/sistemas-interativos/game-xr-human.json +80 -80
- package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -108
- package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -75
- package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -58
- package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -97
- package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -141
- package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -112
- package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -103
- package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -95
- package/node_modules/@sema/gerador-cpp/package.json +1 -1
- package/node_modules/@sema/gerador-dotnet/package.json +1 -1
- package/node_modules/@sema/gerador-lua/dist/index.js +51 -51
- package/node_modules/@sema/gerador-php/dist/index.js +113 -113
- package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +1 -0
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js +1 -0
- package/package.json +9 -4
- package/scripts/postinstall.mjs +148 -0
- package/skills/sema/SKILL.md +199 -0
- package/skills/sema/agents/openai.yaml +4 -0
- package/dist/driftCache.d.ts +0 -49
- package/dist/driftCache.js +0 -311
- package/dist/driftCacheIncremental.d.ts +0 -98
- package/dist/driftCacheIncremental.js +0 -596
- package/dist/driftCatalogoPersistente.d.ts +0 -8
- package/dist/driftCatalogoPersistente.js +0 -77
- package/node_modules/@sema/gerador-cpp/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-css/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-css/dist/index.part01.js.map +0 -1
- package/node_modules/@sema/gerador-css/dist/index.part02.js.map +0 -1
- package/node_modules/@sema/gerador-dart/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-dotnet/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-html/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-javascript/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-lua/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-php/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-python/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-python/dist/index.part01.js.map +0 -1
- package/node_modules/@sema/gerador-python/dist/index.part02.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.part01.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.part02.js.map +0 -1
- package/node_modules/@sema/gerador-typescript/dist/index.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ast/tipos.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/diagnosticos/index.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/diagnosticos/snippets.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/formatador/index.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/formatador/index.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/formatador/index.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/index.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/ir/modelos.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/lexer/lexer.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/lexer/tokens.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.declaracoes.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.modulo.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/parser/parser.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/persistencia/contratos.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part03.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part04.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part05.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part06.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part07.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.part08.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.part01.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/estruturas.part02.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/orcamentoSemantico.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/semantico/seguranca.js.map +0 -1
- package/node_modules/@sema/nucleo/dist/util/arquivos.js.map +0 -1
- package/node_modules/@sema/padroes/dist/index.js.map +0 -1
|
@@ -1,596 +0,0 @@
|
|
|
1
|
-
// SEMA-GOVERNED: sema.produto.governanca_ia.drift
|
|
2
|
-
// Descricao: cache persistente incremental por arquivo e por grupo semantico, com validacao runtime e fast path por metadados.
|
|
3
|
-
import { createHash } from "node:crypto";
|
|
4
|
-
import { lstat, readFile, realpath } from "node:fs/promises";
|
|
5
|
-
import path from "node:path";
|
|
6
|
-
import { digestJsonCanonicoCacheDrift, serializarJsonCanonicoCacheDrift, } from "./driftCache.js";
|
|
7
|
-
import { escreverArquivoWorkspaceSeguro, validarDestinosEscritaWorkspace, } from "./workspaceWrite.js";
|
|
8
|
-
export const FILE_INDEX_SCHEMA = 2;
|
|
9
|
-
export const SCHEMA_MANIFESTO_ARQUIVOS_DRIFT = "sema.drift-file-cache/v2";
|
|
10
|
-
export const SCHEMA_GRUPO_INDICE_DRIFT = "sema.drift-index-group-cache/v2";
|
|
11
|
-
export const DIRETORIO_CACHE_INCREMENTAL_DRIFT = path.join(".tmp", "sema-cache", "drift-index", "v2");
|
|
12
|
-
export const DIRETORIO_IDENTIDADES_CACHE_INCREMENTAL_DRIFT = path.join(DIRETORIO_CACHE_INCREMENTAL_DRIFT, "identities");
|
|
13
|
-
const LIMITE_BYTES_CACHE = 64 * 1024 * 1024;
|
|
14
|
-
const PADRAO_DIGEST = /^sha256:[a-f0-9]{64}$/u;
|
|
15
|
-
function sufixoSeguroIdentidade(identidadeDigest) {
|
|
16
|
-
if (!PADRAO_DIGEST.test(identidadeDigest)) {
|
|
17
|
-
throw new TypeError(`identidade_digest_cache_drift_invalida:${identidadeDigest}`);
|
|
18
|
-
}
|
|
19
|
-
return identidadeDigest.slice("sha256:".length);
|
|
20
|
-
}
|
|
21
|
-
export function caminhoManifestoArquivosDrift(identidadeDigest) {
|
|
22
|
-
return path.join(DIRETORIO_IDENTIDADES_CACHE_INCREMENTAL_DRIFT, sufixoSeguroIdentidade(identidadeDigest), "files.json");
|
|
23
|
-
}
|
|
24
|
-
export function caminhoManifestoGruposDrift(identidadeDigest) {
|
|
25
|
-
return path.join(DIRETORIO_IDENTIDADES_CACHE_INCREMENTAL_DRIFT, sufixoSeguroIdentidade(identidadeDigest), "groups.json");
|
|
26
|
-
}
|
|
27
|
-
function registroObjeto(valor) {
|
|
28
|
-
return typeof valor === "object" && valor !== null && !Array.isArray(valor);
|
|
29
|
-
}
|
|
30
|
-
function emitirEvento(observador, evento) {
|
|
31
|
-
try {
|
|
32
|
-
observador?.(evento);
|
|
33
|
-
}
|
|
34
|
-
catch {
|
|
35
|
-
// Observabilidade nao altera o resultado funcional do drift.
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
function paraJson(valor) {
|
|
39
|
-
return JSON.parse(JSON.stringify(valor));
|
|
40
|
-
}
|
|
41
|
-
function assinaturasIguais(a, b) {
|
|
42
|
-
return a.size === b.size
|
|
43
|
-
&& a.mtimeNs === b.mtimeNs
|
|
44
|
-
&& a.ctimeNs === b.ctimeNs
|
|
45
|
-
&& a.dev === b.dev
|
|
46
|
-
&& a.ino === b.ino;
|
|
47
|
-
}
|
|
48
|
-
function assinaturaValida(valor) {
|
|
49
|
-
if (!registroObjeto(valor)) {
|
|
50
|
-
return false;
|
|
51
|
-
}
|
|
52
|
-
return ["size", "mtimeNs", "ctimeNs", "dev", "ino"]
|
|
53
|
-
.every((campo) => typeof valor[campo] === "string" && /^\d+$/u.test(valor[campo]));
|
|
54
|
-
}
|
|
55
|
-
function caminhoRelativoSeguro(baseProjeto, arquivo) {
|
|
56
|
-
const relativo = path.relative(baseProjeto, path.resolve(arquivo)).replace(/\\/g, "/");
|
|
57
|
-
if (!relativo || relativo === "." || relativo === ".." || relativo.startsWith("../") || path.isAbsolute(relativo)) {
|
|
58
|
-
throw new Error(`arquivo_cache_drift_fora_workspace:${arquivo}`);
|
|
59
|
-
}
|
|
60
|
-
return relativo;
|
|
61
|
-
}
|
|
62
|
-
function caminhoRelativoValido(caminho) {
|
|
63
|
-
return typeof caminho === "string"
|
|
64
|
-
&& caminho.length > 0
|
|
65
|
-
&& caminho !== "."
|
|
66
|
-
&& caminho !== ".."
|
|
67
|
-
&& !caminho.startsWith("../")
|
|
68
|
-
&& !caminho.includes("\\")
|
|
69
|
-
&& !path.posix.isAbsolute(caminho);
|
|
70
|
-
}
|
|
71
|
-
function chaveEstavel(valor) {
|
|
72
|
-
return createHash("sha256")
|
|
73
|
-
.update(serializarJsonCanonicoCacheDrift(valor))
|
|
74
|
-
.digest("hex");
|
|
75
|
-
}
|
|
76
|
-
function analiseValida(valor) {
|
|
77
|
-
return registroObjeto(valor)
|
|
78
|
-
&& typeof valor.payloadDigest === "string"
|
|
79
|
-
&& PADRAO_DIGEST.test(valor.payloadDigest)
|
|
80
|
-
&& digestJsonCanonicoCacheDrift(valor.payload) === valor.payloadDigest;
|
|
81
|
-
}
|
|
82
|
-
function entradaArquivoValida(chave, valor) {
|
|
83
|
-
if (!registroObjeto(valor)
|
|
84
|
-
|| valor.caminho !== chave
|
|
85
|
-
|| !caminhoRelativoValido(valor.caminho)
|
|
86
|
-
|| !assinaturaValida(valor.assinatura)
|
|
87
|
-
|| typeof valor.contentHash !== "string"
|
|
88
|
-
|| !PADRAO_DIGEST.test(valor.contentHash)
|
|
89
|
-
|| !registroObjeto(valor.analises)) {
|
|
90
|
-
return false;
|
|
91
|
-
}
|
|
92
|
-
return Object.values(valor.analises).every(analiseValida);
|
|
93
|
-
}
|
|
94
|
-
function manifestoValido(valor, identidadeDigest) {
|
|
95
|
-
if (!registroObjeto(valor)
|
|
96
|
-
|| valor.identidadeDigest !== identidadeDigest
|
|
97
|
-
|| !registroObjeto(valor.arquivos)) {
|
|
98
|
-
return false;
|
|
99
|
-
}
|
|
100
|
-
return Object.entries(valor.arquivos).every(([chave, entrada]) => entradaArquivoValida(chave, entrada));
|
|
101
|
-
}
|
|
102
|
-
function membrosGrupoValidos(valor) {
|
|
103
|
-
return Array.isArray(valor)
|
|
104
|
-
&& valor.every((item) => registroObjeto(item)
|
|
105
|
-
&& caminhoRelativoValido(item.caminho)
|
|
106
|
-
&& typeof item.contentHash === "string"
|
|
107
|
-
&& PADRAO_DIGEST.test(item.contentHash));
|
|
108
|
-
}
|
|
109
|
-
function membrosIguais(a, b) {
|
|
110
|
-
return a.length === b.length
|
|
111
|
-
&& a.every((item, indice) => (item.caminho === b[indice]?.caminho
|
|
112
|
-
&& item.contentHash === b[indice]?.contentHash));
|
|
113
|
-
}
|
|
114
|
-
function entradaGrupoValida(valor, identidadeDigest) {
|
|
115
|
-
return registroObjeto(valor)
|
|
116
|
-
&& valor.identidadeDigest === identidadeDigest
|
|
117
|
-
&& membrosGrupoValidos(valor.membros)
|
|
118
|
-
&& typeof valor.resumoDigest === "string"
|
|
119
|
-
&& PADRAO_DIGEST.test(valor.resumoDigest)
|
|
120
|
-
&& digestJsonCanonicoCacheDrift(valor.resumo) === valor.resumoDigest;
|
|
121
|
-
}
|
|
122
|
-
function manifestoGruposValido(valor, identidadeDigest) {
|
|
123
|
-
return registroObjeto(valor)
|
|
124
|
-
&& valor.identidadeDigest === identidadeDigest
|
|
125
|
-
&& registroObjeto(valor.grupos)
|
|
126
|
-
&& Object.entries(valor.grupos).every(([chave, entrada]) => (/^[a-f0-9]{64}$/u.test(chave)
|
|
127
|
-
&& entradaGrupoValida(entrada, identidadeDigest)));
|
|
128
|
-
}
|
|
129
|
-
function erroEhAusencia(erro) {
|
|
130
|
-
return ["ENOENT", "ENOTDIR"].includes(erro.code ?? "");
|
|
131
|
-
}
|
|
132
|
-
async function lerEnvelope(baseProjeto, caminhoRelativo, schema, key) {
|
|
133
|
-
try {
|
|
134
|
-
const [destino] = await validarDestinosEscritaWorkspace(baseProjeto, [caminhoRelativo]);
|
|
135
|
-
if (!destino.existe) {
|
|
136
|
-
return { estado: "miss", motivo: "arquivo_ausente" };
|
|
137
|
-
}
|
|
138
|
-
const info = await lstat(destino.caminhoAbsoluto);
|
|
139
|
-
if (!info.isFile() || info.isSymbolicLink() || info.size > LIMITE_BYTES_CACHE) {
|
|
140
|
-
return { estado: "corrupt", motivo: "arquivo_cache_invalido" };
|
|
141
|
-
}
|
|
142
|
-
const bytes = await readFile(destino.caminhoAbsoluto);
|
|
143
|
-
if (bytes.byteLength > LIMITE_BYTES_CACHE) {
|
|
144
|
-
return { estado: "corrupt", motivo: "limite_bytes_excedido" };
|
|
145
|
-
}
|
|
146
|
-
let bruto;
|
|
147
|
-
try {
|
|
148
|
-
bruto = JSON.parse(bytes.toString("utf8"));
|
|
149
|
-
}
|
|
150
|
-
catch {
|
|
151
|
-
return { estado: "corrupt", motivo: "json_invalido" };
|
|
152
|
-
}
|
|
153
|
-
if (!registroObjeto(bruto)
|
|
154
|
-
|| bruto.schema !== schema
|
|
155
|
-
|| bruto.key !== key
|
|
156
|
-
|| typeof bruto.payloadDigest !== "string"
|
|
157
|
-
|| !PADRAO_DIGEST.test(bruto.payloadDigest)) {
|
|
158
|
-
return { estado: "corrupt", motivo: "envelope_invalido" };
|
|
159
|
-
}
|
|
160
|
-
let digest;
|
|
161
|
-
try {
|
|
162
|
-
digest = digestJsonCanonicoCacheDrift(bruto.payload);
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
return { estado: "corrupt", motivo: "payload_nao_canonico" };
|
|
166
|
-
}
|
|
167
|
-
if (digest !== bruto.payloadDigest) {
|
|
168
|
-
return { estado: "corrupt", motivo: "payload_digest_divergente" };
|
|
169
|
-
}
|
|
170
|
-
return { estado: "hit", payload: bruto.payload };
|
|
171
|
-
}
|
|
172
|
-
catch (erro) {
|
|
173
|
-
return {
|
|
174
|
-
estado: "miss",
|
|
175
|
-
motivo: erroEhAusencia(erro) ? "arquivo_ausente" : "cache_indisponivel",
|
|
176
|
-
};
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
async function escreverEnvelope(baseProjeto, caminhoRelativo, schema, key, payload) {
|
|
180
|
-
const envelope = {
|
|
181
|
-
schema,
|
|
182
|
-
key,
|
|
183
|
-
payload,
|
|
184
|
-
payloadDigest: digestJsonCanonicoCacheDrift(payload),
|
|
185
|
-
};
|
|
186
|
-
const conteudo = JSON.stringify(envelope);
|
|
187
|
-
if (Buffer.byteLength(conteudo, "utf8") > LIMITE_BYTES_CACHE) {
|
|
188
|
-
throw new Error("limite_bytes_cache_incremental_excedido");
|
|
189
|
-
}
|
|
190
|
-
await escreverArquivoWorkspaceSeguro(baseProjeto, caminhoRelativo, conteudo, { sobrescrever: true });
|
|
191
|
-
}
|
|
192
|
-
export async function obterAssinaturaArquivoDrift(arquivo) {
|
|
193
|
-
const info = await lstat(arquivo, { bigint: true });
|
|
194
|
-
if (!info.isFile() || info.isSymbolicLink()) {
|
|
195
|
-
throw new Error(`arquivo_cache_drift_nao_regular:${arquivo}`);
|
|
196
|
-
}
|
|
197
|
-
return {
|
|
198
|
-
size: info.size.toString(),
|
|
199
|
-
mtimeNs: info.mtimeNs.toString(),
|
|
200
|
-
ctimeNs: info.ctimeNs.toString(),
|
|
201
|
-
dev: info.dev.toString(),
|
|
202
|
-
ino: info.ino.toString(),
|
|
203
|
-
};
|
|
204
|
-
}
|
|
205
|
-
export class CacheIncrementalDrift {
|
|
206
|
-
identidadeDigest;
|
|
207
|
-
politica;
|
|
208
|
-
baseProjeto;
|
|
209
|
-
baseProjetoReal;
|
|
210
|
-
observador;
|
|
211
|
-
caminhoManifestoArquivos;
|
|
212
|
-
caminhoManifestoGrupos;
|
|
213
|
-
manifesto;
|
|
214
|
-
manifestoEmVoo;
|
|
215
|
-
manifestoSujo = false;
|
|
216
|
-
arquivosSujos = new Set();
|
|
217
|
-
manifestoGrupos;
|
|
218
|
-
manifestoGruposEmVoo;
|
|
219
|
-
manifestoGruposSujo = false;
|
|
220
|
-
gruposSujos = new Set();
|
|
221
|
-
arquivosEmVoo = new Map();
|
|
222
|
-
metricasAtuais = {
|
|
223
|
-
metadataHits: 0,
|
|
224
|
-
contentHits: 0,
|
|
225
|
-
fileMisses: 0,
|
|
226
|
-
groupHits: 0,
|
|
227
|
-
groupMisses: 0,
|
|
228
|
-
corruptos: 0,
|
|
229
|
-
extracoesArquivo: 0,
|
|
230
|
-
extracoesGrupo: 0,
|
|
231
|
-
gravacoes: 0,
|
|
232
|
-
errosGravacao: 0,
|
|
233
|
-
};
|
|
234
|
-
constructor(opcoes) {
|
|
235
|
-
this.baseProjeto = path.resolve(opcoes.baseProjeto);
|
|
236
|
-
this.baseProjetoReal = realpath(this.baseProjeto);
|
|
237
|
-
this.politica = opcoes.politica;
|
|
238
|
-
this.identidadeDigest = digestJsonCanonicoCacheDrift(opcoes.identidade);
|
|
239
|
-
this.caminhoManifestoArquivos = caminhoManifestoArquivosDrift(this.identidadeDigest);
|
|
240
|
-
this.caminhoManifestoGrupos = caminhoManifestoGruposDrift(this.identidadeDigest);
|
|
241
|
-
this.observador = opcoes.observador;
|
|
242
|
-
}
|
|
243
|
-
metricas() {
|
|
244
|
-
return { ...this.metricasAtuais };
|
|
245
|
-
}
|
|
246
|
-
async resolverArquivo(opcoes) {
|
|
247
|
-
const chaveExecucao = `${process.platform === "win32" ? path.resolve(opcoes.arquivo).toLowerCase() : path.resolve(opcoes.arquivo)}\0${opcoes.analise}`;
|
|
248
|
-
const existenteEmVoo = this.arquivosEmVoo.get(chaveExecucao);
|
|
249
|
-
if (existenteEmVoo) {
|
|
250
|
-
return existenteEmVoo;
|
|
251
|
-
}
|
|
252
|
-
const execucao = this.resolverArquivoInterno(opcoes);
|
|
253
|
-
this.arquivosEmVoo.set(chaveExecucao, execucao);
|
|
254
|
-
void execucao.catch(() => {
|
|
255
|
-
if (this.arquivosEmVoo.get(chaveExecucao) === execucao) {
|
|
256
|
-
this.arquivosEmVoo.delete(chaveExecucao);
|
|
257
|
-
}
|
|
258
|
-
});
|
|
259
|
-
return execucao;
|
|
260
|
-
}
|
|
261
|
-
async resolverArquivoInterno(opcoes) {
|
|
262
|
-
await this.validarArquivoNoWorkspace(opcoes.arquivo);
|
|
263
|
-
const caminho = caminhoRelativoSeguro(this.baseProjeto, opcoes.arquivo);
|
|
264
|
-
const assinar = opcoes.assinar ?? (() => obterAssinaturaArquivoDrift(opcoes.arquivo));
|
|
265
|
-
const assinaturaAntes = await assinar();
|
|
266
|
-
const manifesto = await this.obterManifesto();
|
|
267
|
-
const existente = manifesto.arquivos[caminho];
|
|
268
|
-
const analiseExistente = existente?.analises[opcoes.analise];
|
|
269
|
-
const payloadExistente = analiseExistente?.payload;
|
|
270
|
-
const payloadValido = analiseExistente !== undefined && opcoes.validar(payloadExistente);
|
|
271
|
-
if (analiseExistente && !payloadValido) {
|
|
272
|
-
this.registrarCorrupto(opcoes.arquivo, "payload_schema_invalido");
|
|
273
|
-
}
|
|
274
|
-
if (this.politica === "auto"
|
|
275
|
-
&& existente
|
|
276
|
-
&& payloadValido
|
|
277
|
-
&& assinaturasIguais(existente.assinatura, assinaturaAntes)) {
|
|
278
|
-
this.metricasAtuais.metadataHits += 1;
|
|
279
|
-
emitirEvento(this.observador, {
|
|
280
|
-
tipo: "cache.hit",
|
|
281
|
-
caminho: path.resolve(opcoes.arquivo),
|
|
282
|
-
motivo: "metadata_hit",
|
|
283
|
-
});
|
|
284
|
-
return {
|
|
285
|
-
caminho,
|
|
286
|
-
contentHash: existente.contentHash,
|
|
287
|
-
valor: payloadExistente,
|
|
288
|
-
origem: "metadata_hit",
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
this.metricasAtuais.fileMisses += 1;
|
|
292
|
-
emitirEvento(this.observador, {
|
|
293
|
-
tipo: "cache.miss",
|
|
294
|
-
caminho: path.resolve(opcoes.arquivo),
|
|
295
|
-
motivo: this.politica === "refresh" ? "politica_refresh" : this.politica === "off" ? "politica_off" : "metadata_miss",
|
|
296
|
-
});
|
|
297
|
-
const conteudo = await opcoes.ler();
|
|
298
|
-
if (this.politica === "auto"
|
|
299
|
-
&& existente
|
|
300
|
-
&& payloadValido
|
|
301
|
-
&& existente.contentHash === conteudo.digest) {
|
|
302
|
-
const assinaturaDepois = await assinar();
|
|
303
|
-
if (assinaturasIguais(assinaturaAntes, assinaturaDepois)) {
|
|
304
|
-
existente.assinatura = assinaturaDepois;
|
|
305
|
-
this.manifestoSujo = true;
|
|
306
|
-
this.arquivosSujos.add(caminho);
|
|
307
|
-
}
|
|
308
|
-
this.metricasAtuais.contentHits += 1;
|
|
309
|
-
emitirEvento(this.observador, {
|
|
310
|
-
tipo: "cache.hit",
|
|
311
|
-
caminho: path.resolve(opcoes.arquivo),
|
|
312
|
-
motivo: "content_hit",
|
|
313
|
-
});
|
|
314
|
-
return {
|
|
315
|
-
caminho,
|
|
316
|
-
contentHash: conteudo.digest,
|
|
317
|
-
valor: payloadExistente,
|
|
318
|
-
origem: "content_hit",
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
this.metricasAtuais.extracoesArquivo += 1;
|
|
322
|
-
emitirEvento(this.observador, {
|
|
323
|
-
tipo: "extractor.run",
|
|
324
|
-
caminho: path.resolve(opcoes.arquivo),
|
|
325
|
-
motivo: `arquivo:${opcoes.analise}`,
|
|
326
|
-
});
|
|
327
|
-
const valor = paraJson(await opcoes.extrair(conteudo));
|
|
328
|
-
if (!opcoes.validar(valor)) {
|
|
329
|
-
throw new Error(`extrator_cache_drift_payload_invalido:${opcoes.analise}:${caminho}`);
|
|
330
|
-
}
|
|
331
|
-
if (this.politica !== "off") {
|
|
332
|
-
const assinaturaDepois = await assinar();
|
|
333
|
-
if (assinaturasIguais(assinaturaAntes, assinaturaDepois)) {
|
|
334
|
-
const analises = existente?.contentHash === conteudo.digest
|
|
335
|
-
? { ...existente.analises }
|
|
336
|
-
: {};
|
|
337
|
-
analises[opcoes.analise] = {
|
|
338
|
-
payload: valor,
|
|
339
|
-
payloadDigest: digestJsonCanonicoCacheDrift(valor),
|
|
340
|
-
};
|
|
341
|
-
manifesto.arquivos[caminho] = {
|
|
342
|
-
caminho,
|
|
343
|
-
assinatura: assinaturaDepois,
|
|
344
|
-
contentHash: conteudo.digest,
|
|
345
|
-
analises,
|
|
346
|
-
};
|
|
347
|
-
this.manifestoSujo = true;
|
|
348
|
-
this.arquivosSujos.add(caminho);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
return {
|
|
352
|
-
caminho,
|
|
353
|
-
contentHash: conteudo.digest,
|
|
354
|
-
valor,
|
|
355
|
-
origem: "calculado",
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
async resolverGrupo(opcoes) {
|
|
359
|
-
const membros = opcoes.membros
|
|
360
|
-
.map((membro) => ({
|
|
361
|
-
caminho: caminhoRelativoSeguro(this.baseProjeto, membro.caminho),
|
|
362
|
-
contentHash: membro.contentHash,
|
|
363
|
-
}))
|
|
364
|
-
.sort((a, b) => a.caminho.localeCompare(b.caminho, "en"));
|
|
365
|
-
// A chave e ancorada no primeiro arquivo, nao no conteudo nem na composicao
|
|
366
|
-
// atual do grupo. Mudancas sobrescrevem a mesma entrada e evitam crescimento
|
|
367
|
-
// infinito do cache; a lista completa de membros continua validada no envelope.
|
|
368
|
-
const chave = chaveEstavel({ ancora: membros[0]?.caminho ?? "grupo-vazio" });
|
|
369
|
-
const caminhoRelativo = this.caminhoManifestoGrupos;
|
|
370
|
-
if (this.politica === "auto") {
|
|
371
|
-
const manifesto = await this.obterManifestoGrupos();
|
|
372
|
-
const payload = manifesto.grupos[chave];
|
|
373
|
-
if (payload) {
|
|
374
|
-
const identidadeAtual = payload.identidadeDigest === this.identidadeDigest;
|
|
375
|
-
const membrosAtuais = membrosIguais(payload.membros, membros);
|
|
376
|
-
if (identidadeAtual && membrosAtuais) {
|
|
377
|
-
if (opcoes.validar(payload.resumo)) {
|
|
378
|
-
this.metricasAtuais.groupHits += 1;
|
|
379
|
-
emitirEvento(this.observador, {
|
|
380
|
-
tipo: "cache.hit",
|
|
381
|
-
chave,
|
|
382
|
-
caminho: path.resolve(this.baseProjeto, caminhoRelativo),
|
|
383
|
-
motivo: "group_content_hit",
|
|
384
|
-
});
|
|
385
|
-
return { chave, valor: payload.resumo, origem: "cache" };
|
|
386
|
-
}
|
|
387
|
-
this.registrarCorrupto(path.resolve(this.baseProjeto, caminhoRelativo), "payload_schema_invalido");
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
this.metricasAtuais.groupMisses += 1;
|
|
392
|
-
emitirEvento(this.observador, {
|
|
393
|
-
tipo: "cache.miss",
|
|
394
|
-
chave,
|
|
395
|
-
caminho: path.resolve(this.baseProjeto, caminhoRelativo),
|
|
396
|
-
motivo: this.politica === "refresh" ? "politica_refresh" : this.politica === "off" ? "politica_off" : "group_miss",
|
|
397
|
-
});
|
|
398
|
-
this.metricasAtuais.extracoesGrupo += 1;
|
|
399
|
-
emitirEvento(this.observador, {
|
|
400
|
-
tipo: "extractor.run",
|
|
401
|
-
chave,
|
|
402
|
-
caminho: opcoes.membros[0]?.caminho,
|
|
403
|
-
motivo: `grupo:${membros.length}`,
|
|
404
|
-
});
|
|
405
|
-
const valor = paraJson(await opcoes.calcular());
|
|
406
|
-
if (!opcoes.validar(valor)) {
|
|
407
|
-
throw new Error(`extrator_grupo_cache_drift_payload_invalido:${chave}`);
|
|
408
|
-
}
|
|
409
|
-
if (this.politica !== "off") {
|
|
410
|
-
const payload = {
|
|
411
|
-
identidadeDigest: this.identidadeDigest,
|
|
412
|
-
membros,
|
|
413
|
-
resumo: valor,
|
|
414
|
-
resumoDigest: digestJsonCanonicoCacheDrift(valor),
|
|
415
|
-
};
|
|
416
|
-
const manifesto = await this.obterManifestoGrupos();
|
|
417
|
-
manifesto.grupos[chave] = payload;
|
|
418
|
-
this.manifestoGruposSujo = true;
|
|
419
|
-
this.gruposSujos.add(chave);
|
|
420
|
-
}
|
|
421
|
-
return { chave, valor, origem: "calculado" };
|
|
422
|
-
}
|
|
423
|
-
async finalizar() {
|
|
424
|
-
if (this.politica === "off") {
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
if (this.manifestoSujo && this.manifesto) {
|
|
428
|
-
try {
|
|
429
|
-
this.manifesto = await this.gravarManifestoArquivosComMerge(this.manifesto);
|
|
430
|
-
this.metricasAtuais.gravacoes += 1;
|
|
431
|
-
this.manifestoSujo = false;
|
|
432
|
-
this.arquivosSujos.clear();
|
|
433
|
-
}
|
|
434
|
-
catch {
|
|
435
|
-
this.metricasAtuais.errosGravacao += 1;
|
|
436
|
-
}
|
|
437
|
-
}
|
|
438
|
-
if (this.manifestoGruposSujo && this.manifestoGrupos) {
|
|
439
|
-
try {
|
|
440
|
-
this.manifestoGrupos = await this.gravarManifestoGruposComMerge(this.manifestoGrupos);
|
|
441
|
-
this.metricasAtuais.gravacoes += 1;
|
|
442
|
-
this.manifestoGruposSujo = false;
|
|
443
|
-
this.gruposSujos.clear();
|
|
444
|
-
}
|
|
445
|
-
catch {
|
|
446
|
-
this.metricasAtuais.errosGravacao += 1;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
chaveEnvelope(tipo) {
|
|
451
|
-
return `${tipo}:${this.identidadeDigest}`;
|
|
452
|
-
}
|
|
453
|
-
async lerManifestoArquivosAtual() {
|
|
454
|
-
const leitura = await lerEnvelope(this.baseProjeto, this.caminhoManifestoArquivos, SCHEMA_MANIFESTO_ARQUIVOS_DRIFT, this.chaveEnvelope("files"));
|
|
455
|
-
return leitura.estado === "hit" && manifestoValido(leitura.payload, this.identidadeDigest)
|
|
456
|
-
? leitura.payload
|
|
457
|
-
: undefined;
|
|
458
|
-
}
|
|
459
|
-
async lerManifestoGruposAtual() {
|
|
460
|
-
const leitura = await lerEnvelope(this.baseProjeto, this.caminhoManifestoGrupos, SCHEMA_GRUPO_INDICE_DRIFT, this.chaveEnvelope("groups"));
|
|
461
|
-
return leitura.estado === "hit" && manifestoGruposValido(leitura.payload, this.identidadeDigest)
|
|
462
|
-
? leitura.payload
|
|
463
|
-
: undefined;
|
|
464
|
-
}
|
|
465
|
-
async gravarManifestoArquivosComMerge(local) {
|
|
466
|
-
let ultimoErro;
|
|
467
|
-
for (let tentativa = 0; tentativa < 2; tentativa += 1) {
|
|
468
|
-
const publicado = await this.lerManifestoArquivosAtual();
|
|
469
|
-
const mesclado = {
|
|
470
|
-
identidadeDigest: this.identidadeDigest,
|
|
471
|
-
arquivos: publicado ? { ...publicado.arquivos } : {},
|
|
472
|
-
};
|
|
473
|
-
for (const caminho of this.arquivosSujos) {
|
|
474
|
-
const entrada = local.arquivos[caminho];
|
|
475
|
-
if (entrada) {
|
|
476
|
-
mesclado.arquivos[caminho] = entrada;
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
try {
|
|
480
|
-
await escreverEnvelope(this.baseProjeto, this.caminhoManifestoArquivos, SCHEMA_MANIFESTO_ARQUIVOS_DRIFT, this.chaveEnvelope("files"), mesclado);
|
|
481
|
-
return mesclado;
|
|
482
|
-
}
|
|
483
|
-
catch (erro) {
|
|
484
|
-
ultimoErro = erro;
|
|
485
|
-
}
|
|
486
|
-
}
|
|
487
|
-
throw ultimoErro;
|
|
488
|
-
}
|
|
489
|
-
async gravarManifestoGruposComMerge(local) {
|
|
490
|
-
let ultimoErro;
|
|
491
|
-
for (let tentativa = 0; tentativa < 2; tentativa += 1) {
|
|
492
|
-
const publicado = await this.lerManifestoGruposAtual();
|
|
493
|
-
const mesclado = {
|
|
494
|
-
identidadeDigest: this.identidadeDigest,
|
|
495
|
-
grupos: publicado ? { ...publicado.grupos } : {},
|
|
496
|
-
};
|
|
497
|
-
for (const chave of this.gruposSujos) {
|
|
498
|
-
const entrada = local.grupos[chave];
|
|
499
|
-
if (entrada) {
|
|
500
|
-
mesclado.grupos[chave] = entrada;
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
try {
|
|
504
|
-
await escreverEnvelope(this.baseProjeto, this.caminhoManifestoGrupos, SCHEMA_GRUPO_INDICE_DRIFT, this.chaveEnvelope("groups"), mesclado);
|
|
505
|
-
return mesclado;
|
|
506
|
-
}
|
|
507
|
-
catch (erro) {
|
|
508
|
-
ultimoErro = erro;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
throw ultimoErro;
|
|
512
|
-
}
|
|
513
|
-
async obterManifesto() {
|
|
514
|
-
if (this.manifesto) {
|
|
515
|
-
return this.manifesto;
|
|
516
|
-
}
|
|
517
|
-
if (this.manifestoEmVoo) {
|
|
518
|
-
return this.manifestoEmVoo;
|
|
519
|
-
}
|
|
520
|
-
this.manifestoEmVoo = this.carregarManifesto();
|
|
521
|
-
try {
|
|
522
|
-
return await this.manifestoEmVoo;
|
|
523
|
-
}
|
|
524
|
-
finally {
|
|
525
|
-
this.manifestoEmVoo = undefined;
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
async carregarManifesto() {
|
|
529
|
-
if (this.politica === "auto") {
|
|
530
|
-
const leitura = await lerEnvelope(this.baseProjeto, this.caminhoManifestoArquivos, SCHEMA_MANIFESTO_ARQUIVOS_DRIFT, this.chaveEnvelope("files"));
|
|
531
|
-
if (leitura.estado === "hit" && manifestoValido(leitura.payload, this.identidadeDigest)) {
|
|
532
|
-
this.manifesto = leitura.payload;
|
|
533
|
-
return this.manifesto;
|
|
534
|
-
}
|
|
535
|
-
if (leitura.estado === "corrupt" || leitura.estado === "hit") {
|
|
536
|
-
this.registrarCorrupto(path.resolve(this.baseProjeto, this.caminhoManifestoArquivos), leitura.estado === "hit" ? "payload_schema_invalido" : leitura.motivo);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
this.manifesto = {
|
|
540
|
-
identidadeDigest: this.identidadeDigest,
|
|
541
|
-
arquivos: {},
|
|
542
|
-
};
|
|
543
|
-
return this.manifesto;
|
|
544
|
-
}
|
|
545
|
-
async obterManifestoGrupos() {
|
|
546
|
-
if (this.manifestoGrupos) {
|
|
547
|
-
return this.manifestoGrupos;
|
|
548
|
-
}
|
|
549
|
-
if (this.manifestoGruposEmVoo) {
|
|
550
|
-
return this.manifestoGruposEmVoo;
|
|
551
|
-
}
|
|
552
|
-
this.manifestoGruposEmVoo = this.carregarManifestoGrupos();
|
|
553
|
-
try {
|
|
554
|
-
return await this.manifestoGruposEmVoo;
|
|
555
|
-
}
|
|
556
|
-
finally {
|
|
557
|
-
this.manifestoGruposEmVoo = undefined;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
async carregarManifestoGrupos() {
|
|
561
|
-
if (this.politica === "auto") {
|
|
562
|
-
const leitura = await lerEnvelope(this.baseProjeto, this.caminhoManifestoGrupos, SCHEMA_GRUPO_INDICE_DRIFT, this.chaveEnvelope("groups"));
|
|
563
|
-
if (leitura.estado === "hit" && manifestoGruposValido(leitura.payload, this.identidadeDigest)) {
|
|
564
|
-
this.manifestoGrupos = leitura.payload;
|
|
565
|
-
return this.manifestoGrupos;
|
|
566
|
-
}
|
|
567
|
-
if (leitura.estado === "corrupt" || leitura.estado === "hit") {
|
|
568
|
-
this.registrarCorrupto(path.resolve(this.baseProjeto, this.caminhoManifestoGrupos), leitura.estado === "hit" ? "payload_schema_invalido" : leitura.motivo);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
this.manifestoGrupos = {
|
|
572
|
-
identidadeDigest: this.identidadeDigest,
|
|
573
|
-
grupos: {},
|
|
574
|
-
};
|
|
575
|
-
return this.manifestoGrupos;
|
|
576
|
-
}
|
|
577
|
-
registrarCorrupto(caminho, motivo) {
|
|
578
|
-
this.metricasAtuais.corruptos += 1;
|
|
579
|
-
emitirEvento(this.observador, {
|
|
580
|
-
tipo: "cache.corrupt",
|
|
581
|
-
caminho,
|
|
582
|
-
motivo,
|
|
583
|
-
});
|
|
584
|
-
}
|
|
585
|
-
async validarArquivoNoWorkspace(arquivo) {
|
|
586
|
-
const [baseReal, arquivoReal] = await Promise.all([
|
|
587
|
-
this.baseProjetoReal,
|
|
588
|
-
realpath(arquivo),
|
|
589
|
-
]);
|
|
590
|
-
const relativo = path.relative(baseReal, arquivoReal);
|
|
591
|
-
if (relativo === ".." || relativo.startsWith(`..${path.sep}`) || path.isAbsolute(relativo)) {
|
|
592
|
-
throw new Error(`arquivo_cache_drift_fora_workspace_real:${arquivo}`);
|
|
593
|
-
}
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
//# sourceMappingURL=driftCacheIncremental.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type PoliticaCacheDrift, type ValorJson } from "./driftCache.js";
|
|
2
|
-
import { type CatalogoDrift, type OpcoesCatalogoDrift } from "./driftCatalogo.js";
|
|
3
|
-
export declare const SCHEMA_CACHE_CATALOGO_DRIFT: "sema.drift-catalog-cache/v1";
|
|
4
|
-
export interface OpcoesCatalogoPersistenteDrift {
|
|
5
|
-
politica: PoliticaCacheDrift;
|
|
6
|
-
identidade: ValorJson;
|
|
7
|
-
}
|
|
8
|
-
export declare function criarCatalogoPersistenteDrift(opcoes: OpcoesCatalogoDrift, opcoesCache: OpcoesCatalogoPersistenteDrift): Promise<CatalogoDrift>;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
// SEMA-GOVERNED: sema.produto.governanca_ia.drift
|
|
2
|
-
// Descricao: reutiliza um snapshot validado do catalogo global sem transformar escopo estreito em varredura ampla.
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { criarCacheDrift, digestJsonCanonicoCacheDrift, } from "./driftCache.js";
|
|
5
|
-
import { criarCatalogoDrift, } from "./driftCatalogo.js";
|
|
6
|
-
export const SCHEMA_CACHE_CATALOGO_DRIFT = "sema.drift-catalog-cache/v1";
|
|
7
|
-
function chaveRelativa(base, alvo) {
|
|
8
|
-
const relativo = path.relative(base, path.resolve(base, alvo)).replace(/\\/g, "/");
|
|
9
|
-
return relativo || ".";
|
|
10
|
-
}
|
|
11
|
-
function identidadePlanoCatalogo(opcoes) {
|
|
12
|
-
const base = path.resolve(opcoes.baseDiretorio ?? process.cwd());
|
|
13
|
-
const ignorados = [...(opcoes.diretoriosIgnorados ?? [])]
|
|
14
|
-
.map((item) => item.trim().toLowerCase())
|
|
15
|
-
.filter(Boolean)
|
|
16
|
-
.sort((a, b) => a.localeCompare(b, "en"));
|
|
17
|
-
return {
|
|
18
|
-
schema: SCHEMA_CACHE_CATALOGO_DRIFT,
|
|
19
|
-
arquivos: [...(opcoes.arquivos ?? [])]
|
|
20
|
-
.map((arquivo) => chaveRelativa(base, arquivo))
|
|
21
|
-
.sort((a, b) => a.localeCompare(b, "en")),
|
|
22
|
-
raizes: [...(opcoes.raizes ?? [])]
|
|
23
|
-
.map((raiz) => chaveRelativa(base, raiz))
|
|
24
|
-
.sort((a, b) => a.localeCompare(b, "en")),
|
|
25
|
-
extensoes: opcoes.extensoes
|
|
26
|
-
? [...opcoes.extensoes].map((item) => item.toLowerCase()).sort((a, b) => a.localeCompare(b, "en"))
|
|
27
|
-
: null,
|
|
28
|
-
diretoriosIgnorados: ignorados,
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
export async function criarCatalogoPersistenteDrift(opcoes, opcoesCache) {
|
|
32
|
-
const baseProjeto = path.resolve(opcoes.baseDiretorio ?? process.cwd());
|
|
33
|
-
if (opcoesCache.politica === "off" || (opcoes.raizes?.length ?? 0) === 0) {
|
|
34
|
-
return criarCatalogoDrift(opcoes);
|
|
35
|
-
}
|
|
36
|
-
const plano = identidadePlanoCatalogo(opcoes);
|
|
37
|
-
const entrada = {
|
|
38
|
-
fingerprintConteudo: digestJsonCanonicoCacheDrift(plano),
|
|
39
|
-
identidade: {
|
|
40
|
-
schema: SCHEMA_CACHE_CATALOGO_DRIFT,
|
|
41
|
-
executor: opcoesCache.identidade,
|
|
42
|
-
plano,
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
let catalogoCalculado;
|
|
46
|
-
const cache = criarCacheDrift({
|
|
47
|
-
baseProjeto,
|
|
48
|
-
politica: opcoesCache.politica,
|
|
49
|
-
observador: opcoes.observador,
|
|
50
|
-
});
|
|
51
|
-
const resultado = await cache.obterOuCalcular(entrada, async () => {
|
|
52
|
-
catalogoCalculado = await criarCatalogoDrift(opcoes);
|
|
53
|
-
return catalogoCalculado.snapshot();
|
|
54
|
-
});
|
|
55
|
-
if (catalogoCalculado) {
|
|
56
|
-
return catalogoCalculado;
|
|
57
|
-
}
|
|
58
|
-
const restauradoOuRecalculado = await criarCatalogoDrift({
|
|
59
|
-
...opcoes,
|
|
60
|
-
snapshot: resultado.valor,
|
|
61
|
-
});
|
|
62
|
-
if (restauradoOuRecalculado.metricas().origem === "snapshot") {
|
|
63
|
-
return restauradoOuRecalculado;
|
|
64
|
-
}
|
|
65
|
-
// O envelope estava integro, mas o snapshot ficou obsoleto ou falhou na
|
|
66
|
-
// validacao runtime. A caminhada ja executada acima e reaproveitada; apenas
|
|
67
|
-
// substituimos atomicamente a entrada persistente.
|
|
68
|
-
const refresh = criarCacheDrift({
|
|
69
|
-
baseProjeto,
|
|
70
|
-
politica: "refresh",
|
|
71
|
-
observador: opcoes.observador,
|
|
72
|
-
});
|
|
73
|
-
const snapshotAtual = restauradoOuRecalculado.snapshot();
|
|
74
|
-
await refresh.obterOuCalcular(entrada, async () => snapshotAtual);
|
|
75
|
-
return restauradoOuRecalculado;
|
|
76
|
-
}
|
|
77
|
-
//# sourceMappingURL=driftCatalogoPersistente.js.map
|