@semacode/cli 2.3.0 → 2.3.1

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 (177) hide show
  1. package/LICENSE +39 -39
  2. package/README.md +251 -228
  3. package/dist/agentEntryPoints.js +551 -550
  4. package/dist/angular-consumer-standalone.d.ts +3 -1
  5. package/dist/angular-consumer-standalone.js +12 -8
  6. package/dist/drift.part01.d.ts +32 -2
  7. package/dist/drift.part01.js +2 -0
  8. package/dist/drift.part04.d.ts +3 -2
  9. package/dist/drift.part04.js +6 -3
  10. package/dist/drift.part05.d.ts +2 -1
  11. package/dist/drift.part05.js +4 -3
  12. package/dist/drift.part06.d.ts +2 -1
  13. package/dist/drift.part06.js +9 -5
  14. package/dist/drift.part07.d.ts +11 -10
  15. package/dist/drift.part07.js +40 -30
  16. package/dist/drift.part08.d.ts +2 -1
  17. package/dist/drift.part08.js +4 -3
  18. package/dist/drift.part11.js +71 -6
  19. package/dist/drift.part12.js +14 -1
  20. package/dist/drift.part13.d.ts +42 -7
  21. package/dist/drift.part13.js +660 -36
  22. package/dist/driftCache.d.ts +49 -0
  23. package/dist/driftCache.js +311 -0
  24. package/dist/driftCacheIncremental.d.ts +98 -0
  25. package/dist/driftCacheIncremental.js +596 -0
  26. package/dist/driftCatalogo.d.ts +91 -0
  27. package/dist/driftCatalogo.js +657 -0
  28. package/dist/driftCatalogoPersistente.d.ts +8 -0
  29. package/dist/driftCatalogoPersistente.js +77 -0
  30. package/dist/driftEscopo.d.ts +23 -0
  31. package/dist/driftEscopo.js +563 -0
  32. package/dist/driftEscopoReferencias.d.ts +4 -0
  33. package/dist/driftEscopoReferencias.js +265 -0
  34. package/dist/driftOrcamento.d.ts +12 -0
  35. package/dist/driftOrcamento.js +19 -3
  36. package/dist/execucoesExternas.js +5 -19
  37. package/dist/iaPrompts.js +310 -310
  38. package/dist/index.part01.d.ts +16 -1
  39. package/dist/index.part01.js +80 -4
  40. package/dist/index.part02.js +21 -21
  41. package/dist/index.part03.d.ts +2 -2
  42. package/dist/index.part03.js +14 -3
  43. package/dist/index.part04.d.ts +2 -2
  44. package/dist/index.part04.js +113 -101
  45. package/dist/index.part05.d.ts +1 -1
  46. package/dist/index.part05.js +99 -22
  47. package/dist/index.part06.js +3 -2
  48. package/dist/index.part07.js +24 -24
  49. package/dist/index.part08.js +1 -1
  50. package/dist/init/templates.part01.js +393 -393
  51. package/dist/init/templates.part02.js +189 -189
  52. package/dist/initTemplatesBackend.js +73 -73
  53. package/dist/initTemplatesBase.js +81 -81
  54. package/dist/initTemplatesFlutter.js +137 -137
  55. package/dist/initTemplatesRuntime.js +350 -350
  56. package/dist/initTemplatesWeb.js +309 -309
  57. package/dist/pipelineConteudo/command.js +1 -36
  58. package/dist/projeto.d.ts +1 -1
  59. package/dist/projetoCarregar.d.ts +2 -2
  60. package/dist/projetoCarregar.js +47 -24
  61. package/dist/projetoCatalogo.d.ts +7 -0
  62. package/dist/projetoCatalogo.js +125 -0
  63. package/dist/projetoTipos.d.ts +14 -5
  64. package/dist/sync/index.js +35 -35
  65. package/docs/README.md +34 -34
  66. package/docs/ai-integration.md +1 -7
  67. package/docs/ai-onboarding.md +62 -62
  68. package/docs/ai-workflow.md +4 -0
  69. package/docs/auth.md +26 -26
  70. package/docs/cli.md +79 -79
  71. package/docs/commands.md +16 -13
  72. package/docs/database.md +15 -15
  73. package/docs/deploy.md +41 -41
  74. package/docs/descoberta-capacidades.md +106 -106
  75. package/docs/documentation.md +37 -46
  76. package/docs/env.md +16 -16
  77. package/docs/frontend.md +41 -41
  78. package/docs/getting-started.md +57 -57
  79. package/docs/i18n.md +15 -15
  80. package/docs/pipeline-conteudo.md +246 -246
  81. package/docs/profiles.md +54 -54
  82. package/docs/repositories.md +43 -43
  83. package/docs/rollback.md +31 -31
  84. package/docs/security.md +32 -32
  85. package/docs/sistemas-interativos.md +373 -378
  86. package/docs/support.md +8 -8
  87. package/docs/testing.md +51 -44
  88. package/docs/vocabulary.md +29 -29
  89. package/exemplos/agendamento.sema +1 -1
  90. package/exemplos/assinatura.sema +1 -1
  91. package/exemplos/auditoria.sema +1 -1
  92. package/exemplos/autenticacao.sema +1 -1
  93. package/exemplos/author_obra_comum.sema +1 -1
  94. package/exemplos/author_tema_sensivel.sema +1 -1
  95. package/exemplos/automacao.sema +1 -1
  96. package/exemplos/cadastro_usuario.sema +1 -1
  97. package/exemplos/calculadora.sema +1 -1
  98. package/exemplos/crud_simples.sema +1 -1
  99. package/exemplos/estoque.sema +1 -1
  100. package/exemplos/exportacao.sema +1 -1
  101. package/exemplos/fila.sema +1 -1
  102. package/exemplos/integracao_externa.sema +1 -1
  103. package/exemplos/multi_tenant.sema +1 -1
  104. package/exemplos/notificacao.sema +1 -1
  105. package/exemplos/operacao_estrategia.sema +132 -132
  106. package/exemplos/operacao_estrategia_discovery.sema +220 -220
  107. package/exemplos/operacao_estrategia_fluxo.sema +114 -114
  108. package/exemplos/operacao_estrategia_gates.sema +106 -106
  109. package/exemplos/operacao_estrategia_quarentena.sema +133 -133
  110. package/exemplos/operacao_estrategia_rollout.sema +124 -124
  111. package/exemplos/pagamento.sema +1 -1
  112. package/exemplos/pagamento_dominio.sema +1 -1
  113. package/exemplos/pedido.sema +1 -1
  114. package/exemplos/permissao.sema +1 -1
  115. package/exemplos/persistencia_vendor_first.sema +1 -1
  116. package/exemplos/pipeline-conteudo/README.md +44 -44
  117. package/exemplos/pipeline-conteudo/alvos.json +23 -23
  118. package/exemplos/pipeline-conteudo/definicao.json +136 -136
  119. package/exemplos/profile_conversas.sema +165 -165
  120. package/exemplos/profile_game.sema +1 -1
  121. package/exemplos/profile_legal.sema +1 -1
  122. package/exemplos/profile_ops.sema +1 -1
  123. package/exemplos/profile_research.sema +1 -1
  124. package/exemplos/profile_simulation.sema +211 -211
  125. package/exemplos/profile_software.sema +1 -1
  126. package/exemplos/profile_workflow_n8n.sema +1 -1
  127. package/exemplos/relatorio.sema +1 -1
  128. package/exemplos/replica_analitica_erp.sema +1 -1
  129. package/exemplos/sistemas-interativos/README.md +100 -100
  130. package/exemplos/sistemas-interativos/advanced/acceptance-context-evaluate-valid.json +5 -5
  131. package/exemplos/sistemas-interativos/advanced/acceptance-lock-valid.json +16 -16
  132. package/exemplos/sistemas-interativos/advanced/asset-provenance-valid.json +32 -32
  133. package/exemplos/sistemas-interativos/advanced/autonomy-repair-valid.json +93 -93
  134. package/exemplos/sistemas-interativos/advanced/control-run-definition-valid.json +78 -78
  135. package/exemplos/sistemas-interativos/advanced/control-run-valid.json +27 -27
  136. package/exemplos/sistemas-interativos/advanced/distributed-workers-valid.json +79 -79
  137. package/exemplos/sistemas-interativos/advanced/editor-state-valid.json +42 -42
  138. package/exemplos/sistemas-interativos/advanced/engine-snapshot-after-valid.json +32 -32
  139. package/exemplos/sistemas-interativos/advanced/engine-snapshot-before-valid.json +23 -23
  140. package/exemplos/sistemas-interativos/advanced/job-orchestration-valid.json +39 -39
  141. package/exemplos/sistemas-interativos/advanced/multimodal-evidence-valid.json +46 -46
  142. package/exemplos/sistemas-interativos/advanced/multiplayer-authority-valid.json +39 -39
  143. package/exemplos/sistemas-interativos/advanced/playtest-fuzz-valid.json +37 -37
  144. package/exemplos/sistemas-interativos/advanced/portability-valid.json +104 -104
  145. package/exemplos/sistemas-interativos/advanced/temporal-evidence-valid.json +27 -27
  146. package/exemplos/sistemas-interativos/advanced/temporal-valid.json +118 -118
  147. package/exemplos/sistemas-interativos/experience-ir-valid.json +459 -459
  148. package/exemplos/sistemas-interativos/game-2d.json +83 -83
  149. package/exemplos/sistemas-interativos/game-3d-human.json +81 -81
  150. package/exemplos/sistemas-interativos/game-pixel-16-bit.json +97 -97
  151. package/exemplos/sistemas-interativos/game-pixel-8-bit.json +94 -94
  152. package/exemplos/sistemas-interativos/game-xr-human.json +80 -80
  153. package/exemplos/sistemas-interativos/hybrid-2-5d.json +108 -108
  154. package/exemplos/sistemas-interativos/protocol-mutating-rollback-valid.json +75 -75
  155. package/exemplos/sistemas-interativos/protocol-read-only-valid.json +58 -58
  156. package/exemplos/sistemas-interativos/simulation-2d-controlled.json +97 -97
  157. package/exemplos/sistemas-interativos/simulation-3d-calibrated-autonomous.json +141 -141
  158. package/exemplos/sistemas-interativos/simulation-headless-autonomous-batch.json +112 -112
  159. package/exemplos/sistemas-interativos/simulation-pixel-16-bit.json +103 -103
  160. package/exemplos/sistemas-interativos/simulation-text-controlled.json +95 -95
  161. package/exemplos/testes_embutidos.sema +1 -1
  162. package/exemplos/tratamento_erro.sema +1 -1
  163. package/exemplos/upload_arquivo.sema +1 -1
  164. package/exemplos/webhook.sema +1 -1
  165. package/node_modules/@sema/gerador-cpp/dist/index.js +176 -176
  166. package/node_modules/@sema/gerador-cpp/package.json +1 -1
  167. package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
  168. package/node_modules/@sema/gerador-css/dist/index.part02.js +460 -460
  169. package/node_modules/@sema/gerador-dotnet/dist/index.js +169 -169
  170. package/node_modules/@sema/gerador-dotnet/package.json +1 -1
  171. package/node_modules/@sema/gerador-html/dist/index.js +17 -17
  172. package/node_modules/@sema/gerador-lua/dist/index.js +51 -51
  173. package/node_modules/@sema/gerador-php/dist/index.js +113 -113
  174. package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
  175. package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
  176. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
  177. package/package.json +3 -3
