@semacode/cli 0.9.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -16,7 +16,9 @@ const STARTER_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca d
16
16
 
17
17
  Importante:
18
18
  - a Sema se apresenta publicamente como protocolo e funciona tecnicamente como linguagem de intencao
19
- - a Sema e protocolo de governanca semantica, nao gerador magico que deveria fazer tudo
19
+ - a Sema e protocolo de governanca semantica desenhado para IA, nao para ergonomia humana
20
+ - leitura humana e bonus toleravel, nao objetivo de produto
21
+ - a Sema nao e gerador magico que deveria fazer tudo
20
22
  - a Sema modela contratos, estados, fluxos, erros, efeitos, garantias, vinculos e execucao
21
23
  - a Sema gera codigo e scaffolding real para TypeScript, Python e Dart
22
24
  - a Sema usa \`importar\` para bootstrap revisavel, nao para contrato final automatico
@@ -24,7 +26,8 @@ Importante:
24
26
  - a Sema usa \`vinculos\` para ligar contrato a arquivo, simbolo, recurso e superficie real
25
27
  - a Sema usa \`execucao\` para explicitar timeout, retry, compensacao e criticidade
26
28
  - a Sema usa \`drift\` para medir diferenca entre contrato e codigo vivo com score, confianca e lacunas
27
- - a Sema usa \`contexto-ia\` para gerar \`ast.json\`, \`ir.json\`, \`drift.json\` e \`briefing.json\` antes da edicao
29
+ - a Sema usa \`resumo\` e \`prompt-curto\` para IA pequena ou gratuita
30
+ - a Sema usa \`contexto-ia\` para gerar \`ast.json\`, \`ir.json\`, \`drift.json\`, \`briefing.json\` e artefatos compactos antes da edicao
28
31
  - a Sema pode servir de base para interfaces graficas elegantes e coerentes
29
32
  - a Sema nao gera uma interface completa sozinha no estado atual
30
33
  - trate a Sema como cerebro semantico da aplicacao, nao como gerador magico de front-end pronto
@@ -33,6 +36,8 @@ Importante:
33
36
 
34
37
  Regras:
35
38
  - nao invente sintaxe fora da gramatica e dos exemplos oficiais
39
+ - se a IA for pequena, nao tente abrir tudo de uma vez
40
+ - use \`sema resumo\` e \`briefing.min.json\` antes de subir para o pacote completo
36
41
  - trate \`ir --json\` como fonte de verdade semantica
37
42
  - trate \`briefing.json\` como plano de intervencao antes de editar projeto vivo
38
43
  - trate \`diagnosticos --json\` como fonte de correcao
@@ -41,6 +46,8 @@ Regras:
41
46
  - nao cobre da Sema adivinhacao de negocio que nao esta no contrato nem no codigo
42
47
 
43
48
  Comandos essenciais:
49
+ - resumo compacto por capacidade: \`sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
50
+ - prompt curto para IA pequena: \`sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
44
51
  - descoberta do projeto: \`sema inspecionar [arquivo-ou-pasta] --json\`
45
52
  - auditoria do contrato vivo: \`sema drift <arquivo-ou-pasta> [--json]\`
46
53
  - contexto completo do modulo: \`sema contexto-ia <arquivo.sema>\`
@@ -55,10 +62,10 @@ Comandos essenciais:
55
62
 
56
63
  Antes de editar:
57
64
  1. leia README, docs de IA e um exemplo oficial parecido
58
- 2. rode \`sema inspecionar\` para descobrir base, codigo vivo e fontes legado
59
- 3. rode \`sema drift\` para medir impls, vinculos, rotas, score e lacunas
60
- 4. rode \`sema contexto-ia\` e leia \`briefing.json\`
61
- 5. consulte AST e IR do modulo alvo
65
+ 2. se a IA for pequena, rode \`sema resumo <arquivo> --micro\` e leia \`briefing.min.json\`
66
+ 3. se a IA aguentar mais, rode \`sema drift\` para medir impls, vinculos, rotas, score e lacunas
67
+ 4. se a tarefa for pesada, rode \`sema contexto-ia\` e leia \`briefing.json\`
68
+ 5. consulte AST e IR do modulo alvo so quando a capacidade realmente aguentar
62
69
 
63
70
  Depois de editar:
64
71
  1. rode \`sema formatar\`
@@ -66,11 +73,12 @@ Depois de editar:
66
73
  3. se houver falha, use \`diagnosticos --json\`
67
74
  4. rode \`sema drift\` de novo quando mexer em codigo vivo
68
75
  5. se a tarefa pedir codigo derivado, rode \`sema compilar\`
69
- 6. feche com \`sema verificar\` ou \`npm run project:check\`
76
+ 6. feche com \`sema verificar <arquivo-ou-pasta> --json\`
70
77
 
71
78
  Priorize sempre:
72
79
  - exemplos oficiais
73
80
  - JSON da CLI
81
+ - o menor artefato que resolva a tarefa da IA atual
74
82
  - score, confianca e lacunas do \`drift\`
75
83
  - \`briefing.json\` como guia de mudanca
76
84
  - consistencia semantica
@@ -88,16 +96,17 @@ Superficies que a IA deve enxergar como first-class:
88
96
 
89
97
  Nao improvise quando faltar contexto.
90
98
  `;
91
- const PROMPT_BASE_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao orientado a contrato, desenhado para facilitar entendimento e operacao por IA.
99
+ const PROMPT_BASE_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao orientado a contrato, desenhado para operacao por IA.
92
100
 
93
- Trate a Sema como camada semantica e linguagem de especificacao executavel. Nao invente sintaxe, palavras-chave ou blocos fora da gramatica e dos exemplos oficiais.
101
+ Trate a Sema como camada semantica e linguagem de especificacao executavel feita para IA, nao para leitura humana confortavel. Nao invente sintaxe, palavras-chave ou blocos fora da gramatica e dos exemplos oficiais.
94
102
 
95
103
  Fontes de verdade, em ordem:
96
104
  1. README do projeto
97
105
  2. gramatica e documentacao de sintaxe da Sema
98
106
  3. especificacao semantica da linguagem
99
107
  4. exemplos oficiais, com prioridade para o vertical de pagamento
