@semacode/cli 4.1.2 → 4.2.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/dist/agentBootstrap.d.ts +4 -0
- package/dist/agentBootstrap.js +44 -0
- package/dist/agentContext.d.ts +1 -1
- package/dist/agentContext.js +5 -5
- package/dist/agentContextPack.js +22 -31
- package/dist/agentEntryPoints.d.ts +1 -3
- package/dist/agentEntryPoints.js +16 -262
- package/dist/cliArgs.js +1 -0
- package/dist/cliGrammar.js +8 -4
- package/dist/cliHelpTexto.js +5 -4
- package/dist/comandoSessao.d.ts +0 -33
- package/dist/comandoSessao.js +71 -70
- package/dist/contextBudget.d.ts +15 -0
- package/dist/contextBudget.js +64 -0
- package/dist/docs.part01.js +0 -1
- package/dist/docs.part02.js +11 -23
- package/dist/docsRelations.d.ts +2 -0
- package/dist/docsRelations.js +83 -0
- package/dist/geracaoCore.d.ts +1 -1
- package/dist/index.part07.d.ts +1 -0
- package/dist/index.part07.js +54 -31
- package/dist/index.part08.js +3 -3
- package/dist/indexPack.d.ts +1 -0
- package/dist/indexPack.js +1 -1
- package/dist/initCommand.d.ts +1 -0
- package/dist/initCommand.js +10 -1
- package/dist/sessionContext.d.ts +13 -0
- package/dist/sessionContext.js +41 -0
- package/dist/verificacaoPythonLocal.d.ts +17 -0
- package/dist/verificacaoPythonLocal.js +46 -0
- package/docs/ai-integration.md +5 -13
- package/docs/ai-workflow.md +8 -6
- package/docs/commands.md +1 -1
- package/docs/documentation.md +33 -0
- package/docs/testing.md +18 -0
- package/exemplos/python_verificacao.sema +68 -68
- package/node_modules/@sema/gerador-python/dist/runtime.js +65 -65
- package/package.json +1 -1
- package/skills/sema/SKILL.md +82 -169
package/dist/index.part07.js
CHANGED
|
@@ -6,6 +6,7 @@ import pacoteCli from "../package.json" with { type: "json" };
|
|
|
6
6
|
import { compilarCodigo, formatarDiagnosticos, lerArquivoTexto, temErros, } from "@sema/nucleo";
|
|
7
7
|
import { carregarProjeto, resolverAlvosVerificacao, } from "./projeto.js";
|
|
8
8
|
import { SCHEMA_CACHE_VERIFICACAO, calcularChaveVerificacao, carregarCacheVerificacao, gravarCacheVerificacao, } from "./verificacaoCache.js";
|
|
9
|
+
import { erroModoPreservacao, prepararImplementacaoPythonLocal, evidenciaPython } from "./verificacaoPythonLocal.js";
|
|
9
10
|
const FONTES_POR_ALVO_SUPORTADO = {
|
|
10
11
|
typescript: ["typescript", "javascript"],
|
|
11
12
|
javascript: ["typescript", "javascript"],
|
|
@@ -210,7 +211,7 @@ export function imprimirResumoVerificacao(resumos) {
|
|
|
210
211
|
totalArquivos += alvo.arquivosGerados;
|
|
211
212
|
totalTestes += alvo.quantidadeTestes;
|
|
212
213
|
totalAlvos += 1;
|
|
213
|
-
console.log(` alvo=${alvo.alvo} framework=${alvo.framework} estrutura=${alvo.estrutura} status=${alvo.sucesso ? "ok" : "falhou"} arquivos=${alvo.arquivosGerados} testes=${alvo.quantidadeTestes}${alvo.testesExecutados ? "" : " (skip)"} saida=${alvo.pastaSaida}`);
|
|
214
|
+
console.log(` alvo=${alvo.alvo} framework=${alvo.framework} estrutura=${alvo.estrutura} status=${alvo.sucesso ? "ok" : "falhou"} arquivos=${alvo.arquivosGerados} testes=${alvo.quantidadeTestes}${alvo.testesExecutados ? "" : " (skip)"}${alvo.tipoEvidencia ? ` evidencia=${alvo.tipoEvidencia} (não comprova produção)` : ""} saida=${alvo.pastaSaida}`);
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
217
|
console.log(`Totais: modulos=${resumos.length} alvos=${totalAlvos} arquivos=${totalArquivos} testes=${totalTestes}`);
|
|
@@ -240,6 +241,11 @@ export async function comandoVerificar(entrada, baseSaida, cwd = process.cwd(),
|
|
|
240
241
|
...resolverConfiguracaoVerificacaoPorAlvo(alvo, contextoProjeto.configCarregada),
|
|
241
242
|
}));
|
|
242
243
|
const incompatibilidade = configuracoesAlvo.find((item) => item.incompatibilidade);
|
|
244
|
+
const erroPreservacao = erroModoPreservacao(opcoes.preservarImplementacao, configuracoesAlvo);
|
|
245
|
+
if (erroPreservacao) {
|
|
246
|
+
console.error(erroPreservacao);
|
|
247
|
+
return 1;
|
|
248
|
+
}
|
|
243
249
|
if (incompatibilidade?.incompatibilidade) {
|
|
244
250
|
console.error(incompatibilidade.incompatibilidade);
|
|
245
251
|
return 1;
|
|
@@ -272,7 +278,7 @@ export async function comandoVerificar(entrada, baseSaida, cwd = process.cwd(),
|
|
|
272
278
|
estrutura,
|
|
273
279
|
conteudoContrato,
|
|
274
280
|
});
|
|
275
|
-
const emCache = opcoes.semCache ? undefined : await carregarCacheVerificacao(chave, pastaAlvo);
|
|
281
|
+
const emCache = opcoes.semCache || opcoes.preservarImplementacao ? undefined : await carregarCacheVerificacao(chave, pastaAlvo);
|
|
276
282
|
if (emCache) {
|
|
277
283
|
resumoModulo.alvos.push({
|
|
278
284
|
alvo,
|
|
@@ -294,21 +300,27 @@ export async function comandoVerificar(entrada, baseSaida, cwd = process.cwd(),
|
|
|
294
300
|
continue;
|
|
295
301
|
}
|
|
296
302
|
const arquivos = aplicarEstruturaSaida(gerarArquivosPorAlvo(ir, alvo, framework), ir, estrutura);
|
|
297
|
-
const
|
|
303
|
+
const preparacao = opcoes.preservarImplementacao ? await prepararImplementacaoPythonLocal(pastaAlvo, arquivos) : { arquivosParaEscrita: arquivos };
|
|
304
|
+
if (preparacao.erro) {
|
|
305
|
+
console.error(preparacao.erro);
|
|
306
|
+
return 1;
|
|
307
|
+
}
|
|
308
|
+
const escrita = await escreverArquivos(pastaAlvo, preparacao.arquivosParaEscrita, { artefatoGerado: true });
|
|
298
309
|
artefatosGeradosAcimaDoLimite.push(...escrita.artefatosGeradosAcimaDoLimite);
|
|
299
310
|
const { execucao, testesExecutados } = executarTestesParaVerificacao(alvo, pastaAlvo, arquivos, framework);
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
311
|
+
if (!opcoes.preservarImplementacao)
|
|
312
|
+
await gravarCacheVerificacao({
|
|
313
|
+
schemaVersion: SCHEMA_CACHE_VERIFICACAO,
|
|
314
|
+
chave,
|
|
315
|
+
versaoCli: pacoteCli.version,
|
|
316
|
+
alvo,
|
|
317
|
+
modulo: ir.nome,
|
|
318
|
+
sucesso: execucao.codigoSaida === 0,
|
|
319
|
+
quantidadeTestes: execucao.quantidadeTestes,
|
|
320
|
+
testesExecutados,
|
|
321
|
+
arquivosGerados: arquivos.map((arquivo) => arquivo.caminhoRelativo),
|
|
322
|
+
geradoEm: new Date().toISOString(),
|
|
323
|
+
});
|
|
312
324
|
resumoModulo.alvos.push({
|
|
313
325
|
alvo,
|
|
314
326
|
arquivosGerados: arquivos.length,
|
|
@@ -319,7 +331,7 @@ export async function comandoVerificar(entrada, baseSaida, cwd = process.cwd(),
|
|
|
319
331
|
estrutura,
|
|
320
332
|
testesExecutados,
|
|
321
333
|
origem: "executado",
|
|
322
|
-
...(alvo === "python" ?
|
|
334
|
+
...(alvo === "python" ? evidenciaPython(opcoes.preservarImplementacao) : {}),
|
|
323
335
|
});
|
|
324
336
|
if (execucao.codigoSaida !== 0) {
|
|
325
337
|
imprimirResumoVerificacao([...resumos, resumoModulo]);
|
|
@@ -372,6 +384,11 @@ export async function comandoVerificarJson(entrada, baseSaida, cwd = process.cwd
|
|
|
372
384
|
...resolverConfiguracaoVerificacaoPorAlvo(alvo, contextoProjeto.configCarregada),
|
|
373
385
|
}));
|
|
374
386
|
const incompatibilidade = configuracoesAlvo.find((item) => item.incompatibilidade);
|
|
387
|
+
const erroPreservacao = erroModoPreservacao(opcoes.preservarImplementacao, configuracoesAlvo);
|
|
388
|
+
if (erroPreservacao) {
|
|
389
|
+
console.log(JSON.stringify({ comando: "verificar", sucesso: false, erro: erroPreservacao, modulos: [], totais: { modulos: 0, alvos: 0, arquivos: 0, testes: 0 } }));
|
|
390
|
+
return 1;
|
|
391
|
+
}
|
|
375
392
|
if (incompatibilidade?.incompatibilidade) {
|
|
376
393
|
console.log(JSON.stringify({
|
|
377
394
|
comando: "verificar",
|
|
@@ -418,7 +435,7 @@ export async function comandoVerificarJson(entrada, baseSaida, cwd = process.cwd
|
|
|
418
435
|
estrutura,
|
|
419
436
|
conteudoContrato,
|
|
420
437
|
});
|
|
421
|
-
const emCache = opcoes.semCache ? undefined : await carregarCacheVerificacao(chave, pastaAlvo);
|
|
438
|
+
const emCache = opcoes.semCache || opcoes.preservarImplementacao ? undefined : await carregarCacheVerificacao(chave, pastaAlvo);
|
|
422
439
|
if (emCache) {
|
|
423
440
|
resumoModulo.alvos.push({
|
|
424
441
|
alvo,
|
|
@@ -439,21 +456,27 @@ export async function comandoVerificarJson(entrada, baseSaida, cwd = process.cwd
|
|
|
439
456
|
continue;
|
|
440
457
|
}
|
|
441
458
|
const arquivos = aplicarEstruturaSaida(gerarArquivosPorAlvo(ir, alvo, framework), ir, estrutura);
|
|
442
|
-
const
|
|
459
|
+
const preparacao = opcoes.preservarImplementacao ? await prepararImplementacaoPythonLocal(pastaAlvo, arquivos) : { arquivosParaEscrita: arquivos };
|
|
460
|
+
if (preparacao.erro) {
|
|
461
|
+
console.log(JSON.stringify({ comando: "verificar", sucesso: false, erro: preparacao.erro, modulos: resumos, totais: { modulos: resumos.length, alvos: 0, arquivos: 0, testes: 0 } }));
|
|
462
|
+
return 1;
|
|
463
|
+
}
|
|
464
|
+
const escrita = await escreverArquivos(pastaAlvo, preparacao.arquivosParaEscrita, { artefatoGerado: true });
|
|
443
465
|
artefatosGeradosAcimaDoLimite.push(...escrita.artefatosGeradosAcimaDoLimite);
|
|
444
466
|
const { execucao, testesExecutados } = executarTestesParaVerificacao(alvo, pastaAlvo, arquivos, framework, true);
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
467
|
+
if (!opcoes.preservarImplementacao)
|
|
468
|
+
await gravarCacheVerificacao({
|
|
469
|
+
schemaVersion: SCHEMA_CACHE_VERIFICACAO,
|
|
470
|
+
chave,
|
|
471
|
+
versaoCli: pacoteCli.version,
|
|
472
|
+
alvo,
|
|
473
|
+
modulo: ir.nome,
|
|
474
|
+
sucesso: execucao.codigoSaida === 0,
|
|
475
|
+
quantidadeTestes: execucao.quantidadeTestes,
|
|
476
|
+
testesExecutados,
|
|
477
|
+
arquivosGerados: arquivos.map((arquivo) => arquivo.caminhoRelativo),
|
|
478
|
+
geradoEm: new Date().toISOString(),
|
|
479
|
+
});
|
|
457
480
|
resumoModulo.alvos.push({
|
|
458
481
|
alvo,
|
|
459
482
|
arquivosGerados: arquivos.length,
|
|
@@ -464,7 +487,7 @@ export async function comandoVerificarJson(entrada, baseSaida, cwd = process.cwd
|
|
|
464
487
|
estrutura,
|
|
465
488
|
testesExecutados,
|
|
466
489
|
origem: "executado",
|
|
467
|
-
...(alvo === "python" ?
|
|
490
|
+
...(alvo === "python" ? evidenciaPython(opcoes.preservarImplementacao) : {}),
|
|
468
491
|
});
|
|
469
492
|
resumoModulo.saidaTestes.push({ alvo, stdout: execucao.saidaPadrao, stderr: execucao.saidaErro });
|
|
470
493
|
if (execucao.codigoSaida !== 0) {
|
package/dist/index.part08.js
CHANGED
|
@@ -34,7 +34,7 @@ export async function principal() {
|
|
|
34
34
|
let codigoSaida = 0;
|
|
35
35
|
switch (comando) {
|
|
36
36
|
case "iniciar":
|
|
37
|
-
codigoSaida = await comandoIniciar(cwd, normalizarTemplateIniciar(obterOpcao(resto, "--template")), { force: possuiFlag(resto, "--force"), exemplosCompletos: possuiFlag(resto, "--com-exemplos") });
|
|
37
|
+
codigoSaida = await comandoIniciar(cwd, normalizarTemplateIniciar(obterOpcao(resto, "--template")), { force: possuiFlag(resto, "--force"), exemplosCompletos: possuiFlag(resto, "--com-exemplos"), contextoArgs: resto });
|
|
38
38
|
break;
|
|
39
39
|
case "sessao": {
|
|
40
40
|
const { comandoSessao } = await import("./comandoSessao.js");
|
|
@@ -105,8 +105,8 @@ export async function principal() {
|
|
|
105
105
|
break;
|
|
106
106
|
case "verificar":
|
|
107
107
|
codigoSaida = possuiFlag(resto, "--json")
|
|
108
|
-
? await comandoVerificarJson(posicionais[0], resolverSaidaPadrao(obterOpcao(resto, "--saida", "./.tmp/sema-verificar"), "typescript", await carregarConfiguracaoProjeto(posicionais[0] ? path.resolve(cwd, posicionais[0]) : cwd)), cwd, { alvo: obterOpcao(resto, "--alvo"), semCache: possuiFlag(resto, "--sem-cache") })
|
|
109
|
-
: await comandoVerificar(posicionais[0], resolverSaidaPadrao(obterOpcao(resto, "--saida", "./.tmp/sema-verificar"), "typescript", await carregarConfiguracaoProjeto(posicionais[0] ? path.resolve(cwd, posicionais[0]) : cwd)), cwd, { alvo: obterOpcao(resto, "--alvo"), semCache: possuiFlag(resto, "--sem-cache") });
|
|
108
|
+
? await comandoVerificarJson(posicionais[0], resolverSaidaPadrao(obterOpcao(resto, "--saida", "./.tmp/sema-verificar"), "typescript", await carregarConfiguracaoProjeto(posicionais[0] ? path.resolve(cwd, posicionais[0]) : cwd)), cwd, { alvo: obterOpcao(resto, "--alvo"), semCache: possuiFlag(resto, "--sem-cache"), preservarImplementacao: possuiFlag(resto, "--preservar-implementacao") })
|
|
109
|
+
: await comandoVerificar(posicionais[0], resolverSaidaPadrao(obterOpcao(resto, "--saida", "./.tmp/sema-verificar"), "typescript", await carregarConfiguracaoProjeto(posicionais[0] ? path.resolve(cwd, posicionais[0]) : cwd)), cwd, { alvo: obterOpcao(resto, "--alvo"), semCache: possuiFlag(resto, "--sem-cache"), preservarImplementacao: possuiFlag(resto, "--preservar-implementacao") });
|
|
110
110
|
break;
|
|
111
111
|
case "inspecionar":
|
|
112
112
|
codigoSaida = await comandoInspecionar(posicionais[0], possuiFlag(resto, "--json"), cwd, resto);
|
package/dist/indexPack.d.ts
CHANGED
package/dist/indexPack.js
CHANGED
|
@@ -84,7 +84,7 @@ export function selecionarIndiceContexto(input) {
|
|
|
84
84
|
.map((modulo) => compactarModulo(modulo, requestTokens, projetarResumoInteiro))
|
|
85
85
|
.filter((item) => item !== null)
|
|
86
86
|
.sort((a, b) => b.relevanceScore - a.relevanceScore || a.module.localeCompare(b.module, "pt-BR"))
|
|
87
|
-
.slice(0, projetarResumoInteiro ? input.modulos.length : 8);
|
|
87
|
+
.slice(0, input.maximoModulos ?? (projetarResumoInteiro ? input.modulos.length : 8));
|
|
88
88
|
const base = {
|
|
89
89
|
schema: "sema.ai.index-pack/v1",
|
|
90
90
|
selection,
|
package/dist/initCommand.d.ts
CHANGED
|
@@ -2,5 +2,6 @@ import { type TemplateIniciar } from "./initTemplatesBase.js";
|
|
|
2
2
|
export declare function comandoIniciar(cwd: string, template: TemplateIniciar, opcoes?: {
|
|
3
3
|
force?: boolean;
|
|
4
4
|
exemplosCompletos?: boolean;
|
|
5
|
+
contextoArgs?: string[];
|
|
5
6
|
}): Promise<number>;
|
|
6
7
|
export declare function comandoInstalarExemplos(emJson: boolean): Promise<number>;
|
package/dist/initCommand.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// SEMA-GOVERNED: sema.produto.cli_init_templates, sema.produto.escrita_segura_workspace
|
|
2
2
|
// Descrição: inicializa projetos preservando arquivos existentes e bloqueando escapes do workspace.
|
|
3
|
+
import { resolverPerfilContexto, salvarPerfilContexto, ARQUIVO_PERFIL_CONTEXTO, PERGUNTA_CONTEXTO } from "./contextBudget.js";
|
|
3
4
|
import * as fs from "node:fs";
|
|
4
5
|
import { readFile } from "node:fs/promises";
|
|
5
6
|
import path from "node:path";
|
|
@@ -57,8 +58,14 @@ const EXEMPLOS_STARTER_INICIAR = new Set([
|
|
|
57
58
|
"exemplos/autenticacao.sema",
|
|
58
59
|
]);
|
|
59
60
|
export async function comandoIniciar(cwd, template, opcoes = {}) {
|
|
60
|
-
const arquivosCompletos = arquivosTemplateIniciar(template);
|
|
61
61
|
const configAncestral = await carregarConfiguracaoProjeto(cwd);
|
|
62
|
+
const basePerfil = configAncestral?.baseDiretorio ?? cwd;
|
|
63
|
+
const perfilContexto = await resolverPerfilContexto(basePerfil, opcoes.contextoArgs ?? []);
|
|
64
|
+
if (!perfilContexto) {
|
|
65
|
+
console.log(JSON.stringify({ comando: "iniciar", sucesso: false, status: "configuracao_necessaria", pergunta: PERGUNTA_CONTEXTO, proximoPasso: "Repita iniciar com --janela-contexto <tokens>; nenhum arquivo foi criado." }));
|
|
66
|
+
return 1;
|
|
67
|
+
}
|
|
68
|
+
const arquivosCompletos = arquivosTemplateIniciar(template);
|
|
62
69
|
const subpastaGovernada = Boolean(configAncestral
|
|
63
70
|
&& path.resolve(configAncestral.baseDiretorio) !== path.resolve(cwd));
|
|
64
71
|
// Em subpasta de workspace ja governado o config do template e omitido: a
|
|
@@ -84,6 +91,7 @@ export async function comandoIniciar(cwd, template, opcoes = {}) {
|
|
|
84
91
|
]);
|
|
85
92
|
const caminhosTemplate = new Set(arquivos.map((arquivo) => arquivo.caminhoRelativo));
|
|
86
93
|
const destinos = await validarDestinosEscritaWorkspace(cwd, [
|
|
94
|
+
...(basePerfil === cwd ? [ARQUIVO_PERFIL_CONTEXTO] : []),
|
|
87
95
|
...caminhosTemplate,
|
|
88
96
|
...exemplosIniciar.map((arquivo) => arquivo.caminhoRelativo),
|
|
89
97
|
...ARQUIVOS_RESUMO_PROJETO_IA,
|
|
@@ -95,6 +103,7 @@ export async function comandoIniciar(cwd, template, opcoes = {}) {
|
|
|
95
103
|
const arquivosParaEscrever = opcoes.force
|
|
96
104
|
? arquivos
|
|
97
105
|
: arquivos.filter((arquivo) => !existentes.has(arquivo.caminhoRelativo));
|
|
106
|
+
await salvarPerfilContexto(basePerfil, perfilContexto);
|
|
98
107
|
await escreverArquivos(cwd, arquivosParaEscrever, { inserirCabecalhoGovernado: true });
|
|
99
108
|
const exemplos = await materializarExemplosOficiais(cwd, true, opcoes.exemplosCompletos ? undefined : EXEMPLOS_STARTER_INICIAR);
|
|
100
109
|
if (!exemplos.sucesso) {
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare function navegarContextoSessao(base: string, pedido: string, arquivo?: string): Promise<{
|
|
2
|
+
totalModulos: number;
|
|
3
|
+
indiceCaracteres: number;
|
|
4
|
+
candidatos: {
|
|
5
|
+
modulo: any;
|
|
6
|
+
contrato: string;
|
|
7
|
+
motivo: string;
|
|
8
|
+
resumo: any;
|
|
9
|
+
arquivos: any;
|
|
10
|
+
}[];
|
|
11
|
+
status: string;
|
|
12
|
+
execucaoAutorizada: boolean;
|
|
13
|
+
}>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.produto.cli_sessao
|
|
2
|
+
// Descrição: consulta o índice local internamente e retorna candidatos rastreáveis, sem autorização de edição.
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { selecionarIndiceContexto } from "./indexPack.js";
|
|
6
|
+
import { validarDestinosEscritaWorkspace } from "./workspaceWrite.js";
|
|
7
|
+
export async function navegarContextoSessao(base, pedido, arquivo) {
|
|
8
|
+
await validarDestinosEscritaWorkspace(base, ["SEMA_INDEX.json"]);
|
|
9
|
+
const texto = await readFile(path.join(base, "SEMA_INDEX.json"), "utf8");
|
|
10
|
+
const indice = JSON.parse(texto);
|
|
11
|
+
if (!Array.isArray(indice.modulos))
|
|
12
|
+
throw new Error("Índice sem módulos; rode sema sync-codex --json.");
|
|
13
|
+
const relativo = (valor) => {
|
|
14
|
+
const absoluto = path.resolve(base, valor);
|
|
15
|
+
const rel = path.relative(base, absoluto);
|
|
16
|
+
if (rel === ".." || rel.startsWith(`..${path.sep}`) || path.isAbsolute(rel))
|
|
17
|
+
throw new Error("Referência de contexto fora do workspace.");
|
|
18
|
+
return rel.replace(/\\/g, "/");
|
|
19
|
+
};
|
|
20
|
+
const alvo = arquivo ? relativo(arquivo) : undefined;
|
|
21
|
+
const exatos = alvo ? indice.modulos.filter((m) => relativo(m.arquivo) === alvo
|
|
22
|
+
|| m.arquivosProvaveis?.some((p) => relativo(p) === alvo)) : [];
|
|
23
|
+
const pack = selecionarIndiceContexto({ modulos: indice.modulos, request: pedido, baseProject: base, sourceIndexChars: texto.length, maximoModulos: indice.modulos.length });
|
|
24
|
+
const encontrados = alvo ? exatos.map((m) => ({
|
|
25
|
+
module: m.modulo, contract: m.arquivo, purpose: m.faz, likelyFiles: m.arquivosProvaveis,
|
|
26
|
+
})) : pack.matches;
|
|
27
|
+
return {
|
|
28
|
+
totalModulos: indice.modulos.length,
|
|
29
|
+
indiceCaracteres: texto.length,
|
|
30
|
+
candidatos: encontrados.map((m) => ({
|
|
31
|
+
modulo: m.module,
|
|
32
|
+
contrato: relativo(m.contract),
|
|
33
|
+
motivo: alvo ? `Referência exata: ${alvo}` : "Correspondência de intenção; confirme no contrato antes de editar.",
|
|
34
|
+
resumo: m.purpose,
|
|
35
|
+
arquivos: (m.likelyFiles ?? []).map(relativo),
|
|
36
|
+
})),
|
|
37
|
+
status: encontrados.length === 0 ? "sem_correspondencia" : encontrados.length === 1 ? "contrato_localizado" : "selecionar_contrato",
|
|
38
|
+
execucaoAutorizada: false,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=sessionContext.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type Arquivo = {
|
|
2
|
+
caminhoRelativo: string;
|
|
3
|
+
conteudo: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function erroModoPreservacao(preservar: boolean | undefined, configuracoes: Array<{
|
|
6
|
+
alvo: string;
|
|
7
|
+
framework: string;
|
|
8
|
+
}>): string | undefined;
|
|
9
|
+
export declare function prepararImplementacaoPythonLocal(base: string, arquivos: Arquivo[]): Promise<{
|
|
10
|
+
arquivosParaEscrita: Arquivo[];
|
|
11
|
+
erro?: string;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function evidenciaPython(preservar: boolean | undefined): {
|
|
14
|
+
tipoEvidencia: "andaime_demonstrativo" | "implementacao_local_preservada";
|
|
15
|
+
implementacaoExternaExecutada: boolean;
|
|
16
|
+
};
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.produto.cli_verificacao
|
|
2
|
+
// Contrato: contratos/sema/cli_verificacao.sema
|
|
3
|
+
// Descrição: preserva Python local explicitamente; testes continuam derivados do contrato, sem cache.
|
|
4
|
+
import { lstat } from "node:fs/promises";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
export function erroModoPreservacao(preservar, configuracoes) {
|
|
7
|
+
if (preservar && (configuracoes.length !== 1 || configuracoes[0].alvo !== "python" || configuracoes[0].framework !== "base")) {
|
|
8
|
+
return "--preservar-implementacao exige --alvo python e framework base.";
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
export async function prepararImplementacaoPythonLocal(base, arquivos) {
|
|
13
|
+
const implementacoes = arquivos.filter(arquivo => arquivo.caminhoRelativo.endsWith(".py") && !path.basename(arquivo.caminhoRelativo).startsWith("test_"));
|
|
14
|
+
if (implementacoes.length === 0)
|
|
15
|
+
return { arquivosParaEscrita: [], erro: "Nenhuma implementação Python local prevista pelo contrato." };
|
|
16
|
+
try {
|
|
17
|
+
for (const arquivo of implementacoes) {
|
|
18
|
+
const destino = path.resolve(base, arquivo.caminhoRelativo);
|
|
19
|
+
const relativo = path.relative(path.resolve(base), destino);
|
|
20
|
+
if (path.isAbsolute(relativo) || relativo.split(path.sep).includes(".."))
|
|
21
|
+
throw new Error("escape");
|
|
22
|
+
let atual = destino;
|
|
23
|
+
while (true) {
|
|
24
|
+
const info = await lstat(atual);
|
|
25
|
+
if (info.isSymbolicLink() || (atual === destino ? !info.isFile() || info.nlink > 1 : !info.isDirectory()))
|
|
26
|
+
throw new Error("link ou tipo inválido");
|
|
27
|
+
const pai = path.dirname(atual);
|
|
28
|
+
if (pai === atual)
|
|
29
|
+
break;
|
|
30
|
+
atual = pai;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const preservados = new Set(implementacoes.map(arquivo => arquivo.caminhoRelativo));
|
|
34
|
+
return { arquivosParaEscrita: arquivos.filter(arquivo => !preservados.has(arquivo.caminhoRelativo)) };
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return { arquivosParaEscrita: [], erro: "Implementação Python local ausente ou caminho não seguro. Gere e preencha a implementação antes de usar --preservar-implementacao." };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function evidenciaPython(preservar) {
|
|
41
|
+
return {
|
|
42
|
+
tipoEvidencia: preservar ? "implementacao_local_preservada" : "andaime_demonstrativo",
|
|
43
|
+
implementacaoExternaExecutada: false,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=verificacaoPythonLocal.js.map
|
package/docs/ai-integration.md
CHANGED
|
@@ -60,19 +60,11 @@ while contract-only queries keep unobserved implementation fields null inside th
|
|
|
60
60
|
|
|
61
61
|
## Codex Context Tiers
|
|
62
62
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
Codex with a medium context budget should start with `SEMA_BOOT.md`,
|
|
69
|
-
`AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.curto.txt`,
|
|
70
|
-
`SEMA_INDEX.json`, and `AGENTS.md`. They must run docs-impact, drift, and
|
|
71
|
-
impact before edits.
|
|
72
|
-
|
|
73
|
-
Codex with a large context budget may consume `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.md`,
|
|
74
|
-
`SEMA_INDEX.json`, AST, IR, drift, and impact outputs, but larger context does
|
|
75
|
-
not remove the contract-first rule.
|
|
63
|
+
All context capacities start with AGENTS.md, SEMA_BOOT.md and sema sessao.
|
|
64
|
+
The first session asks for the effective window in tokens. Declare --janela-contexto
|
|
65
|
+
and use --salvar-perfil to remember it; --orcamento-contexto and --reserva-saida are adjustable.
|
|
66
|
+
SEMA_INDEX.json and AGENT_CONTEXT_PACK.json are internal CLI data, never mandatory full reads.
|
|
67
|
+
Read the selected contract and its declared dependencies, then the linked code. Ambiguity requires refinement.
|
|
76
68
|
|
|
77
69
|
## Governed Code
|
|
78
70
|
|
package/docs/ai-workflow.md
CHANGED
|
@@ -5,10 +5,10 @@ This is the minimum workflow for Codex in a local workspace.
|
|
|
5
5
|
|
|
6
6
|
1. Read `SEMA_BOOT.md`.
|
|
7
7
|
2. Run `sema --version`. If the shell cannot find it, use `$HOME/.sema/bin/sema` on macOS/Linux. On Windows, PowerShell resolves `sema.ps1` from PATH and cmd.exe resolves `sema.cmd`; use `& "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\.sema\bin\sema-managed.ps1" --version` as the absolute fallback. Only then declare the CLI unavailable.
|
|
8
|
-
3. Run `sema
|
|
9
|
-
4. Run `sema docs-impacto --intencao "<change>" --json`.
|
|
8
|
+
3. Run `sema sessao "<intenção>" --json`; then `sema resumo <contrato> --micro --drift none --json` only for the selected contract.
|
|
9
|
+
4. Run `sema docs-impacto --intencao "<change>" --arquivo <contract> --json`.
|
|
10
10
|
5. Read every required document returned by the command.
|
|
11
|
-
6.
|
|
11
|
+
6. Consult command help or the relevant section of `docs/commands.md` when syntax, a gate or `--saida` is unclear.
|
|
12
12
|
7. If the right capability is unclear, run `sema descobrir recomendar --intencao "<goal>" --json`; do not auto-run ambiguous recommendations.
|
|
13
13
|
8. Use `exemplos/` and `docs/syntax.md` before creating or editing a contract.
|
|
14
14
|
9. Run `sema drift --cache fresh` and `sema impacto` before editing existing code.
|
|
@@ -30,9 +30,11 @@ UI rule: if the task involves an interface, minimum evidence includes desktop an
|
|
|
30
30
|
|
|
31
31
|
## Codex Context Capacity
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
-
|
|
33
|
+
All capacities use AGENTS.md -> SEMA_BOOT.md -> the contract returned by `sema sessao`.
|
|
34
|
+
The first session asks for the configured token window; declare `--janela-contexto <tokens> --salvar-perfil`.
|
|
35
|
+
Use `--orcamento-contexto` and `--reserva-saida` to allocate space. Counts use characters / 4, not the model tokenizer.
|
|
36
|
+
The CLI reads SEMA_INDEX.json internally. Do not load the full index, global pack, or unrelated modules.
|
|
37
|
+
An explicit `--arquivo` selects its contract and declared dependencies. Word matches are optional references.
|
|
36
38
|
|
|
37
39
|
## When to Generate Code
|
|
38
40
|
|
package/docs/commands.md
CHANGED
|
@@ -18,7 +18,7 @@ Then read every required doc returned by `docs-impacto`.
|
|
|
18
18
|
|
|
19
19
|
## Session Opening
|
|
20
20
|
|
|
21
|
-
- `sema sessao "<intencao>" --json`:
|
|
21
|
+
- `sema sessao "<intencao>" [--arquivo <contrato-ou-codigo>] [--janela-contexto <tokens>] [--orcamento-contexto <tokens>] [--reserva-saida <tokens>] [--salvar-perfil] --json`: asks for the effective window when absent and stores the profile only on explicit request. The compact response contains workspace identity, artifact freshness, matching contracts and linked files, mandatory document paths, scoped gates and next steps. The index stays inside the CLI. The budget estimates the public JSON size using characters/4; it does not measure the conversation or the model's exact tokenizer. Omitted candidates are counted and require scope refinement; mandatory readings are never silently waived. Treat `frescor.fresco:false` as a pre-action blocker and run the suggested `sema sync-codex --json`. Navigation never authorizes execution.
|
|
22
22
|
|
|
23
23
|
## Public JSON output
|
|
24
24
|
|
package/docs/documentation.md
CHANGED
|
@@ -47,3 +47,36 @@ same rule applies to drift and semantic-budget governance: keep a cohesive
|
|
|
47
47
|
primary capability in the root contract and move secondary responsibilities to
|
|
48
48
|
named children. Preserve task names, guarantees, implementations, and
|
|
49
49
|
`vinculos`; never create numbered part files.
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## Progressive AI Context
|
|
53
|
+
|
|
54
|
+
The mandatory entry is AGENTS.md and SEMA_BOOT.md. SEMA_INDEX.json and
|
|
55
|
+
AGENT_CONTEXT_PACK.json are internal CLI sources, not required full readings.
|
|
56
|
+
The session asks for the effective context window when it is unknown. The local
|
|
57
|
+
`.sema/contexto-ia.json` profile is saved only by `--salvar-perfil` or by `iniciar`
|
|
58
|
+
with a declared window. Reconfigure it after switching models.
|
|
59
|
+
|
|
60
|
+
`sema sessao "<intent>" --janela-contexto 32768 --salvar-perfil --json`
|
|
61
|
+
configures a 32K window. Defaults allocate 4096 estimated tokens to the session
|
|
62
|
+
response and reserve 4096 for output. Other instructions, tools, conversation
|
|
63
|
+
and code need the remaining space. `--orcamento-contexto` and `--reserva-saida`
|
|
64
|
+
adjust this split. The characters/4 estimate includes the public envelope and
|
|
65
|
+
a margin; it is not an exact tokenizer or a measurement of the client's used
|
|
66
|
+
context. The limit applies to the session response, not every legacy command
|
|
67
|
+
or the cumulative conversation. The output reserve does not configure the model.
|
|
68
|
+
|
|
69
|
+
In docs-impacto and finalizar-mudanca, `--arquivo` fixes the target. Explicit
|
|
70
|
+
contracts are included even beyond the 80th catalog entry. Source files resolve
|
|
71
|
+
through `vinculos.arquivo`. Required expansion follows declared `use` dependencies,
|
|
72
|
+
with reasons and originating contracts. Missing or ambiguous dependencies block.
|
|
73
|
+
`docs.arquivo` references are recommendations and do not expand the dependency
|
|
74
|
+
graph. Intent suggestions stay in `leituraRecomendada`, distinct from
|
|
75
|
+
`leituraObrigatoria`, and do not block closure. Pass the same target at closure
|
|
76
|
+
and confirm the selected contracts before editing code.
|
|
77
|
+
|
|
78
|
+
The context-budget and docs-relevancia tests measure actual CLI output, prove
|
|
79
|
+
that the raw index is absent, verify hash invalidation and configuration before
|
|
80
|
+
writes, and cover WhatsApp alongside 85 unrelated contracts. Drift, contract
|
|
81
|
+
and behavioral gates remain required. To roll back, restore the prior generators
|
|
82
|
+
and resolvers and run sync-codex; preserve manual blocks and the local profile.
|
package/docs/testing.md
CHANGED
|
@@ -169,3 +169,21 @@ this scaffold: its tests and guarantees cannot establish production behavior.
|
|
|
169
169
|
Use the application's real tests and drift evidence for that claim. Generated
|
|
170
170
|
failure cases currently retain the explicit synthetic error context and are
|
|
171
171
|
not evidence that the real implementation produces those errors.
|
|
172
|
+
|
|
173
|
+
To execute an explicitly filled local Python implementation without overwriting
|
|
174
|
+
it, use the same verification output base that contains the generated module:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
sema verificar contratos/app.sema --alvo python --saida .tmp/check --preservar-implementacao --json
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
This opt-in mode supports only Python with the base framework. All expected
|
|
181
|
+
implementation files must already exist as regular files, without symlinks,
|
|
182
|
+
junctions or hardlinks. It preserves those files byte for byte, regenerates the
|
|
183
|
+
contract tests and support artifacts, and always runs the tests without reading
|
|
184
|
+
or writing the verification cache. Missing implementations fail before writes;
|
|
185
|
+
new expectations and incorrect implementation results still fail. The output
|
|
186
|
+
reports `tipoEvidencia: implementacao_local_preservada` and
|
|
187
|
+
`implementacaoExternaExecutada: false`: it proves execution of those local files,
|
|
188
|
+
not automatic execution of a linked `impl`, a remote deployment or production.
|
|
189
|
+
Normal verification retains the demonstration scaffold behavior.
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
module exemplos.python_verificacao {
|
|
2
|
-
docs {
|
|
3
|
-
resumo: "Regressao executavel Python para garantias numericas, formulario tipado, status e metadados aninhados."
|
|
4
|
-
}
|
|
5
|
-
entity FormularioEntrega {
|
|
6
|
-
fields {
|
|
7
|
-
tipo: Texto
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
entity MetaTemplate {
|
|
11
|
-
fields {
|
|
12
|
-
original_campaign_id: Texto
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
entity Template {
|
|
16
|
-
fields {
|
|
17
|
-
_template_meta: MetaTemplate
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
entity Status {
|
|
21
|
-
fields {
|
|
22
|
-
desired_action: Texto
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
task preparar {
|
|
26
|
-
input {
|
|
27
|
-
formulario: FormularioEntrega required
|
|
28
|
-
}
|
|
29
|
-
output {
|
|
30
|
-
poolSize: Inteiro
|
|
31
|
-
workersAplicados: Inteiro
|
|
32
|
-
template: Template
|
|
33
|
-
status: Status
|
|
34
|
-
}
|
|
35
|
-
rules {
|
|
36
|
-
formulario.tipo existe
|
|
37
|
-
}
|
|
38
|
-
guarantees {
|
|
39
|
-
poolSize > 0
|
|
40
|
-
workersAplicados >= 2
|
|
41
|
-
template._template_meta existe
|
|
42
|
-
template._template_meta.original_campaign_id em ["campanha_1"]
|
|
43
|
-
status.desired_action em ["iniciar", "parar"]
|
|
44
|
-
}
|
|
45
|
-
tests {
|
|
46
|
-
caso "verifica cada saida" {
|
|
47
|
-
given {
|
|
48
|
-
formulario {
|
|
49
|
-
tipo: "entrega"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
expect {
|
|
53
|
-
sucesso: verdadeiro
|
|
54
|
-
poolSize: 1
|
|
55
|
-
workersAplicados: 2
|
|
56
|
-
template {
|
|
57
|
-
_template_meta {
|
|
58
|
-
original_campaign_id: "campanha_1"
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
status {
|
|
62
|
-
desired_action: "iniciar"
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
1
|
+
module exemplos.python_verificacao {
|
|
2
|
+
docs {
|
|
3
|
+
resumo: "Regressao executavel Python para garantias numericas, formulario tipado, status e metadados aninhados."
|
|
4
|
+
}
|
|
5
|
+
entity FormularioEntrega {
|
|
6
|
+
fields {
|
|
7
|
+
tipo: Texto
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
entity MetaTemplate {
|
|
11
|
+
fields {
|
|
12
|
+
original_campaign_id: Texto
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
entity Template {
|
|
16
|
+
fields {
|
|
17
|
+
_template_meta: MetaTemplate
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
entity Status {
|
|
21
|
+
fields {
|
|
22
|
+
desired_action: Texto
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
task preparar {
|
|
26
|
+
input {
|
|
27
|
+
formulario: FormularioEntrega required
|
|
28
|
+
}
|
|
29
|
+
output {
|
|
30
|
+
poolSize: Inteiro
|
|
31
|
+
workersAplicados: Inteiro
|
|
32
|
+
template: Template
|
|
33
|
+
status: Status
|
|
34
|
+
}
|
|
35
|
+
rules {
|
|
36
|
+
formulario.tipo existe
|
|
37
|
+
}
|
|
38
|
+
guarantees {
|
|
39
|
+
poolSize > 0
|
|
40
|
+
workersAplicados >= 2
|
|
41
|
+
template._template_meta existe
|
|
42
|
+
template._template_meta.original_campaign_id em ["campanha_1"]
|
|
43
|
+
status.desired_action em ["iniciar", "parar"]
|
|
44
|
+
}
|
|
45
|
+
tests {
|
|
46
|
+
caso "verifica cada saida" {
|
|
47
|
+
given {
|
|
48
|
+
formulario {
|
|
49
|
+
tipo: "entrega"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
expect {
|
|
53
|
+
sucesso: verdadeiro
|
|
54
|
+
poolSize: 1
|
|
55
|
+
workersAplicados: 2
|
|
56
|
+
template {
|
|
57
|
+
_template_meta {
|
|
58
|
+
original_campaign_id: "campanha_1"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
status {
|
|
62
|
+
desired_action: "iniciar"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|