@semacode/cli 1.5.31 → 1.5.34
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/AGENTS.md +308 -0
- package/AGENT_CONTEXT_PACK.json +288 -0
- package/LICENSE +22 -0
- package/README.md +85 -144
- package/SEMA_BRIEF.curto.txt +11 -0
- package/SEMA_BRIEF.md +617 -0
- package/SEMA_BRIEF.micro.txt +9 -0
- package/SEMA_INDEX.json +9805 -0
- package/dist/billing/index.d.ts +46 -0
- package/dist/billing/index.js +143 -0
- package/dist/billing/index.js.map +1 -0
- package/dist/controleComercialSupabase.d.ts +7 -0
- package/dist/controleComercialSupabase.js +6 -0
- package/dist/controleComercialSupabase.js.map +1 -0
- package/dist/controleComercialSupabaseAdmin.d.ts +7 -0
- package/dist/controleComercialSupabaseAdmin.js +138 -0
- package/dist/controleComercialSupabaseAdmin.js.map +1 -0
- package/dist/controleComercialSupabaseCadastro.d.ts +4 -0
- package/dist/controleComercialSupabaseCadastro.js +85 -0
- package/dist/controleComercialSupabaseCadastro.js.map +1 -0
- package/dist/controleComercialSupabaseConstantes.d.ts +28 -0
- package/dist/controleComercialSupabaseConstantes.js +44 -0
- package/dist/controleComercialSupabaseConstantes.js.map +1 -0
- package/dist/controleComercialSupabaseConsumo.d.ts +2 -0
- package/dist/controleComercialSupabaseConsumo.js +77 -0
- package/dist/controleComercialSupabaseConsumo.js.map +1 -0
- package/dist/controleComercialSupabaseConta.d.ts +11 -0
- package/dist/controleComercialSupabaseConta.js +157 -0
- package/dist/controleComercialSupabaseConta.js.map +1 -0
- package/dist/controleComercialSupabaseProfiles.d.ts +4 -0
- package/dist/controleComercialSupabaseProfiles.js +55 -0
- package/dist/controleComercialSupabaseProfiles.js.map +1 -0
- package/dist/controleComercialSupabaseTipos.d.ts +3 -0
- package/dist/controleComercialSupabaseTipos.js +2 -0
- package/dist/controleComercialSupabaseTipos.js.map +1 -0
- package/dist/controleComercialSupabaseTiposAdmin.d.ts +152 -0
- package/dist/controleComercialSupabaseTiposAdmin.js +2 -0
- package/dist/controleComercialSupabaseTiposAdmin.js.map +1 -0
- package/dist/controleComercialSupabaseTiposBase.d.ts +169 -0
- package/dist/controleComercialSupabaseTiposBase.js +2 -0
- package/dist/controleComercialSupabaseTiposBase.js.map +1 -0
- package/dist/controleComercialSupabaseTiposConta.d.ts +220 -0
- package/dist/controleComercialSupabaseTiposConta.js +2 -0
- package/dist/controleComercialSupabaseTiposConta.js.map +1 -0
- package/dist/docs.js +72 -5
- package/dist/docs.js.map +1 -1
- package/dist/index.js +701 -185
- package/dist/index.js.map +1 -1
- package/dist/runnerValidacaoRemota.d.ts +9 -0
- package/dist/runnerValidacaoRemota.js +9 -0
- package/dist/runnerValidacaoRemota.js.map +1 -0
- package/dist/runnerValidacaoRemotaBateria.d.ts +10 -0
- package/dist/runnerValidacaoRemotaBateria.js +115 -0
- package/dist/runnerValidacaoRemotaBateria.js.map +1 -0
- package/dist/runnerValidacaoRemotaCli.d.ts +4 -0
- package/dist/runnerValidacaoRemotaCli.js +86 -0
- package/dist/runnerValidacaoRemotaCli.js.map +1 -0
- package/dist/runnerValidacaoRemotaComandos.d.ts +7 -0
- package/dist/runnerValidacaoRemotaComandos.js +123 -0
- package/dist/runnerValidacaoRemotaComandos.js.map +1 -0
- package/dist/runnerValidacaoRemotaEscopo.d.ts +4 -0
- package/dist/runnerValidacaoRemotaEscopo.js +79 -0
- package/dist/runnerValidacaoRemotaEscopo.js.map +1 -0
- package/dist/runnerValidacaoRemotaExecucao.d.ts +2 -0
- package/dist/runnerValidacaoRemotaExecucao.js +102 -0
- package/dist/runnerValidacaoRemotaExecucao.js.map +1 -0
- package/dist/runnerValidacaoRemotaRelatorio.d.ts +3 -0
- package/dist/runnerValidacaoRemotaRelatorio.js +93 -0
- package/dist/runnerValidacaoRemotaRelatorio.js.map +1 -0
- package/dist/runnerValidacaoRemotaServidor.d.ts +3 -0
- package/dist/runnerValidacaoRemotaServidor.js +157 -0
- package/dist/runnerValidacaoRemotaServidor.js.map +1 -0
- package/dist/runnerValidacaoRemotaSnapshot.d.ts +10 -0
- package/dist/runnerValidacaoRemotaSnapshot.js +217 -0
- package/dist/runnerValidacaoRemotaSnapshot.js.map +1 -0
- package/dist/runnerValidacaoRemotaTipos.d.ts +158 -0
- package/dist/runnerValidacaoRemotaTipos.js +35 -0
- package/dist/runnerValidacaoRemotaTipos.js.map +1 -0
- package/dist/runnerValidacaoRemotaUtil.d.ts +3 -0
- package/dist/runnerValidacaoRemotaUtil.js +18 -0
- package/dist/runnerValidacaoRemotaUtil.js.map +1 -0
- package/dist/runnerValidacaoRemotaWorkspace.d.ts +2 -0
- package/dist/runnerValidacaoRemotaWorkspace.js +110 -0
- package/dist/runnerValidacaoRemotaWorkspace.js.map +1 -0
- package/docs/AGENT_STARTER.md +109 -0
- package/docs/agentes-por-capacidade.md +42 -0
- package/docs/api.md +82 -0
- package/docs/cli.md +93 -0
- package/docs/como-ensinar-a-sema-para-ia.md +30 -0
- package/docs/deploy.md +45 -0
- package/docs/documentacao.md +88 -0
- package/docs/env.md +115 -0
- package/docs/extensao-vscode.md +42 -0
- package/docs/fluxo-pratico-ia-sema.md +195 -0
- package/docs/instalacao-e-primeiro-uso.md +48 -0
- package/docs/integracao-com-ia.md +38 -0
- package/docs/mcp.md +54 -0
- package/docs/pagamento-ponta-a-ponta.md +171 -0
- package/docs/persistencia-vendor-first.md +151 -0
- package/docs/prompt-base-ia-sema.md +111 -0
- package/docs/repositories.md +69 -0
- package/docs/rollback.md +24 -0
- package/docs/seguranca.md +126 -0
- package/docs/sintaxe.md +218 -0
- package/exemplos/profile_conversas.sema +165 -0
- package/llms-full.txt +35 -0
- package/llms.txt +18 -0
- package/node_modules/@sema/gerador-css/package.json +7 -14
- package/node_modules/@sema/gerador-dart/package.json +7 -14
- package/node_modules/@sema/gerador-html/package.json +7 -14
- package/node_modules/@sema/gerador-javascript/package.json +7 -14
- package/node_modules/@sema/gerador-lua/package.json +7 -14
- package/node_modules/@sema/gerador-python/package.json +7 -14
- package/node_modules/@sema/gerador-typescript/package.json +7 -14
- package/node_modules/@sema/nucleo/package.json +7 -10
- package/node_modules/@sema/padroes/package.json +7 -10
- package/package.json +75 -74
- package/exemplos/.prepack-generated +0 -1
- package/node_modules/@sema/gerador-css/src/index.ts +0 -605
- package/node_modules/@sema/gerador-css/tsconfig.json +0 -13
- package/node_modules/@sema/gerador-css/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/gerador-dart/src/index.ts +0 -52
- package/node_modules/@sema/gerador-dart/tsconfig.json +0 -13
- package/node_modules/@sema/gerador-dart/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/gerador-html/src/index.ts +0 -185
- package/node_modules/@sema/gerador-html/tsconfig.json +0 -13
- package/node_modules/@sema/gerador-html/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/gerador-javascript/src/index.ts +0 -461
- package/node_modules/@sema/gerador-javascript/tsconfig.json +0 -13
- package/node_modules/@sema/gerador-javascript/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/gerador-lua/src/index.ts +0 -359
- package/node_modules/@sema/gerador-lua/tsconfig.json +0 -13
- package/node_modules/@sema/gerador-lua/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/gerador-python/src/index.ts +0 -850
- package/node_modules/@sema/gerador-python/tsconfig.json +0 -13
- package/node_modules/@sema/gerador-python/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/gerador-typescript/src/index.ts +0 -876
- package/node_modules/@sema/gerador-typescript/tsconfig.json +0 -13
- package/node_modules/@sema/gerador-typescript/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/nucleo/src/ast/tipos.ts +0 -207
- package/node_modules/@sema/nucleo/src/diagnosticos/index.ts +0 -43
- package/node_modules/@sema/nucleo/src/diagnosticos/melhorador.ts +0 -130
- package/node_modules/@sema/nucleo/src/formatador/index.ts +0 -530
- package/node_modules/@sema/nucleo/src/index.ts +0 -184
- package/node_modules/@sema/nucleo/src/ir/conversor.ts +0 -1037
- package/node_modules/@sema/nucleo/src/ir/modelos.ts +0 -403
- package/node_modules/@sema/nucleo/src/lexer/lexer.ts +0 -166
- package/node_modules/@sema/nucleo/src/lexer/tokens.ts +0 -79
- package/node_modules/@sema/nucleo/src/parser/gramatica.ebnf +0 -41
- package/node_modules/@sema/nucleo/src/parser/parser.ts +0 -936
- package/node_modules/@sema/nucleo/src/persistencia/contratos.ts +0 -379
- package/node_modules/@sema/nucleo/src/semantico/analisador.ts +0 -3126
- package/node_modules/@sema/nucleo/src/semantico/estruturas.ts +0 -665
- package/node_modules/@sema/nucleo/src/semantico/seguranca.ts +0 -362
- package/node_modules/@sema/nucleo/src/util/arquivos.ts +0 -28
- package/node_modules/@sema/nucleo/tsconfig.json +0 -9
- package/node_modules/@sema/nucleo/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@sema/padroes/src/index.ts +0 -382
- package/node_modules/@sema/padroes/tsconfig.json +0 -9
- package/node_modules/@sema/padroes/tsconfig.tsbuildinfo +0 -1
package/dist/index.js
CHANGED
|
@@ -19,6 +19,8 @@ import { importarProjetoLegado, resumoImportacao } from "./importador.js";
|
|
|
19
19
|
import { analisarDriftLegado, assistirRenomeacaoSemantica, gerarMapaImpactoSemantico, } from "./drift.js";
|
|
20
20
|
import { resolverDocumentacaoObrigatoria, verificarDocumentacaoMudanca, } from "./docs.js";
|
|
21
21
|
import { REGISTRO_COMANDOS } from "./comandos.js";
|
|
22
|
+
import { ajudaRunnerValidacaoRemota, comandoRunnerValidacaoRemota, } from "./runnerValidacaoRemotaCli.js";
|
|
23
|
+
import { comandoServidorRunnerValidacaoRemota } from "./runnerValidacaoRemotaServidor.js";
|
|
22
24
|
const STARTER_IA = `Voce esta trabalhando com Sema, um contrato semantico IA-first para agentes operarem software vivo em backend e front consumer.
|
|
23
25
|
|
|
24
26
|
Importante:
|
|
@@ -34,7 +36,7 @@ Importante:
|
|
|
34
36
|
- a Sema usa \`vinculos\` para ligar contrato a arquivo, simbolo, recurso e superficie real
|
|
35
37
|
- a Sema usa \`execucao\` para explicitar timeout, retry, compensacao e criticidade
|
|
36
38
|
- a Sema usa \`drift\` para medir diferenca entre contrato e codigo vivo com score, confianca e lacunas
|
|
37
|
-
- a Sema usa \`resumo\` e \`prompt-curto\` para IA
|
|
39
|
+
- a Sema usa \`resumo\` e \`prompt-curto\` para IA fraca, gratuita ou com pouco contexto
|
|
38
40
|
- a Sema usa \`contexto-ia\` para gerar \`ast.json\`, \`ir.json\`, \`drift.json\`, \`briefing.json\` e artefatos compactos antes da edicao
|
|
39
41
|
- a Sema pode servir de base para interfaces graficas elegantes e coerentes
|
|
40
42
|
- a Sema nao gera uma interface completa sozinha no estado atual
|
|
@@ -45,7 +47,7 @@ Importante:
|
|
|
45
47
|
Regras:
|
|
46
48
|
- nao invente sintaxe fora da gramatica e dos exemplos oficiais
|
|
47
49
|
- 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
|
|
50
|
+
- se a IA for fraca, nao tente abrir tudo de uma vez
|
|
49
51
|
- use \`sema resumo\` e \`briefing.min.json\` antes de subir para o pacote completo
|
|
50
52
|
- trate \`ir --json\` como fonte de verdade semantica
|
|
51
53
|
- trate \`briefing.json\` como plano de intervencao antes de editar projeto vivo
|
|
@@ -56,7 +58,7 @@ Regras:
|
|
|
56
58
|
|
|
57
59
|
Comandos essenciais:
|
|
58
60
|
- resumo compacto por capacidade: \`sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
|
|
59
|
-
- prompt curto para IA
|
|
61
|
+
- prompt curto para IA fraca: \`sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
|
|
60
62
|
- descoberta do projeto: \`sema inspecionar [arquivo-ou-pasta] --json\`
|
|
61
63
|
- auditoria do contrato vivo: \`sema drift <arquivo-ou-pasta> [--escopo <arquivo|modulo|projeto>] [--json]\`
|
|
62
64
|
- mapa de impacto: \`sema impacto <arquivo-ou-pasta> --alvo <token> [--mudanca <descricao>] [--json]\`
|
|
@@ -74,7 +76,7 @@ Comandos essenciais:
|
|
|
74
76
|
|
|
75
77
|
Antes de editar:
|
|
76
78
|
1. leia README, docs de IA e um exemplo oficial parecido
|
|
77
|
-
2. se a IA for
|
|
79
|
+
2. se a IA for fraca, rode \`sema resumo <arquivo> --micro\` e leia \`briefing.min.json\`
|
|
78
80
|
3. se a IA aguentar mais, rode \`sema drift\` para medir impls, vinculos, rotas, score e lacunas
|
|
79
81
|
4. se a tarefa for pesada, rode \`sema contexto-ia\` e leia \`briefing.json\`
|
|
80
82
|
5. consulte AST e IR do modulo alvo so quando a capacidade realmente aguentar
|
|
@@ -121,7 +123,7 @@ Fontes de verdade, em ordem:
|
|
|
121
123
|
6. README do projeto
|
|
122
124
|
7. gramatica e documentacao de sintaxe da Sema
|
|
123
125
|
8. exemplos oficiais, com prioridade para o vertical de pagamento
|
|
124
|
-
9. \`sema resumo\` e \`briefing.min.json\` quando a IA for
|
|
126
|
+
9. \`sema resumo\` e \`briefing.min.json\` quando a IA for fraca
|
|
125
127
|
10. AST, IR e diagnosticos exportados pela CLI em JSON quando a capacidade aguentar
|
|
126
128
|
|
|
127
129
|
Regras de operacao:
|
|
@@ -332,17 +334,30 @@ Comandos uteis da CLI para esse fluxo:
|
|
|
332
334
|
const DIRETORIO_CLI_ATUAL = path.dirname(fileURLToPath(import.meta.url));
|
|
333
335
|
const VERSAO_CLI = pacoteCli.version;
|
|
334
336
|
const requireRuntimeCli = createRequire(import.meta.url);
|
|
337
|
+
const ARQUIVO_SEMA_BOOT = "SEMA_BOOT.md";
|
|
338
|
+
const ARQUIVO_SEMA_SMALL_MODEL = "SEMA_SMALL_MODEL.md";
|
|
335
339
|
const ARQUIVO_AGENT_CONTEXT_PACK = "AGENT_CONTEXT_PACK.json";
|
|
340
|
+
const ARQUIVO_DOC_AGENTES_CAPACIDADE = "docs/agentes-por-capacidade.md";
|
|
336
341
|
const ARQUIVOS_CANONICOS_IA_RAIZ = [
|
|
342
|
+
ARQUIVO_SEMA_BOOT,
|
|
337
343
|
"llms.txt",
|
|
338
344
|
ARQUIVO_AGENT_CONTEXT_PACK,
|
|
345
|
+
ARQUIVO_SEMA_SMALL_MODEL,
|
|
339
346
|
"SEMA_BRIEF.md",
|
|
340
347
|
"SEMA_INDEX.json",
|
|
341
348
|
"AGENTS.md",
|
|
342
349
|
"README.md",
|
|
343
350
|
"llms-full.txt",
|
|
344
351
|
];
|
|
352
|
+
const CAPACIDADES_IA_OPERACIONAIS = ["fraca", "media", "forte"];
|
|
353
|
+
const ALIASES_CAPACIDADE_IA = {
|
|
354
|
+
pequena: "fraca",
|
|
355
|
+
grande: "forte",
|
|
356
|
+
};
|
|
357
|
+
const MARCADOR_SEMA_AGENT_ENTRYPOINT_INICIO = "<!-- sema:agent-entrypoint:start -->";
|
|
358
|
+
const MARCADOR_SEMA_AGENT_ENTRYPOINT_FIM = "<!-- sema:agent-entrypoint:end -->";
|
|
345
359
|
const DOCUMENTOS_SUPORTE_IA = [
|
|
360
|
+
ARQUIVO_DOC_AGENTES_CAPACIDADE,
|
|
346
361
|
"docs/AGENT_STARTER.md",
|
|
347
362
|
"docs/integracao-com-ia.md",
|
|
348
363
|
"docs/fluxo-pratico-ia-sema.md",
|
|
@@ -463,18 +478,18 @@ function ajuda() {
|
|
|
463
478
|
return [
|
|
464
479
|
renderizarCaixaAscii([
|
|
465
480
|
`Sema CLI v${VERSAO_CLI}`,
|
|
466
|
-
"IA-first para contrato,
|
|
467
|
-
"novo projeto,
|
|
481
|
+
"IA-first para contrato, geração e adoção incremental",
|
|
482
|
+
"novo projeto, edição guiada e legado sem contrato inicial",
|
|
468
483
|
]),
|
|
469
484
|
"",
|
|
470
|
-
renderizarSecaoAscii("Fluxos
|
|
471
|
-
"[1] Projeto novo /
|
|
485
|
+
renderizarSecaoAscii("Fluxos rápidos", [
|
|
486
|
+
"[1] Projeto novo / produção inicial",
|
|
472
487
|
"sema iniciar --template <base|nestjs|fastapi|nextjs-api|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer>",
|
|
473
488
|
"sema validar contratos/<modulo>.sema --json",
|
|
474
489
|
"sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart|lua> --saida <diretorio>",
|
|
475
490
|
"sema verificar <arquivo-ou-pasta> --json",
|
|
476
491
|
"",
|
|
477
|
-
"[2] Editar projeto que
|
|
492
|
+
"[2] Editar projeto que já usa Sema",
|
|
478
493
|
"sema inspecionar . --json",
|
|
479
494
|
"sema resumo <arquivo-ou-pasta> --micro --para mudanca",
|
|
480
495
|
"sema drift <arquivo-ou-pasta> --escopo modulo --json",
|
|
@@ -490,14 +505,15 @@ function ajuda() {
|
|
|
490
505
|
"sema author validar-narrativa contratos/author.sema --texto <texto> --texto-anterior <texto> --json",
|
|
491
506
|
"sema author validar-proibicoes contratos/author.sema --texto <texto> --json",
|
|
492
507
|
"",
|
|
493
|
-
"[4] Validar profiles
|
|
508
|
+
"[4] Validar profiles semânticos",
|
|
494
509
|
"sema profile validar workflow contratos/sema/workflow_ops.sema --maturidade production --preset webhook --artefato-arquivo workflow.md --json",
|
|
495
510
|
"sema profile validar ops contratos/sema/workflow_ops.sema --maturidade critical --preset deploy --artefato-arquivo runbook.md --json",
|
|
496
511
|
"sema profile validar game contratos/sema/game.sema --maturidade prototype --preset playtest --artefato-arquivo playtest.md --json",
|
|
512
|
+
"sema profile validar conversas contratos/sema/conversas.sema --maturidade production --preset vendas --artefato-arquivo conversa.md --json",
|
|
497
513
|
"sema profile capabilities --json",
|
|
498
514
|
"sema rule-packs --profile legal --json",
|
|
499
515
|
"",
|
|
500
|
-
"[5] Adotar Sema em projeto que ainda
|
|
516
|
+
"[5] Adotar Sema em projeto que ainda não usa",
|
|
501
517
|
"sema importar <fonte> <diretorio> --saida <diretorio> --json",
|
|
502
518
|
"sema formatar <arquivo-ou-pasta>",
|
|
503
519
|
"sema validar <arquivo-ou-pasta> --json",
|
|
@@ -505,27 +521,27 @@ function ajuda() {
|
|
|
505
521
|
]),
|
|
506
522
|
"",
|
|
507
523
|
renderizarSecaoAscii("IA por capacidade", [
|
|
508
|
-
"
|
|
509
|
-
"
|
|
510
|
-
"
|
|
524
|
+
"fraca: sema resumo --micro + briefing.min.json + prompt-curto.txt",
|
|
525
|
+
"média: sema resumo --curto + drift.json + briefing.min.json",
|
|
526
|
+
"forte: sema contexto-ia + briefing.json + ir.json + ast.json",
|
|
511
527
|
]),
|
|
512
528
|
"",
|
|
513
529
|
renderizarSecaoAscii("Comandos principais", [
|
|
514
530
|
"descoberta: sema inspecionar [arquivo-ou-pasta] [--json]",
|
|
515
531
|
"auditoria: sema drift <arquivo-ou-pasta> [--escopo <arquivo|modulo|projeto>] [--incluir-worktrees] [--incluir-consumidores-laterais] [--json]",
|
|
516
532
|
"impacto: sema impacto <arquivo-ou-pasta> --alvo <token> [--mudanca <descricao>] [--escopo <arquivo|modulo|projeto>] [--json]",
|
|
517
|
-
"
|
|
518
|
-
"
|
|
519
|
-
"
|
|
520
|
-
"
|
|
521
|
-
"
|
|
533
|
+
"renomeação: sema renomear-semantico <arquivo-ou-pasta> --de <nome-atual> --para <nome-novo> [--escopo <arquivo|modulo|projeto>] [--json]",
|
|
534
|
+
"importação: sema importar <nestjs|fastapi|flask|nextjs|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|firebase|dotnet|java|go|rust|cpp|typescript|python|dart> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]",
|
|
535
|
+
"validação: sema validar <arquivo-ou-pasta> [--json]",
|
|
536
|
+
"diagnóstico: sema diagnosticos <arquivo.sema> [--json]",
|
|
537
|
+
"geração: sema compilar <arquivo-ou-pasta> --alvo <python|typescript|dart|lua> --saida <diretorio> [--estrutura <flat|modulos|backend>] [--framework <base|nestjs|fastapi>]",
|
|
522
538
|
"teste local: sema testar <arquivo.sema> --alvo <python|typescript|dart|lua> --saida <diretorio-temporario> [--estrutura <flat|modulos|backend>] [--framework <base|nestjs|fastapi>]",
|
|
523
|
-
"
|
|
524
|
-
"
|
|
539
|
+
"verificação final: sema verificar <arquivo-ou-pasta> [--saida <diretorio-base>] [--json]",
|
|
540
|
+
"formatação: sema formatar <arquivo-ou-pasta> [--check] [--json]",
|
|
525
541
|
"author: sema author <iniciar|validar|briefing|revisar-cliches|validar-narrativa|validar-proibicoes> [arquivo] [--tema-sensivel] [--preset conto|romance|roteiro|lore|campanha] [--saida <arquivo>] [--texto <texto>] [--json]",
|
|
526
|
-
"profile: sema profile validar <software|workflow|ops|game|legal|research> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
|
|
542
|
+
"profile: sema profile validar <software|workflow|ops|game|legal|research|conversas> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
|
|
527
543
|
"capabilities: sema profile capabilities [--json]",
|
|
528
|
-
"rule packs: sema rule-packs [--profile <author|software|workflow|ops|game|legal|research>] [--json]",
|
|
544
|
+
"rule packs: sema rule-packs [--profile <author|software|workflow|ops|game|legal|research|conversas>] [--json]",
|
|
529
545
|
]),
|
|
530
546
|
"",
|
|
531
547
|
renderizarSecaoAscii("Ajuda IA-first", [
|
|
@@ -570,6 +586,52 @@ async function escreverArquivos(base, arquivos) {
|
|
|
570
586
|
await writeFile(destino, arquivo.conteudo, "utf8");
|
|
571
587
|
}
|
|
572
588
|
}
|
|
589
|
+
async function statSeguro(caminho) {
|
|
590
|
+
try {
|
|
591
|
+
return await stat(caminho);
|
|
592
|
+
}
|
|
593
|
+
catch {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
function pareceEntradaSemaLegada(conteudo) {
|
|
598
|
+
return /Sema.*Regras obrigat[oó]rias para IA/is.test(conteudo) ||
|
|
599
|
+
/Sema.*Regras obrigatorias para IA/is.test(conteudo) ||
|
|
600
|
+
/Sema.*Regras obrigatórias para IA/is.test(conteudo);
|
|
601
|
+
}
|
|
602
|
+
function montarBlocoGerenciadoSema(conteudo) {
|
|
603
|
+
return `${MARCADOR_SEMA_AGENT_ENTRYPOINT_INICIO}\n${conteudo.trim()}\n${MARCADOR_SEMA_AGENT_ENTRYPOINT_FIM}\n`;
|
|
604
|
+
}
|
|
605
|
+
async function escreverArquivoGerenciadoSema(caminho, conteudo, substituirLegadoSema = false) {
|
|
606
|
+
const bloco = montarBlocoGerenciadoSema(conteudo);
|
|
607
|
+
const atual = await statSeguro(caminho);
|
|
608
|
+
if (!atual) {
|
|
609
|
+
await mkdir(path.dirname(caminho), { recursive: true });
|
|
610
|
+
await writeFile(caminho, bloco, "utf8");
|
|
611
|
+
return "criado";
|
|
612
|
+
}
|
|
613
|
+
if (!atual.isFile()) {
|
|
614
|
+
return "preservado";
|
|
615
|
+
}
|
|
616
|
+
const textoAtual = await readFile(caminho, "utf8");
|
|
617
|
+
let proximo;
|
|
618
|
+
if (textoAtual.includes(MARCADOR_SEMA_AGENT_ENTRYPOINT_INICIO) && textoAtual.includes(MARCADOR_SEMA_AGENT_ENTRYPOINT_FIM)) {
|
|
619
|
+
const inicio = textoAtual.indexOf(MARCADOR_SEMA_AGENT_ENTRYPOINT_INICIO);
|
|
620
|
+
const fim = textoAtual.indexOf(MARCADOR_SEMA_AGENT_ENTRYPOINT_FIM, inicio) + MARCADOR_SEMA_AGENT_ENTRYPOINT_FIM.length;
|
|
621
|
+
proximo = `${textoAtual.slice(0, inicio)}${bloco.trimEnd()}${textoAtual.slice(fim)}`;
|
|
622
|
+
}
|
|
623
|
+
else if (substituirLegadoSema && pareceEntradaSemaLegada(textoAtual)) {
|
|
624
|
+
proximo = bloco;
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
proximo = `${bloco}\n${textoAtual.trimStart()}`;
|
|
628
|
+
}
|
|
629
|
+
if (proximo === textoAtual) {
|
|
630
|
+
return "preservado";
|
|
631
|
+
}
|
|
632
|
+
await writeFile(caminho, proximo.endsWith("\n") ? proximo : `${proximo}\n`, "utf8");
|
|
633
|
+
return "atualizado";
|
|
634
|
+
}
|
|
573
635
|
function obterOpcao(args, nome, padrao) {
|
|
574
636
|
const nomes = [nome, ...Object.entries(ALIAS_OPCOES).filter(([, v]) => v === nome).map(([k]) => k)];
|
|
575
637
|
for (const n of nomes) {
|
|
@@ -1478,81 +1540,154 @@ function descreverFazModulo(ir, modulo) {
|
|
|
1478
1540
|
: `governa o modulo ${normalizarIdentificadorResumo(modulo)}`;
|
|
1479
1541
|
}
|
|
1480
1542
|
function criarGuiaCapacidadeIa() {
|
|
1543
|
+
const fraca = {
|
|
1544
|
+
descricao: "IA fraca, gratuita, local pequena ou com disciplina baixa. Leia o boot card, pare cedo e chame Sema antes de agir.",
|
|
1545
|
+
artefatos: [ARQUIVO_SEMA_BOOT, ARQUIVO_SEMA_SMALL_MODEL, "agent-context-pack.json", "resumo.micro.txt", "briefing.min.json", "prompt-curto.txt"],
|
|
1546
|
+
ordemLeitura: [ARQUIVO_SEMA_BOOT, ARQUIVO_SEMA_SMALL_MODEL, "agent-context-pack.json", "resumo.micro.txt", "briefing.min.json", "resumo.curto.txt"],
|
|
1547
|
+
evitar: ["ast.json", "ir.json", "diagnosticos.json"],
|
|
1548
|
+
};
|
|
1549
|
+
const media = {
|
|
1550
|
+
descricao: "IA média. Aguenta boot, resumo expandido, briefing mínimo, drift e documentação curta.",
|
|
1551
|
+
artefatos: [ARQUIVO_SEMA_BOOT, "agent-context-pack.json", "resumo.curto.txt", "briefing.min.json", "drift.json", "prompt-curto.txt"],
|
|
1552
|
+
ordemLeitura: [ARQUIVO_SEMA_BOOT, "agent-context-pack.json", "resumo.curto.txt", "briefing.min.json", "drift.json", "resumo.md"],
|
|
1553
|
+
evitar: ["ast.json"],
|
|
1554
|
+
};
|
|
1555
|
+
const forte = {
|
|
1556
|
+
descricao: "IA forte, com tool use bom e contexto grande. Pode consumir o pacote completo, mas ainda deve começar pelo boot e pelos gates Sema.",
|
|
1557
|
+
artefatos: [ARQUIVO_SEMA_BOOT, "agent-context-pack.json", "README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
|
|
1558
|
+
ordemLeitura: [ARQUIVO_SEMA_BOOT, "agent-context-pack.json", "README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
|
|
1559
|
+
evitar: [],
|
|
1560
|
+
};
|
|
1481
1561
|
return {
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1562
|
+
fraca,
|
|
1563
|
+
pequena: fraca,
|
|
1564
|
+
media,
|
|
1565
|
+
forte,
|
|
1566
|
+
grande: forte,
|
|
1567
|
+
};
|
|
1568
|
+
}
|
|
1569
|
+
function criarPoliticaIdiomaAgentContext() {
|
|
1570
|
+
return {
|
|
1571
|
+
regra: "A linguagem humana da resposta deve seguir o idioma do usuário e preservar acentos, cedilha, pontuação e símbolos esperados. A DSL .sema pode ter palavras-chave ASCII; isso não autoriza PT-BR sem acentos.",
|
|
1572
|
+
idiomaHumanoPadrao: "pt-BR quando a conversa ou o projeto estiverem em português; caso contrário, use o idioma falado pelo usuário.",
|
|
1573
|
+
preservarAcentos: true,
|
|
1574
|
+
separarDslDeTextoHumano: true,
|
|
1575
|
+
comandosESimbolos: "Não traduza comandos, nomes de arquivos, rotas, símbolos de código ou palavras-chave da DSL.",
|
|
1576
|
+
};
|
|
1577
|
+
}
|
|
1578
|
+
function criarEntrypointsClientesIa() {
|
|
1579
|
+
return [
|
|
1580
|
+
{
|
|
1581
|
+
cliente: "copilot",
|
|
1582
|
+
arquivos: [".github/copilot-instructions.md", "AGENTS.md", ARQUIVO_SEMA_BOOT],
|
|
1583
|
+
capacidadePadrao: "media",
|
|
1584
|
+
observacao: "VS Code/Copilot deve receber uma instrução curta e repetida no arquivo próprio, sem depender só do AGENTS.md.",
|
|
1487
1585
|
},
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1586
|
+
{
|
|
1587
|
+
cliente: "cline",
|
|
1588
|
+
arquivos: [".clinerules/00-sema.md", ".clinerules", ARQUIVO_SEMA_BOOT],
|
|
1589
|
+
capacidadePadrao: "fraca",
|
|
1590
|
+
observacao: "Cline costuma obedecer melhor quando o gate Sema vem em arquivo curto; se .clinerules for arquivo legado, o Sema atualiza esse fallback.",
|
|
1493
1591
|
},
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1592
|
+
{
|
|
1593
|
+
cliente: "roo",
|
|
1594
|
+
arquivos: [".roo/rules/00-sema.md", "AGENTS.md", ARQUIVO_SEMA_BOOT],
|
|
1595
|
+
capacidadePadrao: "fraca",
|
|
1596
|
+
observacao: "Roo Code deve começar por uma regra dedicada em .roo/rules antes de abrir arquivos longos.",
|
|
1499
1597
|
},
|
|
1500
|
-
|
|
1598
|
+
{
|
|
1599
|
+
cliente: "opencode",
|
|
1600
|
+
arquivos: [".opencode/instructions.md", "AGENTS.md", ARQUIVO_SEMA_BOOT],
|
|
1601
|
+
capacidadePadrao: "media",
|
|
1602
|
+
observacao: "OpenCode deve receber a mesma regra curta em instructions.md quando a pasta .opencode já existir.",
|
|
1603
|
+
},
|
|
1604
|
+
{
|
|
1605
|
+
cliente: "generico",
|
|
1606
|
+
arquivos: [ARQUIVO_SEMA_BOOT, ARQUIVO_SEMA_SMALL_MODEL, ARQUIVO_AGENT_CONTEXT_PACK],
|
|
1607
|
+
capacidadePadrao: "fraca",
|
|
1608
|
+
observacao: "Qualquer agente sem integração específica começa pelo boot card e só sobe contexto se passar pelos gates.",
|
|
1609
|
+
},
|
|
1610
|
+
];
|
|
1611
|
+
}
|
|
1612
|
+
function criarFailClosedAgentContext() {
|
|
1613
|
+
return [
|
|
1614
|
+
"Se não conseguir chamar Sema, pare e declare bloqueio em vez de editar código ou contrato.",
|
|
1615
|
+
"Se não houver contrato aplicável, crie ou edite o .sema antes do código.",
|
|
1616
|
+
"Se o MCP remoto não tiver projeto sincronizado, use sema_chat_contexto e sema_sync/conteúdo inline; não peça para ler C:\\GitHub\\Sema.",
|
|
1617
|
+
"Se for criar ou corrigir .sema, use sema_exemplos antes de escrever sintaxe.",
|
|
1618
|
+
"Se a resposta humana estiver em PT-BR, preserve acentos e símbolos mesmo que a DSL use ASCII.",
|
|
1619
|
+
];
|
|
1501
1620
|
}
|
|
1502
1621
|
function criarAgentContextPack(guiaPorCapacidade) {
|
|
1503
1622
|
const fontes = [
|
|
1504
1623
|
{
|
|
1505
|
-
caminho:
|
|
1624
|
+
caminho: ARQUIVO_SEMA_BOOT,
|
|
1506
1625
|
tipo: "entrypoint",
|
|
1507
1626
|
prioridade: 1,
|
|
1508
1627
|
obrigatorio: true,
|
|
1628
|
+
quandoUsar: "sempre no primeiro contato de qualquer agente com o projeto",
|
|
1629
|
+
incluirTextoBrutoQuando: "a IA precisa de um boot curto, fail-closed e independente do tamanho de contexto",
|
|
1630
|
+
},
|
|
1631
|
+
{
|
|
1632
|
+
caminho: ARQUIVO_SEMA_SMALL_MODEL,
|
|
1633
|
+
tipo: "entrypoint",
|
|
1634
|
+
prioridade: 2,
|
|
1635
|
+
obrigatorio: true,
|
|
1636
|
+
quandoUsar: "IA fraca, Copilot, modelo local pequeno, Cline/Roo com pouco contexto ou tarefa curta",
|
|
1637
|
+
incluirTextoBrutoQuando: "a IA tende a ignorar instruções longas ou copiar a estética ASCII da DSL",
|
|
1638
|
+
},
|
|
1639
|
+
{
|
|
1640
|
+
caminho: "llms.txt",
|
|
1641
|
+
tipo: "entrypoint",
|
|
1642
|
+
prioridade: 3,
|
|
1643
|
+
obrigatorio: true,
|
|
1509
1644
|
quandoUsar: "sempre no primeiro contato com o projeto",
|
|
1510
|
-
incluirTextoBrutoQuando: "a IA precisa de
|
|
1645
|
+
incluirTextoBrutoQuando: "a IA precisa de orientação compacta para operar o repositório",
|
|
1511
1646
|
},
|
|
1512
1647
|
{
|
|
1513
1648
|
caminho: ARQUIVO_AGENT_CONTEXT_PACK,
|
|
1514
1649
|
tipo: "entrypoint",
|
|
1515
|
-
prioridade:
|
|
1650
|
+
prioridade: 4,
|
|
1516
1651
|
obrigatorio: true,
|
|
1517
1652
|
quandoUsar: "sempre antes de decidir quais documentos ou exemplos abrir",
|
|
1518
|
-
incluirTextoBrutoQuando: "a IA precisa auditar regras,
|
|
1653
|
+
incluirTextoBrutoQuando: "a IA precisa auditar regras, proibições, prioridades e fontes de verdade",
|
|
1519
1654
|
},
|
|
1520
1655
|
{
|
|
1521
1656
|
caminho: "SEMA_BRIEF.micro.txt",
|
|
1522
1657
|
tipo: "resumo",
|
|
1523
|
-
prioridade:
|
|
1658
|
+
prioridade: 5,
|
|
1524
1659
|
obrigatorio: true,
|
|
1525
|
-
quandoUsar: "IA
|
|
1660
|
+
quandoUsar: "IA fraca, onboarding, chat remoto ou primeiro triage",
|
|
1526
1661
|
incluirTextoBrutoQuando: "a tarefa cabe em contexto curto",
|
|
1527
1662
|
},
|
|
1528
1663
|
{
|
|
1529
1664
|
caminho: "SEMA_BRIEF.curto.txt",
|
|
1530
1665
|
tipo: "resumo",
|
|
1531
|
-
prioridade:
|
|
1666
|
+
prioridade: 6,
|
|
1532
1667
|
obrigatorio: true,
|
|
1533
|
-
quandoUsar: "IA
|
|
1534
|
-
incluirTextoBrutoQuando: "o
|
|
1668
|
+
quandoUsar: "IA média, mudança pequena ou review rápido",
|
|
1669
|
+
incluirTextoBrutoQuando: "o módulo alvo ainda não está claro pelo micro",
|
|
1535
1670
|
},
|
|
1536
1671
|
{
|
|
1537
1672
|
caminho: "SEMA_INDEX.json",
|
|
1538
1673
|
tipo: "indice",
|
|
1539
|
-
prioridade:
|
|
1674
|
+
prioridade: 7,
|
|
1540
1675
|
obrigatorio: true,
|
|
1541
|
-
quandoUsar: "antes de abrir
|
|
1542
|
-
incluirTextoBrutoQuando: "a IA precisa mapear
|
|
1676
|
+
quandoUsar: "antes de abrir código cru ou escolher contrato alvo",
|
|
1677
|
+
incluirTextoBrutoQuando: "a IA precisa mapear módulos, lacunas, riscos ou arquivos prováveis",
|
|
1543
1678
|
},
|
|
1544
1679
|
{
|
|
1545
1680
|
caminho: "AGENTS.md",
|
|
1546
1681
|
tipo: "operacional",
|
|
1547
|
-
prioridade:
|
|
1682
|
+
prioridade: 8,
|
|
1548
1683
|
obrigatorio: true,
|
|
1549
|
-
quandoUsar: "antes de editar
|
|
1550
|
-
incluirTextoBrutoQuando: "a IA precisa confirmar regras locais
|
|
1684
|
+
quandoUsar: "antes de editar código, contrato, docs operacionais, release ou deploy",
|
|
1685
|
+
incluirTextoBrutoQuando: "a IA precisa confirmar regras locais obrigatórias e prioridades do projeto",
|
|
1551
1686
|
},
|
|
1552
1687
|
{
|
|
1553
1688
|
caminho: "exemplos/",
|
|
1554
1689
|
tipo: "exemplos",
|
|
1555
|
-
prioridade:
|
|
1690
|
+
prioridade: 9,
|
|
1556
1691
|
obrigatorio: true,
|
|
1557
1692
|
quandoUsar: "antes de criar ou corrigir arquivo .sema, profile, Author, workflow, ops, game, legal ou research",
|
|
1558
1693
|
incluirTextoBrutoQuando: "a IA vai escrever sintaxe Sema ou comparar um contrato com formato oficial",
|
|
@@ -1560,71 +1695,245 @@ function criarAgentContextPack(guiaPorCapacidade) {
|
|
|
1560
1695
|
{
|
|
1561
1696
|
caminho: "docs/AGENT_STARTER.md",
|
|
1562
1697
|
tipo: "docs",
|
|
1563
|
-
prioridade:
|
|
1698
|
+
prioridade: 10,
|
|
1699
|
+
obrigatorio: false,
|
|
1700
|
+
quandoUsar: "onboarding de agente novo ou explicação curta do fluxo",
|
|
1701
|
+
incluirTextoBrutoQuando: "o agente remoto não conhece Sema ainda",
|
|
1702
|
+
},
|
|
1703
|
+
{
|
|
1704
|
+
caminho: ARQUIVO_DOC_AGENTES_CAPACIDADE,
|
|
1705
|
+
tipo: "docs",
|
|
1706
|
+
prioridade: 11,
|
|
1564
1707
|
obrigatorio: false,
|
|
1565
|
-
quandoUsar: "
|
|
1566
|
-
incluirTextoBrutoQuando: "
|
|
1708
|
+
quandoUsar: "configurar Copilot, Cline, Roo Code, OpenCode ou outro agente com disciplina variável",
|
|
1709
|
+
incluirTextoBrutoQuando: "a IA precisa entender tiers fraca/média/forte e política de idioma",
|
|
1567
1710
|
},
|
|
1568
1711
|
{
|
|
1569
1712
|
caminho: "docs/sintaxe.md",
|
|
1570
1713
|
tipo: "docs",
|
|
1571
|
-
prioridade:
|
|
1714
|
+
prioridade: 12,
|
|
1572
1715
|
obrigatorio: false,
|
|
1573
|
-
quandoUsar: "
|
|
1574
|
-
incluirTextoBrutoQuando: "a IA vai editar contrato e os exemplos
|
|
1716
|
+
quandoUsar: "dúvida de gramática, blocos ou formato do DSL",
|
|
1717
|
+
incluirTextoBrutoQuando: "a IA vai editar contrato e os exemplos não bastam",
|
|
1575
1718
|
},
|
|
1576
1719
|
{
|
|
1577
1720
|
caminho: "contratos/",
|
|
1578
1721
|
tipo: "contrato",
|
|
1579
|
-
prioridade:
|
|
1722
|
+
prioridade: 13,
|
|
1580
1723
|
obrigatorio: true,
|
|
1581
|
-
quandoUsar: "antes de qualquer
|
|
1724
|
+
quandoUsar: "antes de qualquer implementação ou alteração de comportamento",
|
|
1582
1725
|
incluirTextoBrutoQuando: "a tarefa toca uma capacidade governada por contrato",
|
|
1583
1726
|
},
|
|
1584
1727
|
];
|
|
1585
1728
|
return {
|
|
1586
1729
|
nome: "Agent Context Pack",
|
|
1587
|
-
versao:
|
|
1588
|
-
objetivo: "Dar a agentes IA uma entrada curta, estruturada e
|
|
1730
|
+
versao: 2,
|
|
1731
|
+
objetivo: "Dar a agentes IA uma entrada curta, estruturada e auditável antes de abrir código cru ou inventar contexto.",
|
|
1589
1732
|
ordemLeitura: [
|
|
1733
|
+
ARQUIVO_SEMA_BOOT,
|
|
1590
1734
|
"llms.txt",
|
|
1591
1735
|
ARQUIVO_AGENT_CONTEXT_PACK,
|
|
1736
|
+
ARQUIVO_SEMA_SMALL_MODEL,
|
|
1592
1737
|
"SEMA_BRIEF.micro.txt",
|
|
1593
1738
|
"SEMA_INDEX.json",
|
|
1594
1739
|
"AGENTS.md",
|
|
1595
1740
|
"exemplos/",
|
|
1596
1741
|
],
|
|
1597
1742
|
regrasObrigatorias: [
|
|
1598
|
-
"Contrato vem antes da
|
|
1599
|
-
"Leia
|
|
1743
|
+
"Contrato vem antes da ação.",
|
|
1744
|
+
"Leia SEMA_BOOT.md antes de qualquer outro artefato de IA.",
|
|
1745
|
+
"Leia AGENTS.md antes de editar código, contrato, docs operacionais, release ou deploy.",
|
|
1600
1746
|
"Use exemplos oficiais antes de criar ou corrigir sintaxe .sema.",
|
|
1601
|
-
"Use SEMA_INDEX.json para escolher contrato,
|
|
1747
|
+
"Use SEMA_INDEX.json para escolher contrato, módulo e arquivos prováveis antes de abrir código cru.",
|
|
1602
1748
|
"Valide .sema alterado e rode drift antes de concluir.",
|
|
1603
|
-
"Quando faltar contrato
|
|
1749
|
+
"Quando faltar contrato aplicável, crie ou edite o contrato antes do código.",
|
|
1750
|
+
"Responda no idioma do usuário e preserve acentos, cedilha, pontuação e símbolos humanos.",
|
|
1604
1751
|
],
|
|
1605
1752
|
proibicoes: [
|
|
1606
|
-
"
|
|
1607
|
-
"
|
|
1608
|
-
"
|
|
1609
|
-
"
|
|
1610
|
-
"
|
|
1753
|
+
"Não inventar sintaxe Sema fora da gramática e dos exemplos oficiais.",
|
|
1754
|
+
"Não tratar README, texto livre ou código como fonte superior ao contrato.",
|
|
1755
|
+
"Não sincronizar segredos, .env, node_modules, builds, caches, uploads ou artefatos privados fora do escopo.",
|
|
1756
|
+
"Não publicar, deployar ou remover capacidade sem contrato, drift e verificação.",
|
|
1757
|
+
"Não misturar repositório público e privado sem conferir docs de repositórios e AGENTS.md.",
|
|
1758
|
+
"Não usar a estética ASCII da DSL como desculpa para escrever PT-BR sem acentos.",
|
|
1611
1759
|
],
|
|
1612
1760
|
prioridades: [
|
|
1613
1761
|
"Menor artefato suficiente primeiro.",
|
|
1614
|
-
"Contrato,
|
|
1762
|
+
"Contrato, índice e AGENTS antes de código cru.",
|
|
1615
1763
|
"Exemplos oficiais antes de nova sintaxe.",
|
|
1616
|
-
"
|
|
1617
|
-
"Se risco ou escopo estiver
|
|
1764
|
+
"Diagnóstico estruturado antes de opinião livre.",
|
|
1765
|
+
"Se risco ou escopo estiver ambíguo, parar e pedir contrato/contexto.",
|
|
1618
1766
|
],
|
|
1619
1767
|
fontes,
|
|
1620
1768
|
exemplosOficiais: [...EXEMPLOS_OFICIAIS_AGENT_CONTEXT],
|
|
1621
1769
|
textoBrutoSobDemanda: Object.fromEntries(fontes.map((fonte) => [fonte.caminho, fonte.incluirTextoBrutoQuando])),
|
|
1622
1770
|
guiaPorCapacidade: {
|
|
1771
|
+
fraca: guiaPorCapacidade.fraca.ordemLeitura,
|
|
1623
1772
|
pequena: guiaPorCapacidade.pequena.ordemLeitura,
|
|
1624
1773
|
media: guiaPorCapacidade.media.ordemLeitura,
|
|
1774
|
+
forte: guiaPorCapacidade.forte.ordemLeitura,
|
|
1625
1775
|
grande: guiaPorCapacidade.grande.ordemLeitura,
|
|
1626
1776
|
},
|
|
1777
|
+
aliasesCapacidade: { ...ALIASES_CAPACIDADE_IA },
|
|
1778
|
+
entrypointsClientes: criarEntrypointsClientesIa(),
|
|
1779
|
+
politicaIdioma: criarPoliticaIdiomaAgentContext(),
|
|
1780
|
+
failClosed: criarFailClosedAgentContext(),
|
|
1781
|
+
};
|
|
1782
|
+
}
|
|
1783
|
+
function renderizarSemaBoot(agentContextPack) {
|
|
1784
|
+
const politica = agentContextPack.politicaIdioma;
|
|
1785
|
+
return `# SEMA_BOOT
|
|
1786
|
+
|
|
1787
|
+
Você está em um projeto governado por Sema. O contrato semântico vem antes de qualquer ação.
|
|
1788
|
+
|
|
1789
|
+
## Primeira ação
|
|
1790
|
+
|
|
1791
|
+
1. Se houver MCP Sema, chame Sema antes de editar.
|
|
1792
|
+
2. Em IDE local, confirme que \`AGENTS.md\` existe e chame \`sema_resumo\`.
|
|
1793
|
+
3. Em chat ou MCP remoto sem workspace sincronizado, comece por \`sema_chat_contexto\` e use \`sema_sync\` ou conteúdo inline.
|
|
1794
|
+
4. Antes de criar ou corrigir \`.sema\`, use \`sema_exemplos\`.
|
|
1795
|
+
5. Se não conseguir chamar Sema, pare e diga que está bloqueado.
|
|
1796
|
+
|
|
1797
|
+
## Capacidade do agente
|
|
1798
|
+
|
|
1799
|
+
- Fraca: leia \`${ARQUIVO_SEMA_SMALL_MODEL}\`, \`SEMA_BRIEF.micro.txt\`, \`${ARQUIVO_AGENT_CONTEXT_PACK}\` e só suba contexto se necessário.
|
|
1800
|
+
- Média: leia este boot, \`${ARQUIVO_AGENT_CONTEXT_PACK}\`, \`SEMA_BRIEF.curto.txt\`, \`SEMA_INDEX.json\` e a doc indicada pelo Sema.
|
|
1801
|
+
- Forte: leia este boot, \`${ARQUIVO_AGENT_CONTEXT_PACK}\`, \`SEMA_BRIEF.md\`, \`SEMA_INDEX.json\`, \`AGENTS.md\` e rode os gates completos.
|
|
1802
|
+
|
|
1803
|
+
## Idioma humano
|
|
1804
|
+
|
|
1805
|
+
${politica.regra}
|
|
1806
|
+
|
|
1807
|
+
- Use o idioma falado pelo usuário.
|
|
1808
|
+
- Em PT-BR, escreva com acentos, cedilha e pontuação normal.
|
|
1809
|
+
- Não copie a estética ASCII da DSL para propostas, respostas, docs humanas, mensagens de erro ou textos Author.
|
|
1810
|
+
- Não traduza comandos, rotas, nomes de arquivos, símbolos de código nem palavras-chave da DSL.
|
|
1811
|
+
|
|
1812
|
+
## Falha fechada
|
|
1813
|
+
|
|
1814
|
+
${agentContextPack.failClosed.map((regra) => `- ${regra}`).join("\n")}
|
|
1815
|
+
`;
|
|
1816
|
+
}
|
|
1817
|
+
function renderizarSemaSmallModel(agentContextPack) {
|
|
1818
|
+
return `# SEMA_SMALL_MODEL
|
|
1819
|
+
|
|
1820
|
+
Leia isto primeiro se você tem pouco contexto, pouca memória, pouco tool use ou tendência a ignorar instruções longas.
|
|
1821
|
+
|
|
1822
|
+
1. Não edite nada antes de chamar Sema.
|
|
1823
|
+
2. Se houver MCP: use \`sema_resumo\`, \`sema_docs_impacto\`, \`sema_drift\`, \`sema_validar\` e \`sema_finalizar_mudanca\`.
|
|
1824
|
+
3. Se for remoto sem workspace: não peça para ler pasta local. Use \`sema_chat_contexto\`, \`sema_sync\` ou conteúdo inline.
|
|
1825
|
+
4. Se for escrever \`.sema\`: use \`sema_exemplos\` antes.
|
|
1826
|
+
5. Se não houver contrato: crie ou edite o contrato antes do código.
|
|
1827
|
+
6. Se não conseguir chamar Sema: pare e declare bloqueio.
|
|
1828
|
+
7. Responda no idioma do usuário. Em PT-BR, use acentos e símbolos normais.
|
|
1829
|
+
|
|
1830
|
+
Ordem curta:
|
|
1831
|
+
|
|
1832
|
+
- \`${ARQUIVO_SEMA_BOOT}\`
|
|
1833
|
+
- \`SEMA_BRIEF.micro.txt\`
|
|
1834
|
+
- \`${ARQUIVO_AGENT_CONTEXT_PACK}\`
|
|
1835
|
+
- \`SEMA_INDEX.json\`
|
|
1836
|
+
- \`AGENTS.md\`
|
|
1837
|
+
|
|
1838
|
+
Fail-closed:
|
|
1839
|
+
|
|
1840
|
+
${agentContextPack.failClosed.map((regra) => `- ${regra}`).join("\n")}
|
|
1841
|
+
`;
|
|
1842
|
+
}
|
|
1843
|
+
function renderizarDocumentoAgentesPorCapacidade(agentContextPack) {
|
|
1844
|
+
return `# Agentes por capacidade
|
|
1845
|
+
|
|
1846
|
+
Sema deve funcionar em agentes fortes, médios e fracos. A diferença não é só tamanho de contexto; é disciplina operacional.
|
|
1847
|
+
|
|
1848
|
+
## Fraca
|
|
1849
|
+
|
|
1850
|
+
Use para Copilot em modo simples, Cline/Roo com pouco contexto, modelos locais pequenos e agentes que ignoram instrução longa.
|
|
1851
|
+
|
|
1852
|
+
- Entrada: \`${ARQUIVO_SEMA_BOOT}\` -> \`${ARQUIVO_SEMA_SMALL_MODEL}\` -> \`SEMA_BRIEF.micro.txt\`.
|
|
1853
|
+
- Não abrir AST/IR completos no começo.
|
|
1854
|
+
- Não editar se Sema não respondeu.
|
|
1855
|
+
- Não pedir para MCP remoto ler pasta local.
|
|
1856
|
+
|
|
1857
|
+
## Média
|
|
1858
|
+
|
|
1859
|
+
Use para agentes com bom contexto, mas sem garantia de seguir todos os gates.
|
|
1860
|
+
|
|
1861
|
+
- Entrada: \`${ARQUIVO_SEMA_BOOT}\` -> \`${ARQUIVO_AGENT_CONTEXT_PACK}\` -> \`SEMA_BRIEF.curto.txt\` -> \`SEMA_INDEX.json\`.
|
|
1862
|
+
- Rodar docs-impacto antes de agir.
|
|
1863
|
+
- Validar drift e contrato no fechamento.
|
|
1864
|
+
|
|
1865
|
+
## Forte
|
|
1866
|
+
|
|
1867
|
+
Use para Codex, Claude e agentes com tool use confiável.
|
|
1868
|
+
|
|
1869
|
+
- Entrada: \`${ARQUIVO_SEMA_BOOT}\` -> \`${ARQUIVO_AGENT_CONTEXT_PACK}\` -> \`SEMA_BRIEF.md\` -> \`SEMA_INDEX.json\`.
|
|
1870
|
+
- Pode consumir AST/IR/drift completos.
|
|
1871
|
+
- Ainda deve respeitar contrato primeiro e falha fechada.
|
|
1872
|
+
|
|
1873
|
+
## Idioma
|
|
1874
|
+
|
|
1875
|
+
${agentContextPack.politicaIdioma.regra}
|
|
1876
|
+
|
|
1877
|
+
A gramática Sema pode ter palavras-chave ASCII. Isso não autoriza resposta humana sem acentos.
|
|
1878
|
+
|
|
1879
|
+
## Clientes
|
|
1880
|
+
|
|
1881
|
+
${agentContextPack.entrypointsClientes.map((cliente) => `- ${cliente.cliente}: ${cliente.arquivos.join(", ")}. Capacidade padrão: ${cliente.capacidadePadrao}. ${cliente.observacao}`).join("\n")}
|
|
1882
|
+
`;
|
|
1883
|
+
}
|
|
1884
|
+
function renderizarInstrucaoClienteSema(cliente, capacidade, agentContextPack) {
|
|
1885
|
+
const guia = agentContextPack.guiaPorCapacidade[capacidade];
|
|
1886
|
+
const tituloCliente = cliente === "generico" ? "agente" : cliente;
|
|
1887
|
+
return `# Sema para ${tituloCliente}
|
|
1888
|
+
|
|
1889
|
+
Este workspace é governado por Sema. Antes de qualquer ação em código, contrato, documentação operacional, workflow, profile ou deploy:
|
|
1890
|
+
|
|
1891
|
+
1. Leia \`${ARQUIVO_SEMA_BOOT}\`.
|
|
1892
|
+
2. Chame Sema. Se MCP estiver disponível, use \`sema_resumo\` e depois \`sema_docs_impacto\` com a intenção declarada.
|
|
1893
|
+
3. Antes de editar código existente, rode \`sema_drift\`.
|
|
1894
|
+
4. Antes de criar ou editar \`.sema\`, use \`sema_exemplos\` e \`sema_inspecionar\`.
|
|
1895
|
+
5. Ao concluir mudança de contrato, rode \`sema_validar\`.
|
|
1896
|
+
6. Antes de finalizar, use \`sema_finalizar_mudanca\` com as docs lidas.
|
|
1897
|
+
|
|
1898
|
+
Capacidade padrão deste cliente: ${capacidade}.
|
|
1899
|
+
Ordem de leitura: ${guia.join(" -> ")}.
|
|
1900
|
+
|
|
1901
|
+
Falha fechada:
|
|
1902
|
+
${agentContextPack.failClosed.map((regra) => `- ${regra}`).join("\n")}
|
|
1903
|
+
|
|
1904
|
+
Idioma:
|
|
1905
|
+
- Responda no idioma do usuário.
|
|
1906
|
+
- Em PT-BR, use acentos, cedilha, pontuação e símbolos normais.
|
|
1907
|
+
- A DSL \`.sema\` pode ser ASCII; texto humano não precisa ser.
|
|
1908
|
+
- Não traduza comandos, rotas, arquivos, símbolos de código nem palavras-chave da DSL.
|
|
1909
|
+
`;
|
|
1910
|
+
}
|
|
1911
|
+
async function sincronizarEntryPointsAgentes(baseProjeto, agentContextPack) {
|
|
1912
|
+
const resultados = [];
|
|
1913
|
+
const registrar = async (relativo, conteudo, substituirLegadoSema = false) => {
|
|
1914
|
+
const destino = path.join(baseProjeto, relativo);
|
|
1915
|
+
const status = await escreverArquivoGerenciadoSema(destino, conteudo, substituirLegadoSema);
|
|
1916
|
+
resultados.push({ caminho: relativo, status });
|
|
1627
1917
|
};
|
|
1918
|
+
await registrar(".github/copilot-instructions.md", renderizarInstrucaoClienteSema("copilot", "media", agentContextPack), true);
|
|
1919
|
+
const clinePath = path.join(baseProjeto, ".clinerules");
|
|
1920
|
+
const clineStat = await statSeguro(clinePath);
|
|
1921
|
+
if (clineStat?.isFile()) {
|
|
1922
|
+
await registrar(".clinerules", renderizarInstrucaoClienteSema("cline", "fraca", agentContextPack), true);
|
|
1923
|
+
}
|
|
1924
|
+
else {
|
|
1925
|
+
await registrar(".clinerules/00-sema.md", renderizarInstrucaoClienteSema("cline", "fraca", agentContextPack), true);
|
|
1926
|
+
}
|
|
1927
|
+
await registrar(".roo/rules/00-sema.md", renderizarInstrucaoClienteSema("roo", "fraca", agentContextPack), true);
|
|
1928
|
+
const opencodeDir = path.join(baseProjeto, ".opencode");
|
|
1929
|
+
const opencodeStat = await statSeguro(opencodeDir);
|
|
1930
|
+
if (opencodeStat?.isDirectory()) {
|
|
1931
|
+
await registrar(".opencode/instructions.md", renderizarInstrucaoClienteSema("opencode", "media", agentContextPack), true);
|
|
1932
|
+
}
|
|
1933
|
+
const criados = resultados.filter((item) => item.status === "criado").map((item) => item.caminho);
|
|
1934
|
+
const atualizados = resultados.filter((item) => item.status === "atualizado").map((item) => item.caminho);
|
|
1935
|
+
const preservados = resultados.filter((item) => item.status === "preservado").map((item) => item.caminho);
|
|
1936
|
+
return { arquivos: resultados, criados, atualizados, preservados };
|
|
1628
1937
|
}
|
|
1629
1938
|
function coletarResumoSemanticoModulo(contexto) {
|
|
1630
1939
|
const { arquivo, modulo, geradoEm, ir, briefing, drift } = contexto;
|
|
@@ -1868,7 +2177,7 @@ function renderizarResumoModuloMarkdown(resumo, modo, guiaPorCapacidade) {
|
|
|
1868
2177
|
"## Guia por capacidade de IA",
|
|
1869
2178
|
"",
|
|
1870
2179
|
];
|
|
1871
|
-
for (const capacidade of
|
|
2180
|
+
for (const capacidade of CAPACIDADES_IA_OPERACIONAIS) {
|
|
1872
2181
|
const guia = guiaPorCapacidade[capacidade];
|
|
1873
2182
|
linhas.push(`### ${capacidade}`);
|
|
1874
2183
|
linhas.push("");
|
|
@@ -1921,20 +2230,20 @@ function criarBriefingMinimo(resumo, modo, tamanho) {
|
|
|
1921
2230
|
}
|
|
1922
2231
|
function criarPromptCurtoModulo(resumo, modo, tamanho, capacidade) {
|
|
1923
2232
|
const resumoTexto = renderizarResumoModuloTexto(resumo, tamanho, modo).trim();
|
|
1924
|
-
return `
|
|
1925
|
-
|
|
1926
|
-
Esta linguagem existe para traduzir
|
|
2233
|
+
return `Você está operando Sema em modo IA-first.
|
|
2234
|
+
|
|
2235
|
+
Esta linguagem existe para traduzir intenção operacional em contrato consumível por IA. Humanos aprovam; agentes operam.
|
|
1927
2236
|
|
|
1928
2237
|
Capacidade alvo: ${capacidade}
|
|
1929
2238
|
Modo da tarefa: ${modo}
|
|
1930
2239
|
|
|
1931
2240
|
Regras:
|
|
1932
|
-
-
|
|
1933
|
-
- preserve a
|
|
1934
|
-
- use este resumo como fonte compacta inicial
|
|
1935
|
-
- se a tarefa pedir mais contexto, suba para \`briefing.min.json\`, \`drift.json\` e depois \`ir.json\`
|
|
1936
|
-
-
|
|
1937
|
-
${resumo.consumerFramework ? "- se for tarefa visual consumer, priorize `appRoutes`, `consumerSurfaces` e `consumerBridges` antes de abrir arquivos
|
|
2241
|
+
- não invente sintaxe nem bloco fora da gramática oficial
|
|
2242
|
+
- preserve a intenção do contrato
|
|
2243
|
+
- use este resumo como fonte compacta inicial
|
|
2244
|
+
- se a tarefa pedir mais contexto, suba para \`briefing.min.json\`, \`drift.json\` e depois \`ir.json\`
|
|
2245
|
+
- não saia editando software vivo sem olhar risco, lacuna e checks sugeridos
|
|
2246
|
+
${resumo.consumerFramework ? "- se for tarefa visual consumer, priorize `appRoutes`, `consumerSurfaces` e `consumerBridges` antes de abrir arquivos aleatórios" : ""}
|
|
1938
2247
|
|
|
1939
2248
|
Contexto compacto:
|
|
1940
2249
|
${resumoTexto}
|
|
@@ -1954,9 +2263,10 @@ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
|
1954
2263
|
"## Entrada canonica para IA",
|
|
1955
2264
|
"",
|
|
1956
2265
|
`- Ordem minima: ${entradaCanonica.ordemLeitura.join(" -> ")}`,
|
|
1957
|
-
`- IA
|
|
1958
|
-
`- IA
|
|
1959
|
-
`- IA
|
|
2266
|
+
`- IA fraca: ${entradaCanonica.porCapacidade.fraca.join(" -> ")}`,
|
|
2267
|
+
`- IA média: ${entradaCanonica.porCapacidade.media.join(" -> ")}`,
|
|
2268
|
+
`- IA forte: ${entradaCanonica.porCapacidade.forte.join(" -> ")}`,
|
|
2269
|
+
`- Aliases: pequena -> fraca; grande -> forte`,
|
|
1960
2270
|
"",
|
|
1961
2271
|
"## Agent Context Pack",
|
|
1962
2272
|
"",
|
|
@@ -1968,7 +2278,7 @@ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
|
1968
2278
|
"## Guia por capacidade",
|
|
1969
2279
|
"",
|
|
1970
2280
|
];
|
|
1971
|
-
for (const capacidade of
|
|
2281
|
+
for (const capacidade of CAPACIDADES_IA_OPERACIONAIS) {
|
|
1972
2282
|
const guia = guiaPorCapacidade[capacidade];
|
|
1973
2283
|
linhas.push(`- ${capacidade}: ${guia.descricao} Artefatos: ${guia.artefatos.join(", ")}.`);
|
|
1974
2284
|
}
|
|
@@ -1988,14 +2298,20 @@ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
|
1988
2298
|
}
|
|
1989
2299
|
function criarEntradaCanonicaProjeto(guiaPorCapacidade) {
|
|
1990
2300
|
const agentContextPack = criarAgentContextPack(guiaPorCapacidade);
|
|
2301
|
+
const fraca = [ARQUIVO_SEMA_BOOT, ARQUIVO_SEMA_SMALL_MODEL, "llms.txt", ARQUIVO_AGENT_CONTEXT_PACK, "SEMA_BRIEF.micro.txt", "SEMA_INDEX.json", "AGENTS.md"];
|
|
2302
|
+
const media = [ARQUIVO_SEMA_BOOT, "llms.txt", ARQUIVO_AGENT_CONTEXT_PACK, "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", "AGENTS.md", "README.md"];
|
|
2303
|
+
const forte = [ARQUIVO_SEMA_BOOT, "llms-full.txt", ARQUIVO_AGENT_CONTEXT_PACK, "SEMA_BRIEF.md", "SEMA_INDEX.json", "AGENTS.md", "README.md"];
|
|
1991
2304
|
return {
|
|
1992
|
-
descricao: "Entrada
|
|
2305
|
+
descricao: "Entrada canônica do repositório para IA. O repo não é human-first; a IA deve começar por esses artefatos antes de abrir código cru.",
|
|
1993
2306
|
ordemLeitura: [...ARQUIVOS_CANONICOS_IA_RAIZ],
|
|
1994
2307
|
porCapacidade: {
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
2308
|
+
fraca,
|
|
2309
|
+
pequena: fraca,
|
|
2310
|
+
media,
|
|
2311
|
+
forte,
|
|
2312
|
+
grande: forte,
|
|
1998
2313
|
},
|
|
2314
|
+
aliasesCapacidade: { ...ALIASES_CAPACIDADE_IA },
|
|
1999
2315
|
docsSuporte: [...DOCUMENTOS_SUPORTE_IA],
|
|
2000
2316
|
agentContextPack,
|
|
2001
2317
|
guiaPorCapacidade,
|
|
@@ -2243,8 +2559,12 @@ async function gerarArquivosResumoModuloIa(contexto, pastaBase) {
|
|
|
2243
2559
|
const resumoCurto = renderizarResumoModuloTexto(resumoSemantico, "curto", "resumo");
|
|
2244
2560
|
const resumoMarkdown = renderizarResumoModuloMarkdown(resumoSemantico, "resumo", guiaPorCapacidade);
|
|
2245
2561
|
const briefingMinimo = criarBriefingMinimo(resumoSemantico, "resumo", "curto");
|
|
2246
|
-
const promptCurto = criarPromptCurtoModulo(resumoSemantico, "mudanca", "curto", "
|
|
2562
|
+
const promptCurto = criarPromptCurtoModulo(resumoSemantico, "mudanca", "curto", "fraca");
|
|
2247
2563
|
const agentContextPack = criarAgentContextPack(guiaPorCapacidade);
|
|
2564
|
+
const semaBoot = renderizarSemaBoot(agentContextPack);
|
|
2565
|
+
const semaSmallModel = renderizarSemaSmallModel(agentContextPack);
|
|
2566
|
+
await writeFile(path.join(pastaBase, ARQUIVO_SEMA_BOOT), semaBoot, "utf8");
|
|
2567
|
+
await writeFile(path.join(pastaBase, ARQUIVO_SEMA_SMALL_MODEL), semaSmallModel, "utf8");
|
|
2248
2568
|
await writeFile(path.join(pastaBase, "agent-context-pack.json"), `${JSON.stringify(agentContextPack, null, 2)}\n`, "utf8");
|
|
2249
2569
|
await writeFile(path.join(pastaBase, "resumo.micro.txt"), resumoMicro, "utf8");
|
|
2250
2570
|
await writeFile(path.join(pastaBase, "resumo.curto.txt"), resumoCurto, "utf8");
|
|
@@ -2252,7 +2572,7 @@ async function gerarArquivosResumoModuloIa(contexto, pastaBase) {
|
|
|
2252
2572
|
await writeFile(path.join(pastaBase, "briefing.min.json"), `${JSON.stringify(briefingMinimo, null, 2)}\n`, "utf8");
|
|
2253
2573
|
await writeFile(path.join(pastaBase, "prompt-curto.txt"), promptCurto, "utf8");
|
|
2254
2574
|
return {
|
|
2255
|
-
artefatosCompactos: ["agent-context-pack.json", "resumo.micro.txt", "resumo.curto.txt", "resumo.md", "briefing.min.json", "prompt-curto.txt"],
|
|
2575
|
+
artefatosCompactos: [ARQUIVO_SEMA_BOOT, ARQUIVO_SEMA_SMALL_MODEL, "agent-context-pack.json", "resumo.micro.txt", "resumo.curto.txt", "resumo.md", "briefing.min.json", "prompt-curto.txt"],
|
|
2256
2576
|
guiaPorCapacidade,
|
|
2257
2577
|
};
|
|
2258
2578
|
}
|
|
@@ -2295,6 +2615,9 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
2295
2615
|
: path.resolve(baseProjeto, ".tmp", "sema-resumo");
|
|
2296
2616
|
await mkdir(pastaSaida, { recursive: true });
|
|
2297
2617
|
const semaBrief = renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade);
|
|
2618
|
+
const semaBoot = renderizarSemaBoot(agentContextPack);
|
|
2619
|
+
const semaSmallModel = renderizarSemaSmallModel(agentContextPack);
|
|
2620
|
+
const docAgentesCapacidade = renderizarDocumentoAgentesPorCapacidade(agentContextPack);
|
|
2298
2621
|
const indexJson = {
|
|
2299
2622
|
comando: "resumo-projeto",
|
|
2300
2623
|
geradoEm,
|
|
@@ -2314,7 +2637,7 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
2314
2637
|
`MODULOS: ${modulos.length}`,
|
|
2315
2638
|
`MODO_CODIGO: ${modoVerificacaoCodigo}`,
|
|
2316
2639
|
`FONTES_CONCLUSAO: ${resumirListaTexto(fontesConclusao, 4)}`,
|
|
2317
|
-
`ENTRADA_IA: ${entradaCanonica.porCapacidade.
|
|
2640
|
+
`ENTRADA_IA: ${entradaCanonica.porCapacidade.fraca.join(" -> ")}`,
|
|
2318
2641
|
`TOP_MODULOS: ${resumirListaTexto(modulos.map((modulo) => modulo.modulo), 3)}`,
|
|
2319
2642
|
`TOP_RISCOS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.riscosPrincipais)), 3)}`,
|
|
2320
2643
|
`TOP_LACUNAS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.lacunas)), 3)}`,
|
|
@@ -2341,16 +2664,20 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
2341
2664
|
"",
|
|
2342
2665
|
].join("\n");
|
|
2343
2666
|
await writeFile(path.join(pastaSaida, "SEMA_BRIEF.md"), semaBrief, "utf8");
|
|
2667
|
+
await writeFile(path.join(pastaSaida, ARQUIVO_SEMA_BOOT), semaBoot, "utf8");
|
|
2668
|
+
await writeFile(path.join(pastaSaida, ARQUIVO_SEMA_SMALL_MODEL), semaSmallModel, "utf8");
|
|
2344
2669
|
await writeFile(path.join(pastaSaida, "SEMA_BRIEF.micro.txt"), micro, "utf8");
|
|
2345
2670
|
await writeFile(path.join(pastaSaida, "SEMA_BRIEF.curto.txt"), curto, "utf8");
|
|
2346
2671
|
await writeFile(path.join(pastaSaida, "SEMA_INDEX.json"), `${JSON.stringify(indexJson, null, 2)}\n`, "utf8");
|
|
2347
2672
|
await writeFile(path.join(pastaSaida, ARQUIVO_AGENT_CONTEXT_PACK), `${JSON.stringify(agentContextPack, null, 2)}\n`, "utf8");
|
|
2673
|
+
await mkdir(path.dirname(path.join(pastaSaida, ARQUIVO_DOC_AGENTES_CAPACIDADE)), { recursive: true });
|
|
2674
|
+
await writeFile(path.join(pastaSaida, ARQUIVO_DOC_AGENTES_CAPACIDADE), docAgentesCapacidade, "utf8");
|
|
2348
2675
|
return {
|
|
2349
2676
|
geradoEm,
|
|
2350
2677
|
baseProjeto,
|
|
2351
2678
|
pastaSaida,
|
|
2352
2679
|
modoVerificacaoCodigo,
|
|
2353
|
-
artefatos: ["SEMA_BRIEF.md", "SEMA_BRIEF.micro.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", ARQUIVO_AGENT_CONTEXT_PACK],
|
|
2680
|
+
artefatos: [ARQUIVO_SEMA_BOOT, ARQUIVO_SEMA_SMALL_MODEL, "SEMA_BRIEF.md", "SEMA_BRIEF.micro.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", ARQUIVO_AGENT_CONTEXT_PACK, ARQUIVO_DOC_AGENTES_CAPACIDADE],
|
|
2354
2681
|
modulos,
|
|
2355
2682
|
guiaPorCapacidade,
|
|
2356
2683
|
};
|
|
@@ -2378,8 +2705,10 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
|
|
|
2378
2705
|
|
|
2379
2706
|
## Arquivos gerados neste pacote
|
|
2380
2707
|
|
|
2381
|
-
- \`agent-context-pack.json\`
|
|
2382
|
-
- \`
|
|
2708
|
+
- \`agent-context-pack.json\`
|
|
2709
|
+
- \`${ARQUIVO_SEMA_BOOT}\`
|
|
2710
|
+
- \`${ARQUIVO_SEMA_SMALL_MODEL}\`
|
|
2711
|
+
- \`resumo.micro.txt\`
|
|
2383
2712
|
- \`resumo.curto.txt\`
|
|
2384
2713
|
- \`resumo.md\`
|
|
2385
2714
|
- \`briefing.min.json\`
|
|
@@ -2393,38 +2722,48 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
|
|
|
2393
2722
|
|
|
2394
2723
|
## Fluxo recomendado para o agente
|
|
2395
2724
|
|
|
2396
|
-
Antes de escolher arquivo de
|
|
2397
|
-
|
|
2398
|
-
### IA
|
|
2399
|
-
|
|
2400
|
-
1. Ler
|
|
2401
|
-
2. Ler
|
|
2402
|
-
3. Ler \`
|
|
2403
|
-
4.
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2725
|
+
Antes de escolher arquivo de código, leia \`${ARQUIVO_SEMA_BOOT}\` e \`agent-context-pack.json\`. Eles declaram regras obrigatórias, proibições, prioridades, idioma humano e quando abrir texto bruto como \`AGENTS.md\`, \`exemplos/\`, docs e contratos.
|
|
2726
|
+
|
|
2727
|
+
### IA fraca, gratuita ou com pouca disciplina
|
|
2728
|
+
|
|
2729
|
+
1. Ler \`${ARQUIVO_SEMA_BOOT}\`.
|
|
2730
|
+
2. Ler \`${ARQUIVO_SEMA_SMALL_MODEL}\`.
|
|
2731
|
+
3. Ler \`agent-context-pack.json\`.
|
|
2732
|
+
4. Ler \`resumo.micro.txt\`.
|
|
2733
|
+
5. Ler \`briefing.min.json\`.
|
|
2734
|
+
6. Se ainda couber contexto, ler \`resumo.curto.txt\`.
|
|
2735
|
+
|
|
2736
|
+
### IA média
|
|
2737
|
+
|
|
2738
|
+
1. Ler \`${ARQUIVO_SEMA_BOOT}\`.
|
|
2739
|
+
2. Ler \`agent-context-pack.json\`.
|
|
2740
|
+
3. Ler \`resumo.curto.txt\`.
|
|
2741
|
+
4. Ler \`briefing.min.json\`.
|
|
2742
|
+
5. Ler \`drift.json\`.
|
|
2743
|
+
6. Se precisar, subir para \`resumo.md\`.
|
|
2744
|
+
|
|
2745
|
+
### IA forte ou com tool use
|
|
2746
|
+
|
|
2747
|
+
1. Ler \`${ARQUIVO_SEMA_BOOT}\`.
|
|
2748
|
+
2. Ler \`agent-context-pack.json\`.
|
|
2749
|
+
3. Ler \`README.md\`.
|
|
2750
|
+
4. Ler \`resumo.md\`.
|
|
2751
|
+
5. Ler \`briefing.json\`.
|
|
2752
|
+
6. Ler \`drift.json\`.
|
|
2753
|
+
7. Só depois abrir \`ir.json\` e \`ast.json\`.
|
|
2754
|
+
|
|
2755
|
+
## Idioma humano
|
|
2756
|
+
|
|
2757
|
+
- Responda no idioma do usuário.
|
|
2758
|
+
- Em PT-BR, use acentos, cedilha, pontuação e símbolos normais.
|
|
2759
|
+
- A DSL \`.sema\` pode ser ASCII; texto humano não precisa ser.
|
|
2421
2760
|
|
|
2422
2761
|
## Texto bruto sob demanda
|
|
2423
2762
|
|
|
2424
|
-
- Abra \`AGENTS.md\` antes de editar
|
|
2763
|
+
- Abra \`AGENTS.md\` antes de editar código, contrato, docs operacionais, release ou deploy.
|
|
2425
2764
|
- Abra \`exemplos/\` antes de criar ou corrigir sintaxe \`.sema\`.
|
|
2426
|
-
- Abra \`docs/sintaxe.md\` quando exemplos
|
|
2427
|
-
- Abra \`contratos/\` antes de qualquer
|
|
2765
|
+
- Abra \`docs/sintaxe.md\` quando exemplos não bastarem para resolver a gramática.
|
|
2766
|
+
- Abra \`contratos/\` antes de qualquer implementação ou mudança de comportamento.
|
|
2428
2767
|
|
|
2429
2768
|
## Fechamento
|
|
2430
2769
|
|
|
@@ -4335,6 +4674,13 @@ const REQUISITOS_PROFILE = {
|
|
|
4335
4674
|
{ id: "incerteza_e_limite", descricao: "declara incerteza, lacunas e limites da conclusao", termos: [/incerteza|lacuna|limite/i, /conclusao|afirmacao/i], obrigatorio: true },
|
|
4336
4675
|
{ id: "reprodutibilidade", descricao: "preserva protocolo, dados e reproducibilidade", termos: [/protocolo|dataset|dados/i, /reprodut|replic/i], obrigatorio: false },
|
|
4337
4676
|
],
|
|
4677
|
+
conversas: [
|
|
4678
|
+
{ id: "tom_e_persona", descricao: "declara tom, formalidade, persona e intensidade persuasiva", termos: [/tom|persona|voz/i, /formalidade|persuasiv|comercial|serio/i], obrigatorio: true },
|
|
4679
|
+
{ id: "estado_cliente", descricao: "modela etapa, intencao, sentimento, objecoes e memoria curta", termos: [/etapa|estado|intencao/i, /sentimento|objec|historico|memoria/i], obrigatorio: true },
|
|
4680
|
+
{ id: "limites_comerciais", descricao: "bloqueia promessas, preco, prazo, garantia e insistencia sem base", termos: [/promessa|preco|prazo|garantia|desconto/i, /forbidden|proibid|bloque|sem_base|nao autorizado/i], obrigatorio: true },
|
|
4681
|
+
{ id: "escalacao_humana", descricao: "declara quando transferir para humano", termos: [/escalar_humano|escalacao|humano|atendente/i, /irritado|juridico|cancelamento|reclamacao/i], obrigatorio: true },
|
|
4682
|
+
{ id: "resposta_validada", descricao: "valida resposta, proxima acao e aderencia ao tom antes de enviar", termos: [/validar_resposta|validar resposta|resposta/i, /proxima_acao|proxima acao|cta|aderente_ao_tom/i], obrigatorio: true },
|
|
4683
|
+
],
|
|
4338
4684
|
};
|
|
4339
4685
|
const REQUISITOS_PROFILE_COMUNS = [
|
|
4340
4686
|
{
|
|
@@ -4365,6 +4711,13 @@ const ALIASES_PROFILE = {
|
|
|
4365
4711
|
juridico: "legal",
|
|
4366
4712
|
research: "research",
|
|
4367
4713
|
pesquisa: "research",
|
|
4714
|
+
conversas: "conversas",
|
|
4715
|
+
conversa: "conversas",
|
|
4716
|
+
atendimento: "conversas",
|
|
4717
|
+
atendimento_conversacional: "conversas",
|
|
4718
|
+
bot: "conversas",
|
|
4719
|
+
chatbot: "conversas",
|
|
4720
|
+
chat: "conversas",
|
|
4368
4721
|
};
|
|
4369
4722
|
function normalizarProfileSemantico(valor) {
|
|
4370
4723
|
if (!valor) {
|
|
@@ -4390,6 +4743,7 @@ const PRESETS_PROFILE = {
|
|
|
4390
4743
|
legal: ["lgpd", "contrato", "dpa", "termos_uso", "privacidade", "due_diligence", "compliance"],
|
|
4391
4744
|
research: ["rapida", "tecnica", "decisoria", "critica"],
|
|
4392
4745
|
game: ["casual", "arcade", "rpg", "economia", "playtest"],
|
|
4746
|
+
conversas: ["atendimento", "vendas", "suporte", "qualificacao", "retencao", "cobranca"],
|
|
4393
4747
|
};
|
|
4394
4748
|
const CAPABILITY_MATRIX_GOVERNANCA = {
|
|
4395
4749
|
author: {
|
|
@@ -4497,6 +4851,21 @@ const CAPABILITY_MATRIX_GOVERNANCA = {
|
|
|
4497
4851
|
],
|
|
4498
4852
|
rulePacksSugeridos: ["playtest", "economy-balance", "progression"],
|
|
4499
4853
|
},
|
|
4854
|
+
conversas: {
|
|
4855
|
+
profile: "conversas",
|
|
4856
|
+
detectaLiteral: true,
|
|
4857
|
+
detectaSemantico: "parcial",
|
|
4858
|
+
detectaOrdemExecucao: "parcial",
|
|
4859
|
+
detectaDriftReal: "parcial",
|
|
4860
|
+
validaArtefatoReal: true,
|
|
4861
|
+
interpretaNegacao: true,
|
|
4862
|
+
confianca: "media",
|
|
4863
|
+
limites: [
|
|
4864
|
+
"validacao de resposta depende do historico e politicas comerciais enviados",
|
|
4865
|
+
"handoff humano precisa de integracao do runtime de atendimento para ser executado",
|
|
4866
|
+
],
|
|
4867
|
+
rulePacksSugeridos: ["conversation-safety", "sales-conversation", "support-handoff"],
|
|
4868
|
+
},
|
|
4500
4869
|
};
|
|
4501
4870
|
const RULE_PACKS_SEMA = [
|
|
4502
4871
|
{
|
|
@@ -4609,6 +4978,36 @@ const RULE_PACKS_SEMA = [
|
|
|
4609
4978
|
monetizacao: "cloud",
|
|
4610
4979
|
status: "planejado",
|
|
4611
4980
|
},
|
|
4981
|
+
{
|
|
4982
|
+
id: "conversation-safety",
|
|
4983
|
+
nome: "Customer Conversation Safety",
|
|
4984
|
+
categoria: "oss",
|
|
4985
|
+
profiles: ["conversas"],
|
|
4986
|
+
maturidadeMinima: "prototype",
|
|
4987
|
+
controles: ["forbidden_claims", "tone_policy", "customer_state", "human_handoff", "audit_trace"],
|
|
4988
|
+
monetizacao: "aberto",
|
|
4989
|
+
status: "base",
|
|
4990
|
+
},
|
|
4991
|
+
{
|
|
4992
|
+
id: "sales-conversation",
|
|
4993
|
+
nome: "Sales Conversation Guardrails",
|
|
4994
|
+
categoria: "premium",
|
|
4995
|
+
profiles: ["conversas"],
|
|
4996
|
+
maturidadeMinima: "production",
|
|
4997
|
+
controles: ["objection_handling", "authorized_offer", "honest_cta", "no_fake_discount", "promise_limits"],
|
|
4998
|
+
monetizacao: "cloud",
|
|
4999
|
+
status: "planejado",
|
|
5000
|
+
},
|
|
5001
|
+
{
|
|
5002
|
+
id: "support-handoff",
|
|
5003
|
+
nome: "Support Handoff",
|
|
5004
|
+
categoria: "premium",
|
|
5005
|
+
profiles: ["conversas", "ops"],
|
|
5006
|
+
maturidadeMinima: "production",
|
|
5007
|
+
controles: ["escalation_trigger", "ticket_context", "angry_customer", "legal_risk", "handoff_reason"],
|
|
5008
|
+
monetizacao: "cloud",
|
|
5009
|
+
status: "planejado",
|
|
5010
|
+
},
|
|
4612
5011
|
{
|
|
4613
5012
|
id: "event-driven",
|
|
4614
5013
|
nome: "Event Driven Workflow",
|
|
@@ -4746,38 +5145,56 @@ const REQUISITOS_PRESET_PROFILE = {
|
|
|
4746
5145
|
{ id: "rollback_criterio_recuperacao", descricao: "rollback declara criterio objetivo de recuperacao", termos: [/rollback/i, /criterio|gatilho/i, /recuper/i], obrigatorio: true, severidade: "blocking" },
|
|
4747
5146
|
],
|
|
4748
5147
|
lgpd: [
|
|
4749
|
-
{ id: "lgpd_matriz_dados", descricao: "LGPD declara dado, finalidade, base legal e retencao", termos: [/dado|titular/i, /finalidade/i, /base legal/i, /retencao|
|
|
5148
|
+
{ id: "lgpd_matriz_dados", descricao: "LGPD declara dado, finalidade, base legal e retencao", termos: [/dado|titular/i, /finalidade/i, /base legal/i, /retencao|retenção/i], obrigatorio: true, severidade: "critical" },
|
|
4750
5149
|
],
|
|
4751
5150
|
contrato: [
|
|
4752
|
-
{ id: "contrato_clausulas_nucleo", descricao: "contrato declara partes, objeto, obrigacoes e rescisao", termos: [/partes/i, /objeto/i, /obrigac|obriga
|
|
5151
|
+
{ id: "contrato_clausulas_nucleo", descricao: "contrato declara partes, objeto, obrigacoes e rescisao", termos: [/partes/i, /objeto/i, /obrigac|obrigaç/i, /rescis/i], obrigatorio: true, severidade: "blocking" },
|
|
4753
5152
|
],
|
|
4754
5153
|
dpa: [
|
|
4755
5154
|
{ id: "dpa_operador_controlador", descricao: "DPA declara controlador, operador, dados e subprocessadores", termos: [/controlador/i, /operador/i, /subprocess/i, /dados/i], obrigatorio: true, severidade: "critical" },
|
|
4756
5155
|
],
|
|
4757
5156
|
termos_uso: [
|
|
4758
|
-
{ id: "termos_uso_limites", descricao: "termos de uso declaram uso permitido, proibicoes e limitacao", termos: [/uso permitido/i, /proibid|vedad/i, /limitacao|
|
|
5157
|
+
{ id: "termos_uso_limites", descricao: "termos de uso declaram uso permitido, proibicoes e limitacao", termos: [/uso permitido/i, /proibid|vedad/i, /limitacao|limitação/i], obrigatorio: true, severidade: "blocking" },
|
|
4759
5158
|
],
|
|
4760
5159
|
privacidade: [
|
|
4761
5160
|
{ id: "privacidade_dados_direitos", descricao: "privacidade declara dados, finalidade, direitos e contato", termos: [/dados/i, /finalidade/i, /direitos/i, /contato/i], obrigatorio: true, severidade: "blocking" },
|
|
4762
5161
|
],
|
|
4763
5162
|
due_diligence: [
|
|
4764
|
-
{ id: "due_diligence_risco_evidencia", descricao: "due diligence declara risco, evidencia e pendencias", termos: [/risco/i, /evidencia|
|
|
5163
|
+
{ id: "due_diligence_risco_evidencia", descricao: "due diligence declara risco, evidencia e pendencias", termos: [/risco/i, /evidencia|evidência/i, /pendenc|pendênc/i], obrigatorio: true, severidade: "blocking" },
|
|
4765
5164
|
],
|
|
4766
5165
|
compliance: [
|
|
4767
|
-
{ id: "compliance_controle_auditoria", descricao: "compliance declara controles, auditoria e responsavel", termos: [/controle/i, /auditoria/i, /responsavel|
|
|
5166
|
+
{ id: "compliance_controle_auditoria", descricao: "compliance declara controles, auditoria e responsavel", termos: [/controle/i, /auditoria/i, /responsavel|responsável/i], obrigatorio: true, severidade: "blocking" },
|
|
4768
5167
|
],
|
|
4769
5168
|
decisoria: [
|
|
4770
|
-
{ id: "research_matriz_decisao", descricao: "pesquisa decisoria declara criterio, peso e alternativa", termos: [/criterio|
|
|
5169
|
+
{ id: "research_matriz_decisao", descricao: "pesquisa decisoria declara criterio, peso e alternativa", termos: [/criterio|critério/i, /peso/i, /alternativa/i], obrigatorio: true, severidade: "blocking" },
|
|
4771
5170
|
],
|
|
4772
5171
|
critica: [
|
|
4773
|
-
{ id: "research_contraditorio", descricao: "pesquisa critica tenta derrubar a propria conclusao", termos: [/contradit|contra.?evidencia|contra.?
|
|
5172
|
+
{ id: "research_contraditorio", descricao: "pesquisa critica tenta derrubar a propria conclusao", termos: [/contradit|contra.?evidencia|contra.?evidência/i, /hipotese|hipótese|conclusao|conclusão/i], obrigatorio: true, severidade: "blocking" },
|
|
4774
5173
|
],
|
|
4775
5174
|
playtest: [
|
|
4776
|
-
{ id: "game_playtest_temporal", descricao: "playtest declara primeiros segundos, primeiro minuto e tensao", termos: [/primeiros? 10 segundos|10s/i, /1 minuto|um minuto/i, /tensao|
|
|
5175
|
+
{ id: "game_playtest_temporal", descricao: "playtest declara primeiros segundos, primeiro minuto e tensao", termos: [/primeiros? 10 segundos|10s/i, /1 minuto|um minuto/i, /tensao|tensão/i], obrigatorio: true, severidade: "blocking" },
|
|
4777
5176
|
],
|
|
4778
5177
|
economia: [
|
|
4779
5178
|
{ id: "game_economia_balanceada", descricao: "economia declara moeda, fonte, gasto e exploit", termos: [/moeda|economia/i, /fonte/i, /gasto|sink/i, /exploit/i], obrigatorio: true, severidade: "blocking" },
|
|
4780
5179
|
],
|
|
5180
|
+
atendimento: [
|
|
5181
|
+
{ id: "conversas_atendimento_estado", descricao: "atendimento declara estado do cliente e proxima acao", termos: [/estado|etapa|sentimento/i, /proxima_acao|proxima acao|encaminhar|resolver/i], obrigatorio: true, severidade: "blocking" },
|
|
5182
|
+
],
|
|
5183
|
+
vendas: [
|
|
5184
|
+
{ id: "conversas_vendas_objecao_cta", descricao: "vendas trata objecao e CTA sem promessa falsa", termos: [/objec|duvida|interesse|dor/i, /cta|proxima_acao|proxima acao|agendar|diagnostico|proposta/i], obrigatorio: true, severidade: "blocking" },
|
|
5185
|
+
],
|
|
5186
|
+
suporte: [
|
|
5187
|
+
{ id: "conversas_suporte_escalacao", descricao: "suporte declara problema, solucao e escalacao humana", termos: [/problema|erro|suporte|chamado/i, /escalar|humano|atendente|ticket/i], obrigatorio: true, severidade: "blocking" },
|
|
5188
|
+
],
|
|
5189
|
+
qualificacao: [
|
|
5190
|
+
{ id: "conversas_qualificacao_criterios", descricao: "qualificacao declara criterios e dados minimos do lead", termos: [/qualifica|lead|perfil/i, /criterio|orcamento|prazo|necessidade/i], obrigatorio: true, severidade: "blocking" },
|
|
5191
|
+
],
|
|
5192
|
+
retencao: [
|
|
5193
|
+
{ id: "conversas_retencao_limites", descricao: "retencao declara motivo, proposta autorizada e limites", termos: [/retencao|cancelamento|motivo/i, /autorizad|limite|oferta|proposta/i], obrigatorio: true, severidade: "blocking" },
|
|
5194
|
+
],
|
|
5195
|
+
cobranca: [
|
|
5196
|
+
{ id: "conversas_cobranca_cuidado", descricao: "cobranca declara valor, vencimento, tom e escalacao", termos: [/cobranca|valor|vencimento/i, /tom|respeitoso|humano|escalar/i], obrigatorio: true, severidade: "critical" },
|
|
5197
|
+
],
|
|
4781
5198
|
};
|
|
4782
5199
|
function normalizarPresetProfile(profile, valor) {
|
|
4783
5200
|
if (!valor)
|
|
@@ -4799,6 +5216,16 @@ function normalizarPresetProfile(profile, valor) {
|
|
|
4799
5216
|
modulo_codigo: "modulo",
|
|
4800
5217
|
seguranca: "security",
|
|
4801
5218
|
seguranca_codigo: "security",
|
|
5219
|
+
atendimento_cliente: "atendimento",
|
|
5220
|
+
conversa_atendimento: "atendimento",
|
|
5221
|
+
comercial: "vendas",
|
|
5222
|
+
venda: "vendas",
|
|
5223
|
+
conversa_vendas: "vendas",
|
|
5224
|
+
suporte_cliente: "suporte",
|
|
5225
|
+
qualificar: "qualificacao",
|
|
5226
|
+
qualificacao_lead: "qualificacao",
|
|
5227
|
+
retencao_cliente: "retencao",
|
|
5228
|
+
cobrar: "cobranca",
|
|
4802
5229
|
};
|
|
4803
5230
|
const preset = alias[chave] ?? chave;
|
|
4804
5231
|
return PRESETS_PROFILE[profile].includes(preset) ? preset : null;
|
|
@@ -4808,6 +5235,9 @@ function moduloCombinaComProfile(modulo, caminho, profile) {
|
|
|
4808
5235
|
if (profile === "workflow") {
|
|
4809
5236
|
return /workflow|n8n|orquestracao/.test(alvo);
|
|
4810
5237
|
}
|
|
5238
|
+
if (profile === "conversas") {
|
|
5239
|
+
return /conversas|conversa|atendimento|chatbot|bot/.test(alvo);
|
|
5240
|
+
}
|
|
4811
5241
|
return alvo.includes(profile);
|
|
4812
5242
|
}
|
|
4813
5243
|
function severidadeRequisitoProfile(requisito, profile, maturidade) {
|
|
@@ -4941,8 +5371,8 @@ function selecionarRulePacksProfile(profile) {
|
|
|
4941
5371
|
function contratoProibeTermoProfile(contrato, termo) {
|
|
4942
5372
|
const escaped = termo.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4943
5373
|
const padroes = [
|
|
4944
|
-
new RegExp(`(forbidden|proibid|vedad|nao usar|
|
|
4945
|
-
new RegExp(`${escaped}[^\\n]{0,80}(forbidden|proibid|vedad|nao permitido|
|
|
5374
|
+
new RegExp(`(forbidden|proibid|vedad|nao usar|não usar|sem)\\s+[^\\n]{0,80}${escaped}`, "i"),
|
|
5375
|
+
new RegExp(`${escaped}[^\\n]{0,80}(forbidden|proibid|vedad|nao permitido|não permitido|nao usar|não usar)`, "i"),
|
|
4946
5376
|
];
|
|
4947
5377
|
return padroes.some((padrao) => padrao.test(contrato));
|
|
4948
5378
|
}
|
|
@@ -5009,8 +5439,8 @@ function localizarRegexProfile(texto, regex) {
|
|
|
5009
5439
|
function termoNegadoNoArtefato(texto, indice, tamanho) {
|
|
5010
5440
|
const antes = texto.slice(Math.max(0, indice - 90), indice);
|
|
5011
5441
|
const depois = texto.slice(indice + tamanho, Math.min(texto.length, indice + tamanho + 90));
|
|
5012
|
-
const negacaoAntes = /\b(?:sem|ausente|ausencia|
|
|
5013
|
-
const negacaoDepois = /^[\s\S]{0,80}\b(?:ausente|ausentes|ausencia|
|
|
5442
|
+
const negacaoAntes = /\b(?:sem|ausente|ausencia|ausência|faltando|falta|faltam|inexistente|indefinid[ao]s?|pendente|nao\s+(?:ha|há|define|declara|especifica|possui|tem|existe|inclui|contem|contém|configura|implementa|mapeia|separa|informa|descreve|testa|valida)|não\s+(?:ha|há|define|declara|especifica|possui|tem|existe|inclui|contem|contém|configura|implementa|mapeia|separa|informa|descreve|testa|valida))\b[\s\S]{0,80}$/i;
|
|
5443
|
+
const negacaoDepois = /^[\s\S]{0,80}\b(?:ausente|ausentes|ausencia|ausência|inexistente|indefinid[ao]s?|faltando|pendente|nao\s+(?:definid[ao]|declarad[ao]|especificad[ao]|testad[ao]|valid[ao]|implementad[ao]|configurad[ao]|mapead[ao])|não\s+(?:definid[ao]|declarad[ao]|especificad[ao]|testad[ao]|valid[ao]|implementad[ao]|configurad[ao]|mapead[ao]))\b/i;
|
|
5014
5444
|
return negacaoAntes.test(antes) || negacaoDepois.test(depois);
|
|
5015
5445
|
}
|
|
5016
5446
|
function avaliarPresencaPositivaArtefato(texto, regex) {
|
|
@@ -5236,39 +5666,39 @@ function avaliarArtefatoOpsProfile(artefato, preset) {
|
|
|
5236
5666
|
const checks = [
|
|
5237
5667
|
{ id: "ops_runbook_artefato", descricao: "plano operacional contem runbook", regex: /runbook|passo a passo|procedimento/i, sugestao: "adicione runbook executavel com passos, dono e criterio de parada." },
|
|
5238
5668
|
{ id: "ops_rollback_artefato", descricao: "plano operacional contem rollback", regex: /rollback|reverter|revers/i, sugestao: "adicione comando/criterio de rollback." },
|
|
5239
|
-
{ id: "ops_healthcheck_artefato", descricao: "plano operacional contem healthcheck", regex: /healthcheck|healthz|smoke|verificacao live|
|
|
5240
|
-
{ id: "ops_responsavel_artefato", descricao: "plano operacional declara responsavel/oncall", regex: /responsavel|
|
|
5669
|
+
{ id: "ops_healthcheck_artefato", descricao: "plano operacional contem healthcheck", regex: /healthcheck|healthz|smoke|verificacao live|verificação live/i, sugestao: "declare endpoint, comando ou metrica que prova recuperacao." },
|
|
5670
|
+
{ id: "ops_responsavel_artefato", descricao: "plano operacional declara responsavel/oncall", regex: /responsavel|responsável|owner|oncall|dono/i, sugestao: "declare responsavel operacional, oncall ou dono da mudanca." },
|
|
5241
5671
|
{ id: "ops_comunicacao_artefato", descricao: "plano operacional contem comunicacao", regex: /comunic|avisar|status page|cliente/i, severidade: "warning", sugestao: "adicione quando e quem comunicar." },
|
|
5242
5672
|
];
|
|
5243
5673
|
const achados = validarTermosObrigatoriosArtefato(artefato, checks);
|
|
5244
5674
|
if ((preset === "migration" || preset === "critical") && !avaliarPresencaPositivaArtefato(artefato, /backup|snapshot|revers/i).atendido) {
|
|
5245
5675
|
achados.push(criarAchadoArtefatoProfile("ops_migration_sem_reversibilidade", "migration/critical exige reversibilidade comprovada", false, "critical", undefined, "declare backup, snapshot, down migration ou estrategia manual testada."));
|
|
5246
5676
|
}
|
|
5247
|
-
if (preset === "rollback" && !avaliarPresencaPositivaArtefato(artefato, /criterio|
|
|
5677
|
+
if (preset === "rollback" && !avaliarPresencaPositivaArtefato(artefato, /criterio|critério|gatilho|recuper/i).atendido) {
|
|
5248
5678
|
achados.push(criarAchadoArtefatoProfile("ops_rollback_sem_criterio_recuperacao", "rollback exige criterio objetivo de recuperacao", false, "blocking", undefined, "declare gatilho de rollback e criterio verificavel de recuperacao."));
|
|
5249
5679
|
}
|
|
5250
5680
|
return achados;
|
|
5251
5681
|
}
|
|
5252
5682
|
function avaliarArtefatoLegalProfile(artefato, preset) {
|
|
5253
5683
|
const achados = [];
|
|
5254
|
-
const pareceFinal = /parecer final|opiniao definitiva|
|
|
5255
|
-
const temRevisaoHumana = avaliarPresencaPositivaArtefato(artefato, /revisao humana|
|
|
5256
|
-
const temAvisoNaoParecer = /nao e parecer|
|
|
5684
|
+
const pareceFinal = /parecer final|opiniao definitiva|opinião definitiva|conclusao juridica definitiva|conclusão jurÃdica definitiva/i.test(artefato);
|
|
5685
|
+
const temRevisaoHumana = avaliarPresencaPositivaArtefato(artefato, /revisao humana|revisão humana|advogado|minuta|rascunho|preliminar/i).atendido;
|
|
5686
|
+
const temAvisoNaoParecer = /nao e parecer|não é parecer/i.test(artefato);
|
|
5257
5687
|
const temFreioHumano = temRevisaoHumana || temAvisoNaoParecer;
|
|
5258
5688
|
if (pareceFinal && !temFreioHumano) {
|
|
5259
|
-
achados.push(criarAchadoArtefatoProfile("legal_parecer_final_sem_revisao", "documento legal parece parecer final sem revisao humana obrigatoria", false, "critical", trechoRegexProfile(artefato, /parecer final|opiniao definitiva|
|
|
5689
|
+
achados.push(criarAchadoArtefatoProfile("legal_parecer_final_sem_revisao", "documento legal parece parecer final sem revisao humana obrigatoria", false, "critical", trechoRegexProfile(artefato, /parecer final|opiniao definitiva|opinião definitiva/i), "marque como minuta/preliminar e exija revisao humana por profissional habilitado."));
|
|
5260
5690
|
}
|
|
5261
5691
|
if (preset === "lgpd") {
|
|
5262
5692
|
achados.push(...validarTermosObrigatoriosArtefato(artefato, [
|
|
5263
5693
|
{ id: "legal_lgpd_base_finalidade", descricao: "artefato LGPD declara base legal e finalidade", regex: /base legal[\s\S]{0,160}finalidade|finalidade[\s\S]{0,160}base legal/i, severidade: "critical", sugestao: "inclua matriz dado -> finalidade -> base legal." },
|
|
5264
|
-
{ id: "legal_lgpd_retencao_direitos", descricao: "artefato LGPD declara retencao e direitos do titular", regex: /retencao|
|
|
5694
|
+
{ id: "legal_lgpd_retencao_direitos", descricao: "artefato LGPD declara retencao e direitos do titular", regex: /retencao|retenção/i, severidade: "blocking", sugestao: "inclua retencao, descarte e direitos do titular." },
|
|
5265
5695
|
]));
|
|
5266
5696
|
}
|
|
5267
5697
|
if (preset === "privacidade") {
|
|
5268
5698
|
achados.push(...validarTermosObrigatoriosArtefato(artefato, [
|
|
5269
5699
|
{ id: "legal_privacidade_dados_finalidade", descricao: "politica de privacidade declara dados tratados e finalidade", regex: /dados?[\s\S]{0,120}finalidade|finalidade[\s\S]{0,120}dados?/i, severidade: "critical", sugestao: "inclua dados coletados/tratados e finalidade de cada uso." },
|
|
5270
|
-
{ id: "legal_privacidade_base_legal", descricao: "politica de privacidade declara base legal", regex: /base legal|consentimento|legitimo interesse|
|
|
5271
|
-
{ id: "legal_privacidade_retencao", descricao: "politica de privacidade declara retencao/descarte", regex: /retencao|
|
|
5700
|
+
{ id: "legal_privacidade_base_legal", descricao: "politica de privacidade declara base legal", regex: /base legal|consentimento|legitimo interesse|legÃtimo interesse|execucao de contrato|execução de contrato/i, severidade: "critical", sugestao: "declare base legal por finalidade." },
|
|
5701
|
+
{ id: "legal_privacidade_retencao", descricao: "politica de privacidade declara retencao/descarte", regex: /retencao|retenção|descarte|prazo de guarda/i, severidade: "blocking", sugestao: "declare prazo de retencao e descarte." },
|
|
5272
5702
|
{ id: "legal_privacidade_direitos_contato", descricao: "politica de privacidade declara direitos do titular e contato/DPO", regex: /direitos? do titular[\s\S]{0,160}(contato|dpo|encarregado)|(?:contato|dpo|encarregado)[\s\S]{0,160}direitos? do titular/i, severidade: "blocking", sugestao: "declare direitos do titular e canal de contato/encarregado." },
|
|
5273
5703
|
]));
|
|
5274
5704
|
}
|
|
@@ -5276,11 +5706,11 @@ function avaliarArtefatoLegalProfile(artefato, preset) {
|
|
|
5276
5706
|
}
|
|
5277
5707
|
function avaliarArtefatoResearchProfile(artefato, preset) {
|
|
5278
5708
|
const achados = validarTermosObrigatoriosArtefato(artefato, [
|
|
5279
|
-
{ id: "research_fontes_artefato", descricao: "resposta final cita fontes ou referencias", regex: /https?:\/\/|\[[0-9]+\]|fonte|referencia|
|
|
5280
|
-
{ id: "research_incerteza_artefato", descricao: "resposta final declara incerteza ou limite", regex: /incerteza|limite|baixa confianca|baixa
|
|
5281
|
-
{ id: "research_fato_inferencia_artefato", descricao: "resposta separa fato de inferencia", regex: /fato|inferencia|
|
|
5709
|
+
{ id: "research_fontes_artefato", descricao: "resposta final cita fontes ou referencias", regex: /https?:\/\/|\[[0-9]+\]|fonte|referencia|referência/i, sugestao: "inclua fontes citaveis e separe evidencia de opiniao." },
|
|
5710
|
+
{ id: "research_incerteza_artefato", descricao: "resposta final declara incerteza ou limite", regex: /incerteza|limite|baixa confianca|baixa confiança|lacuna/i, sugestao: "declare limites, incertezas e o que nao foi verificado." },
|
|
5711
|
+
{ id: "research_fato_inferencia_artefato", descricao: "resposta separa fato de inferencia", regex: /fato|inferencia|inferência/i, sugestao: "rotule conclusoes como fato, inferencia ou recomendacao." },
|
|
5282
5712
|
]);
|
|
5283
|
-
if (preset === "critica" && !avaliarPresencaPositivaArtefato(artefato, /contra.?evidencia|contra.?
|
|
5713
|
+
if (preset === "critica" && !avaliarPresencaPositivaArtefato(artefato, /contra.?evidencia|contra.?evidência|evidencia contra|evidência contra|refut/i).atendido) {
|
|
5284
5714
|
achados.push(criarAchadoArtefatoProfile("research_sem_contraditorio", "pesquisa critica nao tentou derrubar a conclusao", false, "blocking", undefined, "adicione secao de evidencias contra a recomendacao principal."));
|
|
5285
5715
|
}
|
|
5286
5716
|
return achados;
|
|
@@ -5288,14 +5718,79 @@ function avaliarArtefatoResearchProfile(artefato, preset) {
|
|
|
5288
5718
|
function avaliarArtefatoGameProfile(artefato, preset) {
|
|
5289
5719
|
const achados = validarTermosObrigatoriosArtefato(artefato, [
|
|
5290
5720
|
{ id: "game_loop_artefato", descricao: "artefato de jogo declara core loop", regex: /core loop|loop|ciclo/i, sugestao: "declare acao principal, feedback, recompensa e reinicio." },
|
|
5291
|
-
{ id: "game_estado_artefato", descricao: "artefato de jogo declara estado e transicoes", regex: /estado|state|playing|game_over|transic|transi
|
|
5292
|
-
{ id: "game_pacing_artefato", descricao: "artefato de jogo declara pacing/curva", regex: /pacing|curva|dificuldade|sessao|
|
|
5721
|
+
{ id: "game_estado_artefato", descricao: "artefato de jogo declara estado e transicoes", regex: /estado|state|playing|game_over|transic|transiç/i, sugestao: "declare estados e transicoes permitidas." },
|
|
5722
|
+
{ id: "game_pacing_artefato", descricao: "artefato de jogo declara pacing/curva", regex: /pacing|curva|dificuldade|sessao|sessão/i, severidade: "warning", sugestao: "adicione ritmo esperado e variacao de dificuldade." },
|
|
5293
5723
|
]);
|
|
5294
5724
|
if (preset === "playtest" && !avaliarPresencaPositivaArtefato(artefato, /10 segundos|1 minuto|um minuto|primeiro minuto/i).atendido) {
|
|
5295
5725
|
achados.push(criarAchadoArtefatoProfile("game_playtest_sem_tempo", "playtest nao descreve primeiros segundos e primeiro minuto", false, "blocking", undefined, "adicione simulacao dos primeiros 10s e do primeiro minuto."));
|
|
5296
5726
|
}
|
|
5297
5727
|
return achados;
|
|
5298
5728
|
}
|
|
5729
|
+
function avaliarArtefatoConversasProfile(artefato, preset) {
|
|
5730
|
+
const achados = validarTermosObrigatoriosArtefato(artefato, [
|
|
5731
|
+
{ id: "conversas_tom_artefato", descricao: "artefato declara tom/persona da conversa", regex: /tom|persona|voz|formalidade|comercial|persuasiv|serio|consultiv/i, sugestao: "declare o tom, persona e nivel de formalidade usados na resposta." },
|
|
5732
|
+
{ id: "conversas_estado_cliente_artefato", descricao: "artefato declara estado, intencao ou objecao do cliente", regex: /estado|etapa|intencao|sentimento|objec|lead|cliente/i, sugestao: "registre etapa, intencao detectada, sentimento e objecoes antes da resposta." },
|
|
5733
|
+
{ id: "conversas_proxima_acao_artefato", descricao: "artefato declara proxima acao ou CTA honesto", regex: /proxima_acao|proxima acao|cta|agendar|encaminhar|diagnostico|abrir chamado|escalar/i, sugestao: "adicione proxima acao clara sem promessa indevida." },
|
|
5734
|
+
{ id: "conversas_estado_visivel_artefato", descricao: "artefato declara ultima mensagem e ultima resposta visivel", regex: /ultima mensagem|ultima resposta visivel|mensagem_cliente_visivel|resposta_anterior_visivel|historico visivel|conversa visivel/i, sugestao: "baseie o turno na conversa visivel ao cliente, nao em pensamento interno ou resposta bruta." },
|
|
5735
|
+
{ id: "conversas_saida_cliente_artefato", descricao: "artefato separa saida interna da resposta enviada", regex: /customer_reply|resposta final ao cliente|unica saida visivel|apenas resposta_cliente|somente resposta_cliente/i, sugestao: "declare que apenas customer_reply/resposta_cliente pode sair para o canal." },
|
|
5736
|
+
{ id: "conversas_dedupe_artefato", descricao: "artefato declara deduplicacao por evento", regex: /dedupe|deduplic|evento_id|message_id|inbound|uma entrada[\s\S]{0,40}uma saida|uma mensagem[\s\S]{0,40}uma resposta/i, sugestao: "declare chave de deduplicacao por evento/mensagem recebida." },
|
|
5737
|
+
]);
|
|
5738
|
+
const promessaSemBase = /garanto|garantia total|100%|sem risco|resultado garantido|vender mais em \d+\s*dias|prometo/i.test(artefato);
|
|
5739
|
+
if (promessaSemBase) {
|
|
5740
|
+
achados.push(criarAchadoArtefatoProfile("conversas_promessa_sem_base", "resposta de bot parece prometer resultado, prazo ou garantia sem base", false, "critical", trechoRegexProfile(artefato, /garanto|garantia total|100%|sem risco|resultado garantido|vender mais em \d+\s*dias|prometo/i), "troque promessa absoluta por condicao verificavel, limite claro ou proposta de diagnostico.", undefined, { risco: "promessa_comercial_indevida" }));
|
|
5741
|
+
}
|
|
5742
|
+
const temContextoAnterior = /ultima resposta visivel|resposta_anterior_visivel|pergunta anterior|escopo faz sentido|proposta faz sentido|etapa atual|etapa escopo/i.test(artefato);
|
|
5743
|
+
const confirmacaoCurta = /\b(sim claro|sim|fechado|pode ser|beleza|ok|certo|manda|bora|ta bom|isso mesmo|gostei)\b/i.test(artefato);
|
|
5744
|
+
const reiniciouAtendimento = /sou [A-Za-z]|me chamo|como posso ajudar|em que posso ajudar|quer organizar|apresentacao|apresenta[cç][aã]o|inicio de conversa/i.test(artefato);
|
|
5745
|
+
if (temContextoAnterior && confirmacaoCurta && reiniciouAtendimento) {
|
|
5746
|
+
achados.push(criarAchadoArtefatoProfile("conversas_confirmacao_reiniciada", "confirmacao curta foi tratada como novo inicio em vez de avancar a etapa anterior", false, "critical", trechoRegexProfile(artefato, /(?:sim claro|sim|fechado|pode ser|beleza|ok|certo|manda|bora)[\s\S]{0,220}(?:sou [A-Za-z]|me chamo|como posso ajudar|quer organizar|apresenta[cç][aã]o)|(?:escopo faz sentido|proposta faz sentido|pergunta anterior)[\s\S]{0,220}(?:sou [A-Za-z]|me chamo|como posso ajudar|quer organizar|apresenta[cç][aã]o)/i), "interprete confirmacoes contra a ultima pergunta visivel e avance a conversa sem repetir saudacao.", undefined, { risco: "estado_conversa_perdido" }));
|
|
5747
|
+
}
|
|
5748
|
+
const vazouInterno = /(?:enviar|mandar|resposta visivel|customer_reply|resposta ao cliente)[\s\S]{0,120}(?:intent|stage|facts|missing_critical_info|internal_trace|raciocinio|pensamento interno|analise interna|JSON interno)|(?:raciocinio|pensamento interno|analise interna|JSON interno)[\s\S]{0,120}(?:cliente|canal|enviado|visivel)/i.test(artefato);
|
|
5749
|
+
if (vazouInterno) {
|
|
5750
|
+
achados.push(criarAchadoArtefatoProfile("conversas_vazamento_interno", "resposta parece expor raciocinio, JSON ou campos internos ao cliente", false, "critical", trechoRegexProfile(artefato, /(?:intent|stage|facts|missing_critical_info|internal_trace|raciocinio|pensamento interno|analise interna|JSON interno)[\s\S]{0,160}(?:cliente|canal|enviado|visivel)|(?:enviar|mandar|resposta visivel)[\s\S]{0,160}(?:intent|stage|facts|missing_critical_info|internal_trace|JSON interno)/i), "mande ao canal apenas customer_reply/resposta_cliente, mantendo interpretacao e auditoria fora da mensagem visivel.", undefined, { risco: "vazamento_de_estado_interno" }));
|
|
5751
|
+
}
|
|
5752
|
+
const whatsapp = /canal\s*:?\s*whatsapp|\bWHATSAPP\b/i.test(artefato);
|
|
5753
|
+
const canalAlternativo = /\b(email|e-mail|inbox|caixa de entrada)\b/i.test(artefato);
|
|
5754
|
+
const clientePediuCanal = /cliente pediu|cliente solicitou|pedido do cliente|solicitou email|pediu email/i.test(artefato);
|
|
5755
|
+
if (whatsapp && canalAlternativo && !clientePediuCanal) {
|
|
5756
|
+
achados.push(criarAchadoArtefatoProfile("conversas_canal_inventado", "conversa em WhatsApp tenta deslocar para email ou inbox sem pedido do cliente", false, "blocking", trechoRegexProfile(artefato, /WHATSAPP[\s\S]{0,180}(?:email|e-mail|inbox|caixa de entrada)|(?:email|e-mail|inbox|caixa de entrada)[\s\S]{0,180}WHATSAPP/i), "resolva no canal atual, a menos que o cliente tenha pedido outro canal.", undefined, { risco: "friccao_de_canal" }));
|
|
5757
|
+
}
|
|
5758
|
+
const respostaDuplicada = /duas respostas|duas mensagens visiveis|respondeu duas vezes|duplicou resposta|mesmo inbound|mesmo evento/i.test(artefato);
|
|
5759
|
+
const temDedupe = /dedupe|deduplic|evento_id|message_id|inbound_id|uma entrada[\s\S]{0,40}uma saida/i.test(artefato);
|
|
5760
|
+
if (respostaDuplicada && !temDedupe) {
|
|
5761
|
+
achados.push(criarAchadoArtefatoProfile("conversas_sem_dedupe_evento", "artefato indica risco de resposta duplicada sem deduplicacao por evento", false, "blocking", trechoRegexProfile(artefato, /duas respostas|duas mensagens visiveis|respondeu duas vezes|duplicou resposta|mesmo inbound|mesmo evento/i), "registre evento_id/message_id e envie no maximo uma resposta visivel por inbound.", undefined, { risco: "resposta_duplicada" }));
|
|
5762
|
+
}
|
|
5763
|
+
const precisaEscalar = /irritad|reclamac|juridic|cancelamento|processo|procon|advogado|ameaca/i.test(artefato);
|
|
5764
|
+
const escalou = avaliarPresencaPositivaArtefato(artefato, /escalar|humano|atendente|supervisor|ticket|chamado/i);
|
|
5765
|
+
if (precisaEscalar && !escalou.atendido) {
|
|
5766
|
+
achados.push(criarAchadoArtefatoProfile("conversas_sem_escalacao_humana", "conversa sensivel exige escalacao humana explicita", false, "critical", escalou.trecho ?? trechoRegexProfile(artefato, /irritad|reclamac|juridic|cancelamento|processo|procon|advogado/i), "declare handoff para humano com motivo e prioridade antes de continuar no bot.", escalou.motivo, {
|
|
5767
|
+
linha: escalou.linha,
|
|
5768
|
+
coluna: escalou.coluna,
|
|
5769
|
+
inicio: escalou.inicio,
|
|
5770
|
+
fim: escalou.fim,
|
|
5771
|
+
risco: "handoff_humano_ausente",
|
|
5772
|
+
}));
|
|
5773
|
+
}
|
|
5774
|
+
if (preset === "vendas") {
|
|
5775
|
+
achados.push(...validarTermosObrigatoriosArtefato(artefato, [
|
|
5776
|
+
{ id: "conversas_vendas_objecao_artefato", descricao: "conversa de vendas trata objecao ou dor do cliente", regex: /objec|duvida|dor|interesse|comparando|orcamento/i, sugestao: "trate a objecao antes do CTA." },
|
|
5777
|
+
{ id: "conversas_vendas_cta_artefato", descricao: "conversa de vendas contem CTA honesto", regex: /agendar|diagnostico|proposta|proxima acao|cta|posso te enviar/i, sugestao: "inclua convite claro e nao agressivo para a proxima etapa." },
|
|
5778
|
+
]));
|
|
5779
|
+
}
|
|
5780
|
+
if (preset === "suporte") {
|
|
5781
|
+
achados.push(...validarTermosObrigatoriosArtefato(artefato, [
|
|
5782
|
+
{ id: "conversas_suporte_problema_artefato", descricao: "suporte identifica problema ou chamado", regex: /problema|erro|chamado|ticket|suporte/i, sugestao: "identifique problema, contexto e o que sera feito." },
|
|
5783
|
+
{ id: "conversas_suporte_handoff_artefato", descricao: "suporte declara escalacao quando necessario", regex: /escalar|humano|atendente|ticket|chamado/i, sugestao: "declare quando o atendimento sai do bot." },
|
|
5784
|
+
]));
|
|
5785
|
+
}
|
|
5786
|
+
if (preset === "cobranca") {
|
|
5787
|
+
achados.push(...validarTermosObrigatoriosArtefato(artefato, [
|
|
5788
|
+
{ id: "conversas_cobranca_tom_artefato", descricao: "cobranca usa tom respeitoso e objetivo", regex: /respeitoso|cordial|tom|sem constrangimento|regularizar/i, severidade: "critical", sugestao: "declare tom respeitoso e evite constrangimento ou ameaca." },
|
|
5789
|
+
{ id: "conversas_cobranca_dado_artefato", descricao: "cobranca menciona valor, vencimento ou referencia autorizada", regex: /valor|vencimento|fatura|boleto|referencia autorizada/i, severidade: "blocking", sugestao: "referencie apenas dados autorizados da cobranca." },
|
|
5790
|
+
]));
|
|
5791
|
+
}
|
|
5792
|
+
return achados;
|
|
5793
|
+
}
|
|
5299
5794
|
function avaliarArtefatoProfile(profile, contrato, artefato, maturidade, preset) {
|
|
5300
5795
|
if (!artefato || !artefato.trim())
|
|
5301
5796
|
return [];
|
|
@@ -5312,6 +5807,8 @@ function avaliarArtefatoProfile(profile, contrato, artefato, maturidade, preset)
|
|
|
5312
5807
|
return avaliarArtefatoResearchProfile(artefato, preset);
|
|
5313
5808
|
case "game":
|
|
5314
5809
|
return avaliarArtefatoGameProfile(artefato, preset);
|
|
5810
|
+
case "conversas":
|
|
5811
|
+
return avaliarArtefatoConversasProfile(artefato, preset);
|
|
5315
5812
|
}
|
|
5316
5813
|
}
|
|
5317
5814
|
async function carregarArtefatoProfile(args) {
|
|
@@ -5325,7 +5822,7 @@ async function carregarArtefatoProfile(args) {
|
|
|
5325
5822
|
}
|
|
5326
5823
|
async function validarProfileSemantico(entrada, profile, opcoes) {
|
|
5327
5824
|
if (!entrada) {
|
|
5328
|
-
throw new Error("Uso: sema profile validar <software|workflow|ops|game|legal|research> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]");
|
|
5825
|
+
throw new Error("Uso: sema profile validar <software|workflow|ops|game|legal|research|conversas> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]");
|
|
5329
5826
|
}
|
|
5330
5827
|
const modulos = await carregarModulos(entrada);
|
|
5331
5828
|
const escolhido = modulos.find((item) => moduloCombinaComProfile(item.resultado.modulo?.nome, item.caminho, profile)) ?? modulos[0];
|
|
@@ -5505,9 +6002,9 @@ async function comandoProfile(posicionais, args, emJson) {
|
|
|
5505
6002
|
"Uso: sema profile <validar|capabilities|rule-packs>",
|
|
5506
6003
|
"",
|
|
5507
6004
|
"Comandos:",
|
|
5508
|
-
" sema profile validar <software|workflow|ops|game|legal|research> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
|
|
6005
|
+
" sema profile validar <software|workflow|ops|game|legal|research|conversas> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
|
|
5509
6006
|
" sema profile capabilities [--json]",
|
|
5510
|
-
" sema profile rule-packs [--profile <author|software|workflow|ops|game|legal|research>] [--json]",
|
|
6007
|
+
" sema profile rule-packs [--profile <author|software|workflow|ops|game|legal|research|conversas>] [--json]",
|
|
5511
6008
|
"",
|
|
5512
6009
|
"O profile e um gate semantico: se requisito obrigatorio faltar, a saida bloqueia.",
|
|
5513
6010
|
].join("\n"));
|
|
@@ -5531,7 +6028,7 @@ async function comandoProfile(posicionais, args, emJson) {
|
|
|
5531
6028
|
const profile = normalizarProfileSemantico(posicionais[1] ?? obterOpcao(args, "--profile"));
|
|
5532
6029
|
const entrada = posicionais[2] ?? obterOpcao(args, "--arquivo");
|
|
5533
6030
|
if (!profile) {
|
|
5534
|
-
console.error("Profile invalido. Use software, workflow, ops, game, legal ou
|
|
6031
|
+
console.error("Profile invalido. Use software, workflow, ops, game, legal, research ou conversas.");
|
|
5535
6032
|
return 1;
|
|
5536
6033
|
}
|
|
5537
6034
|
const preset = normalizarPresetProfile(profile, obterOpcao(args, "--preset"));
|
|
@@ -5892,19 +6389,19 @@ function avaliarPresetAuthor(preset, textoFonte) {
|
|
|
5892
6389
|
const checks = {
|
|
5893
6390
|
conto: [
|
|
5894
6391
|
{ id: "author_conto_sem_conflito", regex: /conflito|quer|precisa|perde|arrisca|custo/i, sugestao: "conto precisa de desejo, custo e conflito visiveis." },
|
|
5895
|
-
{ id: "author_conto_sem_fechamento", regex: /fim|final|consequencia|
|
|
6392
|
+
{ id: "author_conto_sem_fechamento", regex: /fim|final|consequencia|consequência|mudou|perdeu|ganhou/i, sugestao: "feche o conto com mudanca ou consequencia, nao so atmosfera." },
|
|
5896
6393
|
],
|
|
5897
6394
|
romance: [
|
|
5898
|
-
{ id: "author_romance_sem_arco", regex: /arco|capitulo|
|
|
6395
|
+
{ id: "author_romance_sem_arco", regex: /arco|capitulo|capÃtulo|continuidade|promessa|personagem/i, sugestao: "romance precisa preservar arco, promessa e continuidade entre capitulos." },
|
|
5899
6396
|
],
|
|
5900
6397
|
roteiro: [
|
|
5901
|
-
{ id: "author_roteiro_sem_cena", regex: /cena|ato|dialogo|
|
|
6398
|
+
{ id: "author_roteiro_sem_cena", regex: /cena|ato|dialogo|diálogo|acao visual|ação visual|int\.|ext\./i, sugestao: "roteiro precisa de cena, acao visual e/ou dialogo estruturado." },
|
|
5902
6399
|
],
|
|
5903
6400
|
lore: [
|
|
5904
|
-
{ id: "author_lore_sem_canon", regex: /canon|linha do tempo|mundo|
|
|
6401
|
+
{ id: "author_lore_sem_canon", regex: /canon|linha do tempo|mundo|facção|faccao|regra do mundo|continuidade/i, sugestao: "lore precisa de canon, mundo e restricoes de continuidade." },
|
|
5905
6402
|
],
|
|
5906
6403
|
campanha: [
|
|
5907
|
-
{ id: "author_campanha_sem_estado", regex: /estado|memoria|
|
|
6404
|
+
{ id: "author_campanha_sem_estado", regex: /estado|memoria|memória|sessao|sessão|evento irreversivel|evento irreversÃvel|personagem/i, sugestao: "campanha precisa guardar estado, memoria e eventos irreversiveis." },
|
|
5908
6405
|
],
|
|
5909
6406
|
};
|
|
5910
6407
|
return checks[preset].flatMap((check) => {
|
|
@@ -6238,7 +6735,7 @@ async function comandoDrift(entrada, args, emJson, cwd = process.cwd()) {
|
|
|
6238
6735
|
async function comandoImpacto(entrada, args, emJson, cwd = process.cwd()) {
|
|
6239
6736
|
const alvoSemantico = obterOpcao(args, "--alvo");
|
|
6240
6737
|
if (!alvoSemantico) {
|
|
6241
|
-
console.error("Uso: sema impacto <arquivo-ou-pasta> --alvo <token-
|
|
6738
|
+
console.error("Uso: sema impacto <arquivo-ou-pasta> --alvo <token-semântico> [--mudanca <descricao>] [--escopo <arquivo|modulo|projeto>] [--incluir-worktrees] [--incluir-consumidores-laterais] [--json]");
|
|
6242
6739
|
return 1;
|
|
6243
6740
|
}
|
|
6244
6741
|
const contextoProjeto = await carregarProjeto(entrada, cwd);
|
|
@@ -6542,9 +7039,11 @@ async function comandoSyncAiEntrypoints(emJson) {
|
|
|
6542
7039
|
return 1;
|
|
6543
7040
|
}
|
|
6544
7041
|
const indexJson = JSON.parse(await readFile(path.join(resumoProjeto.pastaSaida, "SEMA_INDEX.json"), "utf8"));
|
|
7042
|
+
const entrypointsClientes = await sincronizarEntryPointsAgentes(resumoProjeto.baseProjeto, indexJson.agentContextPack);
|
|
6545
7043
|
const artefatos = [...new Set([
|
|
6546
7044
|
...ARQUIVOS_CANONICOS_IA_RAIZ,
|
|
6547
7045
|
...resumoProjeto.artefatos,
|
|
7046
|
+
...entrypointsClientes.arquivos.map((item) => item.caminho),
|
|
6548
7047
|
"exemplos",
|
|
6549
7048
|
])];
|
|
6550
7049
|
if (emJson) {
|
|
@@ -6555,6 +7054,7 @@ async function comandoSyncAiEntrypoints(emJson) {
|
|
|
6555
7054
|
pastaSaida: resumoProjeto.pastaSaida,
|
|
6556
7055
|
artefatos,
|
|
6557
7056
|
entradaCanonica: indexJson.entradaCanonica,
|
|
7057
|
+
entrypointsClientes,
|
|
6558
7058
|
exemplos,
|
|
6559
7059
|
}, null, 2));
|
|
6560
7060
|
return 0;
|
|
@@ -6562,10 +7062,11 @@ async function comandoSyncAiEntrypoints(emJson) {
|
|
|
6562
7062
|
console.log("Entrypoints IA-first sincronizados");
|
|
6563
7063
|
console.log("");
|
|
6564
7064
|
console.log(`Base do projeto: ${resumoProjeto.baseProjeto}`);
|
|
6565
|
-
console.log(`Ordem
|
|
6566
|
-
console.log(`IA
|
|
6567
|
-
console.log(`IA
|
|
6568
|
-
console.log(`IA
|
|
7065
|
+
console.log(`Ordem canônica: ${indexJson.entradaCanonica.ordemLeitura.join(" -> ")}`);
|
|
7066
|
+
console.log(`IA fraca: ${indexJson.entradaCanonica.porCapacidade.fraca.join(" -> ")}`);
|
|
7067
|
+
console.log(`IA média: ${indexJson.entradaCanonica.porCapacidade.media.join(" -> ")}`);
|
|
7068
|
+
console.log(`IA forte: ${indexJson.entradaCanonica.porCapacidade.forte.join(" -> ")}`);
|
|
7069
|
+
console.log(`Clientes: ${entrypointsClientes.criados.length} criados, ${entrypointsClientes.atualizados.length} atualizados, ${entrypointsClientes.preservados.length} preservados`);
|
|
6569
7070
|
console.log(`Exemplos oficiais: ${exemplos.criados.length} criados, ${exemplos.preservados.length} preservados em ${exemplos.destino}`);
|
|
6570
7071
|
return 0;
|
|
6571
7072
|
}
|
|
@@ -6587,16 +7088,16 @@ async function comandoAjudaIa() {
|
|
|
6587
7088
|
]));
|
|
6588
7089
|
console.log("");
|
|
6589
7090
|
console.log(renderizarSecaoAscii("Capacidade de IA", [
|
|
6590
|
-
"
|
|
6591
|
-
"
|
|
6592
|
-
"
|
|
7091
|
+
"fraca: `sema resumo --micro`, `briefing.min.json`, `prompt-curto.txt`",
|
|
7092
|
+
"média: `sema resumo --curto`, `drift.json`, `briefing.min.json`",
|
|
7093
|
+
"forte: `sema contexto-ia`, `briefing.json`, `ir.json`, `ast.json`",
|
|
6593
7094
|
]));
|
|
6594
7095
|
console.log("");
|
|
6595
7096
|
console.log(renderizarSecaoAscii("Fluxo recomendado", [
|
|
6596
7097
|
"Use `sema starter-ia` para um texto curto de onboarding.",
|
|
6597
7098
|
"Use `sema sync-ai-entrypoints` para regenerar `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.*` e `SEMA_INDEX.json` na raiz.",
|
|
6598
7099
|
"Use `sema instalar-exemplos` para materializar `exemplos/` oficiais sem sobrescrever arquivos locais.",
|
|
6599
|
-
"Use `sema resumo <arquivo> --micro --para onboarding` para IA
|
|
7100
|
+
"Use `sema resumo <arquivo> --micro --para onboarding` para IA fraca.",
|
|
6600
7101
|
"Use `sema prompt-curto <arquivo> --curto --para mudanca` para colar contexto em modelo gratuito.",
|
|
6601
7102
|
"Use `sema prompt-ia`, `sema prompt-ia-ui`, `sema prompt-ia-react` e `sema prompt-ia-sema-primeiro` conforme a tarefa.",
|
|
6602
7103
|
"Use `sema exemplos-prompt-ia` para pegar modelos prontos de prompt.",
|
|
@@ -6615,7 +7116,7 @@ async function comandoAjudaIa() {
|
|
|
6615
7116
|
"Se voce quer testar a Sema de verdade, nao peca so HTML solto.",
|
|
6616
7117
|
"Peca `.sema` + arquitetura + React + TypeScript, ou use o modo `Sema primeiro`.",
|
|
6617
7118
|
"Se o projeto ja existe, trate `importar` como rascunho e `drift` como juiz.",
|
|
6618
|
-
"IA
|
|
7119
|
+
"IA fraca comeca no menor artefato que resolve a tarefa; nao enfie `ast.json` inteiro nela de bobeira.",
|
|
6619
7120
|
"Antes de editar software vivo, leia `briefing.min.json` ou `briefing.json` em vez de sair cavando arquivo na fe.",
|
|
6620
7121
|
"Trate `route`, `worker`, `evento`, `fila`, `cron`, `webhook`, `cache`, `storage` e `policy` como superficies de primeira classe.",
|
|
6621
7122
|
]));
|
|
@@ -6744,7 +7245,7 @@ async function comandoPromptCurto(entrada, args, emJson) {
|
|
|
6744
7245
|
if (entrada && entrada.toLowerCase().endsWith(".sema")) {
|
|
6745
7246
|
const contexto = await carregarContextoModuloIa(alvo);
|
|
6746
7247
|
const resumoSemantico = coletarResumoSemanticoModulo(contexto);
|
|
6747
|
-
const capacidade = tamanho === "micro" ? "
|
|
7248
|
+
const capacidade = tamanho === "micro" ? "fraca" : tamanho === "curto" ? "media" : "forte";
|
|
6748
7249
|
const prompt = criarPromptCurtoModulo(resumoSemantico, modo, tamanho, capacidade);
|
|
6749
7250
|
if (emJson) {
|
|
6750
7251
|
console.log(JSON.stringify({
|
|
@@ -6769,16 +7270,16 @@ async function comandoPromptCurto(entrada, args, emJson) {
|
|
|
6769
7270
|
? "SEMA_BRIEF.curto.txt"
|
|
6770
7271
|
: "SEMA_BRIEF.md";
|
|
6771
7272
|
const contextoProjeto = await readFile(path.join(resumoProjeto.pastaSaida, arquivoResumo), "utf8");
|
|
6772
|
-
const capacidade = tamanho === "micro" ? "
|
|
6773
|
-
const prompt =
|
|
7273
|
+
const capacidade = tamanho === "micro" ? "fraca" : tamanho === "curto" ? "media" : "forte";
|
|
7274
|
+
const prompt = `âš ï¸ REGRA OBRIGATÓRIA DE GOVERNANÇA:
|
|
6774
7275
|
|
|
6775
|
-
ANTES DE QUALQUER
|
|
6776
|
-
1. Chame sema_docs_impacto com sua
|
|
6777
|
-
2. Aguarde a resposta com as docs
|
|
7276
|
+
ANTES DE QUALQUER AÇÃO (editar, criar, deletar, executar, consultar, modificar):
|
|
7277
|
+
1. Chame sema_docs_impacto com sua intenção declarada
|
|
7278
|
+
2. Aguarde a resposta com as docs obrigatórias
|
|
6778
7279
|
3. Leia as docs antes de agir
|
|
6779
7280
|
4. Use sema_finalizar_mudanca para comprovar que leu as docs
|
|
6780
7281
|
|
|
6781
|
-
|
|
7282
|
+
Você está operando Sema em modo IA-first.
|
|
6782
7283
|
|
|
6783
7284
|
Isto e contexto comprimido para IA operar contrato semantico antes de tocar codigo vivo.
|
|
6784
7285
|
|
|
@@ -6786,7 +7287,7 @@ Capacidade alvo: ${capacidade}
|
|
|
6786
7287
|
Modo da tarefa: ${modo}
|
|
6787
7288
|
|
|
6788
7289
|
Regras:
|
|
6789
|
-
- ANTES DE TUDO: chame sema_docs_impacto com sua
|
|
7290
|
+
- ANTES DE TUDO: chame sema_docs_impacto com sua intenção declarada
|
|
6790
7291
|
- comece pelo resumo compacto abaixo
|
|
6791
7292
|
- se a tarefa pedir mais contexto, abra \`AGENT_CONTEXT_PACK.json\` e depois \`SEMA_INDEX.json\`
|
|
6792
7293
|
- nao tente ler o repo inteiro se o resumo ja disser onde tocar
|
|
@@ -7047,6 +7548,21 @@ async function principal() {
|
|
|
7047
7548
|
codigoSaida = 0;
|
|
7048
7549
|
}
|
|
7049
7550
|
break;
|
|
7551
|
+
case "runner":
|
|
7552
|
+
{
|
|
7553
|
+
const subcomando = posicionais[0];
|
|
7554
|
+
if (subcomando === "validar-remoto") {
|
|
7555
|
+
codigoSaida = await comandoRunnerValidacaoRemota(resto, cwd);
|
|
7556
|
+
}
|
|
7557
|
+
else if (subcomando === "servidor") {
|
|
7558
|
+
codigoSaida = await comandoServidorRunnerValidacaoRemota(resto, cwd);
|
|
7559
|
+
}
|
|
7560
|
+
else {
|
|
7561
|
+
console.log(ajudaRunnerValidacaoRemota());
|
|
7562
|
+
codigoSaida = subcomando ? 1 : 0;
|
|
7563
|
+
}
|
|
7564
|
+
}
|
|
7565
|
+
break;
|
|
7050
7566
|
case "validar":
|
|
7051
7567
|
codigoSaida = possuiFlag(resto, "--json")
|
|
7052
7568
|
? await comandoValidarJson(posicionais[0])
|