100
- 5. AST, IR e diagnosticos exportados pela CLI em JSON
108
+ 5. \`sema resumo\` e \`briefing.min.json\` quando a IA for pequena
109
+ 6. AST, IR e diagnosticos exportados pela CLI em JSON quando a capacidade aguentar
101
110
 
102
111
  Regras de operacao:
103
112
  - preserve o significado semantico
@@ -105,6 +114,7 @@ Regras de operacao:
105
114
  - use diagnosticos estruturados como contrato de correcao
106
115
  - use a IR como fonte de verdade semantica quando houver duvida
107
116
  - nao conclua uma alteracao sem validar e verificar o modulo
117
+ - comece pelo menor artefato semantico que resolva a tarefa
108
118
 
109
119
  Antes de editar \`.sema\`, entenda:
110
120
  - o module alvo
@@ -292,6 +302,8 @@ Nao transforme isso em um \`index.html\` solto.
292
302
  Comandos uteis da CLI para esse fluxo:
293
303
  - \`sema starter-ia\`
294
304
  - \`sema ajuda-ia\`
305
+ - \`sema resumo <arquivo-ou-pasta>\`
306
+ - \`sema prompt-curto <arquivo-ou-pasta>\`
295
307
  - \`sema prompt-ia\`
296
308
  - \`sema prompt-ia-ui\`
297
309
  - \`sema prompt-ia-react\`
@@ -327,6 +339,8 @@ Comandos:
327
339
  sema formatar <arquivo-ou-pasta> [--check] [--json]
328
340
  sema ajuda-ia
329
341
  sema starter-ia
342
+ sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>] [--saida <diretorio>] [--raiz] [--json]
343
+ sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>] [--json]
330
344
  sema prompt-ia
331
345
  sema prompt-ia-ui
332
346
  sema prompt-ia-react
@@ -356,18 +370,51 @@ function obterOpcao(args, nome, padrao) {
356
370
  function possuiFlag(args, nome) {
357
371
  return args.includes(nome);
358
372
  }
373
+ const OPCOES_COM_VALOR = new Set([
374
+ "--template",
375
+ "--alvo",
376
+ "--saida",
377
+ "--estrutura",
378
+ "--framework",
379
+ "--namespace",
380
+ "--para",
381
+ ]);
359
382
  function obterPosicionais(args) {
360
383
  const posicionais = [];
361
384
  for (let indice = 0; indice < args.length; indice += 1) {
362
385
  const atual = args[indice];
363
386
  if (atual.startsWith("--")) {
364
- indice += 1;
387
+ if (OPCOES_COM_VALOR.has(atual)) {
388
+ indice += 1;
389
+ }
365
390
  continue;
366
391
  }
367
392
  posicionais.push(atual);
368
393
  }
369
394
  return posicionais;
370
395
  }
396
+ function normalizarTamanhoResumo(args) {
397
+ const escolhas = [
398
+ possuiFlag(args, "--micro") ? "micro" : null,
399
+ possuiFlag(args, "--curto") ? "curto" : null,
400
+ possuiFlag(args, "--medio") ? "medio" : null,
401
+ ].filter((item) => item !== null);
402
+ if (escolhas.length > 1) {
403
+ throw new Error("Use apenas uma entre as flags --micro, --curto ou --medio.");
404
+ }
405
+ return escolhas[0] ?? "curto";
406
+ }
407
+ function normalizarModoResumo(valor) {
408
+ if (valor === "resumo"
409
+ || valor === "onboarding"
410
+ || valor === "review"
411
+ || valor === "mudanca"
412
+ || valor === "bug"
413
+ || valor === "arquitetura") {
414
+ return valor;
415
+ }
416
+ return "resumo";
417
+ }
371
418
  function comandoDisponivel(comando, argumentos = ["--version"]) {
372
419
  const execucao = spawnSync(comando, argumentos, { stdio: "ignore", shell: process.platform === "win32" });
373
420
  return (execucao.status ?? 1) === 0;
@@ -641,23 +688,329 @@ async function descobrirDocsIa() {
641
688
  };
642
689
  }
643
690
  function renderizarCabecalhoDocsIa(descoberta) {
691
+ const documentos = descoberta.documentos.map((documento) => `\`${documento.nome}\``);
644
692
  const linhas = [
645
- "Informacoes da instalacao atual",
646
- `- Origem da instalacao: ${descoberta.origemInstalacao}`,
647
- `- Base detectada: ${descoberta.baseDetectada ?? "nao encontrada"}`,
693
+ "Modo IA-first da instalacao atual",
694
+ "- Use `sema` como interface publica principal.",
695
+ "- Nao assuma monorepo, `node pacotes/cli/dist/index.js`, `npm run project:check` ou uma pasta `exemplos` externa ao projeto atual.",
696
+ "- Se a IA tiver contexto curto, comece por `sema resumo` e `sema prompt-curto`.",
697
+ "- Se a IA aguentar mais contexto, suba para `sema drift --json` e `sema contexto-ia`.",
698
+ "- So leia `ast.json` e `ir.json` completos quando a capacidade da IA realmente aguentar esse volume.",
648
699
  ];
649
- if (descoberta.documentos.length > 0) {
650
- linhas.push("- Documentos locais encontrados:");
651
- for (const documento of descoberta.documentos) {
652
- linhas.push(` - ${documento.nome}: ${documento.caminho}`);
653
- }
700
+ if (documentos.length > 0) {
701
+ linhas.push(`- Documentos locais empacotados: ${documentos.join(", ")}.`);
654
702
  }
655
703
  else {
656
- linhas.push("- Documentos locais encontrados: nenhum");
657
- linhas.push(" - Esta instalacao da CLI nao conseguiu localizar a pasta docs ao redor do pacote atual.");
704
+ linhas.push("- Documentos locais empacotados: nenhum extra detectado. Siga a CLI, o contrato atual e os artefatos JSON.");
658
705
  }
659
706
  return linhas.join("\n");
660
707
  }
