@semacode/cli 1.5.27 → 1.5.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/AGENTS.md +279 -265
  2. package/AGENT_CONTEXT_PACK.json +164 -0
  3. package/README.md +144 -144
  4. package/SEMA_BRIEF.curto.txt +7 -7
  5. package/SEMA_BRIEF.md +464 -65
  6. package/SEMA_BRIEF.micro.txt +6 -6
  7. package/SEMA_INDEX.json +6723 -667
  8. package/dist/bridge.d.ts +52 -0
  9. package/dist/bridge.js +318 -0
  10. package/dist/bridge.js.map +1 -0
  11. package/dist/comandos.d.ts +11 -0
  12. package/dist/comandos.js +110 -0
  13. package/dist/comandos.js.map +1 -0
  14. package/dist/contexto.d.ts +34 -0
  15. package/dist/contexto.js +197 -0
  16. package/dist/contexto.js.map +1 -0
  17. package/dist/drift.d.ts +1 -1
  18. package/dist/drift.js +32 -5
  19. package/dist/drift.js.map +1 -1
  20. package/dist/index.js +391 -64
  21. package/dist/index.js.map +1 -1
  22. package/dist/lua-symbols.d.ts +0 -6
  23. package/dist/lua-symbols.js +11 -78
  24. package/dist/lua-symbols.js.map +1 -1
  25. package/dist/projeto.js +6 -0
  26. package/dist/projeto.js.map +1 -1
  27. package/dist/tipos.d.ts +1 -1
  28. package/docs/AGENT_STARTER.md +109 -109
  29. package/docs/api.md +82 -0
  30. package/docs/cli.md +175 -175
  31. package/docs/como-ensinar-a-sema-para-ia.md +155 -155
  32. package/docs/deploy.md +93 -0
  33. package/docs/documentacao.md +88 -88
  34. package/docs/env.md +105 -105
  35. package/docs/extensao-vscode.md +53 -53
  36. package/docs/fluxo-pratico-ia-sema.md +187 -187
  37. package/docs/instalacao-e-primeiro-uso.md +134 -134
  38. package/docs/integracao-com-ia.md +110 -110
  39. package/docs/mcp.md +292 -292
  40. package/docs/pagamento-ponta-a-ponta.md +171 -171
  41. package/docs/persistencia-vendor-first.md +151 -151
  42. package/docs/prompt-base-ia-sema.md +111 -111
  43. package/docs/repositories.md +54 -54
  44. package/docs/rollback.md +49 -49
  45. package/docs/seguranca.md +126 -126
  46. package/docs/sintaxe.md +218 -218
  47. package/exemplos/author_obra_comum.sema +294 -294
  48. package/exemplos/author_tema_sensivel.sema +264 -264
  49. package/exemplos/profile_game.sema +114 -114
  50. package/exemplos/profile_legal.sema +105 -105
  51. package/exemplos/profile_ops.sema +110 -110
  52. package/exemplos/profile_research.sema +104 -104
  53. package/exemplos/profile_software.sema +123 -123
  54. package/exemplos/profile_workflow_n8n.sema +99 -99
  55. package/llms-full.txt +10 -9
  56. package/llms.txt +8 -7
  57. package/node_modules/@sema/gerador-css/package.json +1 -1
  58. package/node_modules/@sema/gerador-dart/package.json +1 -1
  59. package/node_modules/@sema/gerador-html/package.json +1 -1
  60. package/node_modules/@sema/gerador-javascript/package.json +1 -1
  61. package/node_modules/@sema/gerador-lua/package.json +1 -1
  62. package/node_modules/@sema/gerador-python/package.json +1 -1
  63. package/node_modules/@sema/gerador-typescript/package.json +1 -1
  64. package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +1 -1
  65. package/node_modules/@sema/nucleo/dist/index.d.ts +17 -0
  66. package/node_modules/@sema/nucleo/dist/index.js +28 -0
  67. package/node_modules/@sema/nucleo/dist/index.js.map +1 -1
  68. package/node_modules/@sema/nucleo/dist/ir/conversor.js +4 -0
  69. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
  70. package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -3
  71. package/node_modules/@sema/nucleo/dist/parser/parser.js +2 -0
  72. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
  73. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +2 -2
  74. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +3 -1
  75. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
  76. package/node_modules/@sema/nucleo/package.json +1 -1
  77. package/node_modules/@sema/padroes/package.json +1 -1
  78. package/package.json +11 -10
  79. package/dist/php-symbols.d.ts +0 -24
  80. package/dist/php-symbols.js +0 -375
  81. package/dist/php-symbols.js.map +0 -1
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. \`SEMA_BRIEF.md\`
117
- 3. \`SEMA_INDEX.json\`
118
- 4. README do projeto
119
- 5. gramatica e documentacao de sintaxe da Sema
120
- 6. especificacao semantica da linguagem
121
- 7. exemplos oficiais, com prioridade para o vertical de pagamento
122
- 8. \`sema resumo\` e \`briefing.min.json\` quando a IA for pequena
123
- 9. AST, IR e diagnosticos exportados pela CLI em JSON quando a capacidade aguentar
124
-
125
- Regras de operacao:
126
- - 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
127
- - preserve o significado semantico
128
- - use o formatador oficial da Sema como fonte unica de estilo
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, { stdio: "ignore", shell: process.platform === "win32" });
655
- return (execucao.status ?? 1) === 0;
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 \`resumo.micro.txt\`.
2235
- 2. Ler \`briefing.min.json\`.
2236
- 3. Se ainda couber contexto, ler \`resumo.curto.txt\`.
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 \`resumo.curto.txt\`.
2241
- 2. Ler \`briefing.min.json\`.
2242
- 3. Ler \`drift.json\`.
2243
- 4. Se precisar, subir para \`resumo.md\`.
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 \`README.md\`.
2248
- 2. Ler \`resumo.md\`.
2249
- 3. Ler \`briefing.json\`.
2250
- 4. Ler \`drift.json\`.
2251
- 5. So depois abrir \`ir.json\` e \`ast.json\`.
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
- return regras.flatMap((regra) => {
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 resultados = modulos.map((item) => ({
5747
- caminho: item.caminho,
5748
- modulo: item.resultado.modulo?.nome ?? null,
5749
- sucesso: !temErros(item.resultado.diagnosticos),
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 = `Voce esta operando Sema em modo IA-first.
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")));