@semacode/cli 1.5.28 → 1.5.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +144 -144
- package/dist/bridge.d.ts +52 -0
- package/dist/bridge.js +318 -0
- package/dist/bridge.js.map +1 -0
- package/dist/comandos.d.ts +11 -0
- package/dist/comandos.js +146 -0
- package/dist/comandos.js.map +1 -0
- package/dist/contexto.d.ts +34 -0
- package/dist/contexto.js +197 -0
- package/dist/contexto.js.map +1 -0
- package/dist/drift.d.ts +1 -1
- package/dist/drift.js +32 -5
- package/dist/drift.js.map +1 -1
- package/dist/guard.d.ts +35 -0
- package/dist/guard.js +164 -0
- package/dist/guard.js.map +1 -0
- package/dist/index.js +391 -64
- package/dist/index.js.map +1 -1
- package/dist/lua-symbols.d.ts +0 -6
- package/dist/lua-symbols.js +11 -78
- package/dist/lua-symbols.js.map +1 -1
- package/dist/projeto.js +6 -0
- package/dist/projeto.js.map +1 -1
- package/dist/tipos.d.ts +1 -1
- package/exemplos/.prepack-generated +1 -0
- package/exemplos/author_obra_comum.sema +294 -294
- package/exemplos/author_tema_sensivel.sema +264 -264
- package/exemplos/profile_game.sema +114 -114
- package/exemplos/profile_legal.sema +105 -105
- package/exemplos/profile_ops.sema +110 -110
- package/exemplos/profile_research.sema +104 -104
- package/exemplos/profile_software.sema +123 -123
- package/exemplos/profile_workflow_n8n.sema +99 -99
- package/node_modules/@sema/gerador-css/package.json +14 -7
- package/node_modules/@sema/gerador-css/src/index.ts +605 -0
- package/node_modules/@sema/gerador-css/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-css/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-dart/package.json +14 -7
- package/node_modules/@sema/gerador-dart/src/index.ts +52 -0
- package/node_modules/@sema/gerador-dart/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-dart/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-html/package.json +14 -7
- package/node_modules/@sema/gerador-html/src/index.ts +185 -0
- package/node_modules/@sema/gerador-html/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-html/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-javascript/package.json +14 -7
- package/node_modules/@sema/gerador-javascript/src/index.ts +461 -0
- package/node_modules/@sema/gerador-javascript/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-javascript/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-lua/package.json +14 -7
- package/node_modules/@sema/gerador-lua/src/index.ts +359 -0
- package/node_modules/@sema/gerador-lua/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-lua/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-python/package.json +14 -7
- package/node_modules/@sema/gerador-python/src/index.ts +850 -0
- package/node_modules/@sema/gerador-python/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-python/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/gerador-typescript/package.json +14 -7
- package/node_modules/@sema/gerador-typescript/src/index.ts +876 -0
- package/node_modules/@sema/gerador-typescript/tsconfig.json +13 -0
- package/node_modules/@sema/gerador-typescript/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +1 -1
- package/node_modules/@sema/nucleo/dist/index.d.ts +17 -0
- package/node_modules/@sema/nucleo/dist/index.js +28 -0
- package/node_modules/@sema/nucleo/dist/index.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/conversor.js +4 -0
- package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -3
- package/node_modules/@sema/nucleo/dist/parser/parser.js +2 -0
- package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +2 -2
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js +3 -1
- package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
- package/node_modules/@sema/nucleo/package.json +10 -7
- package/node_modules/@sema/nucleo/src/ast/tipos.ts +207 -0
- package/node_modules/@sema/nucleo/src/diagnosticos/index.ts +43 -0
- package/node_modules/@sema/nucleo/src/formatador/index.ts +530 -0
- package/node_modules/@sema/nucleo/src/index.ts +183 -0
- package/node_modules/@sema/nucleo/src/ir/conversor.ts +1037 -0
- package/node_modules/@sema/nucleo/src/ir/modelos.ts +403 -0
- package/node_modules/@sema/nucleo/src/lexer/lexer.ts +166 -0
- package/node_modules/@sema/nucleo/src/lexer/tokens.ts +79 -0
- package/node_modules/@sema/nucleo/src/parser/gramatica.ebnf +41 -0
- package/node_modules/@sema/nucleo/src/parser/parser.ts +936 -0
- package/node_modules/@sema/nucleo/src/persistencia/contratos.ts +379 -0
- package/node_modules/@sema/nucleo/src/semantico/analisador.ts +3126 -0
- package/node_modules/@sema/nucleo/src/semantico/estruturas.ts +665 -0
- package/node_modules/@sema/nucleo/src/semantico/seguranca.ts +362 -0
- package/node_modules/@sema/nucleo/src/util/arquivos.ts +28 -0
- package/node_modules/@sema/nucleo/tsconfig.json +9 -0
- package/node_modules/@sema/nucleo/tsconfig.tsbuildinfo +1 -0
- package/node_modules/@sema/padroes/package.json +10 -7
- package/node_modules/@sema/padroes/src/index.ts +382 -0
- package/node_modules/@sema/padroes/tsconfig.json +9 -0
- package/node_modules/@sema/padroes/tsconfig.tsbuildinfo +1 -0
- package/package.json +74 -74
- package/AGENTS.md +0 -280
- package/LICENSE +0 -22
- package/SEMA_BRIEF.curto.txt +0 -11
- package/SEMA_BRIEF.md +0 -112
- package/SEMA_BRIEF.micro.txt +0 -9
- package/SEMA_INDEX.json +0 -1534
- package/dist/php-symbols.d.ts +0 -24
- package/dist/php-symbols.js +0 -375
- package/dist/php-symbols.js.map +0 -1
- package/docs/AGENT_STARTER.md +0 -109
- package/docs/cli.md +0 -175
- package/docs/como-ensinar-a-sema-para-ia.md +0 -155
- package/docs/deploy.md +0 -93
- package/docs/documentacao.md +0 -88
- package/docs/env.md +0 -105
- package/docs/extensao-vscode.md +0 -53
- package/docs/fluxo-pratico-ia-sema.md +0 -187
- package/docs/instalacao-e-primeiro-uso.md +0 -134
- package/docs/integracao-com-ia.md +0 -110
- package/docs/mcp.md +0 -292
- package/docs/pagamento-ponta-a-ponta.md +0 -171
- package/docs/persistencia-vendor-first.md +0 -151
- package/docs/prompt-base-ia-sema.md +0 -111
- package/docs/repositories.md +0 -54
- package/docs/rollback.md +0 -49
- package/docs/seguranca.md +0 -126
- package/docs/sintaxe.md +0 -218
- package/llms-full.txt +0 -34
- package/llms.txt +0 -17
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import { spawnSync } from "node:child_process";
|
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
import pacoteCli from "../package.json" with { type: "json" };
|
|
8
|
-
import { compilarCodigo, formatarCodigo, formatarDiagnosticos, lerArquivoTexto, temErros, } from "@sema/nucleo";
|
|
8
|
+
import { compilarCodigo, formatarCodigo, formatarDiagnosticos, gerarRespostaValidacao, lerArquivoTexto, temErros, } from "@sema/nucleo";
|
|
9
9
|
import { descreverEstruturaModulo } from "@sema/padroes";
|
|
10
10
|
import { gerarDart } from "@sema/gerador-dart";
|
|
11
11
|
import { gerarLua } from "@sema/gerador-lua";
|
|
@@ -18,6 +18,7 @@ import { carregarConfiguracaoProjeto, carregarProjeto, resolverAlvoPadrao, resol
|
|
|
18
18
|
import { importarProjetoLegado, resumoImportacao } from "./importador.js";
|
|
19
19
|
import { analisarDriftLegado, assistirRenomeacaoSemantica, gerarMapaImpactoSemantico, } from "./drift.js";
|
|
20
20
|
import { resolverDocumentacaoObrigatoria, verificarDocumentacaoMudanca, } from "./docs.js";
|
|
21
|
+
import { REGISTRO_COMANDOS } from "./comandos.js";
|
|
21
22
|
const STARTER_IA = `Voce esta trabalhando com Sema, um contrato semantico IA-first para agentes operarem software vivo em backend e front consumer.
|
|
22
23
|
|
|
23
24
|
Importante:
|
|
@@ -41,11 +42,11 @@ Importante:
|
|
|
41
42
|
- se a tarefa envolver UI, prefira pedir Sema + React + TypeScript ou Sema + arquitetura de front-end
|
|
42
43
|
- evite pedir HTML unico solto quando a intencao for testar a Sema de verdade
|
|
43
44
|
|
|
44
|
-
Regras:
|
|
45
|
-
- nao invente sintaxe fora da gramatica e dos exemplos oficiais
|
|
46
|
-
- antes de qualquer acao, crie, edite ou remova o contrato .sema aplicavel; isso vale para Software, Author, Workflow, Ops, Game, Legal e Research
|
|
47
|
-
- se a IA for pequena, nao tente abrir tudo de uma vez
|
|
48
|
-
- use \`sema resumo\` e \`briefing.min.json\` antes de subir para o pacote completo
|
|
45
|
+
Regras:
|
|
46
|
+
- nao invente sintaxe fora da gramatica e dos exemplos oficiais
|
|
47
|
+
- antes de qualquer acao, crie, edite ou remova o contrato .sema aplicavel; isso vale para Software, Author, Workflow, Ops, Game, Legal e Research
|
|
48
|
+
- se a IA for pequena, nao tente abrir tudo de uma vez
|
|
49
|
+
- use \`sema resumo\` e \`briefing.min.json\` antes de subir para o pacote completo
|
|
49
50
|
- trate \`ir --json\` como fonte de verdade semantica
|
|
50
51
|
- trate \`briefing.json\` como plano de intervencao antes de editar projeto vivo
|
|
51
52
|
- trate \`diagnosticos --json\` como fonte de correcao
|
|
@@ -113,19 +114,20 @@ Trate a Sema como protocolo de governanca semantica e linguagem de intencao feit
|
|
|
113
114
|
|
|
114
115
|
Fontes de verdade, em ordem:
|
|
115
116
|
1. se o projeto expuser \`SEMA_CONTEXT.md\`, comece por ele
|
|
116
|
-
2. \`
|
|
117
|
-
3. \`
|
|
118
|
-
4.
|
|
119
|
-
5.
|
|
120
|
-
6.
|
|
121
|
-
7.
|
|
122
|
-
8.
|
|
123
|
-
9.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
-
|
|
128
|
-
-
|
|
117
|
+
2. \`AGENT_CONTEXT_PACK.json\`
|
|
118
|
+
3. \`SEMA_BRIEF.md\`
|
|
119
|
+
4. \`SEMA_INDEX.json\`
|
|
120
|
+
5. \`AGENTS.md\`
|
|
121
|
+
6. README do projeto
|
|
122
|
+
7. gramatica e documentacao de sintaxe da Sema
|
|
123
|
+
8. exemplos oficiais, com prioridade para o vertical de pagamento
|
|
124
|
+
9. \`sema resumo\` e \`briefing.min.json\` quando a IA for pequena
|
|
125
|
+
10. AST, IR e diagnosticos exportados pela CLI em JSON quando a capacidade aguentar
|
|
126
|
+
|
|
127
|
+
Regras de operacao:
|
|
128
|
+
- contrato vem antes da acao: crie, edite ou remova o .sema aplicavel antes de codigo, docs operacionais, texto Author, workflow, jogo, pesquisa, legal ou ops
|
|
129
|
+
- preserve o significado semantico
|
|
130
|
+
- use o formatador oficial da Sema como fonte unica de estilo
|
|
129
131
|
- use diagnosticos estruturados como contrato de correcao
|
|
130
132
|
- use a IR como fonte de verdade semantica quando houver duvida
|
|
131
133
|
- use predicados canonicos como normalizacao opcional, preservando a forma original
|
|
@@ -243,10 +245,10 @@ Se houver duvida, siga os exemplos oficiais e mantenha a separacao:
|
|
|
243
245
|
`;
|
|
244
246
|
const PROMPT_IA_SEMA_PRIMEIRO = `Quero que voce trabalhe no modo "Sema primeiro".
|
|
245
247
|
|
|
246
|
-
Regra principal:
|
|
247
|
-
- modele primeiro o dominio em arquivos \`.sema\`
|
|
248
|
-
- se a intencao mudar, crie, edite ou remova o contrato antes de qualquer acao operacional
|
|
249
|
-
- so depois proponha ou gere codigo de aplicacao derivado disso
|
|
248
|
+
Regra principal:
|
|
249
|
+
- modele primeiro o dominio em arquivos \`.sema\`
|
|
250
|
+
- se a intencao mudar, crie, edite ou remova o contrato antes de qualquer acao operacional
|
|
251
|
+
- so depois proponha ou gere codigo de aplicacao derivado disso
|
|
250
252
|
|
|
251
253
|
Fluxo obrigatorio:
|
|
252
254
|
1. entender o dominio pedido
|
|
@@ -330,8 +332,10 @@ Comandos uteis da CLI para esse fluxo:
|
|
|
330
332
|
const DIRETORIO_CLI_ATUAL = path.dirname(fileURLToPath(import.meta.url));
|
|
331
333
|
const VERSAO_CLI = pacoteCli.version;
|
|
332
334
|
const requireRuntimeCli = createRequire(import.meta.url);
|
|
335
|
+
const ARQUIVO_AGENT_CONTEXT_PACK = "AGENT_CONTEXT_PACK.json";
|
|
333
336
|
const ARQUIVOS_CANONICOS_IA_RAIZ = [
|
|
334
337
|
"llms.txt",
|
|
338
|
+
ARQUIVO_AGENT_CONTEXT_PACK,
|
|
335
339
|
"SEMA_BRIEF.md",
|
|
336
340
|
"SEMA_INDEX.json",
|
|
337
341
|
"AGENTS.md",
|
|
@@ -356,6 +360,17 @@ const DOCUMENTOS_SUPORTE_IA = [
|
|
|
356
360
|
"docs/rollback.md",
|
|
357
361
|
"docs/extensao-vscode.md",
|
|
358
362
|
];
|
|
363
|
+
const EXEMPLOS_OFICIAIS_AGENT_CONTEXT = [
|
|
364
|
+
"exemplos/calculadora.sema",
|
|
365
|
+
"exemplos/pagamento.sema",
|
|
366
|
+
"exemplos/profile_software.sema",
|
|
367
|
+
"exemplos/profile_workflow_n8n.sema",
|
|
368
|
+
"exemplos/profile_ops.sema",
|
|
369
|
+
"exemplos/profile_game.sema",
|
|
370
|
+
"exemplos/profile_legal.sema",
|
|
371
|
+
"exemplos/profile_research.sema",
|
|
372
|
+
"exemplos/author_obra_comum.sema",
|
|
373
|
+
];
|
|
359
374
|
function resolverImportadorNodeOpcional(especificador) {
|
|
360
375
|
try {
|
|
361
376
|
return requireRuntimeCli.resolve(especificador);
|
|
@@ -650,9 +665,15 @@ function normalizarModoResumo(valor) {
|
|
|
650
665
|
}
|
|
651
666
|
return "resumo";
|
|
652
667
|
}
|
|
668
|
+
const TIMEOUT_CHECAGEM_COMANDO_MS = 5_000;
|
|
653
669
|
function comandoDisponivel(comando, argumentos = ["--version"]) {
|
|
654
|
-
const execucao = spawnSync(comando, argumentos, {
|
|
655
|
-
|
|
670
|
+
const execucao = spawnSync(comando, argumentos, {
|
|
671
|
+
stdio: "ignore",
|
|
672
|
+
shell: process.platform === "win32",
|
|
673
|
+
timeout: TIMEOUT_CHECAGEM_COMANDO_MS,
|
|
674
|
+
windowsHide: true,
|
|
675
|
+
});
|
|
676
|
+
return !execucao.error && execucao.signal === null && (execucao.status ?? 1) === 0;
|
|
656
677
|
}
|
|
657
678
|
const MCP_CLIENT_TOKEN_ENV_VAR = "SEMA_MCP_AUTH_TOKEN";
|
|
658
679
|
const MCP_CLIENT_ENDPOINT_ENV_VAR = "SEMA_MCP_ENDPOINT";
|
|
@@ -1460,24 +1481,151 @@ function criarGuiaCapacidadeIa() {
|
|
|
1460
1481
|
return {
|
|
1461
1482
|
pequena: {
|
|
1462
1483
|
descricao: "IA gratuita ou com contexto curto. Leia so o cartao semantico e o briefing minimo.",
|
|
1463
|
-
artefatos: ["resumo.micro.txt", "briefing.min.json", "prompt-curto.txt"],
|
|
1464
|
-
ordemLeitura: ["resumo.micro.txt", "briefing.min.json", "resumo.curto.txt"],
|
|
1484
|
+
artefatos: ["agent-context-pack.json", "resumo.micro.txt", "briefing.min.json", "prompt-curto.txt"],
|
|
1485
|
+
ordemLeitura: ["agent-context-pack.json", "resumo.micro.txt", "briefing.min.json", "resumo.curto.txt"],
|
|
1465
1486
|
evitar: ["ast.json", "ir.json", "diagnosticos.json"],
|
|
1466
1487
|
},
|
|
1467
1488
|
media: {
|
|
1468
1489
|
descricao: "IA com contexto medio. Aguenta resumo expandido, briefing minimo e drift.",
|
|
1469
|
-
artefatos: ["resumo.curto.txt", "briefing.min.json", "drift.json", "prompt-curto.txt"],
|
|
1470
|
-
ordemLeitura: ["resumo.curto.txt", "briefing.min.json", "drift.json", "resumo.md"],
|
|
1490
|
+
artefatos: ["agent-context-pack.json", "resumo.curto.txt", "briefing.min.json", "drift.json", "prompt-curto.txt"],
|
|
1491
|
+
ordemLeitura: ["agent-context-pack.json", "resumo.curto.txt", "briefing.min.json", "drift.json", "resumo.md"],
|
|
1471
1492
|
evitar: ["ast.json"],
|
|
1472
1493
|
},
|
|
1473
1494
|
grande: {
|
|
1474
1495
|
descricao: "IA com contexto grande ou tool use. Pode consumir o pacote completo.",
|
|
1475
|
-
artefatos: ["README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
|
|
1476
|
-
ordemLeitura: ["README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
|
|
1496
|
+
artefatos: ["agent-context-pack.json", "README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
|
|
1497
|
+
ordemLeitura: ["agent-context-pack.json", "README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
|
|
1477
1498
|
evitar: [],
|
|
1478
1499
|
},
|
|
1479
1500
|
};
|
|
1480
1501
|
}
|
|
1502
|
+
function criarAgentContextPack(guiaPorCapacidade) {
|
|
1503
|
+
const fontes = [
|
|
1504
|
+
{
|
|
1505
|
+
caminho: "llms.txt",
|
|
1506
|
+
tipo: "entrypoint",
|
|
1507
|
+
prioridade: 1,
|
|
1508
|
+
obrigatorio: true,
|
|
1509
|
+
quandoUsar: "sempre no primeiro contato com o projeto",
|
|
1510
|
+
incluirTextoBrutoQuando: "a IA precisa de orientacao compacta para operar o repositorio",
|
|
1511
|
+
},
|
|
1512
|
+
{
|
|
1513
|
+
caminho: ARQUIVO_AGENT_CONTEXT_PACK,
|
|
1514
|
+
tipo: "entrypoint",
|
|
1515
|
+
prioridade: 2,
|
|
1516
|
+
obrigatorio: true,
|
|
1517
|
+
quandoUsar: "sempre antes de decidir quais documentos ou exemplos abrir",
|
|
1518
|
+
incluirTextoBrutoQuando: "a IA precisa auditar regras, proibicoes, prioridades e fontes de verdade",
|
|
1519
|
+
},
|
|
1520
|
+
{
|
|
1521
|
+
caminho: "SEMA_BRIEF.micro.txt",
|
|
1522
|
+
tipo: "resumo",
|
|
1523
|
+
prioridade: 3,
|
|
1524
|
+
obrigatorio: true,
|
|
1525
|
+
quandoUsar: "IA pequena, onboarding, chat remoto ou primeiro triage",
|
|
1526
|
+
incluirTextoBrutoQuando: "a tarefa cabe em contexto curto",
|
|
1527
|
+
},
|
|
1528
|
+
{
|
|
1529
|
+
caminho: "SEMA_BRIEF.curto.txt",
|
|
1530
|
+
tipo: "resumo",
|
|
1531
|
+
prioridade: 4,
|
|
1532
|
+
obrigatorio: true,
|
|
1533
|
+
quandoUsar: "IA media, mudanca pequena ou review rapido",
|
|
1534
|
+
incluirTextoBrutoQuando: "o modulo alvo ainda nao esta claro pelo micro",
|
|
1535
|
+
},
|
|
1536
|
+
{
|
|
1537
|
+
caminho: "SEMA_INDEX.json",
|
|
1538
|
+
tipo: "indice",
|
|
1539
|
+
prioridade: 5,
|
|
1540
|
+
obrigatorio: true,
|
|
1541
|
+
quandoUsar: "antes de abrir codigo cru ou escolher contrato alvo",
|
|
1542
|
+
incluirTextoBrutoQuando: "a IA precisa mapear modulos, lacunas, riscos ou arquivos provaveis",
|
|
1543
|
+
},
|
|
1544
|
+
{
|
|
1545
|
+
caminho: "AGENTS.md",
|
|
1546
|
+
tipo: "operacional",
|
|
1547
|
+
prioridade: 6,
|
|
1548
|
+
obrigatorio: true,
|
|
1549
|
+
quandoUsar: "antes de editar codigo, contrato, docs operacionais, release ou deploy",
|
|
1550
|
+
incluirTextoBrutoQuando: "a IA precisa confirmar regras locais obrigatorias e prioridades do projeto",
|
|
1551
|
+
},
|
|
1552
|
+
{
|
|
1553
|
+
caminho: "exemplos/",
|
|
1554
|
+
tipo: "exemplos",
|
|
1555
|
+
prioridade: 7,
|
|
1556
|
+
obrigatorio: true,
|
|
1557
|
+
quandoUsar: "antes de criar ou corrigir arquivo .sema, profile, Author, workflow, ops, game, legal ou research",
|
|
1558
|
+
incluirTextoBrutoQuando: "a IA vai escrever sintaxe Sema ou comparar um contrato com formato oficial",
|
|
1559
|
+
},
|
|
1560
|
+
{
|
|
1561
|
+
caminho: "docs/AGENT_STARTER.md",
|
|
1562
|
+
tipo: "docs",
|
|
1563
|
+
prioridade: 8,
|
|
1564
|
+
obrigatorio: false,
|
|
1565
|
+
quandoUsar: "onboarding de agente novo ou explicacao curta do fluxo",
|
|
1566
|
+
incluirTextoBrutoQuando: "o agente remoto nao conhece Sema ainda",
|
|
1567
|
+
},
|
|
1568
|
+
{
|
|
1569
|
+
caminho: "docs/sintaxe.md",
|
|
1570
|
+
tipo: "docs",
|
|
1571
|
+
prioridade: 9,
|
|
1572
|
+
obrigatorio: false,
|
|
1573
|
+
quandoUsar: "duvida de gramatica, blocos ou formato do DSL",
|
|
1574
|
+
incluirTextoBrutoQuando: "a IA vai editar contrato e os exemplos nao bastam",
|
|
1575
|
+
},
|
|
1576
|
+
{
|
|
1577
|
+
caminho: "contratos/",
|
|
1578
|
+
tipo: "contrato",
|
|
1579
|
+
prioridade: 10,
|
|
1580
|
+
obrigatorio: true,
|
|
1581
|
+
quandoUsar: "antes de qualquer implementacao ou alteracao de comportamento",
|
|
1582
|
+
incluirTextoBrutoQuando: "a tarefa toca uma capacidade governada por contrato",
|
|
1583
|
+
},
|
|
1584
|
+
];
|
|
1585
|
+
return {
|
|
1586
|
+
nome: "Agent Context Pack",
|
|
1587
|
+
versao: 1,
|
|
1588
|
+
objetivo: "Dar a agentes IA uma entrada curta, estruturada e auditavel antes de abrir codigo cru ou inventar contexto.",
|
|
1589
|
+
ordemLeitura: [
|
|
1590
|
+
"llms.txt",
|
|
1591
|
+
ARQUIVO_AGENT_CONTEXT_PACK,
|
|
1592
|
+
"SEMA_BRIEF.micro.txt",
|
|
1593
|
+
"SEMA_INDEX.json",
|
|
1594
|
+
"AGENTS.md",
|
|
1595
|
+
"exemplos/",
|
|
1596
|
+
],
|
|
1597
|
+
regrasObrigatorias: [
|
|
1598
|
+
"Contrato vem antes da acao.",
|
|
1599
|
+
"Leia AGENTS.md antes de editar codigo, contrato, docs operacionais, release ou deploy.",
|
|
1600
|
+
"Use exemplos oficiais antes de criar ou corrigir sintaxe .sema.",
|
|
1601
|
+
"Use SEMA_INDEX.json para escolher contrato, modulo e arquivos provaveis antes de abrir codigo cru.",
|
|
1602
|
+
"Valide .sema alterado e rode drift antes de concluir.",
|
|
1603
|
+
"Quando faltar contrato aplicavel, crie ou edite o contrato antes do codigo.",
|
|
1604
|
+
],
|
|
1605
|
+
proibicoes: [
|
|
1606
|
+
"Nao inventar sintaxe Sema fora da gramatica e dos exemplos oficiais.",
|
|
1607
|
+
"Nao tratar README, texto livre ou codigo como fonte superior ao contrato.",
|
|
1608
|
+
"Nao sincronizar segredos, .env, node_modules, builds, caches, uploads ou artefatos privados fora do escopo.",
|
|
1609
|
+
"Nao publicar, deployar ou remover capacidade sem contrato, drift e verificacao.",
|
|
1610
|
+
"Nao misturar repositorio publico e privado sem conferir docs de repositorios e AGENTS.md.",
|
|
1611
|
+
],
|
|
1612
|
+
prioridades: [
|
|
1613
|
+
"Menor artefato suficiente primeiro.",
|
|
1614
|
+
"Contrato, indice e AGENTS antes de codigo cru.",
|
|
1615
|
+
"Exemplos oficiais antes de nova sintaxe.",
|
|
1616
|
+
"Diagnostico estruturado antes de opiniao livre.",
|
|
1617
|
+
"Se risco ou escopo estiver ambigui, parar e pedir contrato/contexto.",
|
|
1618
|
+
],
|
|
1619
|
+
fontes,
|
|
1620
|
+
exemplosOficiais: [...EXEMPLOS_OFICIAIS_AGENT_CONTEXT],
|
|
1621
|
+
textoBrutoSobDemanda: Object.fromEntries(fontes.map((fonte) => [fonte.caminho, fonte.incluirTextoBrutoQuando])),
|
|
1622
|
+
guiaPorCapacidade: {
|
|
1623
|
+
pequena: guiaPorCapacidade.pequena.ordemLeitura,
|
|
1624
|
+
media: guiaPorCapacidade.media.ordemLeitura,
|
|
1625
|
+
grande: guiaPorCapacidade.grande.ordemLeitura,
|
|
1626
|
+
},
|
|
1627
|
+
};
|
|
1628
|
+
}
|
|
1481
1629
|
function coletarResumoSemanticoModulo(contexto) {
|
|
1482
1630
|
const { arquivo, modulo, geradoEm, ir, briefing, drift } = contexto;
|
|
1483
1631
|
const modoVerificacaoCodigo = contexto.modoVerificacaoCodigo ?? "codigo_completo";
|
|
@@ -1794,6 +1942,7 @@ ${resumoTexto}
|
|
|
1794
1942
|
}
|
|
1795
1943
|
function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
1796
1944
|
const entradaCanonica = criarEntradaCanonicaProjeto(guiaPorCapacidade);
|
|
1945
|
+
const agentContextPack = entradaCanonica.agentContextPack;
|
|
1797
1946
|
const linhas = [
|
|
1798
1947
|
"# SEMA_BRIEF",
|
|
1799
1948
|
"",
|
|
@@ -1809,6 +1958,13 @@ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
|
1809
1958
|
`- IA media: ${entradaCanonica.porCapacidade.media.join(" -> ")}`,
|
|
1810
1959
|
`- IA grande: ${entradaCanonica.porCapacidade.grande.join(" -> ")}`,
|
|
1811
1960
|
"",
|
|
1961
|
+
"## Agent Context Pack",
|
|
1962
|
+
"",
|
|
1963
|
+
`- Arquivo: \`${ARQUIVO_AGENT_CONTEXT_PACK}\``,
|
|
1964
|
+
`- Objetivo: ${agentContextPack.objetivo}`,
|
|
1965
|
+
`- Regras: ${agentContextPack.regrasObrigatorias.slice(0, 4).join(" | ")}`,
|
|
1966
|
+
`- Fontes brutas sob demanda: ${agentContextPack.fontes.map((fonte) => fonte.caminho).slice(0, 7).join(", ")}`,
|
|
1967
|
+
"",
|
|
1812
1968
|
"## Guia por capacidade",
|
|
1813
1969
|
"",
|
|
1814
1970
|
];
|
|
@@ -1831,15 +1987,17 @@ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
|
1831
1987
|
return `${linhas.join("\n").trim()}\n`;
|
|
1832
1988
|
}
|
|
1833
1989
|
function criarEntradaCanonicaProjeto(guiaPorCapacidade) {
|
|
1990
|
+
const agentContextPack = criarAgentContextPack(guiaPorCapacidade);
|
|
1834
1991
|
return {
|
|
1835
1992
|
descricao: "Entrada canonica do repositorio para IA. O repo nao e human-first; a IA deve comecar por esses artefatos antes de abrir codigo cru.",
|
|
1836
1993
|
ordemLeitura: [...ARQUIVOS_CANONICOS_IA_RAIZ],
|
|
1837
1994
|
porCapacidade: {
|
|
1838
|
-
pequena: ["llms.txt", "SEMA_BRIEF.micro.txt", "SEMA_INDEX.json", "AGENTS.md"],
|
|
1839
|
-
media: ["llms.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", "AGENTS.md", "README.md"],
|
|
1840
|
-
grande: ["llms-full.txt", "SEMA_BRIEF.md", "SEMA_INDEX.json", "AGENTS.md", "README.md"],
|
|
1995
|
+
pequena: ["llms.txt", ARQUIVO_AGENT_CONTEXT_PACK, "SEMA_BRIEF.micro.txt", "SEMA_INDEX.json", "AGENTS.md"],
|
|
1996
|
+
media: ["llms.txt", ARQUIVO_AGENT_CONTEXT_PACK, "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", "AGENTS.md", "README.md"],
|
|
1997
|
+
grande: ["llms-full.txt", ARQUIVO_AGENT_CONTEXT_PACK, "SEMA_BRIEF.md", "SEMA_INDEX.json", "AGENTS.md", "README.md"],
|
|
1841
1998
|
},
|
|
1842
1999
|
docsSuporte: [...DOCUMENTOS_SUPORTE_IA],
|
|
2000
|
+
agentContextPack,
|
|
1843
2001
|
guiaPorCapacidade,
|
|
1844
2002
|
};
|
|
1845
2003
|
}
|
|
@@ -2086,13 +2244,15 @@ async function gerarArquivosResumoModuloIa(contexto, pastaBase) {
|
|
|
2086
2244
|
const resumoMarkdown = renderizarResumoModuloMarkdown(resumoSemantico, "resumo", guiaPorCapacidade);
|
|
2087
2245
|
const briefingMinimo = criarBriefingMinimo(resumoSemantico, "resumo", "curto");
|
|
2088
2246
|
const promptCurto = criarPromptCurtoModulo(resumoSemantico, "mudanca", "curto", "pequena");
|
|
2247
|
+
const agentContextPack = criarAgentContextPack(guiaPorCapacidade);
|
|
2248
|
+
await writeFile(path.join(pastaBase, "agent-context-pack.json"), `${JSON.stringify(agentContextPack, null, 2)}\n`, "utf8");
|
|
2089
2249
|
await writeFile(path.join(pastaBase, "resumo.micro.txt"), resumoMicro, "utf8");
|
|
2090
2250
|
await writeFile(path.join(pastaBase, "resumo.curto.txt"), resumoCurto, "utf8");
|
|
2091
2251
|
await writeFile(path.join(pastaBase, "resumo.md"), resumoMarkdown, "utf8");
|
|
2092
2252
|
await writeFile(path.join(pastaBase, "briefing.min.json"), `${JSON.stringify(briefingMinimo, null, 2)}\n`, "utf8");
|
|
2093
2253
|
await writeFile(path.join(pastaBase, "prompt-curto.txt"), promptCurto, "utf8");
|
|
2094
2254
|
return {
|
|
2095
|
-
artefatosCompactos: ["resumo.micro.txt", "resumo.curto.txt", "resumo.md", "briefing.min.json", "prompt-curto.txt"],
|
|
2255
|
+
artefatosCompactos: ["agent-context-pack.json", "resumo.micro.txt", "resumo.curto.txt", "resumo.md", "briefing.min.json", "prompt-curto.txt"],
|
|
2096
2256
|
guiaPorCapacidade,
|
|
2097
2257
|
};
|
|
2098
2258
|
}
|
|
@@ -2101,6 +2261,7 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
2101
2261
|
const geradoEm = new Date().toISOString();
|
|
2102
2262
|
const guiaPorCapacidade = criarGuiaCapacidadeIa();
|
|
2103
2263
|
const entradaCanonica = criarEntradaCanonicaProjeto(guiaPorCapacidade);
|
|
2264
|
+
const agentContextPack = entradaCanonica.agentContextPack;
|
|
2104
2265
|
const modoVerificacaoCodigo = await detectarModoVerificacaoCodigo(contextoProjeto.baseProjeto, contextoProjeto.diretoriosCodigo);
|
|
2105
2266
|
const fontesConclusao = await detectarFontesConclusaoSnapshot(contextoProjeto.baseProjeto);
|
|
2106
2267
|
const resultadoDrift = await analisarDriftLegado(contextoProjeto);
|
|
@@ -2144,6 +2305,7 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
2144
2305
|
conclusoesPorFonte: descreverFontesConclusao(fontesConclusao, modoVerificacaoCodigo),
|
|
2145
2306
|
totalModulos: modulos.length,
|
|
2146
2307
|
entradaCanonica,
|
|
2308
|
+
agentContextPack,
|
|
2147
2309
|
guiaPorCapacidade,
|
|
2148
2310
|
modulos,
|
|
2149
2311
|
};
|
|
@@ -2182,12 +2344,13 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
2182
2344
|
await writeFile(path.join(pastaSaida, "SEMA_BRIEF.micro.txt"), micro, "utf8");
|
|
2183
2345
|
await writeFile(path.join(pastaSaida, "SEMA_BRIEF.curto.txt"), curto, "utf8");
|
|
2184
2346
|
await writeFile(path.join(pastaSaida, "SEMA_INDEX.json"), `${JSON.stringify(indexJson, null, 2)}\n`, "utf8");
|
|
2347
|
+
await writeFile(path.join(pastaSaida, ARQUIVO_AGENT_CONTEXT_PACK), `${JSON.stringify(agentContextPack, null, 2)}\n`, "utf8");
|
|
2185
2348
|
return {
|
|
2186
2349
|
geradoEm,
|
|
2187
2350
|
baseProjeto,
|
|
2188
2351
|
pastaSaida,
|
|
2189
2352
|
modoVerificacaoCodigo,
|
|
2190
|
-
artefatos: ["SEMA_BRIEF.md", "SEMA_BRIEF.micro.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json"],
|
|
2353
|
+
artefatos: ["SEMA_BRIEF.md", "SEMA_BRIEF.micro.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", ARQUIVO_AGENT_CONTEXT_PACK],
|
|
2191
2354
|
modulos,
|
|
2192
2355
|
guiaPorCapacidade,
|
|
2193
2356
|
};
|
|
@@ -2215,6 +2378,7 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
|
|
|
2215
2378
|
|
|
2216
2379
|
## Arquivos gerados neste pacote
|
|
2217
2380
|
|
|
2381
|
+
- \`agent-context-pack.json\`
|
|
2218
2382
|
- \`resumo.micro.txt\`
|
|
2219
2383
|
- \`resumo.curto.txt\`
|
|
2220
2384
|
- \`resumo.md\`
|
|
@@ -2229,26 +2393,38 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
|
|
|
2229
2393
|
|
|
2230
2394
|
## Fluxo recomendado para o agente
|
|
2231
2395
|
|
|
2396
|
+
Antes de escolher arquivo de codigo, leia \`agent-context-pack.json\`. Ele declara regras obrigatorias, proibicoes, prioridades e quando abrir texto bruto como \`AGENTS.md\`, \`exemplos/\`, docs e contratos.
|
|
2397
|
+
|
|
2232
2398
|
### IA pequena ou gratuita
|
|
2233
2399
|
|
|
2234
|
-
1. Ler \`
|
|
2235
|
-
2. Ler \`
|
|
2236
|
-
3.
|
|
2400
|
+
1. Ler \`agent-context-pack.json\`.
|
|
2401
|
+
2. Ler \`resumo.micro.txt\`.
|
|
2402
|
+
3. Ler \`briefing.min.json\`.
|
|
2403
|
+
4. Se ainda couber contexto, ler \`resumo.curto.txt\`.
|
|
2237
2404
|
|
|
2238
2405
|
### IA media
|
|
2239
2406
|
|
|
2240
|
-
1. Ler \`
|
|
2241
|
-
2. Ler \`
|
|
2242
|
-
3. Ler \`
|
|
2243
|
-
4.
|
|
2407
|
+
1. Ler \`agent-context-pack.json\`.
|
|
2408
|
+
2. Ler \`resumo.curto.txt\`.
|
|
2409
|
+
3. Ler \`briefing.min.json\`.
|
|
2410
|
+
4. Ler \`drift.json\`.
|
|
2411
|
+
5. Se precisar, subir para \`resumo.md\`.
|
|
2244
2412
|
|
|
2245
2413
|
### IA grande ou com tool use
|
|
2246
2414
|
|
|
2247
|
-
1. Ler \`
|
|
2248
|
-
2. Ler \`
|
|
2249
|
-
3. Ler \`
|
|
2250
|
-
4. Ler \`
|
|
2251
|
-
5.
|
|
2415
|
+
1. Ler \`agent-context-pack.json\`.
|
|
2416
|
+
2. Ler \`README.md\`.
|
|
2417
|
+
3. Ler \`resumo.md\`.
|
|
2418
|
+
4. Ler \`briefing.json\`.
|
|
2419
|
+
5. Ler \`drift.json\`.
|
|
2420
|
+
6. So depois abrir \`ir.json\` e \`ast.json\`.
|
|
2421
|
+
|
|
2422
|
+
## Texto bruto sob demanda
|
|
2423
|
+
|
|
2424
|
+
- Abra \`AGENTS.md\` antes de editar codigo, contrato, docs operacionais, release ou deploy.
|
|
2425
|
+
- Abra \`exemplos/\` antes de criar ou corrigir sintaxe \`.sema\`.
|
|
2426
|
+
- Abra \`docs/sintaxe.md\` quando exemplos nao bastarem para resolver a gramatica.
|
|
2427
|
+
- Abra \`contratos/\` antes de qualquer implementacao ou mudanca de comportamento.
|
|
2252
2428
|
|
|
2253
2429
|
## Fechamento
|
|
2254
2430
|
|
|
@@ -4872,6 +5048,59 @@ function validarTermosObrigatoriosArtefato(texto, checks) {
|
|
|
4872
5048
|
});
|
|
4873
5049
|
});
|
|
4874
5050
|
}
|
|
5051
|
+
function artefatoPareceWebhookProfile(artefato, preset) {
|
|
5052
|
+
return preset === "webhook" || /webhook|externalEventId|invoiceId|paidAt|paymentEvent|pagamento/i.test(artefato);
|
|
5053
|
+
}
|
|
5054
|
+
function artefatoParecePagamentoWebhookProfile(artefato) {
|
|
5055
|
+
return /invoiceId|fatura|cobranc|paymentEvent|paidAt|pagamento/i.test(artefato) &&
|
|
5056
|
+
/webhook|externalEventId|evento externo|evento de pagamento/i.test(artefato);
|
|
5057
|
+
}
|
|
5058
|
+
function artefatoPareceMultiTenantProfile(contrato, artefato) {
|
|
5059
|
+
return /workspace|tenant|multi[- ]?tenant|multi[- ]?workspace|organiz/i.test(`${contrato}\n${artefato}`);
|
|
5060
|
+
}
|
|
5061
|
+
function presencaAutenticacaoWebhookProfile(artefato) {
|
|
5062
|
+
return avaliarPresencaPositivaArtefato(artefato, /authorization|bearer|webhookSecret|webhook_secret|secret|assinatura|signature|hmac|x-webhook-secret|api[-_ ]?key|token/i);
|
|
5063
|
+
}
|
|
5064
|
+
function presencaWorkspaceWebhookProfile(artefato) {
|
|
5065
|
+
return avaliarPresencaPositivaArtefato(artefato, /workspace(?:Id|Slug)?|workspace_id|workspace_slug|tenant(?:Id)?|tenant_id|organizationId|orgId|accountId|x-workspace(?:-slug|-id)?|isolamento por workspace/i);
|
|
5066
|
+
}
|
|
5067
|
+
function presencaIdempotenciaWorkspaceScopedProfile(artefato) {
|
|
5068
|
+
const workspace = presencaWorkspaceWebhookProfile(artefato);
|
|
5069
|
+
if (!workspace.atendido) {
|
|
5070
|
+
return {
|
|
5071
|
+
atendido: false,
|
|
5072
|
+
trecho: workspace.trecho,
|
|
5073
|
+
linha: workspace.linha,
|
|
5074
|
+
coluna: workspace.coluna,
|
|
5075
|
+
inicio: workspace.inicio,
|
|
5076
|
+
fim: workspace.fim,
|
|
5077
|
+
motivo: workspace.motivo ?? "idempotencia com externalEventId precisa de workspace/tenant positivo no mesmo artefato.",
|
|
5078
|
+
};
|
|
5079
|
+
}
|
|
5080
|
+
const regexes = [
|
|
5081
|
+
/@@unique\s*\(\s*\[[^\]]*(?:workspaceId|workspace_id|workspace|tenantId|tenant_id|tenant|organizationId|orgId|accountId)[^\]]*externalEventId[^\]]*\]\s*\)/i,
|
|
5082
|
+
/@@unique\s*\(\s*\[[^\]]*externalEventId[^\]]*(?:workspaceId|workspace_id|workspace|tenantId|tenant_id|tenant|organizationId|orgId|accountId)[^\]]*\]\s*\)/i,
|
|
5083
|
+
/(?:workspace|tenant|organization|orgId|accountId|x-workspace)[\s\S]{0,180}externalEventId/i,
|
|
5084
|
+
/externalEventId[\s\S]{0,180}(?:workspace|tenant|organization|orgId|accountId|x-workspace)/i,
|
|
5085
|
+
];
|
|
5086
|
+
for (const regex of regexes) {
|
|
5087
|
+
const presenca = avaliarPresencaPositivaArtefato(artefato, regex);
|
|
5088
|
+
if (presenca.atendido)
|
|
5089
|
+
return presenca;
|
|
5090
|
+
}
|
|
5091
|
+
const negada = regexes
|
|
5092
|
+
.map((regex) => avaliarPresencaPositivaArtefato(artefato, regex))
|
|
5093
|
+
.find((presenca) => presenca.trecho);
|
|
5094
|
+
return negada ?? { atendido: false };
|
|
5095
|
+
}
|
|
5096
|
+
function localizarIdempotenciaGlobalExternalEventProfile(artefato) {
|
|
5097
|
+
return localizarRegexProfile(artefato, /\bexternalEventId\b[^\n\r;{}]*@unique/i) ??
|
|
5098
|
+
localizarRegexProfile(artefato, /@@unique\s*\(\s*\[\s*externalEventId\s*\]\s*\)/i) ??
|
|
5099
|
+
localizarRegexProfile(artefato, /externalEventId[\s\S]{0,120}global/i) ??
|
|
5100
|
+
localizarRegexProfile(artefato, /global[\s\S]{0,120}externalEventId/i) ??
|
|
5101
|
+
localizarRegexProfile(artefato, /externalEventId[\s\S]{0,120}(?:unico global|globalmente|global unique|unique global)/i) ??
|
|
5102
|
+
localizarRegexProfile(artefato, /(?:unico global|globalmente|global unique|unique global)[\s\S]{0,120}externalEventId/i);
|
|
5103
|
+
}
|
|
4875
5104
|
function avaliarArtefatoSoftwareProfile(contrato, artefato, maturidade, preset) {
|
|
4876
5105
|
const regras = [
|
|
4877
5106
|
{ id: "software_eval_proibido", termo: "eval", regex: /\beval\s*\(/i, descricao: "codigo usa eval, risco basico de execucao dinamica", sugestao: "troque por parser explicito, tabela de operacoes ou validacao estruturada." },
|
|
@@ -4882,7 +5111,7 @@ function avaliarArtefatoSoftwareProfile(contrato, artefato, maturidade, preset)
|
|
|
4882
5111
|
{ id: "software_tls_desativado", termo: "TLS", regex: /rejectUnauthorized\s*:\s*false|NODE_TLS_REJECT_UNAUTHORIZED\s*=\s*["']?0/i, descricao: "codigo aparenta desativar validacao TLS/certificado", sugestao: "corrija cadeia de certificado ou use ambiente de teste isolado sem desligar TLS em producao." },
|
|
4883
5112
|
{ id: "software_shell_input_dinamico", termo: "shell", regex: /\b(exec|execSync|spawn|spawnSync)\s*\([\s\S]{0,160}(req\.|request\.|params|query|body|input|usuario|userInput)/i, descricao: "codigo aparenta executar shell com entrada dinamica", sugestao: "modele allowlist de comandos/argumentos e evite interpolar entrada do usuario." },
|
|
4884
5113
|
];
|
|
4885
|
-
|
|
5114
|
+
const achados = regras.flatMap((regra) => {
|
|
4886
5115
|
const achou = contemArtefatoProfile(artefato, regra.regex);
|
|
4887
5116
|
if (!achou)
|
|
4888
5117
|
return [];
|
|
@@ -4894,6 +5123,56 @@ function avaliarArtefatoSoftwareProfile(contrato, artefato, maturidade, preset)
|
|
|
4894
5123
|
: "warning";
|
|
4895
5124
|
return [criarAchadoArtefatoProfile(regra.id, regra.descricao, false, severidade, trechoRegexProfile(artefato, regra.regex), regra.sugestao)];
|
|
4896
5125
|
});
|
|
5126
|
+
const pareceWebhook = artefatoPareceWebhookProfile(artefato, preset);
|
|
5127
|
+
const pareceWebhookPagamento = artefatoParecePagamentoWebhookProfile(artefato);
|
|
5128
|
+
const pareceMultiTenant = artefatoPareceMultiTenantProfile(contrato, artefato);
|
|
5129
|
+
if (pareceWebhook && (pareceMultiTenant || pareceWebhookPagamento)) {
|
|
5130
|
+
const auth = presencaAutenticacaoWebhookProfile(artefato);
|
|
5131
|
+
if (!auth.atendido) {
|
|
5132
|
+
achados.push(criarAchadoArtefatoProfile("software_webhook_sem_autenticacao", "webhook sensivel nao demonstra autenticacao, assinatura ou segredo", false, maturidade === "critical" ? "critical" : "blocking", auth.trecho ?? trechoRegexProfile(artefato, /webhook|externalEventId|invoiceId|paymentEvent|pagamento/i), "exija Authorization, assinatura HMAC ou segredo de webhook antes de aplicar efeito sensivel.", auth.motivo, {
|
|
5133
|
+
linha: auth.linha,
|
|
5134
|
+
coluna: auth.coluna,
|
|
5135
|
+
inicio: auth.inicio,
|
|
5136
|
+
fim: auth.fim,
|
|
5137
|
+
risco: "webhook_sensivel_sem_auth",
|
|
5138
|
+
}));
|
|
5139
|
+
}
|
|
5140
|
+
const workspace = presencaWorkspaceWebhookProfile(artefato);
|
|
5141
|
+
if (!workspace.atendido) {
|
|
5142
|
+
achados.push(criarAchadoArtefatoProfile("software_webhook_sem_workspace", "webhook multi-workspace nao demonstra fronteira de workspace/tenant", false, maturidade === "critical" ? "critical" : "blocking", workspace.trecho ?? trechoRegexProfile(artefato, /invoiceId|externalEventId|webhook|paymentEvent/i), "resolva workspace por header/slug/tenant autenticado e valide a invoice dentro desse escopo.", workspace.motivo, {
|
|
5143
|
+
linha: workspace.linha,
|
|
5144
|
+
coluna: workspace.coluna,
|
|
5145
|
+
inicio: workspace.inicio,
|
|
5146
|
+
fim: workspace.fim,
|
|
5147
|
+
risco: "isolamento_multi_workspace_ausente",
|
|
5148
|
+
}));
|
|
5149
|
+
}
|
|
5150
|
+
}
|
|
5151
|
+
const externalEventGlobal = localizarIdempotenciaGlobalExternalEventProfile(artefato);
|
|
5152
|
+
const externalEventPresente = /\bexternalEventId\b/i.test(artefato);
|
|
5153
|
+
const idempotenciaScoped = presencaIdempotenciaWorkspaceScopedProfile(artefato);
|
|
5154
|
+
if (externalEventGlobal || (pareceMultiTenant && pareceWebhook && externalEventPresente && !idempotenciaScoped.atendido)) {
|
|
5155
|
+
achados.push(criarAchadoArtefatoProfile("software_external_event_idempotencia_global", "externalEventId parece unico globalmente em contexto multi-workspace", false, maturidade === "critical" ? "critical" : "blocking", externalEventGlobal?.trecho ?? idempotenciaScoped.trecho ?? trechoRegexProfile(artefato, /\bexternalEventId\b/i), "use chave composta por workspaceId/tenantId + externalEventId para idempotencia por workspace.", idempotenciaScoped.motivo, {
|
|
5156
|
+
linha: externalEventGlobal?.linha ?? idempotenciaScoped.linha,
|
|
5157
|
+
coluna: externalEventGlobal?.coluna ?? idempotenciaScoped.coluna,
|
|
5158
|
+
inicio: externalEventGlobal?.inicio ?? idempotenciaScoped.inicio,
|
|
5159
|
+
fim: externalEventGlobal?.fim ?? idempotenciaScoped.fim,
|
|
5160
|
+
risco: "idempotencia_global_multi_tenant",
|
|
5161
|
+
}));
|
|
5162
|
+
}
|
|
5163
|
+
const prismaManualSql = /schema\.prisma|\bPrisma\b|model\s+\w+\s*\{/i.test(artefato) &&
|
|
5164
|
+
/CREATE\s+TABLE|setup-db\.ts|schema SQL manual|sql manual|duplica(?:r|do)? manualmente/i.test(artefato);
|
|
5165
|
+
if (prismaManualSql) {
|
|
5166
|
+
const severidade = maturidade === "draft" || maturidade === "prototype" ? "warning" : "blocking";
|
|
5167
|
+
achados.push(criarAchadoArtefatoProfile("software_schema_prisma_duplicado", "artefato aparenta duplicar schema Prisma em SQL manual", false, maturidade === "critical" ? "critical" : severidade, trechoRegexProfile(artefato, /CREATE\s+TABLE|setup-db\.ts|schema SQL manual|sql manual|duplica(?:r|do)? manualmente/i), "derive o banco de migrations Prisma ou gere o bootstrap a partir do schema, evitando duas fontes de verdade.", undefined, { risco: "drift_schema_persistencia" }));
|
|
5168
|
+
}
|
|
5169
|
+
const eslintNextSemIgnore = /eslint\.config|npm run lint|lint/i.test(artefato) &&
|
|
5170
|
+
/\.next/i.test(artefato) &&
|
|
5171
|
+
!/ignores?\s*[:=][\s\S]{0,180}\.next|\.next\/\*\*|ignora\s+\.next/i.test(artefato);
|
|
5172
|
+
if (eslintNextSemIgnore) {
|
|
5173
|
+
achados.push(criarAchadoArtefatoProfile("software_lint_next_sem_ignore", "lint de Next.js parece varrer .next sem ignore explicito", false, "warning", trechoRegexProfile(artefato, /\.next/i), "adicione ignore para .next no flat config ou ajuste o script de lint.", undefined, { risco: "ruido_operacional_de_build" }));
|
|
5174
|
+
}
|
|
5175
|
+
return achados;
|
|
4897
5176
|
}
|
|
4898
5177
|
function avaliarArtefatoWorkflowProfile(contrato, artefato, preset) {
|
|
4899
5178
|
const achados = validarTermosObrigatoriosArtefato(artefato, [
|
|
@@ -4910,6 +5189,47 @@ function avaliarArtefatoWorkflowProfile(contrato, artefato, preset) {
|
|
|
4910
5189
|
if (preset === "webhook" && !avaliarPresencaPositivaArtefato(artefato, /webhook/i).atendido) {
|
|
4911
5190
|
achados.push(criarAchadoArtefatoProfile("workflow_preset_webhook_sem_superficie", "preset webhook exige superficie webhook no artefato", false, "blocking", undefined, "nomeie endpoint/evento, payload e idempotencia."));
|
|
4912
5191
|
}
|
|
5192
|
+
const pareceWebhook = artefatoPareceWebhookProfile(artefato, preset);
|
|
5193
|
+
if (pareceWebhook) {
|
|
5194
|
+
const auth = presencaAutenticacaoWebhookProfile(artefato);
|
|
5195
|
+
if (!auth.atendido) {
|
|
5196
|
+
achados.push(criarAchadoArtefatoProfile("workflow_webhook_sem_autenticacao", "webhook real nao declara autenticacao, assinatura ou segredo", false, "blocking", auth.trecho ?? trechoRegexProfile(artefato, /webhook|externalEventId|invoiceId|pagamento/i), "declare secret, assinatura, token ou Authorization para o endpoint.", auth.motivo, {
|
|
5197
|
+
linha: auth.linha,
|
|
5198
|
+
coluna: auth.coluna,
|
|
5199
|
+
inicio: auth.inicio,
|
|
5200
|
+
fim: auth.fim,
|
|
5201
|
+
risco: "webhook_sem_auth",
|
|
5202
|
+
}));
|
|
5203
|
+
}
|
|
5204
|
+
const exigeWorkspace = artefatoPareceMultiTenantProfile(contrato, artefato) || artefatoParecePagamentoWebhookProfile(artefato);
|
|
5205
|
+
if (exigeWorkspace) {
|
|
5206
|
+
const workspace = presencaWorkspaceWebhookProfile(artefato);
|
|
5207
|
+
if (!workspace.atendido) {
|
|
5208
|
+
achados.push(criarAchadoArtefatoProfile("workflow_webhook_sem_workspace", "webhook multi-tenant nao declara workspace/tenant de fronteira", false, "blocking", workspace.trecho ?? trechoRegexProfile(artefato, /webhook|invoiceId|externalEventId|pagamento/i), "inclua workspaceSlug/workspaceId/tenant autenticado e valide efeitos dentro desse escopo.", workspace.motivo, {
|
|
5209
|
+
linha: workspace.linha,
|
|
5210
|
+
coluna: workspace.coluna,
|
|
5211
|
+
inicio: workspace.inicio,
|
|
5212
|
+
fim: workspace.fim,
|
|
5213
|
+
risco: "isolamento_multi_workspace_ausente",
|
|
5214
|
+
}));
|
|
5215
|
+
}
|
|
5216
|
+
}
|
|
5217
|
+
const externalEventGlobal = localizarIdempotenciaGlobalExternalEventProfile(artefato);
|
|
5218
|
+
const externalEventPresente = /\bexternalEventId\b/i.test(artefato);
|
|
5219
|
+
const idempotenciaScoped = presencaIdempotenciaWorkspaceScopedProfile(artefato);
|
|
5220
|
+
if (externalEventGlobal || (externalEventPresente && !idempotenciaScoped.atendido && (artefatoPareceMultiTenantProfile(contrato, artefato) || artefatoParecePagamentoWebhookProfile(artefato)))) {
|
|
5221
|
+
achados.push(criarAchadoArtefatoProfile("workflow_webhook_idempotencia_global", "webhook usa externalEventId sem escopo de workspace/tenant", false, "blocking", externalEventGlobal?.trecho ?? idempotenciaScoped.trecho ?? trechoRegexProfile(artefato, /\bexternalEventId\b/i), "modele idempotencia por workspaceId/tenantId + externalEventId.", idempotenciaScoped.motivo, {
|
|
5222
|
+
linha: externalEventGlobal?.linha ?? idempotenciaScoped.linha,
|
|
5223
|
+
coluna: externalEventGlobal?.coluna ?? idempotenciaScoped.coluna,
|
|
5224
|
+
inicio: externalEventGlobal?.inicio ?? idempotenciaScoped.inicio,
|
|
5225
|
+
fim: externalEventGlobal?.fim ?? idempotenciaScoped.fim,
|
|
5226
|
+
risco: "idempotencia_global_multi_tenant",
|
|
5227
|
+
}));
|
|
5228
|
+
}
|
|
5229
|
+
if (/invoiceId/i.test(artefato) && (!auth.atendido || !presencaWorkspaceWebhookProfile(artefato).atendido)) {
|
|
5230
|
+
achados.push(criarAchadoArtefatoProfile("workflow_webhook_apenas_invoice_id", "webhook de pagamento parece aplicar efeito sensivel a partir de invoiceId sem fronteira suficiente", false, "critical", trechoRegexProfile(artefato, /invoiceId[\s\S]{0,160}(?:paidAt|amount|pago|pagamento|paid)|(?:paidAt|amount|pago|pagamento|paid)[\s\S]{0,160}invoiceId/i), "resolva workspace/autenticacao antes de buscar a invoice e rejeite invoice fora do escopo.", undefined, { risco: "efeito_sensivel_cross_tenant" }));
|
|
5231
|
+
}
|
|
5232
|
+
}
|
|
4913
5233
|
return achados;
|
|
4914
5234
|
}
|
|
4915
5235
|
function avaliarArtefatoOpsProfile(artefato, preset) {
|
|
@@ -5743,18 +6063,10 @@ async function comandoValidar(entrada) {
|
|
|
5743
6063
|
}
|
|
5744
6064
|
async function comandoValidarJson(entrada) {
|
|
5745
6065
|
const modulos = await carregarModulos(entrada);
|
|
5746
|
-
const
|
|
5747
|
-
|
|
5748
|
-
|
|
5749
|
-
|
|
5750
|
-
diagnosticos: item.resultado.diagnosticos,
|
|
5751
|
-
}));
|
|
5752
|
-
console.log(JSON.stringify({
|
|
5753
|
-
comando: "validar",
|
|
5754
|
-
sucesso: resultados.every((resultado) => resultado.sucesso),
|
|
5755
|
-
resultados,
|
|
5756
|
-
}, null, 2));
|
|
5757
|
-
return resultados.every((resultado) => resultado.sucesso) ? 0 : 1;
|
|
6066
|
+
const diagnosticos = modulos.flatMap((item) => item.resultado.diagnosticos);
|
|
6067
|
+
const resultado = gerarRespostaValidacao(diagnosticos);
|
|
6068
|
+
console.log(JSON.stringify(resultado, null, 2));
|
|
6069
|
+
return resultado.valido ? 0 : 1;
|
|
5758
6070
|
}
|
|
5759
6071
|
async function comandoInspecionar(entrada, emJson, cwd = process.cwd()) {
|
|
5760
6072
|
const contextoProjeto = await carregarProjeto(entrada, cwd);
|
|
@@ -6282,7 +6594,7 @@ async function comandoAjudaIa() {
|
|
|
6282
6594
|
console.log("");
|
|
6283
6595
|
console.log(renderizarSecaoAscii("Fluxo recomendado", [
|
|
6284
6596
|
"Use `sema starter-ia` para um texto curto de onboarding.",
|
|
6285
|
-
"Use `sema sync-ai-entrypoints` para regenerar `SEMA_BRIEF.*` e `SEMA_INDEX.json` na raiz.",
|
|
6597
|
+
"Use `sema sync-ai-entrypoints` para regenerar `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.*` e `SEMA_INDEX.json` na raiz.",
|
|
6286
6598
|
"Use `sema instalar-exemplos` para materializar `exemplos/` oficiais sem sobrescrever arquivos locais.",
|
|
6287
6599
|
"Use `sema resumo <arquivo> --micro --para onboarding` para IA pequena.",
|
|
6288
6600
|
"Use `sema prompt-curto <arquivo> --curto --para mudanca` para colar contexto em modelo gratuito.",
|
|
@@ -6458,7 +6770,15 @@ async function comandoPromptCurto(entrada, args, emJson) {
|
|
|
6458
6770
|
: "SEMA_BRIEF.md";
|
|
6459
6771
|
const contextoProjeto = await readFile(path.join(resumoProjeto.pastaSaida, arquivoResumo), "utf8");
|
|
6460
6772
|
const capacidade = tamanho === "micro" ? "pequena" : tamanho === "curto" ? "media" : "grande";
|
|
6461
|
-
const prompt =
|
|
6773
|
+
const prompt = `⚠️ REGRA OBRIGATÓRIA DE GOVERNANÇA:
|
|
6774
|
+
|
|
6775
|
+
ANTES DE QUALQUER AÇÃO (editar, criar, deletar, executar, consultar, modificar):
|
|
6776
|
+
1. Chame sema_docs_impacto com sua intenção declarada
|
|
6777
|
+
2. Aguarde a resposta com as docs obrigatórias
|
|
6778
|
+
3. Leia as docs antes de agir
|
|
6779
|
+
4. Use sema_finalizar_mudanca para comprovar que leu as docs
|
|
6780
|
+
|
|
6781
|
+
Você está operando Sema em modo IA-first.
|
|
6462
6782
|
|
|
6463
6783
|
Isto e contexto comprimido para IA operar contrato semantico antes de tocar codigo vivo.
|
|
6464
6784
|
|
|
@@ -6466,8 +6786,9 @@ Capacidade alvo: ${capacidade}
|
|
|
6466
6786
|
Modo da tarefa: ${modo}
|
|
6467
6787
|
|
|
6468
6788
|
Regras:
|
|
6789
|
+
- ANTES DE TUDO: chame sema_docs_impacto com sua intenção declarada
|
|
6469
6790
|
- comece pelo resumo compacto abaixo
|
|
6470
|
-
- se a tarefa pedir mais contexto, abra \`SEMA_INDEX.json\`
|
|
6791
|
+
- se a tarefa pedir mais contexto, abra \`AGENT_CONTEXT_PACK.json\` e depois \`SEMA_INDEX.json\`
|
|
6471
6792
|
- nao tente ler o repo inteiro se o resumo ja disser onde tocar
|
|
6472
6793
|
- preserve contrato, risco, lacuna e checks sugeridos
|
|
6473
6794
|
|
|
@@ -6702,6 +7023,12 @@ async function principal() {
|
|
|
6702
7023
|
const cwd = process.cwd();
|
|
6703
7024
|
const posicionais = obterPosicionais(resto);
|
|
6704
7025
|
let codigoSaida = 0;
|
|
7026
|
+
// --- Comandos registrados via REGISTRO_COMANDOS (mcp-client, bridge-config, contexto-chat, etc.) ---
|
|
7027
|
+
const handlerRegistrado = REGISTRO_COMANDOS[comando];
|
|
7028
|
+
if (handlerRegistrado) {
|
|
7029
|
+
codigoSaida = await handlerRegistrado(posicionais, resto, possuiFlag(resto, "--json"));
|
|
7030
|
+
process.exit(codigoSaida);
|
|
7031
|
+
}
|
|
6705
7032
|
switch (comando) {
|
|
6706
7033
|
case "iniciar":
|
|
6707
7034
|
codigoSaida = await comandoIniciar(cwd, normalizarTemplateIniciar(obterOpcao(resto, "--template")));
|