708
+ function unicos(itens) {
709
+ return [...new Set(itens)];
710
+ }
711
+ function unicosOrdenados(itens) {
712
+ return unicos(itens).sort((a, b) => a.localeCompare(b, "pt-BR"));
713
+ }
714
+ function limitarLista(itens, limite) {
715
+ return itens.slice(0, limite);
716
+ }
717
+ function resumirListaTexto(itens, limite, padrao = "nenhum") {
718
+ if (itens.length === 0) {
719
+ return padrao;
720
+ }
721
+ const visiveis = itens.slice(0, limite);
722
+ const restante = itens.length - visiveis.length;
723
+ return restante > 0 ? `${visiveis.join(", ")} (+${restante})` : visiveis.join(", ");
724
+ }
725
+ function normalizarIdentificadorResumo(valor) {
726
+ return valor.replace(/[._]/g, " ").replace(/\s+/g, " ").trim();
727
+ }
728
+ function resumirCamposTask(task, campo, limiteCampos) {
729
+ const campos = (task[campo] ?? []).map((item) => item.nome).slice(0, limiteCampos);
730
+ if (campos.length === 0) {
731
+ return `${task.nome}(-)`;
732
+ }
733
+ return `${task.nome}(${campos.join(", ")})`;
734
+ }
735
+ function formatarEfeitoSemanticoResumido(efeito) {
736
+ if (efeito.textoOriginal) {
737
+ return efeito.textoOriginal;
738
+ }
739
+ const partes = [`${efeito.categoria} ${efeito.alvo}`];
740
+ if (efeito.criticidade) {
741
+ partes.push(`criticidade=${efeito.criticidade}`);
742
+ }
743
+ if (efeito.detalhe) {
744
+ partes.push(efeito.detalhe);
745
+ }
746
+ return partes.join(" ");
747
+ }
748
+ function calcularRiscoOperacionalResumo(resumoDrift) {
749
+ if (resumoDrift.tasks.some((task) => task.riscoOperacional === "alto")) {
750
+ return "alto";
751
+ }
752
+ if (resumoDrift.tasks.some((task) => task.riscoOperacional === "medio")) {
753
+ return "medio";
754
+ }
755
+ return "baixo";
756
+ }
757
+ function descreverFazModulo(ir, modulo) {
758
+ if (!ir) {
759
+ return `governa o modulo ${normalizarIdentificadorResumo(modulo)}`;
760
+ }
761
+ const partes = [];
762
+ if (ir.routes.length > 0) {
763
+ partes.push(`${ir.routes.length} rota(s)`);
764
+ }
765
+ if (ir.superficies.length > 0) {
766
+ partes.push(`${ir.superficies.length} superficie(s)`);
767
+ }
768
+ if (ir.tasks.length > 0) {
769
+ partes.push(`${ir.tasks.length} task(s)`);
770
+ }
771
+ const foco = ir.routes[0]?.nome ?? ir.superficies[0]?.nome ?? ir.tasks[0]?.nome ?? modulo;
772
+ return partes.length > 0
773
+ ? `governa ${partes.join(", ")} com foco em ${normalizarIdentificadorResumo(foco)}`
774
+ : `governa o modulo ${normalizarIdentificadorResumo(modulo)}`;
775
+ }
776
+ function criarGuiaCapacidadeIa() {
777
+ return {
778
+ pequena: {
779
+ descricao: "IA gratuita ou com contexto curto. Leia so o cartao semantico e o briefing minimo.",
780
+ artefatos: ["resumo.micro.txt", "briefing.min.json", "prompt-curto.txt"],
781
+ ordemLeitura: ["resumo.micro.txt", "briefing.min.json", "resumo.curto.txt"],
782
+ evitar: ["ast.json", "ir.json", "diagnosticos.json"],
783
+ },
784
+ media: {
785
+ descricao: "IA com contexto medio. Aguenta resumo expandido, briefing minimo e drift.",
786
+ artefatos: ["resumo.curto.txt", "briefing.min.json", "drift.json", "prompt-curto.txt"],
787
+ ordemLeitura: ["resumo.curto.txt", "briefing.min.json", "drift.json", "resumo.md"],
788
+ evitar: ["ast.json"],
789
+ },
790
+ grande: {
791
+ descricao: "IA com contexto grande ou tool use. Pode consumir o pacote completo.",
792
+ artefatos: ["README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
793
+ ordemLeitura: ["README.md", "resumo.md", "briefing.json", "drift.json", "ir.json", "ast.json"],
794
+ evitar: [],
795
+ },
796
+ };
797
+ }
798
+ function coletarResumoSemanticoModulo(contexto) {
799
+ const { arquivo, modulo, geradoEm, ir, briefing, drift } = contexto;
800
+ const tarefas = ir?.tasks ?? [];
801
+ const rotas = ir?.routes ?? [];
802
+ const superficies = ir?.superficies ?? [];
803
+ const regrasCriticas = unicosOrdenados([
804
+ ...tarefas.flatMap((task) => task.rules),
805
+ ...tarefas.flatMap((task) => task.guarantees),
806
+ ]);
807
+ const efeitos = unicosOrdenados([
808
+ ...tarefas.flatMap((task) => task.effects),
809
+ ...rotas.flatMap((route) => route.efeitosPublicos.map((efeito) => formatarEfeitoSemanticoResumido(efeito))),
810
+ ...superficies.flatMap((superficie) => superficie.effects.map((efeito) => formatarEfeitoSemanticoResumido(efeito))),
811
+ ]);
812
+ const erros = unicosOrdenados([
813
+ ...tarefas.flatMap((task) => Object.keys(task.errors)),
814
+ ...tarefas.flatMap((task) => task.errosDetalhados.map((erro) => erro.codigo)),
815
+ ...rotas.flatMap((route) => route.errosPublicos.map((erro) => erro.codigo)),
816
+ ]);
817
+ const entidadesAfetadas = unicosOrdenados([
818
+ ...(ir?.resumoAgente.entidadesAfetadas ?? []),
819
+ ...tarefas.flatMap((task) => task.resumoAgente.entidadesAfetadas),
820
+ ...rotas.flatMap((route) => route.resumoAgente.entidadesAfetadas),
821
+ ...superficies.flatMap((superficie) => superficie.resumoAgente.entidadesAfetadas),
822
+ ]);
823
+ return {
824
+ geradoEm,
825
+ arquivo,
826
+ modulo,
827
+ perfilCompatibilidade: ir?.perfilCompatibilidade ?? briefing.perfilCompatibilidade,
828
+ scoreSemantico: briefing.scoreSemantico,
829
+ confiancaGeral: briefing.confiancaGeral,
830
+ riscoOperacional: calcularRiscoOperacionalResumo(drift.resumo),
831
+ faz: descreverFazModulo(ir, modulo),
832
+ tarefasPrincipais: limitarLista(tarefas.map((task) => task.nome), 6),
833
+ entradasChave: limitarLista(tarefas.map((task) => resumirCamposTask(task, "input", 4)), 4),
834
+ saidasChave: limitarLista(tarefas.map((task) => resumirCamposTask(task, "output", 4)), 4),
835
+ superficiesPublicas: limitarLista(unicosOrdenados([
836
+ ...briefing.superficiesImpactadas,
837
+ ...rotas.map((route) => `${route.metodo ?? "?"} ${route.caminho ?? route.nome}`),
838
+ ]), 8),
839
+ regrasCriticas: limitarLista(regrasCriticas, 8),
840
+ efeitos: limitarLista(efeitos, 8),
841
+ erros: limitarLista(erros, 8),
842
+ entidadesAfetadas: limitarLista(entidadesAfetadas, 8),
843
+ arquivosProvaveis: limitarLista(unicosOrdenados(briefing.oQueTocar), 8),
844
+ simbolosRelacionados: limitarLista(unicosOrdenados(briefing.simbolosRelacionados), 8),
845
+ riscosPrincipais: limitarLista(unicosOrdenados(briefing.riscosPrincipais), 6),
846
+ lacunas: limitarLista(unicosOrdenados(briefing.oQueEstaFrouxo), 6),
847
+ inferido: limitarLista(unicosOrdenados(briefing.oQueFoiInferido), 6),
848
+ checksSugeridos: limitarLista(unicosOrdenados(briefing.oQueValidar), 6),
849
+ testesMinimos: limitarLista(unicosOrdenados(briefing.testesMinimos), 6),
850
+ };
851
+ }
852
+ function renderizarResumoModuloTexto(resumo, tamanho, modo) {
853
+ const limite = tamanho === "micro" ? 2 : tamanho === "curto" ? 4 : 6;
854
+ const linhas = [
855
+ `MODO: ${modo}`,
856
+ `MODULO: ${resumo.modulo}`,
857
+ `FAZ: ${resumo.faz}`,
858
+ `PERFIL: ${resumo.perfilCompatibilidade}`,
859
+ `PUBLICO: ${resumirListaTexto(resumo.superficiesPublicas, limite)}`,
860
+ `TAREFAS: ${resumirListaTexto(resumo.tarefasPrincipais, limite)}`,
861
+ `ENTRADAS: ${resumirListaTexto(resumo.entradasChave, limite)}`,
862
+ `SAIDAS: ${resumirListaTexto(resumo.saidasChave, limite)}`,
863
+ `REGRAS: ${resumirListaTexto(resumo.regrasCriticas, limite)}`,
864
+ `EFEITOS: ${resumirListaTexto(resumo.efeitos, limite)}`,
865
+ `ERROS: ${resumirListaTexto(resumo.erros, limite)}`,
866
+ `TOCAR: ${resumirListaTexto(resumo.arquivosProvaveis, limite)}`,
867
+ `VALIDAR: ${resumirListaTexto(resumo.checksSugeridos, limite)}`,
868
+ `TESTES: ${resumirListaTexto(resumo.testesMinimos, limite)}`,
869
+ `RISCOS: ${resumirListaTexto(resumo.riscosPrincipais, limite)}`,
870
+ `LACUNAS: ${resumirListaTexto(resumo.lacunas, limite)}`,
871
+ `INFERIDO: ${resumirListaTexto(resumo.inferido, limite)}`,
872
+ `CONFIANCA: ${resumo.confiancaGeral}`,
873
+ `RISCO_OPERACIONAL: ${resumo.riscoOperacional}`,
874
+ `SCORE: ${resumo.scoreSemantico}`,
875
+ `GERADO_EM: ${resumo.geradoEm}`,
876
+ ];
877
+ if (tamanho === "micro") {
878
+ return `${linhas.slice(0, 12).join("\n")}\n`;
879
+ }
880
+ return `${linhas.join("\n")}\n`;
881
+ }
882
+ function renderizarResumoModuloMarkdown(resumo, modo, guiaPorCapacidade) {
883
+ const linhas = [
884
+ `# Resumo Sema para ${resumo.modulo}`,
885
+ "",
886
+ `- Modo: \`${modo}\``,
887
+ `- Gerado em: \`${resumo.geradoEm}\``,
888
+ `- Arquivo: \`${resumo.arquivo}\``,
889
+ `- Perfil: \`${resumo.perfilCompatibilidade}\``,
890
+ `- Score: \`${resumo.scoreSemantico}\``,
891
+ `- Confianca: \`${resumo.confiancaGeral}\``,
892
+ `- Risco operacional: \`${resumo.riscoOperacional}\``,
893
+ "",
894
+ "## O que este modulo faz",
895
+ "",
896
+ `- ${resumo.faz}`,
897
+ `- Superficies publicas: ${resumirListaTexto(resumo.superficiesPublicas, 8)}`,
898
+ `- Tarefas principais: ${resumirListaTexto(resumo.tarefasPrincipais, 8)}`,
899
+ "",
900
+ "## Contrato util para IA",
901
+ "",
902
+ `- Entradas chave: ${resumirListaTexto(resumo.entradasChave, 6)}`,
903
+ `- Saidas chave: ${resumirListaTexto(resumo.saidasChave, 6)}`,
904
+ `- Regras criticas: ${resumirListaTexto(resumo.regrasCriticas, 6)}`,
905
+ `- Efeitos: ${resumirListaTexto(resumo.efeitos, 6)}`,
906
+ `- Erros: ${resumirListaTexto(resumo.erros, 6)}`,
907
+ `- Entidades afetadas: ${resumirListaTexto(resumo.entidadesAfetadas, 6)}`,
908
+ "",
909
+ "## Intervencao segura",
910
+ "",
911
+ `- Arquivos provaveis: ${resumirListaTexto(resumo.arquivosProvaveis, 6)}`,
912
+ `- Simbolos relacionados: ${resumirListaTexto(resumo.simbolosRelacionados, 6)}`,
913
+ `- Riscos principais: ${resumirListaTexto(resumo.riscosPrincipais, 6)}`,
914
+ `- Lacunas: ${resumirListaTexto(resumo.lacunas, 6)}`,
915
+ `- O que foi inferido: ${resumirListaTexto(resumo.inferido, 6)}`,
916
+ `- Checks sugeridos: ${resumirListaTexto(resumo.checksSugeridos, 6)}`,
917
+ `- Testes minimos: ${resumirListaTexto(resumo.testesMinimos, 6)}`,
918
+ "",
919
+ "## Guia por capacidade de IA",
920
+ "",
921
+ ];
922
+ for (const capacidade of ["pequena", "media", "grande"]) {
923
+ const guia = guiaPorCapacidade[capacidade];
924
+ linhas.push(`### ${capacidade}`);
925
+ linhas.push("");
926
+ linhas.push(`- ${guia.descricao}`);
927
+ linhas.push(`- Artefatos: ${guia.artefatos.map((item) => `\`${item}\``).join(", ")}`);
928
+ linhas.push(`- Ordem de leitura: ${guia.ordemLeitura.map((item) => `\`${item}\``).join(" -> ")}`);
929
+ linhas.push(`- Evitar: ${guia.evitar.length > 0 ? guia.evitar.map((item) => `\`${item}\``).join(", ") : "nada obrigatorio"}`);
930
+ linhas.push("");
931
+ }
932
+ return `${linhas.join("\n").trim()}\n`;
933
+ }
934
+ function criarBriefingMinimo(resumo, modo, tamanho) {
935
+ return {
936
+ comando: "briefing-minimo",
937
+ geradoEm: resumo.geradoEm,
938
+ cliVersao: VERSAO_CLI,
939
+ modo,
940
+ tamanho,
941
+ arquivo: resumo.arquivo,
942
+ modulo: resumo.modulo,
943
+ perfilCompatibilidade: resumo.perfilCompatibilidade,
944
+ scoreSemantico: resumo.scoreSemantico,
945
+ confiancaGeral: resumo.confiancaGeral,
946
+ riscoOperacional: resumo.riscoOperacional,
947
+ faz: resumo.faz,
948
+ publico: resumo.superficiesPublicas,
949
+ tarefasPrincipais: resumo.tarefasPrincipais,
950
+ entradasChave: resumo.entradasChave,
951
+ saidasChave: resumo.saidasChave,
952
+ regrasCriticas: resumo.regrasCriticas,
953
+ efeitos: resumo.efeitos,
954
+ erros: resumo.erros,
955
+ arquivosProvaveis: resumo.arquivosProvaveis,
956
+ simbolosRelacionados: resumo.simbolosRelacionados,
957
+ riscosPrincipais: resumo.riscosPrincipais,
958
+ lacunas: resumo.lacunas,
959
+ inferido: resumo.inferido,
960
+ checksSugeridos: resumo.checksSugeridos,
961
+ testesMinimos: resumo.testesMinimos,
962
+ };
963
+ }
964
+ function criarPromptCurtoModulo(resumo, modo, tamanho, capacidade) {
965
+ const resumoTexto = renderizarResumoModuloTexto(resumo, tamanho, modo).trim();
966
+ return `Voce esta operando Sema em modo IA-first.
967
+
968
+ Esta linguagem nao foi desenhada para agradar humano; ela existe para reduzir ambiguidade para IA.
969
+
970
+ Capacidade alvo: ${capacidade}
971
+ Modo da tarefa: ${modo}
972
+
973
+ Regras:
974
+ - nao invente sintaxe nem bloco fora da gramatica oficial
975
+ - preserve a intencao do contrato
976
+ - use este resumo como fonte compacta inicial
977
+ - se a tarefa pedir mais contexto, suba para \`briefing.min.json\`, \`drift.json\` e depois \`ir.json\`
978
+ - nao saia editando backend vivo sem olhar risco, lacuna e checks sugeridos
979
+
980
+ Contexto compacto:
981
+ ${resumoTexto}
982
+ `;
983
+ }
984
+ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
985
+ const linhas = [
986
+ "# SEMA_BRIEF",
987
+ "",
988
+ "Sema e IA-first. Este arquivo existe para IA achar o ponto de entrada do projeto sem ter que catar o repo inteiro feito barata tonta.",
989
+ "",
990
+ `- Gerado em: \`${geradoEm}\``,
991
+ `- Modulos: \`${modulos.length}\``,
992
+ "",
993
+ "## Guia por capacidade",
994
+ "",
995
+ ];
996
+ for (const capacidade of ["pequena", "media", "grande"]) {
997
+ const guia = guiaPorCapacidade[capacidade];
998
+ linhas.push(`- ${capacidade}: ${guia.descricao} Artefatos: ${guia.artefatos.join(", ")}.`);
999
+ }
1000
+ linhas.push("");
1001
+ linhas.push("## Modulos");
1002
+ linhas.push("");
1003
+ for (const modulo of modulos) {
1004
+ linhas.push(`### ${modulo.modulo}`);
1005
+ linhas.push(`- Faz: ${modulo.faz}`);
1006
+ linhas.push(`- Publico: ${resumirListaTexto(modulo.superficiesPublicas, 4)}`);
1007
+ linhas.push(`- Tocar: ${resumirListaTexto(modulo.arquivosProvaveis, 4)}`);
1008
+ linhas.push(`- Score: ${modulo.scoreSemantico} | Confianca: ${modulo.confiancaGeral} | Risco: ${modulo.riscoOperacional}`);
1009
+ linhas.push(`- Lacunas: ${resumirListaTexto(modulo.lacunas, 4)}`);
1010
+ linhas.push("");
1011
+ }
1012
+ return `${linhas.join("\n").trim()}\n`;
1013
+ }
661
1014
  function falharContextoIa(mensagem) {
662
1015
  throw new Error(mensagem);
663
1016
  }
