@semacode/cli 3.9.3 → 3.10.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/bin.js +10 -0
- package/dist/cliControlError.d.ts +7 -2
- package/dist/cliControlError.js +12 -1
- package/dist/cliGrammar.js +2 -1
- package/dist/cliHelpTexto.js +1 -0
- package/dist/cliRuntime.js +15 -1
- package/dist/comandoSessao.d.ts +34 -0
- package/dist/comandoSessao.js +86 -0
- package/dist/docs.part01.js +1 -1
- package/dist/index.part01.d.ts +1 -1
- package/dist/index.part02.js +8 -2
- package/dist/index.part04.d.ts +7 -0
- package/dist/index.part04.js +46 -2
- package/dist/index.part05.js +1 -1
- package/dist/index.part06.js +1 -1
- package/dist/index.part08.js +5 -0
- package/dist/projetoCarregar.d.ts +6 -0
- package/dist/projetoCarregar.js +43 -1
- package/dist/saidaCli.d.ts +3 -1
- package/dist/saidaCli.js +5 -0
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -105,6 +105,16 @@ export async function executarCliPublica(argv = process.argv.slice(2)) {
|
|
|
105
105
|
if (!execucao) {
|
|
106
106
|
return emitirFalhaControle(argv, "FATAL_ERROR", "CLI_FATAL_ERROR", "Falha ao executar a CLI da Sema.", 1);
|
|
107
107
|
}
|
|
108
|
+
try {
|
|
109
|
+
const doc = JSON.parse(execucao.stdout.trim());
|
|
110
|
+
if (doc.schemaVersion === "sema.cli.control/v1" && typeof doc.kind === "string" && doc.exitCode === execucao.codigoSaida) {
|
|
111
|
+
console.log(execucao.stdout);
|
|
112
|
+
return execucao.codigoSaida;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// nao e um envelope de controle; segue o caminho normal
|
|
117
|
+
}
|
|
108
118
|
return emitirResultadoCliJsonV1({
|
|
109
119
|
comando: sintaxe.comando,
|
|
110
120
|
codigoSaida: execucao.codigoSaida,
|
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
export type CategoriaFalhaControleCli = "UNKNOWN_COMMAND" | "ARGUMENT_ERROR" | "FATAL_ERROR";
|
|
1
|
+
export type CategoriaFalhaControleCli = "UNKNOWN_COMMAND" | "ARGUMENT_ERROR" | "CONTRACT_NOT_FOUND" | "FATAL_ERROR";
|
|
2
2
|
export declare class CliControlError extends Error {
|
|
3
3
|
readonly categoria: CategoriaFalhaControleCli;
|
|
4
4
|
readonly codigoPublico: string;
|
|
5
5
|
readonly mensagemPublica: string;
|
|
6
6
|
readonly codigoSaida: number;
|
|
7
|
-
|
|
7
|
+
readonly detalhes?: Record<string, unknown>;
|
|
8
|
+
constructor(categoria: CategoriaFalhaControleCli, detalhes?: Record<string, unknown>);
|
|
8
9
|
}
|
|
9
10
|
export declare function erroComandoDesconhecido(): CliControlError;
|
|
10
11
|
export declare function erroArgumentoInvalido(): CliControlError;
|
|
12
|
+
export declare function erroContratoNaoEncontrado(detalhes: {
|
|
13
|
+
caminhoTentado: string;
|
|
14
|
+
sugeridos: string[];
|
|
15
|
+
}): CliControlError;
|
|
11
16
|
export declare function erroFatalCli(): CliControlError;
|
|
12
17
|
export declare function ehCliControlError(valor: unknown): valor is CliControlError;
|
package/dist/cliControlError.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// SEMA-GOVERNED: sema.produto.cli_invocacao_publica.argumentos
|
|
2
2
|
// Descrição: representa falhas públicas de controle sem carregar argv, stack ou caminhos na mensagem.
|
|
3
|
+
const MENSAGEM_CONTRATO_NAO_ENCONTRADO = "Contrato Sema nao encontrado. Consulte os contratos sugeridos no envelope.";
|
|
3
4
|
const DEFINICOES_FALHA_CONTROLE = Object.freeze({
|
|
4
5
|
UNKNOWN_COMMAND: Object.freeze({
|
|
5
6
|
codigoPublico: "CLI_UNKNOWN_COMMAND",
|
|
@@ -11,6 +12,11 @@ const DEFINICOES_FALHA_CONTROLE = Object.freeze({
|
|
|
11
12
|
mensagemPublica: "Argumentos inválidos. Consulte a ajuda do comando.",
|
|
12
13
|
codigoSaida: 1,
|
|
13
14
|
}),
|
|
15
|
+
CONTRACT_NOT_FOUND: Object.freeze({
|
|
16
|
+
codigoPublico: "CLI_CONTRACT_NOT_FOUND",
|
|
17
|
+
mensagemPublica: MENSAGEM_CONTRATO_NAO_ENCONTRADO,
|
|
18
|
+
codigoSaida: 2,
|
|
19
|
+
}),
|
|
14
20
|
FATAL_ERROR: Object.freeze({
|
|
15
21
|
codigoPublico: "CLI_FATAL_ERROR",
|
|
16
22
|
mensagemPublica: "Falha ao executar a CLI da Sema.",
|
|
@@ -22,7 +28,8 @@ export class CliControlError extends Error {
|
|
|
22
28
|
codigoPublico;
|
|
23
29
|
mensagemPublica;
|
|
24
30
|
codigoSaida;
|
|
25
|
-
|
|
31
|
+
detalhes;
|
|
32
|
+
constructor(categoria, detalhes) {
|
|
26
33
|
const definicao = DEFINICOES_FALHA_CONTROLE[categoria];
|
|
27
34
|
super(definicao.mensagemPublica);
|
|
28
35
|
this.name = "CliControlError";
|
|
@@ -30,6 +37,7 @@ export class CliControlError extends Error {
|
|
|
30
37
|
this.codigoPublico = definicao.codigoPublico;
|
|
31
38
|
this.mensagemPublica = definicao.mensagemPublica;
|
|
32
39
|
this.codigoSaida = definicao.codigoSaida;
|
|
40
|
+
this.detalhes = detalhes;
|
|
33
41
|
}
|
|
34
42
|
}
|
|
35
43
|
export function erroComandoDesconhecido() {
|
|
@@ -38,6 +46,9 @@ export function erroComandoDesconhecido() {
|
|
|
38
46
|
export function erroArgumentoInvalido() {
|
|
39
47
|
return new CliControlError("ARGUMENT_ERROR");
|
|
40
48
|
}
|
|
49
|
+
export function erroContratoNaoEncontrado(detalhes) {
|
|
50
|
+
return new CliControlError("CONTRACT_NOT_FOUND", detalhes);
|
|
51
|
+
}
|
|
41
52
|
export function erroFatalCli() {
|
|
42
53
|
return new CliControlError("FATAL_ERROR");
|
|
43
54
|
}
|
package/dist/cliGrammar.js
CHANGED
|
@@ -10,7 +10,7 @@ const COMANDOS_PUBLICOS = new Set([
|
|
|
10
10
|
"impacto", "importar", "iniciar", "init", "inspecionar", "instalar-exemplos",
|
|
11
11
|
"interativo", "ir", "pipeline", "profile", "prompt-curto", "prompt-ia",
|
|
12
12
|
"prompt-ia-react", "prompt-ia-sema-primeiro", "prompt-ia-ui", "renomear-semantico",
|
|
13
|
-
"resumo", "rule-packs", "skill", "starter-ia", "sync", "sync-codex", "testar",
|
|
13
|
+
"resumo", "rule-packs", "sessao", "skill", "starter-ia", "sync", "sync-codex", "testar",
|
|
14
14
|
"validar", "verificar", "ast",
|
|
15
15
|
]);
|
|
16
16
|
const TEMPLATES_INICIAR = new Set([
|
|
@@ -451,6 +451,7 @@ function validarComandoBasico(comando, args) {
|
|
|
451
451
|
return Boolean(alvo && ALVOS_GERACAO.has(alvo)) && (!estrutura || ESTRUTURAS.has(estrutura)) && (!framework || FRAMEWORKS.has(framework));
|
|
452
452
|
}
|
|
453
453
|
case "verificar": return parsearArgumentos(args, { opcoes: ["--saida", "--alvo"], flags: ["--sem-cache"], maxPosicionais: 1 }) !== null;
|
|
454
|
+
case "sessao": return parsearArgumentos(args, { flags: ["--json"], maxPosicionais: 2 }) !== null;
|
|
454
455
|
case "formatar": return parsearArgumentos(args, { flags: ["--check"], maxPosicionais: 1 }) !== null;
|
|
455
456
|
case "inspecionar": {
|
|
456
457
|
const parsed = parsearArgumentos(args, { opcoes: ["--drift", "--cache"], flags: ["--com-drift"], maxPosicionais: 1 });
|
package/dist/cliHelpTexto.js
CHANGED
|
@@ -143,6 +143,7 @@ export function criarAjudaRaiz(versao) {
|
|
|
143
143
|
"sema contexto-ia <arquivo.sema> [--saida <diretorio>] [--json]",
|
|
144
144
|
"sema sync-codex [--json]",
|
|
145
145
|
"sema instalar-exemplos [--json]",
|
|
146
|
+
"sema sessao [intencao] [entrada] [--json]",
|
|
146
147
|
"sema docs-impacto --intencao <acao> [--arquivo <caminho>] [--criar-ausentes] [--completo] [--json]",
|
|
147
148
|
"sema finalizar-mudanca --intencao <acao> [--arquivo <caminho>] [--doc-lida <caminho>] [--json]",
|
|
148
149
|
"sema author briefing <arquivo.sema> [--json]",
|
package/dist/cliRuntime.js
CHANGED
|
@@ -12,7 +12,21 @@ export async function executarCliRuntimeInterno(principalInjetado) {
|
|
|
12
12
|
? codigoSaida
|
|
13
13
|
: CODIGO_SAIDA_FATAL_RUNTIME_CLI;
|
|
14
14
|
}
|
|
15
|
-
catch {
|
|
15
|
+
catch (erro) {
|
|
16
|
+
if (typeof erro?.categoria === "string" && erro.categoria) {
|
|
17
|
+
const cli = erro;
|
|
18
|
+
const envelope = {
|
|
19
|
+
schemaVersion: "sema.cli.control/v1",
|
|
20
|
+
ok: false,
|
|
21
|
+
kind: cli.categoria,
|
|
22
|
+
code: cli.codigoPublico,
|
|
23
|
+
message: cli.mensagemPublica,
|
|
24
|
+
exitCode: cli.codigoSaida,
|
|
25
|
+
...(cli.detalhes ? { details: cli.detalhes } : {}),
|
|
26
|
+
};
|
|
27
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
28
|
+
return cli.codigoSaida;
|
|
29
|
+
}
|
|
16
30
|
return CODIGO_SAIDA_FATAL_RUNTIME_CLI;
|
|
17
31
|
}
|
|
18
32
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface SessaoEnvelope {
|
|
2
|
+
comando: "sessao";
|
|
3
|
+
sucesso: boolean;
|
|
4
|
+
workspace: {
|
|
5
|
+
baseProjeto: string;
|
|
6
|
+
nomePasta: string;
|
|
7
|
+
hashContratos: string;
|
|
8
|
+
cliVersao: string;
|
|
9
|
+
};
|
|
10
|
+
frescor: {
|
|
11
|
+
fresco: boolean;
|
|
12
|
+
hashArtefato: string | null;
|
|
13
|
+
hashAtual: string;
|
|
14
|
+
sugestao: string;
|
|
15
|
+
};
|
|
16
|
+
contratos: {
|
|
17
|
+
total: number;
|
|
18
|
+
modulos: string[];
|
|
19
|
+
};
|
|
20
|
+
intencoes: {
|
|
21
|
+
intencao: string;
|
|
22
|
+
categorias: string[];
|
|
23
|
+
docsBloqueantes: string[];
|
|
24
|
+
docsRecomendadas: string[];
|
|
25
|
+
};
|
|
26
|
+
gates: {
|
|
27
|
+
drift: string;
|
|
28
|
+
validar: string;
|
|
29
|
+
verificar: string;
|
|
30
|
+
finalizar: string;
|
|
31
|
+
};
|
|
32
|
+
proximosPassos: string[];
|
|
33
|
+
}
|
|
34
|
+
export declare function comandoSessao(posicionais: string[], args: string[], emJson: boolean, cwd?: string): Promise<number>;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// SEMA-GOVERNED: sema.produto.cli_sessao
|
|
2
|
+
// Descricao: comando sessao devolve envelope compacto de abertura governada.
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { verificarFrescorArtefatos } from "./index.part04.js";
|
|
5
|
+
import { carregarProjeto } from "./projetoCarregar.js";
|
|
6
|
+
import { resolverDocumentacaoObrigatoria } from "./docs.js";
|
|
7
|
+
export async function comandoSessao(posicionais, args, emJson, cwd = process.cwd()) {
|
|
8
|
+
const intencao = posicionais[0] ?? args.find((arg) => arg.startsWith("--intencao="))?.split("=")[1] ?? "";
|
|
9
|
+
const entrada = posicionais[1];
|
|
10
|
+
const baseProjeto = entrada ? path.resolve(cwd, entrada) : cwd;
|
|
11
|
+
const contextoProjeto = await carregarProjeto(entrada, cwd, {
|
|
12
|
+
escopo: "projeto",
|
|
13
|
+
adiarDescobertaCodigo: true,
|
|
14
|
+
});
|
|
15
|
+
const pacoteCli = (await import("../package.json", { with: { type: "json" } })).default;
|
|
16
|
+
const frescor = await verificarFrescorArtefatos(contextoProjeto.baseProjeto);
|
|
17
|
+
const modulosNomes = contextoProjeto.modulosSelecionados.map((item) => item.resultado.modulo?.nome ?? path.basename(item.caminho, ".sema"));
|
|
18
|
+
let categorias = [];
|
|
19
|
+
let docsBloqueantes = [];
|
|
20
|
+
let docsRecomendadas = [];
|
|
21
|
+
if (intencao.trim()) {
|
|
22
|
+
const impacto = await resolverDocumentacaoObrigatoria({
|
|
23
|
+
baseProjeto: contextoProjeto.baseProjeto,
|
|
24
|
+
intencao,
|
|
25
|
+
arquivosAlvo: [],
|
|
26
|
+
criarAusentes: false,
|
|
27
|
+
});
|
|
28
|
+
categorias = impacto.categorias;
|
|
29
|
+
docsBloqueantes = impacto.leituraObrigatoria
|
|
30
|
+
.filter((doc) => doc.obrigatoriedade !== "recomendada" && doc.existe)
|
|
31
|
+
.map((doc) => doc.relativo);
|
|
32
|
+
docsRecomendadas = impacto.leituraRecomendada.map((doc) => doc.relativo);
|
|
33
|
+
}
|
|
34
|
+
const envelope = {
|
|
35
|
+
comando: "sessao",
|
|
36
|
+
sucesso: true,
|
|
37
|
+
workspace: {
|
|
38
|
+
baseProjeto: contextoProjeto.baseProjeto,
|
|
39
|
+
nomePasta: path.basename(contextoProjeto.baseProjeto),
|
|
40
|
+
hashContratos: frescor.hashAtual,
|
|
41
|
+
cliVersao: pacoteCli.version,
|
|
42
|
+
},
|
|
43
|
+
frescor,
|
|
44
|
+
contratos: {
|
|
45
|
+
total: contextoProjeto.modulosSelecionados.length,
|
|
46
|
+
modulos: modulosNomes.slice(0, 10),
|
|
47
|
+
},
|
|
48
|
+
intencoes: {
|
|
49
|
+
intencao,
|
|
50
|
+
categorias,
|
|
51
|
+
docsBloqueantes,
|
|
52
|
+
docsRecomendadas,
|
|
53
|
+
},
|
|
54
|
+
gates: {
|
|
55
|
+
drift: "sema drift . --escopo projeto --cache fresh --json",
|
|
56
|
+
validar: "sema validar contratos --json",
|
|
57
|
+
verificar: "sema verificar contratos --alvo typescript --json",
|
|
58
|
+
finalizar: 'sema finalizar-mudanca --intencao "<intencao>" --doc-lida <doc> --json',
|
|
59
|
+
},
|
|
60
|
+
proximosPassos: [
|
|
61
|
+
...(!frescor.fresco ? ["Artefatos stale detectados — rode sema sync-codex --json antes de agir"] : []),
|
|
62
|
+
...(docsBloqueantes.length > 0 ? [`Leia antes de agir: ${docsBloqueantes.slice(0, 5).join(", ")}`] : []),
|
|
63
|
+
...(intencao.trim() ? ["Siga o protocolo AGENTS.md passo a passo"] : ["Declare --intencao para receber gates especificos"]),
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
if (emJson) {
|
|
67
|
+
console.log(JSON.stringify(envelope, null, 2));
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
console.log(`Sessao Sema — ${envelope.workspace.nomePasta}`);
|
|
71
|
+
console.log(` Hash contratos: ${envelope.workspace.hashContratos}`);
|
|
72
|
+
console.log(` CLI: ${envelope.workspace.cliVersao}`);
|
|
73
|
+
console.log(` Frescor: ${frescor.fresco ? "fresco" : "STALE"} ${!frescor.fresco ? `(${frescor.sugestao})` : ""}`);
|
|
74
|
+
console.log(` Contratos: ${envelope.contratos.total}`);
|
|
75
|
+
if (intencao) {
|
|
76
|
+
console.log(` Intencao: ${intencao}`);
|
|
77
|
+
console.log(` Categorias: ${categorias.join(", ")}`);
|
|
78
|
+
console.log(` Docs bloqueantes: ${docsBloqueantes.length}`);
|
|
79
|
+
console.log(` Docs recomendadas: ${docsRecomendadas.length}`);
|
|
80
|
+
}
|
|
81
|
+
for (const passo of envelope.proximosPassos) {
|
|
82
|
+
console.log(` → ${passo}`);
|
|
83
|
+
}
|
|
84
|
+
return 0;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=comandoSessao.js.map
|
package/dist/docs.part01.js
CHANGED
|
@@ -128,7 +128,7 @@ export async function listarArquivosRecursivo(base, limite = 80) {
|
|
|
128
128
|
export const REGRAS_DOCUMENTACAO = [
|
|
129
129
|
{
|
|
130
130
|
categoria: "deploy",
|
|
131
|
-
padroes: [/deploy/, /publicar/, /producao/, /release/, /pipeline/, /\bci\b/, /\bcd\b/, /vercel/, /cloudflare/, /docker/],
|
|
131
|
+
padroes: [/deploy/, /publicar/, /producao/, /release/, /pipeline/, /\bci\b/, /\bcd\b/, /vercel/, /cloudflare/, /docker/, /edge.?function/i, /\bruntime\b/i, /\blambda\b/i, /\bworker\b/i, /\bserverless\b/i],
|
|
132
132
|
docs: [
|
|
133
133
|
{ relativo: "docs/deploy.md", tipo: "runbook", motivo: "runbook de deploy antes de publicar ou alterar pipeline", permitirCriacao: true },
|
|
134
134
|
{ relativo: "docs/env.md", tipo: "runbook", motivo: "variaveis, secrets e ambientes usados no deploy", permitirCriacao: true },
|
package/dist/index.part01.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type GuiaCapacidadeIaMap } from './agentContextTipos.js';
|
|
|
4
4
|
import { renderizarCaixaAscii, renderizarSecaoAscii } from './cliHelpTexto.js';
|
|
5
5
|
import { criarBriefingAgente, criarBriefingAgenteContratos, resumirDriftPorModulo } from "./index.part03.js";
|
|
6
6
|
import { type ComandoConsultaDrift, type ModoCacheDrift, type ResolucaoModoCacheDrift } from "./driftCacheModes.js";
|
|
7
|
-
export type Comando = "iniciar" | "init" | "dev" | "sync" | "author" | "profile" | "conteudo" | "interativo" | "descobrir" | "pipeline" | "capabilities" | "validar" | "ast" | "ir" | "compilar" | "gerar" | "testar" | "diagnosticos" | "verificar" | "inspecionar" | "drift" | "impacto" | "renomear-semantico" | "importar" | "doctor" | "formatar" | "ajuda-ia" | "starter-ia" | "sync-codex" | "skill" | "instalar-exemplos" | "rule-packs" | "docs-impacto" | "finalizar-mudanca" | "resumo" | "prompt-curto" | "prompt-ia" | "prompt-ia-ui" | "prompt-ia-react" | "prompt-ia-sema-primeiro" | "exemplos-prompt-ia" | "contexto-ia";
|
|
7
|
+
export type Comando = "iniciar" | "init" | "dev" | "sync" | "author" | "profile" | "conteudo" | "interativo" | "descobrir" | "pipeline" | "capabilities" | "validar" | "ast" | "ir" | "compilar" | "gerar" | "testar" | "diagnosticos" | "verificar" | "inspecionar" | "drift" | "impacto" | "renomear-semantico" | "importar" | "doctor" | "formatar" | "ajuda-ia" | "starter-ia" | "sync-codex" | "skill" | "instalar-exemplos" | "rule-packs" | "docs-impacto" | "finalizar-mudanca" | "resumo" | "sessao" | "prompt-curto" | "prompt-ia" | "prompt-ia-ui" | "prompt-ia-react" | "prompt-ia-sema-primeiro" | "exemplos-prompt-ia" | "contexto-ia";
|
|
8
8
|
export interface ResultadoFormatacaoArquivo {
|
|
9
9
|
caminho: string;
|
|
10
10
|
alterado: boolean;
|
package/dist/index.part02.js
CHANGED
|
@@ -84,7 +84,7 @@ export function coletarResumoSemanticoModulo(contexto) {
|
|
|
84
84
|
efeitos: limitarLista(efeitos, 8),
|
|
85
85
|
erros: limitarLista(erros, 8),
|
|
86
86
|
entidadesAfetadas: limitarLista(entidadesAfetadas, 8),
|
|
87
|
-
arquivosProvaveis: limitarLista(unicosOrdenados(briefing.oQueTocar), 8),
|
|
87
|
+
arquivosProvaveis: limitarLista(unicosOrdenados(briefing.oQueTocar.map((item) => relativizarCaminho(item))), 8),
|
|
88
88
|
simbolosRelacionados: limitarLista(unicosOrdenados(briefing.simbolosRelacionados), 8),
|
|
89
89
|
riscosPrincipais: limitarLista(unicosOrdenados(briefing.riscosPrincipais), 6),
|
|
90
90
|
lacunas: limitarLista(unicosOrdenados(briefing.oQueEstaFrouxo), 6),
|
|
@@ -96,7 +96,7 @@ export function coletarResumoSemanticoModulo(contexto) {
|
|
|
96
96
|
consumerSurfaces: limitarLista(unicosOrdenados(briefing.consumerSurfaces ?? []), 8),
|
|
97
97
|
consumerBridges: limitarLista(unicosOrdenados(briefing.consumerBridges ?? []), 8),
|
|
98
98
|
ancoragensVinculo: limitarLista(unicosOrdenados(briefing.ancoragensVinculo ?? []), 8),
|
|
99
|
-
arquivosProvaveisEditar: limitarLista(unicosOrdenados(briefing.arquivosProvaveisEditar ?? briefing.oQueTocar), 8),
|
|
99
|
+
arquivosProvaveisEditar: limitarLista(unicosOrdenados((briefing.arquivosProvaveisEditar ?? briefing.oQueTocar).map((item) => relativizarCaminho(item))), 8),
|
|
100
100
|
};
|
|
101
101
|
return modoVerificacaoCodigo === "codigo_completo"
|
|
102
102
|
? resumo
|
|
@@ -357,4 +357,10 @@ Contexto compacto:
|
|
|
357
357
|
${resumoTexto}
|
|
358
358
|
`;
|
|
359
359
|
}
|
|
360
|
+
function relativizarCaminho(caminho) {
|
|
361
|
+
const base = process.cwd();
|
|
362
|
+
const absoluto = path.resolve(base, caminho);
|
|
363
|
+
const relativo = path.relative(base, absoluto);
|
|
364
|
+
return relativo && !relativo.startsWith("..") ? relativo.replace(/[\\/]/g, "/") : caminho.replace(/[\\/]/g, "/");
|
|
365
|
+
}
|
|
360
366
|
//# sourceMappingURL=index.part02.js.map
|
package/dist/index.part04.d.ts
CHANGED
|
@@ -2,6 +2,13 @@ import { type GuiaCapacidadeIaMap } from './agentContextTipos.js';
|
|
|
2
2
|
import { ContextoIaGerado, ResumoSemanticoModuloIa, type ResultadoDriftIa } from "./index.part01.js";
|
|
3
3
|
import type { ResolucaoModoCacheDrift } from "./driftCacheModes.js";
|
|
4
4
|
export declare const ARQUIVOS_RESUMO_PROJETO_IA: readonly ["SEMA_BOOT.md", "SEMA_SMALL_MODEL.md", "SEMA_BRIEF.md", "SEMA_BRIEF.micro.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", "AGENT_CONTEXT_PACK.json", "docs/ai-integration.md"];
|
|
5
|
+
export declare function verificarFrescorArtefatos(baseProjeto: string): Promise<{
|
|
6
|
+
fresco: boolean;
|
|
7
|
+
hashArtefato: string | null;
|
|
8
|
+
hashAtual: string;
|
|
9
|
+
contratosMudaram: boolean;
|
|
10
|
+
sugestao: string;
|
|
11
|
+
}>;
|
|
5
12
|
export declare function gerarResumoProjetoIa(entrada: string | undefined, pastaSaidaOpcional?: string, escreverNaRaiz?: boolean, analiseDrift?: ResolucaoModoCacheDrift): Promise<{
|
|
6
13
|
geradoEm: string;
|
|
7
14
|
baseProjeto: string;
|
package/dist/index.part04.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SEMA-GOVERNED: sema.governanca_ia_contexto, sema.produto.escrita_segura_workspace, sema.produto.governanca_ia.drift.cache.modos
|
|
2
2
|
// Descrição: gera contexto local e grava artefatos somente dentro da base validada.
|
|
3
|
-
import { mkdir } from "node:fs/promises";
|
|
3
|
+
import { mkdir, readFile } from "node:fs/promises";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { formatarDiagnosticos, gerarRespostaValidacao, temErros, } from "@sema/nucleo";
|
|
6
7
|
import { carregarProjeto, } from "./projeto.js";
|
|
@@ -53,6 +54,43 @@ function escolherTopArquivosResumo(modulos, arquivosCodigoDetectados) {
|
|
|
53
54
|
}
|
|
54
55
|
return { arquivos: [], fonte: "nenhum" };
|
|
55
56
|
}
|
|
57
|
+
async function calcularHashContratos(caminhosContratos, baseProjeto) {
|
|
58
|
+
const hash = createHash("sha256");
|
|
59
|
+
const base = baseProjeto ?? (caminhosContratos[0] ? path.dirname(caminhosContratos[0]) : process.cwd());
|
|
60
|
+
const ordenados = [...caminhosContratos].sort();
|
|
61
|
+
for (const caminho of ordenados) {
|
|
62
|
+
const conteudo = await readFile(caminho, "utf8").catch(() => "");
|
|
63
|
+
const relativo = path.relative(base, caminho).replace(/[\\/]/g, "/");
|
|
64
|
+
hash.update(relativo);
|
|
65
|
+
hash.update(":");
|
|
66
|
+
hash.update(conteudo);
|
|
67
|
+
hash.update(String.fromCharCode(0));
|
|
68
|
+
}
|
|
69
|
+
return hash.digest("hex").slice(0, 16);
|
|
70
|
+
}
|
|
71
|
+
export async function verificarFrescorArtefatos(baseProjeto) {
|
|
72
|
+
const caminhoIndex = path.join(baseProjeto, "SEMA_INDEX.json");
|
|
73
|
+
let hashArtefato = null;
|
|
74
|
+
try {
|
|
75
|
+
const index = JSON.parse(await readFile(caminhoIndex, "utf8"));
|
|
76
|
+
hashArtefato = index.hashContratos ?? null;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
hashArtefato = null;
|
|
80
|
+
}
|
|
81
|
+
const origens = await (await import("./projetoOrigens.js")).resolverOrigensProjeto(baseProjeto, baseProjeto, undefined);
|
|
82
|
+
const { listarArquivosDeOrigens } = await import("./projetoOrigens.js");
|
|
83
|
+
const contratos = await listarArquivosDeOrigens(origens);
|
|
84
|
+
const hashAtual = await calcularHashContratos(contratos, baseProjeto);
|
|
85
|
+
const fresco = hashArtefato === hashAtual;
|
|
86
|
+
return {
|
|
87
|
+
fresco,
|
|
88
|
+
hashArtefato,
|
|
89
|
+
hashAtual,
|
|
90
|
+
contratosMudaram: !fresco,
|
|
91
|
+
sugestao: fresco ? "" : "Artefatos de contexto estao desatualizados; rode sema sync-codex --json para regenerar.",
|
|
92
|
+
};
|
|
93
|
+
}
|
|
56
94
|
export async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz = false, analiseDrift = { modo: "none", executar: false, avisos: [] }) {
|
|
57
95
|
const contextoProjeto = await carregarProjeto(entrada, process.cwd(), {
|
|
58
96
|
escopo: "projeto",
|
|
@@ -121,10 +159,13 @@ export async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escrever
|
|
|
121
159
|
const semaBoot = renderizarSemaBoot(agentContextPack);
|
|
122
160
|
const semaSmallModel = renderizarSemaSmallModel(agentContextPack);
|
|
123
161
|
const docAgentesCapacidade = renderizarDocumentoAgentesPorCapacidade(agentContextPack);
|
|
162
|
+
const caminhosContratos = contextoProjeto.modulosSelecionados.map((item) => item.caminho);
|
|
163
|
+
const hashContratos = await calcularHashContratos(caminhosContratos, contextoProjeto.baseProjeto);
|
|
124
164
|
const indexJson = {
|
|
125
165
|
comando: "resumo-projeto",
|
|
126
166
|
geradoEm,
|
|
127
167
|
cliVersao: VERSAO_CLI,
|
|
168
|
+
hashContratos,
|
|
128
169
|
baseProjeto,
|
|
129
170
|
modoVerificacaoCodigo,
|
|
130
171
|
analiseDrift: {
|
|
@@ -142,7 +183,10 @@ export async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escrever
|
|
|
142
183
|
entradaCanonica,
|
|
143
184
|
agentContextPack,
|
|
144
185
|
guiaPorCapacidade,
|
|
145
|
-
topArquivosCodigoDetectados: arquivosCodigoDetectados
|
|
186
|
+
topArquivosCodigoDetectados: arquivosCodigoDetectados.map((item) => {
|
|
187
|
+
const rel = path.relative(contextoProjeto.baseProjeto, item);
|
|
188
|
+
return rel && !rel.startsWith("..") ? rel.replace(/[\\/]/g, "/") : item.replace(/[\\/]/g, "/");
|
|
189
|
+
}),
|
|
146
190
|
modulos,
|
|
147
191
|
};
|
|
148
192
|
const micro = [
|
package/dist/index.part05.js
CHANGED
|
@@ -14,7 +14,7 @@ import { resolverAnaliseDriftConsultaCli, resolverOpcoesDriftCli } from "./index
|
|
|
14
14
|
export async function comandoInspecionar(entrada, emJson, cwd = process.cwd(), args = []) {
|
|
15
15
|
const analiseDrift = resolverAnaliseDriftConsultaCli(args, "inspecionar");
|
|
16
16
|
const alvo = entrada ? path.resolve(cwd, entrada) : cwd;
|
|
17
|
-
const alvoEhArquivo = (await stat(alvo))
|
|
17
|
+
const alvoEhArquivo = (await stat(alvo).catch(() => undefined))?.isFile() ?? false;
|
|
18
18
|
const escopoEstreito = analiseDrift.opcoes.escopo === "arquivo"
|
|
19
19
|
|| analiseDrift.opcoes.escopo === "modulo"
|
|
20
20
|
|| (analiseDrift.opcoes.escopo === undefined
|
package/dist/index.part06.js
CHANGED
|
@@ -291,7 +291,7 @@ export async function comandoResumo(entrada, args, emJson) {
|
|
|
291
291
|
const escreverNaRaiz = possuiFlag(args, "--raiz");
|
|
292
292
|
const alvo = entrada ? path.resolve(process.cwd(), entrada) : process.cwd();
|
|
293
293
|
const analiseDrift = resolverAnaliseDriftConsultaCli(args, "resumo");
|
|
294
|
-
const alvoEhArquivo = (await stat(alvo))
|
|
294
|
+
const alvoEhArquivo = (await stat(alvo).catch(() => undefined))?.isFile() ?? false;
|
|
295
295
|
if (alvoEhArquivo) {
|
|
296
296
|
const contexto = await carregarContextoModuloIa(alvo, analiseDrift);
|
|
297
297
|
const resumoSemantico = coletarResumoSemanticoModulo(contexto);
|
package/dist/index.part08.js
CHANGED
|
@@ -36,6 +36,11 @@ export async function principal() {
|
|
|
36
36
|
case "iniciar":
|
|
37
37
|
codigoSaida = await comandoIniciar(cwd, normalizarTemplateIniciar(obterOpcao(resto, "--template")), { force: possuiFlag(resto, "--force"), exemplosCompletos: possuiFlag(resto, "--com-exemplos") });
|
|
38
38
|
break;
|
|
39
|
+
case "sessao": {
|
|
40
|
+
const { comandoSessao } = await import("./comandoSessao.js");
|
|
41
|
+
codigoSaida = await comandoSessao(posicionais, resto, possuiFlag(resto, "--json"), cwd);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
39
44
|
case "author":
|
|
40
45
|
codigoSaida = await comandoAuthor(posicionais, resto, possuiFlag(resto, "--json"));
|
|
41
46
|
break;
|
|
@@ -1,2 +1,8 @@
|
|
|
1
1
|
import type { ContextoProjetoCarregado, OpcoesCarregarProjeto } from './projetoTipos.js';
|
|
2
|
+
export declare class ErroContratoNaoEncontrado extends Error {
|
|
3
|
+
readonly caminhoTentado: string;
|
|
4
|
+
readonly sugeridos: string[];
|
|
5
|
+
constructor(mensagem: string, caminhoTentado: string, sugeridos: string[]);
|
|
6
|
+
paraControleCli(): import("./cliControlError.js").CliControlError;
|
|
7
|
+
}
|
|
2
8
|
export declare function carregarProjeto(entrada: string | undefined, cwd: string, opcoes?: OpcoesCarregarProjeto): Promise<ContextoProjetoCarregado>;
|
package/dist/projetoCarregar.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SEMA-GOVERNED: sema.produto.governanca_ia.contexto, sema.produto.governanca_ia.drift.cache.modos
|
|
2
2
|
// Descrição: orquestra leitura de contratos, compilação e seleção de módulos do projeto.
|
|
3
3
|
import { stat } from 'node:fs/promises';
|
|
4
|
+
import { erroContratoNaoEncontrado } from './cliControlError.js';
|
|
4
5
|
import path from 'node:path';
|
|
5
6
|
import { compilarProjeto, listarArquivosSema } from '@sema/nucleo';
|
|
6
7
|
import { canonicalizarContratosNoProjeto, carregarFechamentoContratosSema, carregarFontesContratos, } from './projetoCatalogo.js';
|
|
@@ -19,12 +20,53 @@ function resolverFontesLegadoDeclaradas(configCarregada) {
|
|
|
19
20
|
.filter((fonte) => Boolean(fonte)))]
|
|
20
21
|
.sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
21
22
|
}
|
|
23
|
+
export class ErroContratoNaoEncontrado extends Error {
|
|
24
|
+
caminhoTentado;
|
|
25
|
+
sugeridos;
|
|
26
|
+
constructor(mensagem, caminhoTentado, sugeridos) {
|
|
27
|
+
super(mensagem);
|
|
28
|
+
this.caminhoTentado = caminhoTentado;
|
|
29
|
+
this.sugeridos = sugeridos;
|
|
30
|
+
this.name = "ErroContratoNaoEncontrado";
|
|
31
|
+
}
|
|
32
|
+
paraControleCli() {
|
|
33
|
+
return erroContratoNaoEncontrado({ caminhoTentado: this.caminhoTentado, sugeridos: this.sugeridos });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function sugerirContratosProximos(baseProjeto, nomeArquivo) {
|
|
37
|
+
const origens = await resolverOrigensProjeto(baseProjeto, baseProjeto, undefined);
|
|
38
|
+
const encontrados = [];
|
|
39
|
+
for (const origem of origens) {
|
|
40
|
+
const arquivos = await listarArquivosDeOrigens([origem]);
|
|
41
|
+
for (const arquivo of arquivos) {
|
|
42
|
+
encontrados.push(path.relative(baseProjeto, arquivo).replace(/\\/g, "/"));
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const alvo = nomeArquivo.replace(/\.sema$/i, "").toLowerCase();
|
|
46
|
+
return encontrados
|
|
47
|
+
.map((relativo) => ({
|
|
48
|
+
relativo,
|
|
49
|
+
pontuacao: relativo.toLowerCase().includes(alvo) ? 0 : 1,
|
|
50
|
+
}))
|
|
51
|
+
.sort((a, b) => a.pontuacao - b.pontuacao || a.relativo.localeCompare(b.relativo, "pt-BR"))
|
|
52
|
+
.map((item) => item.relativo).slice(0, 5);
|
|
53
|
+
}
|
|
22
54
|
export async function carregarProjeto(entrada, cwd, opcoes = {}) {
|
|
23
55
|
const entradaBase = entrada ? path.resolve(cwd, entrada) : cwd;
|
|
24
56
|
const configCarregada = await carregarConfiguracaoProjeto(entradaBase);
|
|
25
57
|
const entradaResolvida = entrada ? path.resolve(cwd, entrada) : await resolverEntradaPadrao(cwd, configCarregada);
|
|
58
|
+
const infoEntrada = await stat(entradaResolvida).catch(() => undefined);
|
|
59
|
+
if (!infoEntrada) {
|
|
60
|
+
const baseSugestao = configCarregada?.baseDiretorio ?? path.dirname(entradaResolvida);
|
|
61
|
+
const contratosProximos = entradaResolvida.toLowerCase().endsWith(".sema")
|
|
62
|
+
? await sugerirContratosProximos(baseSugestao, path.basename(entradaResolvida))
|
|
63
|
+
: [];
|
|
64
|
+
throw erroContratoNaoEncontrado({
|
|
65
|
+
caminhoTentado: entradaResolvida,
|
|
66
|
+
sugeridos: contratosProximos.slice(0, 5),
|
|
67
|
+
});
|
|
68
|
+
}
|
|
26
69
|
const baseProjeto = await resolverBaseProjeto(entradaResolvida, configCarregada);
|
|
27
|
-
const infoEntrada = await stat(entradaResolvida);
|
|
28
70
|
if (infoEntrada.isFile() && path.extname(entradaResolvida).toLowerCase() !== ".sema") {
|
|
29
71
|
throw new Error(`Entrada de contrato precisa terminar em .sema: ${entradaResolvida}`);
|
|
30
72
|
}
|
package/dist/saidaCli.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type EntradaEnvelopeResultadoCliV1, type EnvelopeResultadoCliV1 } from "./resultadoCli.js";
|
|
2
2
|
export { CODIGO_SAIDA_FATAL_RUNTIME_CLI, SCHEMA_RESULTADO_CLI_V1, criarEnvelopeResultadoCliV1, interpretarPayloadRuntimeCli, type EntradaEnvelopeResultadoCliV1, type EnvelopeResultadoCliV1, type TipoResultadoCliV1, } from "./resultadoCli.js";
|
|
3
3
|
export declare const SCHEMA_CONTROLE_CLI_V1: "sema.cli.control/v1";
|
|
4
|
-
export type TipoControleCli = "HELP" | "UNKNOWN_COMMAND" | "ARGUMENT_ERROR" | "FATAL_ERROR";
|
|
4
|
+
export type TipoControleCli = "HELP" | "UNKNOWN_COMMAND" | "ARGUMENT_ERROR" | "CONTRACT_NOT_FOUND" | "FATAL_ERROR";
|
|
5
5
|
export interface EnvelopeControleJsonV1 {
|
|
6
6
|
readonly schemaVersion: typeof SCHEMA_CONTROLE_CLI_V1;
|
|
7
7
|
readonly ok: boolean;
|
|
@@ -9,12 +9,14 @@ export interface EnvelopeControleJsonV1 {
|
|
|
9
9
|
readonly code: string;
|
|
10
10
|
readonly message: string;
|
|
11
11
|
readonly exitCode: number;
|
|
12
|
+
readonly details?: Record<string, unknown>;
|
|
12
13
|
}
|
|
13
14
|
export interface EntradaEnvelopeControleJsonV1 {
|
|
14
15
|
readonly categoria: TipoControleCli;
|
|
15
16
|
readonly codigoPublico: string;
|
|
16
17
|
readonly mensagemPublica: string;
|
|
17
18
|
readonly codigoSaida: number;
|
|
19
|
+
readonly detalhes?: Record<string, unknown>;
|
|
18
20
|
}
|
|
19
21
|
export interface OpcoesInvocacaoPublica {
|
|
20
22
|
readonly resultado: TipoControleCli;
|
package/dist/saidaCli.js
CHANGED
|
@@ -7,12 +7,14 @@ const CODIGO_PADRAO = {
|
|
|
7
7
|
HELP: "CLI_HELP",
|
|
8
8
|
UNKNOWN_COMMAND: "CLI_UNKNOWN_COMMAND",
|
|
9
9
|
ARGUMENT_ERROR: "CLI_ARGUMENT_ERROR",
|
|
10
|
+
CONTRACT_NOT_FOUND: "CLI_CONTRACT_NOT_FOUND",
|
|
10
11
|
FATAL_ERROR: "CLI_FATAL_ERROR",
|
|
11
12
|
};
|
|
12
13
|
const MENSAGEM_PADRAO = {
|
|
13
14
|
HELP: "Ajuda da CLI Sema.",
|
|
14
15
|
UNKNOWN_COMMAND: "Comando Sema desconhecido.",
|
|
15
16
|
ARGUMENT_ERROR: "Argumentos inválidos. Consulte a ajuda do comando.",
|
|
17
|
+
CONTRACT_NOT_FOUND: "Contrato Sema nao encontrado. Consulte os detalhes no envelope.",
|
|
16
18
|
FATAL_ERROR: "Falha ao executar a CLI da Sema.",
|
|
17
19
|
};
|
|
18
20
|
const CODIGO_PUBLICO_VALIDO = /^[A-Z][A-Z0-9_]{2,63}$/u;
|
|
@@ -75,6 +77,9 @@ export function criarEnvelopeControleJsonV1(entrada) {
|
|
|
75
77
|
code: normalizarCodigoPublico(entrada.categoria, entrada.codigoPublico),
|
|
76
78
|
message: normalizarMensagemPublica(entrada.categoria, entrada.mensagemPublica),
|
|
77
79
|
exitCode,
|
|
80
|
+
...(entrada.detalhes && entrada.categoria === "CONTRACT_NOT_FOUND"
|
|
81
|
+
? { details: entrada.detalhes }
|
|
82
|
+
: {}),
|
|
78
83
|
};
|
|
79
84
|
}
|
|
80
85
|
export function emitirResultadoCliJsonV1(entrada) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@semacode/cli",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.10.0",
|
|
4
4
|
"description": "Local-first semantic governance CLI for AI agents, proven with Claude, Codex, zCode (GLM) and Kimi: contracts, drift, impact, docs gates, and code generation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"icon": "logo.png",
|