@@ -0,0 +1,77 @@
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
@@ -0,0 +1,23 @@
1
+ import type { ContextoProjetoCarregado } from "./projeto.js";
2
+ import type { ConfiguracaoEscopoDriftAplicada, EscopoDriftReal } from "./drift.part01.js";
3
+ import type { CatalogoDrift } from "./driftCatalogo.js";
4
+ import type { CacheIncrementalDrift } from "./driftCacheIncremental.js";
5
+ export { extrairReferenciasLocaisDrift } from "./driftEscopoReferencias.js";
6
+ export type EstrategiaEscopoDrift = "arquivos_vinculados" | "projeto";
7
+ export type CoberturaEscopoDrift = "completa" | "parcial";
8
+ export interface PlanoEscopoDrift {
9
+ escopo: EscopoDriftReal;
10
+ estrategia: EstrategiaEscopoDrift;
11
+ arquivos: string[];
12
+ arquivosDeclarados: string[];
13
+ arquivosInferidos: string[];
14
+ arquivosAusentes: string[];
15
+ diretorios: string[];
16
+ modulos: string[];
17
+ cobertura: CoberturaEscopoDrift;
18
+ bloqueios: string[];
19
+ dependencias: Record<string, string[]>;
20
+ }
21
+ export declare function planejarEscopoDrift(contexto: ContextoProjetoCarregado, configuracao: ConfiguracaoEscopoDriftAplicada): Promise<PlanoEscopoDrift>;
22
+ export declare function expandirDependenciasPlanoDrift(contexto: ContextoProjetoCarregado, plano: PlanoEscopoDrift, catalogo: CatalogoDrift, cache?: CacheIncrementalDrift): Promise<PlanoEscopoDrift>;
23
+ export declare function mapearDependenciasCatalogadasDrift(contexto: ContextoProjetoCarregado, catalogo: CatalogoDrift, cache: CacheIncrementalDrift, arquivos?: readonly string[]): Promise<Record<string, string[]>>;
@@ -0,0 +1,563 @@
1
+ // SEMA-GOVERNED: sema.produto.governanca_ia.drift
2
+ // Descricao: planeja o conjunto fisico minimo que pode ser indexado antes de qualquer caminhada de drift.
3
+ import { lstat, realpath } from "node:fs/promises";
4
+ import path from "node:path";
5
+ import { resolverDiretoriosCodigoEscopoReal } from "./drift.part02.js";
6
+ import { candidatosReferenciaLocalDrift, extrairReferenciasLocaisDrift, raizesCodigoLogicasDrift, } from "./driftEscopoReferencias.js";
7
+ export { extrairReferenciasLocaisDrift } from "./driftEscopoReferencias.js";
8
+ const CONCORRENCIA_SONDAGENS_DRIFT = 16;
9
+ const CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT = 8;
10
+ const EXTENSAO_POR_ORIGEM = {
11
+ // O indexador TypeScript tambem cobre JavaScript legado. Essa compatibilidade
12
+ // e necessaria para contratos antigos que usam `ts:` para simbolos browser-side.
13
+ ts: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"],
14
+ // O resolvedor semantico trata JS/TS como a mesma familia. O planejamento
15
+ // precisa sondar a mesma familia para nao descartar uma implementacao `js:`
16
+ // escrita fisicamente em TypeScript antes de o resolvedor poder avalia-la.
17
+ js: [".js", ".jsx", ".mjs", ".cjs", ".ts", ".tsx"],
18
+ py: [".py"],
19
+ dart: [".dart"],
20
+ lua: [".lua"],
21
+ cs: [".cs"],
22
+ java: [".java"],
23
+ go: [".go"],
24
+ rust: [".rs"],
25
+ cpp: [".cpp", ".cc", ".cxx", ".hpp", ".h"],
26
+ php: [".php"],
27
+ };
28
+ function chaveCaminho(caminho) {
29
+ const absoluto = path.normalize(path.resolve(caminho));
30
+ return process.platform === "win32" ? absoluto.toLowerCase() : absoluto;
31
+ }
32
+ function caminhoEstaDentro(raiz, alvo) {
33
+ const relativo = path.relative(path.resolve(raiz), path.resolve(alvo));
34
+ return relativo === "" || (relativo !== ".."
35
+ && !relativo.startsWith(`..${path.sep}`)
36
+ && !path.isAbsolute(relativo));
37
+ }
38
+ async function mapearComLimite(itens, limite, executar) {
39
+ if (itens.length === 0) {
40
+ return [];
41
+ }
42
+ const resultados = new Array(itens.length);
43
+ let proximoIndice = 0;
44
+ const trabalhador = async () => {
45
+ for (;;) {
46
+ const indice = proximoIndice;
47
+ proximoIndice += 1;
48
+ if (indice >= itens.length) {
49
+ return;
50
+ }
51
+ resultados[indice] = await executar(itens[indice]);
52
+ }
53
+ };
54
+ await Promise.all(Array.from({ length: Math.min(Math.max(1, limite), itens.length) }, () => trabalhador()));
55
+ return resultados;
56
+ }
57
+ async function arquivoRegularContido(caminho, raizReal) {
58
+ try {
59
+ const informacao = await lstat(caminho);
60
+ if (!informacao.isFile() || informacao.isSymbolicLink()) {
61
+ return false;
62
+ }
63
+ const caminhoReal = await realpath(caminho);
64
+ return caminhoEstaDentro(raizReal, caminhoReal);
65
+ }
66
+ catch {
67
+ return false;
68
+ }
69
+ }
70
+ async function sondarArquivosRegularesContidos(caminhos, raizReal) {
71
+ const unicos = [...new Map(caminhos.map((caminho) => [chaveCaminho(caminho), caminho])).entries()];
72
+ const resultados = await mapearComLimite(unicos, CONCORRENCIA_SONDAGENS_DRIFT, async ([chave, caminho]) => [chave, await arquivoRegularContido(caminho, raizReal)]);
73
+ return new Map(resultados);
74
+ }
75
+ function vinculosModulo(ir) {
76
+ return [
77
+ ...ir.vinculos,
78
+ ...ir.tasks.flatMap((task) => task.vinculos),
79
+ ...ir.flows.flatMap((flow) => flow.vinculos),
80
+ ...ir.routes.flatMap((route) => route.vinculos),
81
+ ...ir.superficies.flatMap((superficie) => superficie.vinculos),
82
+ ];
83
+ }
84
+ function implementacoesModulo(ir) {
85
+ return [
86
+ ...ir.tasks.flatMap((task) => task.implementacoesExternas),
87
+ ...ir.superficies.flatMap((superficie) => superficie.implementacoesExternas),
88
+ ];
89
+ }
90
+ function resolverArquivoWorkspace(baseProjeto, valor) {
91
+ const absoluto = path.isAbsolute(valor)
92
+ ? path.resolve(valor)
93
+ : path.resolve(baseProjeto, valor);
94
+ return caminhoEstaDentro(baseProjeto, absoluto) ? absoluto : undefined;
95
+ }
96
+ function variantesSegmentoDiretorio(segmento) {
97
+ const camel = segmento.replace(/_([a-z0-9])/gi, (_ocorrencia, caractere) => caractere.toUpperCase());
98
+ return [...new Set([
99
+ segmento,
100
+ segmento.includes("_") ? segmento.replace(/_/g, "-") : undefined,
101
+ /(?:^|_)id$/i.test(segmento) ? `[${segmento}]` : undefined,
102
+ /(?:^|_)id$/i.test(segmento) && camel !== segmento ? `[${camel}]` : undefined,
103
+ ].filter((item) => Boolean(item)))];
104
+ }
105
+ function adicionarCandidatoPreservandoForma(candidatos, baseProjeto, caminho) {
106
+ const absoluto = path.resolve(caminho);
107
+ if (!caminhoEstaDentro(baseProjeto, absoluto)) {
108
+ return;
109
+ }
110
+ const chave = chaveCaminho(absoluto);
111
+ if (!candidatos.has(chave)) {
112
+ candidatos.set(chave, absoluto);
113
+ }
114
+ }
115
+ function variantesNomeArquivo(segmento) {
116
+ const pascal = segmento
117
+ .split(/[_-]+/)
118
+ .filter(Boolean)
119
+ .map((parte) => `${parte[0]?.toUpperCase() ?? ""}${parte.slice(1)}`)
120
+ .join("");
121
+ return [...new Set([
122
+ segmento,
123
+ segmento.includes("_") ? segmento.replace(/_/g, "-") : undefined,
124
+ segmento.includes("_") ? segmento.replace(/_/g, ".") : undefined,
125
+ pascal && pascal !== segmento ? pascal : undefined,
126
+ ].filter((item) => Boolean(item)))];
127
+ }
128
+ function variantesCaminhoSegmentos(segmentos) {
129
+ let variantes = [[]];
130
+ for (const segmento of segmentos) {
131
+ const opcoes = variantesSegmentoDiretorio(segmento);
132
+ variantes = variantes.flatMap((prefixo) => opcoes.map((opcao) => [...prefixo, opcao]));
133
+ }
134
+ return variantes.slice(0, 16);
135
+ }
136
+ function candidatosArquivoImpl(contexto, impl) {
137
+ const candidatos = new Map();
138
+ const adicionar = (caminho) => {
139
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
140
+ };
141
+ if (impl.origemArquivo) {
142
+ const declarado = resolverArquivoWorkspace(contexto.baseProjeto, impl.origemArquivo);
143
+ if (declarado) {
144
+ adicionar(declarado);
145
+ }
146
+ }
147
+ const partes = impl.caminho.split(".").map((parte) => parte.trim()).filter(Boolean);
148
+ if (partes.length < 2) {
149
+ return [...candidatos.values()];
150
+ }
151
+ const bases = [contexto.baseProjeto, ...contexto.diretoriosCodigo];
152
+ const extensoes = EXTENSAO_POR_ORIGEM[impl.origem] ?? [];
153
+ for (const removerCauda of [1, 2]) {
154
+ const segmentosOriginais = partes.slice(0, Math.max(1, partes.length - removerCauda));
155
+ for (const base of bases) {
156
+ const nomeBase = path.basename(base).toLowerCase();
157
+ const segmentos = segmentosOriginais[0]?.toLowerCase() === nomeBase
158
+ ? segmentosOriginais.slice(1)
159
+ : segmentosOriginais;
160
+ if (segmentos.length === 0) {
161
+ continue;
162
+ }
163
+ for (const diretorios of variantesCaminhoSegmentos(segmentos.slice(0, -1))) {
164
+ for (const nomeArquivo of variantesNomeArquivo(segmentos.at(-1))) {
165
+ for (const extensao of extensoes) {
166
+ adicionar(path.join(base, ...diretorios, `${nomeArquivo}${extensao}`));
167
+ }
168
+ }
169
+ }
170
+ for (const caminhoDiretorio of variantesCaminhoSegmentos(segmentos)) {
171
+ for (const extensao of extensoes) {
172
+ adicionar(path.join(base, ...caminhoDiretorio, `index${extensao}`));
173
+ }
174
+ }
175
+ }
176
+ }
177
+ return [...candidatos.values()];
178
+ }
179
+ function candidatosConsumerDeterministicos(contexto, irs, termosEscopo) {
180
+ const segmentos = new Set();
181
+ for (const termo of termosEscopo) {
182
+ segmentos.add(termo);
183
+ segmentos.add(termo.replace(/_/g, "-"));
184
+ }
185
+ for (const ir of irs) {
186
+ for (const rota of ir.routes) {
187
+ for (const segmento of (rota.caminho ?? "").split("/").filter((item) => item && !item.startsWith(":"))) {
188
+ segmentos.add(segmento);
189
+ }
190
+ }
191
+ }
192
+ const candidatos = new Map();
193
+ const extensoes = [".ts", ".tsx", ".js", ".jsx"];
194
+ for (const raiz of contexto.diretoriosCodigo) {
195
+ for (const segmento of segmentos) {
196
+ for (const extensao of extensoes) {
197
+ for (const relativo of [
198
+ ["src", "app", segmento, `page${extensao}`],
199
+ ["app", segmento, `page${extensao}`],
200
+ ["src", "pages", `${segmento}${extensao}`],
201
+ ["pages", `${segmento}${extensao}`],
202
+ ]) {
203
+ const absoluto = path.resolve(raiz, ...relativo);
204
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, absoluto);
205
+ }
206
+ }
207
+ }
208
+ }
209
+ return [...candidatos.values()];
210
+ }
211
+ function candidatosRotasDeterministicos(contexto, irs) {
212
+ const candidatos = new Map();
213
+ const extensoes = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py"];
214
+ const segmentos = new Set();
215
+ for (const ir of irs) {
216
+ for (const rota of ir.routes) {
217
+ for (const segmento of (rota.caminho ?? "").split("/").filter((item) => item && !item.startsWith(":") && !item.startsWith("{"))) {
218
+ segmentos.add(segmento);
219
+ }
220
+ }
221
+ }
222
+ for (const raiz of contexto.diretoriosCodigo) {
223
+ for (const segmento of segmentos) {
224
+ const nomes = variantesNomeArquivo(segmento);
225
+ for (const nome of nomes) {
226
+ for (const extensao of extensoes) {
227
+ for (const relativo of [
228
+ [segmento, `${nome}.controller${extensao}`],
229
+ [`${nome}.controller${extensao}`],
230
+ ["controllers", `${nome}.controller${extensao}`],
231
+ ["routes", `${nome}${extensao}`],
232
+ ]) {
233
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, path.resolve(raiz, ...relativo));
234
+ }
235
+ }
236
+ }
237
+ }
238
+ }
239
+ return [...candidatos.values()];
240
+ }
241
+ function candidatosConvencionaisEscopo(contexto, irs) {
242
+ const candidatos = new Map();
243
+ const adicionar = (caminho) => {
244
+ adicionarCandidatoPreservandoForma(candidatos, contexto.baseProjeto, caminho);
245
+ };
246
+ const origens = new Set(irs.flatMap((ir) => implementacoesModulo(ir).map((impl) => impl.origem)));
247
+ const possuiRotas = irs.some((ir) => ir.routes.length > 0);
248
+ const possuiPersistencia = irs.some((ir) => ir.databases.length > 0
249
+ || ir.tasks.some((task) => task.effects.some((efeito) => /\b(?:db|database|persist|storage)\b/i.test(efeito))));
250
+ const bases = [contexto.baseProjeto, ...contexto.diretoriosCodigo];
251
+ if (possuiRotas && origens.has("rust")) {
252
+ for (const base of bases) {
253
+ adicionar(path.join(base, "main.rs"));
254
+ adicionar(path.join(base, "src", "main.rs"));
255
+ adicionar(path.join(base, "lib.rs"));
256
+ adicionar(path.join(base, "src", "lib.rs"));
257
+ }
258
+ }
259
+ if (possuiPersistencia) {
260
+ for (const base of bases) {
261
+ adicionar(path.join(base, "schema.sql"));
262
+ adicionar(path.join(base, "schema.prisma"));
263
+ adicionar(path.join(base, "db", "schema.sql"));
264
+ adicionar(path.join(base, "prisma", "schema.prisma"));
265
+ }
266
+ }
267
+ return [...candidatos.values()];
268
+ }
269
+ function escolherDiretoriosLogicos(contexto, arquivos) {
270
+ const candidatos = [...new Map(contexto.diretoriosCodigo
271
+ .map((diretorio) => path.resolve(diretorio))
272
+ .map((diretorio) => [chaveCaminho(diretorio), diretorio])).values()]
273
+ .sort((a, b) => b.length - a.length || a.localeCompare(b, "pt-BR"));
274
+ const escolhidos = new Map();
275
+ for (const arquivo of arquivos) {
276
+ const raiz = candidatos.find((diretorio) => caminhoEstaDentro(diretorio, arquivo))
277
+ ?? path.dirname(arquivo);
278
+ escolhidos.set(chaveCaminho(raiz), raiz);
279
+ }
280
+ return [...escolhidos.values()]
281
+ .sort((a, b) => a.localeCompare(b, "pt-BR"));
282
+ }
283
+ export async function planejarEscopoDrift(contexto, configuracao) {
284
+ if (configuracao.escopo === "projeto") {
285
+ const diretorios = resolverDiretoriosCodigoEscopoReal(contexto, configuracao);
286
+ return {
287
+ escopo: configuracao.escopo,
288
+ estrategia: "projeto",
289
+ arquivos: [],
290
+ arquivosDeclarados: [],
291
+ arquivosInferidos: [],
292
+ arquivosAusentes: [],
293
+ diretorios,
294
+ modulos: contexto.modulosSelecionados
295
+ .map((modulo) => modulo.resultado.ir?.nome)
296
+ .filter((nome) => Boolean(nome)),
297
+ cobertura: "completa",
298
+ bloqueios: [],
299
+ dependencias: {},
300
+ };
301
+ }
302
+ const modulosFonte = configuracao.escopo === "arquivo"
303
+ ? contexto.modulosSelecionados
304
+ : contexto.modulosCarregados;
305
+ const irs = modulosFonte
306
+ .map((modulo) => modulo.resultado.ir)
307
+ .filter((ir) => Boolean(ir));
308
+ const declarados = new Map();
309
+ const ausentes = new Map();
310
+ const inferidos = new Map();
311
+ const raizReal = await realpath(contexto.baseProjeto);
312
+ const vinculosPlanejados = irs.flatMap((ir) => vinculosModulo(ir))
313
+ .map((vinculo) => vinculo.arquivo ?? (vinculo.tipo === "arquivo" ? vinculo.valor : undefined))
314
+ .filter((valor) => Boolean(valor))
315
+ .map((valor) => ({
316
+ valor,
317
+ absoluto: resolverArquivoWorkspace(contexto.baseProjeto, valor),
318
+ }));
319
+ const implementacoesPlanejadas = irs
320
+ .flatMap((ir) => implementacoesModulo(ir))
321
+ .map((impl) => candidatosArquivoImpl(contexto, impl));
322
+ const candidatosDeterministicos = [
323
+ ...candidatosConsumerDeterministicos(contexto, irs, configuracao.termosEscopo),
324
+ ...candidatosRotasDeterministicos(contexto, irs),
325
+ ...candidatosConvencionaisEscopo(contexto, irs),
326
+ ];
327
+ const resultadoSondagens = await sondarArquivosRegularesContidos([
328
+ ...vinculosPlanejados.flatMap((vinculo) => vinculo.absoluto ? [vinculo.absoluto] : []),
329
+ ...implementacoesPlanejadas.flat(),
330
+ ...candidatosDeterministicos,
331
+ ], raizReal);
332
+ const arquivoExiste = (arquivo) => resultadoSondagens.get(chaveCaminho(arquivo)) === true;
333
+ for (const vinculo of vinculosPlanejados) {
334
+ if (!vinculo.absoluto) {
335
+ ausentes.set(`fora:${vinculo.valor}`, vinculo.valor);
336
+ continue;
337
+ }
338
+ if (arquivoExiste(vinculo.absoluto)) {
339
+ const chave = chaveCaminho(vinculo.absoluto);
340
+ if (!declarados.has(chave)) {
341
+ declarados.set(chave, vinculo.absoluto);
342
+ }
343
+ }
344
+ else {
345
+ ausentes.set(chaveCaminho(vinculo.absoluto), vinculo.absoluto);
346
+ }
347
+ }
348
+ for (const candidatos of implementacoesPlanejadas) {
349
+ const encontrados = candidatos.filter(arquivoExiste);
350
+ for (const candidato of encontrados) {
351
+ const chave = chaveCaminho(candidato);
352
+ if (!declarados.has(chave) && !inferidos.has(chave)) {
353
+ inferidos.set(chave, candidato);
354
+ }
355
+ }
356
+ if (encontrados.length === 0 && candidatos[0]) {
357
+ ausentes.set(chaveCaminho(candidatos[0]), candidatos[0]);
358
+ }
359
+ }
360
+ for (const candidato of candidatosDeterministicos.filter(arquivoExiste)) {
361
+ const chave = chaveCaminho(candidato);
362
+ if (!declarados.has(chave) && !inferidos.has(chave)) {
363
+ inferidos.set(chave, candidato);
364
+ }
365
+ }
366
+ const arquivosMesclados = new Map(declarados);
367
+ for (const [chave, arquivo] of inferidos) {
368
+ if (!arquivosMesclados.has(chave)) {
369
+ arquivosMesclados.set(chave, arquivo);
370
+ }
371
+ }
372
+ const arquivos = [...arquivosMesclados.values()]
373
+ .sort((a, b) => a.localeCompare(b, "pt-BR"));
374
+ const arquivosAusentes = [...ausentes.values()]
375
+ .sort((a, b) => a.localeCompare(b, "pt-BR"));
376
+ const bloqueios = arquivos.length === 0
377
+ ? ["escopo_estreito_sem_vinculos"]
378
+ : [];
379
+ return {
380
+ escopo: configuracao.escopo,
381
+ estrategia: "arquivos_vinculados",
382
+ arquivos,
383
+ arquivosDeclarados: [...declarados.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
384
+ arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
385
+ arquivosAusentes,
386
+ diretorios: escolherDiretoriosLogicos(contexto, arquivos),
387
+ modulos: irs.map((ir) => ir.nome),
388
+ cobertura: arquivosAusentes.length === 0 && bloqueios.length === 0 ? "completa" : "parcial",
389
+ bloqueios,
390
+ dependencias: {},
391
+ };
392
+ }
393
+ async function construirConfinamentoDependencias(contexto) {
394
+ const raizWorkspaceReal = await realpath(contexto.baseProjeto);
395
+ const logicas = raizesCodigoLogicasDrift(contexto);
396
+ const reaisPossiveis = await mapearComLimite(logicas, CONCORRENCIA_SONDAGENS_DRIFT, async (raiz) => {
397
+ try {
398
+ const raizReal = await realpath(raiz);
399
+ return caminhoEstaDentro(raizWorkspaceReal, raizReal) ? raizReal : undefined;
400
+ }
401
+ catch {
402
+ return undefined;
403
+ }
404
+ });
405
+ const raizesCodigoReais = [...new Map(reaisPossiveis
406
+ .filter((raiz) => Boolean(raiz))
407
+ .map((raiz) => [chaveCaminho(raiz), raiz])).values()];
408
+ return {
409
+ raizWorkspaceReal,
410
+ raizesCodigoLogicas: logicas,
411
+ raizesCodigoReais,
412
+ };
413
+ }
414
+ async function arquivoRegularConfinadoDependencias(caminho, confinamento) {
415
+ const absoluto = path.resolve(caminho);
416
+ if (!confinamento.raizesCodigoLogicas.some((raiz) => caminhoEstaDentro(raiz, absoluto))) {
417
+ return false;
418
+ }
419
+ try {
420
+ const informacao = await lstat(absoluto);
421
+ if (!informacao.isFile() || informacao.isSymbolicLink()) {
422
+ return false;
423
+ }
424
+ const caminhoReal = await realpath(absoluto);
425
+ return caminhoEstaDentro(confinamento.raizWorkspaceReal, caminhoReal)
426
+ && confinamento.raizesCodigoReais.some((raiz) => caminhoEstaDentro(raiz, caminhoReal));
427
+ }
428
+ catch {
429
+ return false;
430
+ }
431
+ }
432
+ async function resolverReferenciaLocalExistente(contexto, arquivoOrigem, referencia, confinamento, catalogados) {
433
+ for (const candidatoBruto of candidatosReferenciaLocalDrift(contexto, arquivoOrigem, referencia)) {
434
+ const candidato = catalogados?.get(chaveCaminho(candidatoBruto)) ?? candidatoBruto;
435
+ if (catalogados && !catalogados.has(chaveCaminho(candidatoBruto))) {
436
+ continue;
437
+ }
438
+ if (await arquivoRegularConfinadoDependencias(candidato, confinamento)) {
439
+ return candidato;
440
+ }
441
+ }
442
+ return undefined;
443
+ }
444
+ export async function expandirDependenciasPlanoDrift(contexto, plano, catalogo, cache) {
445
+ if (plano.estrategia !== "arquivos_vinculados" || plano.arquivos.length === 0) {
446
+ return plano;
447
+ }
448
+ const arquivos = new Map(plano.arquivos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
449
+ const inferidos = new Map(plano.arquivosInferidos.map((arquivo) => [chaveCaminho(arquivo), arquivo]));
450
+ const visitados = new Set();
451
+ const fila = [...plano.arquivos];
452
+ const confinamento = await construirConfinamentoDependencias(contexto);
453
+ const dependencias = new Map(Object.entries(plano.dependencias).map(([arquivo, itens]) => [arquivo, new Set(itens)]));
454
+ while (fila.length > 0) {
455
+ const lote = fila.splice(0)
456
+ .filter((arquivo) => {
457
+ const chave = chaveCaminho(arquivo);
458
+ if (visitados.has(chave)) {
459
+ return false;
460
+ }
461
+ visitados.add(chave);
462
+ return true;
463
+ });
464
+ const resultadosLote = await mapearComLimite(lote, CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT, async (arquivo) => {
465
+ let referencias;
466
+ try {
467
+ if (cache) {
468
+ const estado = await cache.resolverArquivo({
469
+ arquivo,
470
+ analise: "dependencias-v4",
471
+ ler: () => catalogo.ler(arquivo),
472
+ extrair: (conteudo) => extrairReferenciasLocaisDrift(conteudo.texto),
473
+ validar: (valor) => Array.isArray(valor) && valor.every((item) => typeof item === "string"),
474
+ });
475
+ referencias = estado.valor;
476
+ }
477
+ else {
478
+ referencias = extrairReferenciasLocaisDrift(await catalogo.lerTexto(arquivo));
479
+ }
480
+ }
481
+ catch {
482
+ return { arquivo, resolvidas: [] };
483
+ }
484
+ const resolvidas = new Map();
485
+ for (const referencia of referencias) {
486
+ const candidato = await resolverReferenciaLocalExistente(contexto, arquivo, referencia, confinamento);
487
+ if (candidato) {
488
+ resolvidas.set(chaveCaminho(candidato), candidato);
489
+ }
490
+ }
491
+ return { arquivo, resolvidas: [...resolvidas.values()] };
492
+ });
493
+ const novos = new Map();
494
+ for (const { arquivo, resolvidas } of resultadosLote) {
495
+ if (resolvidas.length > 0) {
496
+ const lista = dependencias.get(arquivo) ?? new Set();
497
+ for (const candidato of resolvidas) {
498
+ lista.add(candidato);
499
+ const chave = chaveCaminho(candidato);
500
+ if (!arquivos.has(chave)) {
501
+ novos.set(chave, candidato);
502
+ }
503
+ }
504
+ dependencias.set(arquivo, lista);
505
+ }
506
+ }
507
+ if (novos.size > 0) {
508
+ const novosOrdenados = [...novos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
509
+ await catalogo.incluir(novosOrdenados);
510
+ for (const candidato of novosOrdenados) {
511
+ const chave = chaveCaminho(candidato);
512
+ arquivos.set(chave, candidato);
513
+ inferidos.set(chave, candidato);
514
+ fila.push(candidato);
515
+ }
516
+ }
517
+ }
518
+ const arquivosExpandidos = [...arquivos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
519
+ return {
520
+ ...plano,
521
+ arquivos: arquivosExpandidos,
522
+ arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
523
+ diretorios: escolherDiretoriosLogicos(contexto, arquivosExpandidos),
524
+ dependencias: Object.fromEntries([...dependencias.entries()]
525
+ .sort(([a], [b]) => a.localeCompare(b, "pt-BR"))
526
+ .map(([arquivo, itens]) => [arquivo, [...itens].sort((a, b) => a.localeCompare(b, "pt-BR"))])),
527
+ };
528
+ }
529
+ export async function mapearDependenciasCatalogadasDrift(contexto, catalogo, cache, arquivos = catalogo.arquivosCatalogados()) {
530
+ const confinamento = await construirConfinamentoDependencias(contexto);
531
+ const catalogados = new Map(catalogo.arquivosCatalogados().map((arquivo) => [chaveCaminho(arquivo), arquivo]));
532
+ const arquivosOrdenados = [...arquivos].sort((a, b) => a.localeCompare(b, "pt-BR"));
533
+ const resultados = await mapearComLimite(arquivosOrdenados, CONCORRENCIA_MAPEAMENTO_DEPENDENCIAS_DRIFT, async (arquivo) => {
534
+ let referencias;
535
+ try {
536
+ const estado = await cache.resolverArquivo({
537
+ arquivo,
538
+ analise: "dependencias-v4",
539
+ ler: () => catalogo.ler(arquivo),
540
+ extrair: (conteudo) => extrairReferenciasLocaisDrift(conteudo.texto),
541
+ validar: (valor) => Array.isArray(valor) && valor.every((item) => typeof item === "string"),
542
+ });
543
+ referencias = estado.valor;
544
+ }
545
+ catch {
546
+ return undefined;
547
+ }
548
+ const resolvidas = new Map();
549
+ for (const referencia of referencias) {
550
+ const existente = await resolverReferenciaLocalExistente(contexto, arquivo, referencia, confinamento, catalogados);
551
+ if (existente) {
552
+ resolvidas.set(chaveCaminho(existente), existente);
553
+ }
554
+ }
555
+ return [
556
+ arquivo,
557
+ [...resolvidas.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
558
+ ];
559
+ });
560
+ const dependencias = new Map(resultados.filter((item) => Boolean(item)));
561
+ return Object.fromEntries([...dependencias.entries()].sort(([a], [b]) => a.localeCompare(b, "pt-BR")));
562
+ }
563
+ //# sourceMappingURL=driftEscopo.js.map
@@ -0,0 +1,4 @@
1
+ import type { ContextoProjetoCarregado } from "./projeto.js";
2
+ export declare function extrairReferenciasLocaisDrift(codigo: string): string[];
3
+ export declare function raizesCodigoLogicasDrift(contexto: ContextoProjetoCarregado): string[];
4
+ export declare function candidatosReferenciaLocalDrift(contexto: ContextoProjetoCarregado, arquivoOrigem: string, referencia: string): string[];