@@ -767,17 +1120,13 @@ function criarBriefingAgente(arquivo, modulo, ir, resumoDrift, resultadoDrift) {
767
1120
  testesMinimos: [
768
1121
  "sema validar <arquivo> --json",
769
1122
  "sema drift <arquivo> --json",
770
- "sema verificar exemplos --json",
1123
+ "sema verificar <arquivo-ou-pasta> --json",
771
1124
  ],
772
1125
  };
773
1126
  }
774
- async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
1127
+ async function carregarContextoModuloIa(arquivoEntrada) {
775
1128
  const arquivo = path.resolve(arquivoEntrada);
776
1129
  garantirArquivoSema(arquivo);
777
- const pastaBase = pastaSaidaOpcional
778
- ? path.resolve(pastaSaidaOpcional)
779
- : path.resolve(process.cwd(), ".tmp", "contexto-ia", path.basename(arquivo, ".sema"));
780
- await mkdir(pastaBase, { recursive: true });
781
1130
  const contextoProjeto = await carregarProjeto(arquivo, process.cwd());
782
1131
  const resultadoModulo = contextoProjeto.modulosSelecionados.find((item) => path.resolve(item.caminho) === arquivo)?.resultado;
783
1132
  if (!resultadoModulo) {
@@ -785,6 +1134,7 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
785
1134
  }
786
1135
  const sucesso = !temErros(resultadoModulo.diagnosticos);
787
1136
  const modulo = resultadoModulo.modulo?.nome ?? path.basename(arquivo, ".sema");
1137
+ const geradoEm = new Date().toISOString();
788
1138
  const resultadoDrift = await analisarDriftLegado(contextoProjeto);
789
1139
  const drift = {
790
1140
  comando: "drift",
@@ -829,21 +1179,142 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
829
1179
  ir: resultadoModulo.ir ?? null,
830
1180
  };
831
1181
  const briefing = criarBriefingAgente(arquivo, modulo, resultadoModulo.ir ?? null, drift.resumo, resultadoDrift);
832
- await writeFile(path.join(pastaBase, "validar.json"), `${JSON.stringify(validar, null, 2)}\n`, "utf8");
833
- await writeFile(path.join(pastaBase, "diagnosticos.json"), `${JSON.stringify(diagnosticos, null, 2)}\n`, "utf8");
834
- await writeFile(path.join(pastaBase, "ast.json"), `${JSON.stringify(ast, null, 2)}\n`, "utf8");
835
- await writeFile(path.join(pastaBase, "ir.json"), `${JSON.stringify(ir, null, 2)}\n`, "utf8");
836
- await writeFile(path.join(pastaBase, "drift.json"), `${JSON.stringify(drift, null, 2)}\n`, "utf8");
837
- await writeFile(path.join(pastaBase, "briefing.json"), `${JSON.stringify(briefing, null, 2)}\n`, "utf8");
838
- const resumo = `# Contexto de IA para ${modulo}
839
-
840
- - Arquivo alvo: \`${arquivo}\`
841
- - Modulo: \`${modulo}\`
842
- - Sucesso em validar: \`${sucesso}\`
843
- - Quantidade de diagnosticos: \`${resultadoModulo.diagnosticos.length}\`
1182
+ return {
1183
+ arquivo,
1184
+ modulo,
1185
+ sucesso,
1186
+ geradoEm,
1187
+ diagnosticos: resultadoModulo.diagnosticos,
1188
+ ir: resultadoModulo.ir ?? null,
1189
+ validar,
1190
+ diagnosticosJson: diagnosticos,
1191
+ ast,
1192
+ irJson: ir,
1193
+ drift,
1194
+ briefing,
1195
+ };
1196
+ }
1197
+ async function gerarArquivosResumoModuloIa(contexto, pastaBase) {
1198
+ const guiaPorCapacidade = criarGuiaCapacidadeIa();
1199
+ const resumoSemantico = coletarResumoSemanticoModulo(contexto);
1200
+ const resumoMicro = renderizarResumoModuloTexto(resumoSemantico, "micro", "resumo");
1201
+ const resumoCurto = renderizarResumoModuloTexto(resumoSemantico, "curto", "resumo");
1202
+ const resumoMarkdown = renderizarResumoModuloMarkdown(resumoSemantico, "resumo", guiaPorCapacidade);
1203
+ const briefingMinimo = criarBriefingMinimo(resumoSemantico, "resumo", "curto");
1204
+ const promptCurto = criarPromptCurtoModulo(resumoSemantico, "mudanca", "curto", "pequena");
1205
+ await writeFile(path.join(pastaBase, "resumo.micro.txt"), resumoMicro, "utf8");
1206
+ await writeFile(path.join(pastaBase, "resumo.curto.txt"), resumoCurto, "utf8");
1207
+ await writeFile(path.join(pastaBase, "resumo.md"), resumoMarkdown, "utf8");
1208
+ await writeFile(path.join(pastaBase, "briefing.min.json"), `${JSON.stringify(briefingMinimo, null, 2)}\n`, "utf8");
1209
+ await writeFile(path.join(pastaBase, "prompt-curto.txt"), promptCurto, "utf8");
1210
+ return {
1211
+ artefatosCompactos: ["resumo.micro.txt", "resumo.curto.txt", "resumo.md", "briefing.min.json", "prompt-curto.txt"],
1212
+ guiaPorCapacidade,
1213
+ };
1214
+ }
1215
+ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz = false) {
1216
+ const contextoProjeto = await carregarProjeto(entrada, process.cwd());
1217
+ const geradoEm = new Date().toISOString();
1218
+ const guiaPorCapacidade = criarGuiaCapacidadeIa();
1219
+ const resultadoDrift = await analisarDriftLegado(contextoProjeto);
1220
+ const modulos = contextoProjeto.modulosSelecionados.map((item) => {
1221
+ const modulo = item.resultado.modulo?.nome ?? path.basename(item.caminho, ".sema");
1222
+ const driftResumo = resumirDriftPorModulo(modulo, item.caminho, resultadoDrift);
1223
+ const briefing = criarBriefingAgente(item.caminho, modulo, item.resultado.ir ?? null, driftResumo, resultadoDrift);
1224
+ return coletarResumoSemanticoModulo({
1225
+ arquivo: item.caminho,
1226
+ modulo,
1227
+ geradoEm,
1228
+ ir: item.resultado.ir ?? null,
1229
+ briefing,
1230
+ drift: {
1231
+ comando: "drift",
1232
+ caminho: item.caminho,
1233
+ modulo,
1234
+ sucesso: resultadoDrift.sucesso,
1235
+ resumo: driftResumo,
1236
+ drift: resultadoDrift,
1237
+ },
1238
+ });
1239
+ });
1240
+ const baseProjeto = contextoProjeto.baseProjeto;
1241
+ const pastaSaida = escreverNaRaiz
1242
+ ? baseProjeto
1243
+ : pastaSaidaOpcional
1244
+ ? path.resolve(pastaSaidaOpcional)
1245
+ : path.resolve(baseProjeto, ".tmp", "sema-resumo");
1246
+ await mkdir(pastaSaida, { recursive: true });
1247
+ const semaBrief = renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade);
1248
+ const indexJson = {
1249
+ comando: "resumo-projeto",
1250
+ geradoEm,
1251
+ cliVersao: VERSAO_CLI,
1252
+ baseProjeto,
1253
+ totalModulos: modulos.length,
1254
+ guiaPorCapacidade,
1255
+ modulos,
1256
+ };
1257
+ const micro = [
1258
+ `PROJETO: ${path.basename(baseProjeto)}`,
1259
+ `MODULOS: ${modulos.length}`,
1260
+ `TOP_MODULOS: ${resumirListaTexto(modulos.map((modulo) => modulo.modulo), 3)}`,
1261
+ `TOP_RISCOS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.riscosPrincipais)), 3)}`,
1262
+ `TOP_LACUNAS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.lacunas)), 3)}`,
1263
+ `GERADO_EM: ${geradoEm}`,
1264
+ "",
1265
+ ].join("\n");
1266
+ const curto = [
1267
+ `PROJETO: ${path.basename(baseProjeto)}`,
1268
+ `BASE: ${baseProjeto}`,
1269
+ `MODULOS: ${modulos.length}`,
1270
+ `TOP_MODULOS: ${resumirListaTexto(modulos.map((modulo) => modulo.modulo), 6)}`,
1271
+ `TOP_RISCOS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.riscosPrincipais)), 6)}`,
1272
+ `TOP_LACUNAS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.lacunas)), 6)}`,
1273
+ `TOP_ARQUIVOS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.arquivosProvaveis)), 6)}`,
1274
+ `GERADO_EM: ${geradoEm}`,
1275
+ "",
1276
+ ].join("\n");
1277
+ await writeFile(path.join(pastaSaida, "SEMA_BRIEF.md"), semaBrief, "utf8");
1278
+ await writeFile(path.join(pastaSaida, "SEMA_BRIEF.micro.txt"), micro, "utf8");
1279
+ await writeFile(path.join(pastaSaida, "SEMA_BRIEF.curto.txt"), curto, "utf8");
1280
+ await writeFile(path.join(pastaSaida, "SEMA_INDEX.json"), `${JSON.stringify(indexJson, null, 2)}\n`, "utf8");
1281
+ return {
1282
+ geradoEm,
1283
+ baseProjeto,
1284
+ pastaSaida,
1285
+ artefatos: ["SEMA_BRIEF.md", "SEMA_BRIEF.micro.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json"],
1286
+ modulos,
1287
+ guiaPorCapacidade,
1288
+ };
1289
+ }
1290
+ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
1291
+ const contexto = await carregarContextoModuloIa(arquivoEntrada);
1292
+ const pastaBase = pastaSaidaOpcional
1293
+ ? path.resolve(pastaSaidaOpcional)
1294
+ : path.resolve(process.cwd(), ".tmp", "contexto-ia", path.basename(contexto.arquivo, ".sema"));
1295
+ await mkdir(pastaBase, { recursive: true });
1296
+ await writeFile(path.join(pastaBase, "validar.json"), `${JSON.stringify(contexto.validar, null, 2)}\n`, "utf8");
1297
+ await writeFile(path.join(pastaBase, "diagnosticos.json"), `${JSON.stringify(contexto.diagnosticosJson, null, 2)}\n`, "utf8");
1298
+ await writeFile(path.join(pastaBase, "ast.json"), `${JSON.stringify(contexto.ast, null, 2)}\n`, "utf8");
1299
+ await writeFile(path.join(pastaBase, "ir.json"), `${JSON.stringify(contexto.irJson, null, 2)}\n`, "utf8");
1300
+ await writeFile(path.join(pastaBase, "drift.json"), `${JSON.stringify(contexto.drift, null, 2)}\n`, "utf8");
1301
+ await writeFile(path.join(pastaBase, "briefing.json"), `${JSON.stringify(contexto.briefing, null, 2)}\n`, "utf8");
1302
+ const resumoGerado = await gerarArquivosResumoModuloIa(contexto, pastaBase);
1303
+ const resumo = `# Contexto de IA para ${contexto.modulo}
1304
+
1305
+ - Arquivo alvo: \`${contexto.arquivo}\`
1306
+ - Modulo: \`${contexto.modulo}\`
1307
+ - Sucesso em validar: \`${contexto.sucesso}\`
1308
+ - Quantidade de diagnosticos: \`${contexto.diagnosticos.length}\`
1309
+ - Gerado em: \`${contexto.geradoEm}\`
844
1310
 
845
1311
  ## Arquivos gerados neste pacote
846
1312
 
1313
+ - \`resumo.micro.txt\`
1314
+ - \`resumo.curto.txt\`
1315
+ - \`resumo.md\`
1316
+ - \`briefing.min.json\`
1317
+ - \`prompt-curto.txt\`
847
1318
  - \`validar.json\`
848
1319
  - \`diagnosticos.json\`
849
1320
  - \`ast.json\`
@@ -853,28 +1324,61 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
853
1324
 
854
1325
  ## Fluxo recomendado para o agente
855
1326
 
856
- 1. Ler \`ast.json\` para entender a forma escrita.
857
- 2. Ler \`ir.json\` para entender a forma semantica resolvida.
858
- 3. Ler \`drift.json\` para ver quais arquivos e simbolos vivos sustentam a implementacao.
859
- 4. Ler \`briefing.json\` para saber o que tocar, o que validar e o que esta frouxo.
860
- 5. Ler \`diagnosticos.json\` se houver falha ou aviso relevante.
861
- 6. Editar o arquivo \`.sema\`.
862
- 7. Rodar \`sema formatar "${arquivo}"\`.
863
- 8. Rodar \`sema validar "${arquivo}" --json\`.
864
- 9. Fechar com \`sema verificar exemplos --json --saida ./.tmp/verificacao-ia\` ou \`npm run project:check\`.
1327
+ ### IA pequena ou gratuita
1328
+
1329
+ 1. Ler \`resumo.micro.txt\`.
1330
+ 2. Ler \`briefing.min.json\`.
1331
+ 3. Se ainda couber contexto, ler \`resumo.curto.txt\`.
1332
+
1333
+ ### IA media
1334
+
1335
+ 1. Ler \`resumo.curto.txt\`.
1336
+ 2. Ler \`briefing.min.json\`.
1337
+ 3. Ler \`drift.json\`.
1338
+ 4. Se precisar, subir para \`resumo.md\`.
1339
+
1340
+ ### IA grande ou com tool use
1341
+
1342
+ 1. Ler \`README.md\`.
1343
+ 2. Ler \`resumo.md\`.
1344
+ 3. Ler \`briefing.json\`.
1345
+ 4. Ler \`drift.json\`.
1346
+ 5. So depois abrir \`ir.json\` e \`ast.json\`.
1347
+
1348
+ ## Fechamento
1349
+
1350
+ 1. Editar o arquivo \`.sema\`.
1351
+ 2. Rodar \`sema formatar "${contexto.arquivo}"\`.
1352
+ 3. Rodar \`sema validar "${contexto.arquivo}" --json\`.
1353
+ 4. Rodar \`sema drift "${contexto.arquivo}" --json\`.
1354
+ 5. Fechar com \`sema verificar <arquivo-ou-pasta> --json --saida ./.tmp/verificacao-ia\`.
865
1355
 
866
1356
  ## Textos base para onboarding do agente
867
1357
 
868
1358
  - \`sema starter-ia\`
1359
+ - \`sema resumo "${contexto.arquivo}" --micro --para onboarding\`
1360
+ - \`sema prompt-curto "${contexto.arquivo}" --para mudanca\`
869
1361
  - \`sema prompt-ia\`
870
1362
  `;
871
1363
  await writeFile(path.join(pastaBase, "README.md"), resumo, "utf8");
872
1364
  return {
873
- sucesso: true,
874
- arquivo,
875
- modulo,
1365
+ sucesso: contexto.sucesso,
1366
+ arquivo: contexto.arquivo,
1367
+ modulo: contexto.modulo,
876
1368
  pastaSaida: pastaBase,
877
- artefatos: ["validar.json", "diagnosticos.json", "ast.json", "ir.json", "drift.json", "briefing.json", "README.md"],
1369
+ artefatos: [
1370
+ "validar.json",
1371
+ "diagnosticos.json",
1372
+ "ast.json",
1373
+ "ir.json",
1374
+ "drift.json",
1375
+ "briefing.json",
1376
+ "README.md",
1377
+ ...resumoGerado.artefatosCompactos,
1378
+ ],
1379
+ artefatosCompactos: resumoGerado.artefatosCompactos,
1380
+ geradoEm: contexto.geradoEm,
1381
+ guiaPorCapacidade: resumoGerado.guiaPorCapacidade,
878
1382
  };
879
1383
  }
880
1384
  async function comandoIniciar(cwd, template) {
@@ -1943,13 +2447,15 @@ async function comandoAjudaIa() {
1943
2447
  console.log(renderizarCabecalhoDocsIa(descoberta));
1944
2448
  console.log("");
1945
2449
  console.log("O que a Sema faz de verdade");
2450
+ console.log("- Foi feita para IA operar melhor; leitura humana e consequencia, nao centro de produto.");
1946
2451
  console.log("- Governa contrato, intencao, erro, efeito, garantia, fluxo, vinculos e execucao.");
1947
2452
  console.log("- Usa `importar` para bootstrap revisavel de legado.");
1948
2453
  console.log("- Usa `impl` para ligar contrato a simbolos reais.");
1949
2454
  console.log("- Usa `vinculos` para ligar contrato a arquivo, simbolo, recurso e superficie real.");
1950
2455
  console.log("- Usa `execucao` para explicitar timeout, retry, compensacao e criticidade.");
1951
2456
  console.log("- Usa `drift` para medir divergencia entre contrato e codigo vivo com score, confianca e lacunas.");
1952
- console.log("- Usa `contexto-ia` para preparar AST, IR, diagnosticos, drift e `briefing.json` antes da edicao.");
2457
+ console.log("- Usa `resumo` e `prompt-curto` para IA pequena ou gratuita.");
2458
+ console.log("- Usa `contexto-ia` para preparar AST, IR, diagnosticos, drift, `briefing.json` e artefatos compactos antes da edicao.");
1953
2459
  console.log("");
1954
2460
  console.log("O que a Sema nao promete");
1955
2461
  console.log("- Nao escreve contrato final sozinho.");
@@ -1958,6 +2464,8 @@ async function comandoAjudaIa() {
1958
2464
  console.log("");
1959
2465
  console.log("Fluxo recomendado");
1960
2466
  console.log("- Use `sema starter-ia` para um texto curto de onboarding.");
2467
+ console.log("- Use `sema resumo <arquivo> --micro --para onboarding` para IA pequena.");
2468
+ console.log("- Use `sema prompt-curto <arquivo> --curto --para mudanca` para colar contexto em modelo gratuito.");
1961
2469
  console.log("- Use `sema prompt-ia` para o prompt-base geral.");
1962
2470
  console.log("- Use `sema prompt-ia-ui` para tarefas visuais com Sema + UI.");
1963
2471
  console.log("- Use `sema prompt-ia-react` para projeto com Sema + React + TypeScript.");
@@ -1965,14 +2473,15 @@ async function comandoAjudaIa() {
1965
2473
  console.log("- Use `sema exemplos-prompt-ia` para pegar modelos prontos de prompt.");
1966
2474
  console.log("- Use `sema inspecionar` para descobrir base, codigo vivo e fontes legado.");
1967
2475
  console.log("- Use `sema drift` para medir impls, vinculos, rotas, score e lacunas.");
1968
- console.log("- Use `sema contexto-ia <arquivo.sema>` para gerar AST, IR, drift e `briefing.json` do modulo alvo.");
2476
+ console.log("- Use `sema contexto-ia <arquivo.sema>` para gerar AST, IR, drift, `briefing.json` e `briefing.min.json` do modulo alvo.");
1969
2477
  console.log("- Use `sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart> --saida <diretorio>` quando a tarefa pedir codigo derivado.");
1970
2478
  console.log("");
1971
2479
  console.log("Regra pratica");
1972
2480
  console.log("- Se voce quer testar a Sema de verdade, nao peca so HTML solto.");
1973
2481
  console.log("- Peca `.sema` + arquitetura + React + TypeScript, ou use o modo `Sema primeiro`.");
1974
2482
  console.log("- Se o projeto ja existe, trate `importar` como rascunho e `drift` como juiz.");
1975
- console.log("- Antes de editar backend vivo, leia `briefing.json` em vez de sair cavando arquivo na fe.");
2483
+ console.log("- IA pequena comeca no menor artefato que resolve a tarefa; nao enfie `ast.json` inteiro nela de bobeira.");
2484
+ console.log("- Antes de editar backend vivo, leia `briefing.min.json` ou `briefing.json` em vez de sair cavando arquivo na fe.");
1976
2485
  console.log("- Trate `route`, `worker`, `evento`, `fila`, `cron`, `webhook`, `cache`, `storage` e `policy` como superficies de primeira classe.");
1977
2486
  return 0;
1978
2487
  }
@@ -2021,6 +2530,142 @@ async function comandoExemplosPromptIa() {
2021
2530
  console.log(EXEMPLOS_PROMPT_IA);
2022
2531
  return 0;
2023
2532
  }
2533
+ async function comandoResumo(entrada, args, emJson) {
2534
+ const tamanho = normalizarTamanhoResumo(args);
2535
+ const modo = normalizarModoResumo(obterOpcao(args, "--para"));
2536
+ const pastaSaida = obterOpcao(args, "--saida");
2537
+ const escreverNaRaiz = possuiFlag(args, "--raiz");
2538
+ const alvo = entrada ? path.resolve(process.cwd(), entrada) : process.cwd();
2539
+ if (entrada && entrada.toLowerCase().endsWith(".sema")) {
2540
+ const contexto = await carregarContextoModuloIa(alvo);
2541
+ const resumoSemantico = coletarResumoSemanticoModulo(contexto);
2542
+ const guiaPorCapacidade = criarGuiaCapacidadeIa();
2543
+ const texto = tamanho === "medio"
2544
+ ? renderizarResumoModuloMarkdown(resumoSemantico, modo, guiaPorCapacidade)
2545
+ : renderizarResumoModuloTexto(resumoSemantico, tamanho, modo);
2546
+ let pastaResumo;
2547
+ let artefatosCompactos = [];
2548
+ if (pastaSaida) {
2549
+ pastaResumo = path.resolve(pastaSaida);
2550
+ await mkdir(pastaResumo, { recursive: true });
2551
+ const gerado = await gerarArquivosResumoModuloIa(contexto, pastaResumo);
2552
+ artefatosCompactos = gerado.artefatosCompactos;
2553
+ }
2554
+ if (emJson) {
2555
+ console.log(JSON.stringify({
2556
+ comando: "resumo",
2557
+ modo,
2558
+ tamanho,
2559
+ geradoEm: contexto.geradoEm,
2560
+ arquivo: contexto.arquivo,
2561
+ modulo: contexto.modulo,
2562
+ pastaSaida: pastaResumo ?? null,
2563
+ artefatosCompactos,
2564
+ guiaPorCapacidade,
2565
+ resumo: resumoSemantico,
2566
+ texto,
2567
+ }, null, 2));
2568
+ return 0;
2569
+ }
2570
+ if (pastaResumo) {
2571
+ console.log(`Resumo IA-first gerado em ${pastaResumo}`);
2572
+ console.log("");
2573
+ }
2574
+ console.log(texto);
2575
+ return 0;
2576
+ }
2577
+ const resumoProjeto = await gerarResumoProjetoIa(alvo, pastaSaida, escreverNaRaiz);
2578
+ const arquivoResumo = tamanho === "micro"
2579
+ ? "SEMA_BRIEF.micro.txt"
2580
+ : tamanho === "curto"
2581
+ ? "SEMA_BRIEF.curto.txt"
2582
+ : "SEMA_BRIEF.md";
2583
+ const texto = await readFile(path.join(resumoProjeto.pastaSaida, arquivoResumo), "utf8");
2584
+ if (emJson) {
2585
+ console.log(JSON.stringify({
2586
+ comando: "resumo",
2587
+ modo,
2588
+ tamanho,
2589
+ geradoEm: resumoProjeto.geradoEm,
2590
+ baseProjeto: resumoProjeto.baseProjeto,
2591
+ pastaSaida: resumoProjeto.pastaSaida,
2592
+ artefatos: resumoProjeto.artefatos,
2593
+ guiaPorCapacidade: resumoProjeto.guiaPorCapacidade,
2594
+ modulos: resumoProjeto.modulos,
2595
+ texto,
2596
+ }, null, 2));
2597
+ return 0;
2598
+ }
2599
+ console.log(`Resumo IA-first do projeto gerado em ${resumoProjeto.pastaSaida}`);
2600
+ console.log("");
2601
+ console.log(texto);
2602
+ return 0;
2603
+ }
2604
+ async function comandoPromptCurto(entrada, args, emJson) {
2605
+ const tamanho = normalizarTamanhoResumo(args);
2606
+ const modo = normalizarModoResumo(obterOpcao(args, "--para"));
2607
+ const alvo = entrada ? path.resolve(process.cwd(), entrada) : process.cwd();
2608
+ if (entrada && entrada.toLowerCase().endsWith(".sema")) {
2609
+ const contexto = await carregarContextoModuloIa(alvo);
2610
+ const resumoSemantico = coletarResumoSemanticoModulo(contexto);
2611
+ const capacidade = tamanho === "micro" ? "pequena" : tamanho === "curto" ? "media" : "grande";
2612
+ const prompt = criarPromptCurtoModulo(resumoSemantico, modo, tamanho, capacidade);
2613
+ if (emJson) {
2614
+ console.log(JSON.stringify({
2615
+ comando: "prompt-curto",
2616
+ modo,
2617
+ tamanho,
2618
+ capacidade,
2619
+ geradoEm: contexto.geradoEm,
2620
+ arquivo: contexto.arquivo,
2621
+ modulo: contexto.modulo,
2622
+ prompt,
2623
+ }, null, 2));
2624
+ return 0;
2625
+ }
2626
+ console.log(prompt);
2627
+ return 0;
2628
+ }
2629
+ const resumoProjeto = await gerarResumoProjetoIa(alvo);
2630
+ const arquivoResumo = tamanho === "micro"
2631
+ ? "SEMA_BRIEF.micro.txt"
2632
+ : tamanho === "curto"
2633
+ ? "SEMA_BRIEF.curto.txt"
2634
+ : "SEMA_BRIEF.md";
2635
+ const contextoProjeto = await readFile(path.join(resumoProjeto.pastaSaida, arquivoResumo), "utf8");
2636
+ const capacidade = tamanho === "micro" ? "pequena" : tamanho === "curto" ? "media" : "grande";
2637
+ const prompt = `Voce esta operando Sema em modo IA-first.
2638
+
2639
+ Isto nao e material feito para humano; e contexto comprimido para IA.
2640
+
2641
+ Capacidade alvo: ${capacidade}
2642
+ Modo da tarefa: ${modo}
2643
+
2644
+ Regras:
2645
+ - comece pelo resumo compacto abaixo
2646
+ - se a tarefa pedir mais contexto, abra \`SEMA_INDEX.json\`
2647
+ - nao tente ler o repo inteiro se o resumo ja disser onde tocar
2648
+ - preserve contrato, risco, lacuna e checks sugeridos
2649
+
2650
+ Contexto do projeto:
2651
+ ${contextoProjeto.trim()}
2652
+ `;
2653
+ if (emJson) {
2654
+ console.log(JSON.stringify({
2655
+ comando: "prompt-curto",
2656
+ modo,
2657
+ tamanho,
2658
+ capacidade,
2659
+ geradoEm: resumoProjeto.geradoEm,
2660
+ baseProjeto: resumoProjeto.baseProjeto,
2661
+ pastaSaida: resumoProjeto.pastaSaida,
2662
+ prompt,
2663
+ }, null, 2));
2664
+ return 0;
2665
+ }
2666
+ console.log(prompt);
2667
+ return 0;
2668
+ }
2024
2669
  async function comandoContextoIa(arquivo, pastaSaida, emJson) {
2025
2670
  const resultado = await gerarContextoIa(arquivo, pastaSaida);
2026
2671
  if (emJson) {
@@ -2271,6 +2916,12 @@ async function principal() {
2271
2916
  case "starter-ia":
2272
2917
  codigoSaida = await comandoStarterIa();
2273
2918
  break;
2919
+ case "resumo":
2920
+ codigoSaida = await comandoResumo(posicionais[0], resto, possuiFlag(resto, "--json"));
2921
+ break;
2922
+ case "prompt-curto":
2923
+ codigoSaida = await comandoPromptCurto(posicionais[0], resto, possuiFlag(resto, "--json"));
2924
+ break;
2274
2925
  case "prompt-ia":
2275
2926
  codigoSaida = await comandoPromptIa();
2276
2927
  break;