@semacode/cli 1.0.0 → 1.1.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/AGENTS.md +50 -0
- package/README.md +15 -2
- package/SEMA_BRIEF.curto.txt +9 -0
- package/SEMA_BRIEF.md +49 -0
- package/SEMA_BRIEF.micro.txt +7 -0
- package/SEMA_INDEX.json +501 -0
- package/dist/drift.d.ts +15 -0
- package/dist/drift.js +496 -5
- package/dist/drift.js.map +1 -1
- package/dist/importador.d.ts +1 -1
- package/dist/importador.js +681 -3
- package/dist/importador.js.map +1 -1
- package/dist/index.js +883 -79
- package/dist/index.js.map +1 -1
- package/dist/projeto.js +49 -1
- package/dist/projeto.js.map +1 -1
- package/dist/tipos.d.ts +1 -1
- package/docs/AGENT_STARTER.md +30 -4
- package/docs/instalacao-e-primeiro-uso.md +14 -7
- package/llms-full.txt +34 -0
- package/llms.txt +17 -0
- package/node_modules/@sema/gerador-dart/package.json +1 -1
- package/node_modules/@sema/gerador-python/dist/index.js +92 -10
- package/node_modules/@sema/gerador-python/dist/index.js.map +1 -1
- package/node_modules/@sema/gerador-python/package.json +1 -1
- package/node_modules/@sema/gerador-typescript/package.json +1 -1
- package/node_modules/@sema/nucleo/package.json +1 -1
- package/node_modules/@sema/padroes/dist/index.js +47 -1
- package/node_modules/@sema/padroes/dist/index.js.map +1 -1
- package/node_modules/@sema/padroes/package.json +1 -1
- package/package.json +14 -7
package/dist/index.js
CHANGED
|
@@ -12,7 +12,7 @@ import { gerarTypeScript } from "@sema/gerador-typescript";
|
|
|
12
12
|
import { carregarConfiguracaoProjeto, carregarProjeto, resolverAlvoPadrao, resolverAlvosVerificacao, resolverEstruturaSaidaPadrao, resolverFrameworkPadrao, resolverSaidaPadrao, } from "./projeto.js";
|
|
13
13
|
import { importarProjetoLegado, resumoImportacao } from "./importador.js";
|
|
14
14
|
import { analisarDriftLegado } from "./drift.js";
|
|
15
|
-
const STARTER_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao para IA
|
|
15
|
+
const STARTER_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao para IA sobre software vivo em backend e front consumer.
|
|
16
16
|
|
|
17
17
|
Importante:
|
|
18
18
|
- a Sema se apresenta publicamente como protocolo e funciona tecnicamente como linguagem de intencao
|
|
@@ -56,7 +56,7 @@ Comandos essenciais:
|
|
|
56
56
|
- validacao: \`sema validar <arquivo.sema> --json\`
|
|
57
57
|
- diagnosticos: \`sema diagnosticos <arquivo.sema> --json\`
|
|
58
58
|
- formatacao: \`sema formatar <arquivo.sema>\`
|
|
59
|
-
- importacao assistida de legado: \`sema importar <nestjs|fastapi|flask|nextjs|firebase|dotnet|java|go|rust|cpp|typescript|python|dart> <diretorio> --saida <diretorio>\`
|
|
59
|
+
- importacao assistida de legado: \`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>\`
|
|
60
60
|
- geracao de codigo: \`sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart> --saida <diretorio>\`
|
|
61
61
|
- verificacao final: \`sema verificar <arquivo-ou-pasta> [--json]\`
|
|
62
62
|
|
|
@@ -312,42 +312,106 @@ Comandos uteis da CLI para esse fluxo:
|
|
|
312
312
|
`;
|
|
313
313
|
const DIRETORIO_CLI_ATUAL = path.dirname(fileURLToPath(import.meta.url));
|
|
314
314
|
const VERSAO_CLI = pacoteCli.version;
|
|
315
|
+
const ARQUIVOS_CANONICOS_IA_RAIZ = [
|
|
316
|
+
"llms.txt",
|
|
317
|
+
"SEMA_BRIEF.md",
|
|
318
|
+
"SEMA_INDEX.json",
|
|
319
|
+
"AGENTS.md",
|
|
320
|
+
"README.md",
|
|
321
|
+
"llms-full.txt",
|
|
322
|
+
];
|
|
323
|
+
const DOCUMENTOS_SUPORTE_IA = [
|
|
324
|
+
"docs/AGENT_STARTER.md",
|
|
325
|
+
"docs/integracao-com-ia.md",
|
|
326
|
+
"docs/fluxo-pratico-ia-sema.md",
|
|
327
|
+
"docs/como-ensinar-a-sema-para-ia.md",
|
|
328
|
+
"docs/sintaxe.md",
|
|
329
|
+
"docs/cli.md",
|
|
330
|
+
];
|
|
315
331
|
function obterArgumentos() {
|
|
316
332
|
const [, , comando, ...resto] = process.argv;
|
|
317
333
|
return { comando: comando, resto };
|
|
318
334
|
}
|
|
335
|
+
function renderizarCaixaAscii(linhas) {
|
|
336
|
+
const largura = Math.max(...linhas.map((linha) => linha.length), 12);
|
|
337
|
+
const borda = `+${"-".repeat(largura + 2)}+`;
|
|
338
|
+
return [
|
|
339
|
+
borda,
|
|
340
|
+
...linhas.map((linha) => `| ${linha.padEnd(largura, " ")} |`),
|
|
341
|
+
borda,
|
|
342
|
+
].join("\n");
|
|
343
|
+
}
|
|
344
|
+
function renderizarSecaoAscii(titulo, linhas) {
|
|
345
|
+
return [
|
|
346
|
+
titulo,
|
|
347
|
+
...linhas.map((linha) => ` ${linha}`),
|
|
348
|
+
].join("\n");
|
|
349
|
+
}
|
|
319
350
|
function ajuda() {
|
|
320
|
-
return
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
+
return [
|
|
352
|
+
renderizarCaixaAscii([
|
|
353
|
+
`Sema CLI v${VERSAO_CLI}`,
|
|
354
|
+
"IA-first para contrato, geracao e adocao incremental",
|
|
355
|
+
"novo projeto, edicao guiada e legado sem contrato inicial",
|
|
356
|
+
]),
|
|
357
|
+
"",
|
|
358
|
+
renderizarSecaoAscii("Fluxos rapidos", [
|
|
359
|
+
"[1] Projeto novo / producao inicial",
|
|
360
|
+
"sema iniciar --template <base|nestjs|fastapi|nextjs-api|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer>",
|
|
361
|
+
"sema validar contratos/<modulo>.sema --json",
|
|
362
|
+
"sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart> --saida <diretorio>",
|
|
363
|
+
"sema verificar <arquivo-ou-pasta> --json",
|
|
364
|
+
"",
|
|
365
|
+
"[2] Editar projeto que ja usa Sema",
|
|
366
|
+
"sema inspecionar . --json",
|
|
367
|
+
"sema resumo <arquivo-ou-pasta> --micro --para mudanca",
|
|
368
|
+
"sema drift <arquivo-ou-pasta> --json",
|
|
369
|
+
"sema contexto-ia <arquivo.sema> --saida ./.tmp/contexto --json",
|
|
370
|
+
"",
|
|
371
|
+
"[3] Adotar Sema em projeto que ainda nao usa",
|
|
372
|
+
"sema importar <fonte> <diretorio> --saida <diretorio> --json",
|
|
373
|
+
"sema formatar <arquivo-ou-pasta>",
|
|
374
|
+
"sema validar <arquivo-ou-pasta> --json",
|
|
375
|
+
"sema drift <arquivo-ou-pasta> --json",
|
|
376
|
+
]),
|
|
377
|
+
"",
|
|
378
|
+
renderizarSecaoAscii("IA por capacidade", [
|
|
379
|
+
"pequena: sema resumo --micro + briefing.min.json + prompt-curto.txt",
|
|
380
|
+
"media: sema resumo --curto + drift.json + briefing.min.json",
|
|
381
|
+
"grande: sema contexto-ia + briefing.json + ir.json + ast.json",
|
|
382
|
+
]),
|
|
383
|
+
"",
|
|
384
|
+
renderizarSecaoAscii("Comandos principais", [
|
|
385
|
+
"descoberta: sema inspecionar [arquivo-ou-pasta] [--json]",
|
|
386
|
+
"auditoria: sema drift <arquivo-ou-pasta> [--json]",
|
|
387
|
+
"importacao: 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]",
|
|
388
|
+
"validacao: sema validar <arquivo-ou-pasta> [--json]",
|
|
389
|
+
"diagnostico: sema diagnosticos <arquivo.sema> [--json]",
|
|
390
|
+
"geracao: sema compilar <arquivo-ou-pasta> --alvo <python|typescript|dart> --saida <diretorio> [--estrutura <flat|modulos|backend>] [--framework <base|nestjs|fastapi>]",
|
|
391
|
+
"teste local: sema testar <arquivo.sema> --alvo <python|typescript|dart> --saida <diretorio-temporario> [--estrutura <flat|modulos|backend>] [--framework <base|nestjs|fastapi>]",
|
|
392
|
+
"verificacao final: sema verificar <arquivo-ou-pasta> [--saida <diretorio-base>] [--json]",
|
|
393
|
+
"formatacao: sema formatar <arquivo-ou-pasta> [--check] [--json]",
|
|
394
|
+
]),
|
|
395
|
+
"",
|
|
396
|
+
renderizarSecaoAscii("Ajuda IA-first", [
|
|
397
|
+
"sema ajuda-ia",
|
|
398
|
+
"sema starter-ia",
|
|
399
|
+
"sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>] [--saida <diretorio>] [--raiz] [--json]",
|
|
400
|
+
"sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>] [--json]",
|
|
401
|
+
"sema prompt-ia",
|
|
402
|
+
"sema prompt-ia-ui",
|
|
403
|
+
"sema prompt-ia-react",
|
|
404
|
+
"sema prompt-ia-sema-primeiro",
|
|
405
|
+
"sema exemplos-prompt-ia",
|
|
406
|
+
"sema contexto-ia <arquivo.sema> [--saida <diretorio>] [--json]",
|
|
407
|
+
"sema sync-ai-entrypoints [--json]",
|
|
408
|
+
]),
|
|
409
|
+
"",
|
|
410
|
+
renderizarSecaoAscii("Operacional", [
|
|
411
|
+
"sema doctor",
|
|
412
|
+
"sema --versao | --version | -v",
|
|
413
|
+
]),
|
|
414
|
+
].join("\n");
|
|
351
415
|
}
|
|
352
416
|
async function carregarModulos(entrada, cwd = process.cwd()) {
|
|
353
417
|
return (await carregarProjeto(entrada, cwd)).modulosSelecionados;
|
|
@@ -430,7 +494,10 @@ async function comandoDoctor() {
|
|
|
430
494
|
{ nome: "java", ok: comandoDisponivel("java") },
|
|
431
495
|
{ nome: "code", ok: comandoDisponivel("code", ["--version"]) },
|
|
432
496
|
];
|
|
433
|
-
console.log(
|
|
497
|
+
console.log(renderizarCaixaAscii([
|
|
498
|
+
"Sema doctor",
|
|
499
|
+
"checa a toolchain minima para validar, gerar e operar a CLI",
|
|
500
|
+
]));
|
|
434
501
|
for (const check of checks) {
|
|
435
502
|
console.log(`- ${check.nome}: ${check.ok ? "ok" : "ausente"}`);
|
|
436
503
|
}
|
|
@@ -471,6 +538,18 @@ function normalizarFonteImportacao(valor) {
|
|
|
471
538
|
if (valor === "next") {
|
|
472
539
|
return "nextjs";
|
|
473
540
|
}
|
|
541
|
+
if (valor === "next-consumer" || valor === "nextjs-consumer") {
|
|
542
|
+
return "nextjs-consumer";
|
|
543
|
+
}
|
|
544
|
+
if (valor === "react-vite" || valor === "react-vite-consumer" || valor === "react-consumer") {
|
|
545
|
+
return "react-vite-consumer";
|
|
546
|
+
}
|
|
547
|
+
if (valor === "angular" || valor === "angular-consumer") {
|
|
548
|
+
return "angular-consumer";
|
|
549
|
+
}
|
|
550
|
+
if (valor === "flutter" || valor === "flutter-consumer") {
|
|
551
|
+
return "flutter-consumer";
|
|
552
|
+
}
|
|
474
553
|
if (valor === "fb") {
|
|
475
554
|
return "firebase";
|
|
476
555
|
}
|
|
@@ -493,6 +572,10 @@ function normalizarFonteImportacao(valor) {
|
|
|
493
572
|
|| valor === "fastapi"
|
|
494
573
|
|| valor === "flask"
|
|
495
574
|
|| valor === "nextjs"
|
|
575
|
+
|| valor === "nextjs-consumer"
|
|
576
|
+
|| valor === "react-vite-consumer"
|
|
577
|
+
|| valor === "angular-consumer"
|
|
578
|
+
|| valor === "flutter-consumer"
|
|
496
579
|
|| valor === "firebase"
|
|
497
580
|
|| valor === "dotnet"
|
|
498
581
|
|| valor === "java"
|
|
@@ -510,6 +593,10 @@ function normalizarTemplateIniciar(valor) {
|
|
|
510
593
|
if (valor === "nestjs"
|
|
511
594
|
|| valor === "fastapi"
|
|
512
595
|
|| valor === "nextjs-api"
|
|
596
|
+
|| valor === "nextjs-consumer"
|
|
597
|
+
|| valor === "react-vite-consumer"
|
|
598
|
+
|| valor === "angular-consumer"
|
|
599
|
+
|| valor === "flutter-consumer"
|
|
513
600
|
|| valor === "node-firebase-worker"
|
|
514
601
|
|| valor === "aspnet-api"
|
|
515
602
|
|| valor === "springboot-api"
|
|
@@ -692,6 +779,7 @@ function renderizarCabecalhoDocsIa(descoberta) {
|
|
|
692
779
|
const linhas = [
|
|
693
780
|
"Modo IA-first da instalacao atual",
|
|
694
781
|
"- Use `sema` como interface publica principal.",
|
|
782
|
+
"- A Sema entra em projeto novo, projeto ja semantizado e adocao incremental em legado sem contrato inicial.",
|
|
695
783
|
"- Nao assuma monorepo, `node pacotes/cli/dist/index.js`, `npm run project:check` ou uma pasta `exemplos` externa ao projeto atual.",
|
|
696
784
|
"- Se a IA tiver contexto curto, comece por `sema resumo` e `sema prompt-curto`.",
|
|
697
785
|
"- Se a IA aguentar mais contexto, suba para `sema drift --json` e `sema contexto-ia`.",
|
|
@@ -847,6 +935,11 @@ function coletarResumoSemanticoModulo(contexto) {
|
|
|
847
935
|
inferido: limitarLista(unicosOrdenados(briefing.oQueFoiInferido), 6),
|
|
848
936
|
checksSugeridos: limitarLista(unicosOrdenados(briefing.oQueValidar), 6),
|
|
849
937
|
testesMinimos: limitarLista(unicosOrdenados(briefing.testesMinimos), 6),
|
|
938
|
+
consumerFramework: briefing.consumerFramework ?? drift.drift.consumerFramework ?? null,
|
|
939
|
+
appRoutes: limitarLista(unicosOrdenados(briefing.appRoutes ?? drift.drift.appRoutes ?? []), 8),
|
|
940
|
+
consumerSurfaces: limitarLista(unicosOrdenados(briefing.consumerSurfaces ?? []), 8),
|
|
941
|
+
consumerBridges: limitarLista(unicosOrdenados(briefing.consumerBridges ?? []), 8),
|
|
942
|
+
arquivosProvaveisEditar: limitarLista(unicosOrdenados(briefing.arquivosProvaveisEditar ?? briefing.oQueTocar), 8),
|
|
850
943
|
};
|
|
851
944
|
}
|
|
852
945
|
function renderizarResumoModuloTexto(resumo, tamanho, modo) {
|
|
@@ -856,6 +949,10 @@ function renderizarResumoModuloTexto(resumo, tamanho, modo) {
|
|
|
856
949
|
`MODULO: ${resumo.modulo}`,
|
|
857
950
|
`FAZ: ${resumo.faz}`,
|
|
858
951
|
`PERFIL: ${resumo.perfilCompatibilidade}`,
|
|
952
|
+
`CONSUMER_FRAMEWORK: ${resumo.consumerFramework ?? "nenhum"}`,
|
|
953
|
+
`APP_ROUTES: ${resumirListaTexto(resumo.appRoutes, limite)}`,
|
|
954
|
+
`CONSUMER_SURFACES: ${resumirListaTexto(resumo.consumerSurfaces, limite)}`,
|
|
955
|
+
`CONSUMER_BRIDGES: ${resumirListaTexto(resumo.consumerBridges, limite)}`,
|
|
859
956
|
`PUBLICO: ${resumirListaTexto(resumo.superficiesPublicas, limite)}`,
|
|
860
957
|
`TAREFAS: ${resumirListaTexto(resumo.tarefasPrincipais, limite)}`,
|
|
861
958
|
`ENTRADAS: ${resumirListaTexto(resumo.entradasChave, limite)}`,
|
|
@@ -906,6 +1003,17 @@ function renderizarResumoModuloMarkdown(resumo, modo, guiaPorCapacidade) {
|
|
|
906
1003
|
`- Erros: ${resumirListaTexto(resumo.erros, 6)}`,
|
|
907
1004
|
`- Entidades afetadas: ${resumirListaTexto(resumo.entidadesAfetadas, 6)}`,
|
|
908
1005
|
"",
|
|
1006
|
+
...(resumo.consumerFramework
|
|
1007
|
+
? [
|
|
1008
|
+
"## Consumer IA-first",
|
|
1009
|
+
"",
|
|
1010
|
+
`- Framework consumer: ${resumo.consumerFramework}`,
|
|
1011
|
+
`- Rotas de app: ${resumirListaTexto(resumo.appRoutes, 6)}`,
|
|
1012
|
+
`- Superficies consumer: ${resumirListaTexto(resumo.consumerSurfaces, 6)}`,
|
|
1013
|
+
`- Bridges consumer: ${resumirListaTexto(resumo.consumerBridges, 6)}`,
|
|
1014
|
+
"",
|
|
1015
|
+
]
|
|
1016
|
+
: []),
|
|
909
1017
|
"## Intervencao segura",
|
|
910
1018
|
"",
|
|
911
1019
|
`- Arquivos provaveis: ${resumirListaTexto(resumo.arquivosProvaveis, 6)}`,
|
|
@@ -953,12 +1061,17 @@ function criarBriefingMinimo(resumo, modo, tamanho) {
|
|
|
953
1061
|
efeitos: resumo.efeitos,
|
|
954
1062
|
erros: resumo.erros,
|
|
955
1063
|
arquivosProvaveis: resumo.arquivosProvaveis,
|
|
1064
|
+
arquivosProvaveisEditar: resumo.arquivosProvaveisEditar,
|
|
956
1065
|
simbolosRelacionados: resumo.simbolosRelacionados,
|
|
957
1066
|
riscosPrincipais: resumo.riscosPrincipais,
|
|
958
1067
|
lacunas: resumo.lacunas,
|
|
959
1068
|
inferido: resumo.inferido,
|
|
960
1069
|
checksSugeridos: resumo.checksSugeridos,
|
|
961
1070
|
testesMinimos: resumo.testesMinimos,
|
|
1071
|
+
consumerFramework: resumo.consumerFramework,
|
|
1072
|
+
appRoutes: resumo.appRoutes,
|
|
1073
|
+
consumerSurfaces: resumo.consumerSurfaces,
|
|
1074
|
+
consumerBridges: resumo.consumerBridges,
|
|
962
1075
|
};
|
|
963
1076
|
}
|
|
964
1077
|
function criarPromptCurtoModulo(resumo, modo, tamanho, capacidade) {
|
|
@@ -975,13 +1088,15 @@ Regras:
|
|
|
975
1088
|
- preserve a intencao do contrato
|
|
976
1089
|
- use este resumo como fonte compacta inicial
|
|
977
1090
|
- se a tarefa pedir mais contexto, suba para \`briefing.min.json\`, \`drift.json\` e depois \`ir.json\`
|
|
978
|
-
- nao saia editando
|
|
1091
|
+
- nao saia editando software vivo sem olhar risco, lacuna e checks sugeridos
|
|
1092
|
+
${resumo.consumerFramework ? "- se for tarefa visual consumer, priorize `appRoutes`, `consumerSurfaces` e `consumerBridges` antes de abrir arquivos aleatorios" : ""}
|
|
979
1093
|
|
|
980
1094
|
Contexto compacto:
|
|
981
1095
|
${resumoTexto}
|
|
982
1096
|
`;
|
|
983
1097
|
}
|
|
984
1098
|
function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
1099
|
+
const entradaCanonica = criarEntradaCanonicaProjeto(guiaPorCapacidade);
|
|
985
1100
|
const linhas = [
|
|
986
1101
|
"# SEMA_BRIEF",
|
|
987
1102
|
"",
|
|
@@ -990,6 +1105,13 @@ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
|
990
1105
|
`- Gerado em: \`${geradoEm}\``,
|
|
991
1106
|
`- Modulos: \`${modulos.length}\``,
|
|
992
1107
|
"",
|
|
1108
|
+
"## Entrada canonica para IA",
|
|
1109
|
+
"",
|
|
1110
|
+
`- Ordem minima: ${entradaCanonica.ordemLeitura.join(" -> ")}`,
|
|
1111
|
+
`- IA pequena: ${entradaCanonica.porCapacidade.pequena.join(" -> ")}`,
|
|
1112
|
+
`- IA media: ${entradaCanonica.porCapacidade.media.join(" -> ")}`,
|
|
1113
|
+
`- IA grande: ${entradaCanonica.porCapacidade.grande.join(" -> ")}`,
|
|
1114
|
+
"",
|
|
993
1115
|
"## Guia por capacidade",
|
|
994
1116
|
"",
|
|
995
1117
|
];
|
|
@@ -1011,6 +1133,19 @@ function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
|
|
|
1011
1133
|
}
|
|
1012
1134
|
return `${linhas.join("\n").trim()}\n`;
|
|
1013
1135
|
}
|
|
1136
|
+
function criarEntradaCanonicaProjeto(guiaPorCapacidade) {
|
|
1137
|
+
return {
|
|
1138
|
+
descricao: "Entrada canonica do repositorio para IA. O repo nao e human-first; a IA deve começar por esses artefatos antes de abrir codigo cru.",
|
|
1139
|
+
ordemLeitura: [...ARQUIVOS_CANONICOS_IA_RAIZ],
|
|
1140
|
+
porCapacidade: {
|
|
1141
|
+
pequena: ["llms.txt", "SEMA_BRIEF.micro.txt", "SEMA_INDEX.json", "AGENTS.md"],
|
|
1142
|
+
media: ["llms.txt", "SEMA_BRIEF.curto.txt", "SEMA_INDEX.json", "AGENTS.md", "README.md"],
|
|
1143
|
+
grande: ["llms-full.txt", "SEMA_BRIEF.md", "SEMA_INDEX.json", "AGENTS.md", "README.md"],
|
|
1144
|
+
},
|
|
1145
|
+
docsSuporte: [...DOCUMENTOS_SUPORTE_IA],
|
|
1146
|
+
guiaPorCapacidade,
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1014
1149
|
function falharContextoIa(mensagem) {
|
|
1015
1150
|
throw new Error(mensagem);
|
|
1016
1151
|
}
|
|
@@ -1044,6 +1179,41 @@ function resumirDriftPorModulo(modulo, caminho, resultadoDrift) {
|
|
|
1044
1179
|
const recursosDivergentes = modulo
|
|
1045
1180
|
? resultadoDrift.recursos_divergentes.filter((recurso) => recurso.modulo === modulo)
|
|
1046
1181
|
: [];
|
|
1182
|
+
const vinculosModulo = modulo
|
|
1183
|
+
? [
|
|
1184
|
+
...resultadoDrift.vinculos_validos.filter((vinculo) => vinculo.modulo === modulo),
|
|
1185
|
+
...resultadoDrift.vinculos_quebrados.filter((vinculo) => vinculo.modulo === modulo),
|
|
1186
|
+
]
|
|
1187
|
+
: [];
|
|
1188
|
+
const rotasConsumerModulo = new Set(vinculosModulo
|
|
1189
|
+
.filter((vinculo) => vinculo.tipo === "superficie")
|
|
1190
|
+
.map((vinculo) => vinculo.valor));
|
|
1191
|
+
const arquivosRelacionados = [...new Set([
|
|
1192
|
+
...tasks.flatMap((task) => task.arquivosReferenciados),
|
|
1193
|
+
...tasks.flatMap((task) => task.arquivosProvaveisEditar),
|
|
1194
|
+
...implsValidos.map((impl) => impl.arquivo).filter((item) => Boolean(item)),
|
|
1195
|
+
...implsQuebrados.flatMap((impl) => impl.candidatos?.map((candidato) => candidato.arquivo) ?? []),
|
|
1196
|
+
...vinculosValidos.map((vinculo) => vinculo.arquivo).filter((item) => Boolean(item)),
|
|
1197
|
+
...recursosValidos.map((recurso) => recurso.arquivo).filter(Boolean),
|
|
1198
|
+
...recursosDivergentes.map((recurso) => recurso.arquivo).filter(Boolean),
|
|
1199
|
+
])].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
1200
|
+
const consumerSurfaces = resultadoDrift.consumerSurfaces
|
|
1201
|
+
.filter((surface) => arquivosRelacionados.includes(surface.arquivo)
|
|
1202
|
+
|| rotasConsumerModulo.has(surface.rota))
|
|
1203
|
+
.map((surface) => `${surface.tipoArquivo}:${surface.rota} -> ${surface.arquivo}`)
|
|
1204
|
+
.sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
1205
|
+
const consumerBridges = resultadoDrift.consumerBridges
|
|
1206
|
+
.filter((bridge) => arquivosRelacionados.includes(bridge.arquivo))
|
|
1207
|
+
.map((bridge) => bridge.caminho)
|
|
1208
|
+
.sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
1209
|
+
const appRoutes = [...new Set(resultadoDrift.consumerSurfaces
|
|
1210
|
+
.filter((surface) => arquivosRelacionados.includes(surface.arquivo)
|
|
1211
|
+
|| rotasConsumerModulo.has(surface.rota))
|
|
1212
|
+
.map((surface) => surface.rota))]
|
|
1213
|
+
.sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
1214
|
+
const consumerFramework = appRoutes.length > 0 || consumerBridges.length > 0
|
|
1215
|
+
? resultadoDrift.consumerFramework
|
|
1216
|
+
: null;
|
|
1047
1217
|
return {
|
|
1048
1218
|
caminho,
|
|
1049
1219
|
modulo,
|
|
@@ -1060,15 +1230,12 @@ function resumirDriftPorModulo(modulo, caminho, resultadoDrift) {
|
|
|
1060
1230
|
: tasks.some((task) => task.confiancaVinculo === "media")
|
|
1061
1231
|
? "media"
|
|
1062
1232
|
: "baixa",
|
|
1063
|
-
arquivosRelacionados
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
...recursosValidos.map((recurso) => recurso.arquivo).filter(Boolean),
|
|
1070
|
-
...recursosDivergentes.map((recurso) => recurso.arquivo).filter(Boolean),
|
|
1071
|
-
])].sort((a, b) => a.localeCompare(b, "pt-BR")),
|
|
1233
|
+
arquivosRelacionados,
|
|
1234
|
+
arquivosProvaveisEditar: arquivosRelacionados,
|
|
1235
|
+
consumerFramework,
|
|
1236
|
+
appRoutes,
|
|
1237
|
+
consumerSurfaces,
|
|
1238
|
+
consumerBridges,
|
|
1072
1239
|
checksSugeridos: [...new Set(tasks.flatMap((task) => task.checksSugeridos))],
|
|
1073
1240
|
lacunas: [...new Set(tasks.flatMap((task) => task.lacunas))],
|
|
1074
1241
|
tasks,
|
|
@@ -1090,6 +1257,7 @@ function criarBriefingAgente(arquivo, modulo, ir, resumoDrift, resultadoDrift) {
|
|
|
1090
1257
|
...(ir?.resumoAgente.riscos ?? []),
|
|
1091
1258
|
])],
|
|
1092
1259
|
oQueTocar: resumoDrift.arquivosRelacionados,
|
|
1260
|
+
arquivosProvaveisEditar: resumoDrift.arquivosProvaveisEditar,
|
|
1093
1261
|
oQueValidar: [...new Set([
|
|
1094
1262
|
...resumoDrift.checksSugeridos,
|
|
1095
1263
|
...resultadoDrift.resumo_operacional.oQueValidar,
|
|
@@ -1117,6 +1285,10 @@ function criarBriefingAgente(arquivo, modulo, ir, resumoDrift, resultadoDrift) {
|
|
|
1117
1285
|
...(ir?.routes.map((route) => `${route.metodo ?? "?"} ${route.caminho ?? route.nome}`) ?? []),
|
|
1118
1286
|
...(ir?.superficies.map((superficie) => `${superficie.tipo}:${superficie.nome}`) ?? []),
|
|
1119
1287
|
],
|
|
1288
|
+
consumerFramework: resumoDrift.consumerFramework,
|
|
1289
|
+
appRoutes: resumoDrift.appRoutes,
|
|
1290
|
+
consumerSurfaces: resumoDrift.consumerSurfaces,
|
|
1291
|
+
consumerBridges: resumoDrift.consumerBridges,
|
|
1120
1292
|
testesMinimos: [
|
|
1121
1293
|
"sema validar <arquivo> --json",
|
|
1122
1294
|
"sema drift <arquivo> --json",
|
|
@@ -1216,6 +1388,7 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
1216
1388
|
const contextoProjeto = await carregarProjeto(entrada, process.cwd());
|
|
1217
1389
|
const geradoEm = new Date().toISOString();
|
|
1218
1390
|
const guiaPorCapacidade = criarGuiaCapacidadeIa();
|
|
1391
|
+
const entradaCanonica = criarEntradaCanonicaProjeto(guiaPorCapacidade);
|
|
1219
1392
|
const resultadoDrift = await analisarDriftLegado(contextoProjeto);
|
|
1220
1393
|
const modulos = contextoProjeto.modulosSelecionados.map((item) => {
|
|
1221
1394
|
const modulo = item.resultado.modulo?.nome ?? path.basename(item.caminho, ".sema");
|
|
@@ -1251,12 +1424,14 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
1251
1424
|
cliVersao: VERSAO_CLI,
|
|
1252
1425
|
baseProjeto,
|
|
1253
1426
|
totalModulos: modulos.length,
|
|
1427
|
+
entradaCanonica,
|
|
1254
1428
|
guiaPorCapacidade,
|
|
1255
1429
|
modulos,
|
|
1256
1430
|
};
|
|
1257
1431
|
const micro = [
|
|
1258
1432
|
`PROJETO: ${path.basename(baseProjeto)}`,
|
|
1259
1433
|
`MODULOS: ${modulos.length}`,
|
|
1434
|
+
`ENTRADA_IA: ${entradaCanonica.porCapacidade.pequena.join(" -> ")}`,
|
|
1260
1435
|
`TOP_MODULOS: ${resumirListaTexto(modulos.map((modulo) => modulo.modulo), 3)}`,
|
|
1261
1436
|
`TOP_RISCOS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.riscosPrincipais)), 3)}`,
|
|
1262
1437
|
`TOP_LACUNAS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.lacunas)), 3)}`,
|
|
@@ -1267,6 +1442,7 @@ async function gerarResumoProjetoIa(entrada, pastaSaidaOpcional, escreverNaRaiz
|
|
|
1267
1442
|
`PROJETO: ${path.basename(baseProjeto)}`,
|
|
1268
1443
|
`BASE: ${baseProjeto}`,
|
|
1269
1444
|
`MODULOS: ${modulos.length}`,
|
|
1445
|
+
`ENTRADA_IA: ${entradaCanonica.porCapacidade.media.join(" -> ")}`,
|
|
1270
1446
|
`TOP_MODULOS: ${resumirListaTexto(modulos.map((modulo) => modulo.modulo), 6)}`,
|
|
1271
1447
|
`TOP_RISCOS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.riscosPrincipais)), 6)}`,
|
|
1272
1448
|
`TOP_LACUNAS: ${resumirListaTexto(unicosOrdenados(modulos.flatMap((modulo) => modulo.lacunas)), 6)}`,
|
|
@@ -1548,6 +1724,596 @@ async function comandoIniciar(cwd, template) {
|
|
|
1548
1724
|
- Contratos em \`contratos/\`
|
|
1549
1725
|
- Handlers App Router em \`src/app/api/\`
|
|
1550
1726
|
- Rota de exemplo validada por \`drift\`
|
|
1727
|
+
`,
|
|
1728
|
+
},
|
|
1729
|
+
];
|
|
1730
|
+
}
|
|
1731
|
+
else if (template === "nextjs-consumer") {
|
|
1732
|
+
arquivos = [
|
|
1733
|
+
{
|
|
1734
|
+
caminhoRelativo: "sema.config.json",
|
|
1735
|
+
conteudo: `{
|
|
1736
|
+
"origens": ["./contratos"],
|
|
1737
|
+
"saida": "./generated",
|
|
1738
|
+
"alvos": ["typescript"],
|
|
1739
|
+
"alvoPadrao": "typescript",
|
|
1740
|
+
"estruturaSaida": "modulos",
|
|
1741
|
+
"framework": "base",
|
|
1742
|
+
"modoEstrito": true,
|
|
1743
|
+
"diretoriosCodigo": ["./src"],
|
|
1744
|
+
"fontesLegado": ["nextjs-consumer", "typescript"],
|
|
1745
|
+
"diretoriosSaidaPorAlvo": {
|
|
1746
|
+
"typescript": "./generated/typescript"
|
|
1747
|
+
},
|
|
1748
|
+
"convencoesGeracaoPorProjeto": "base"
|
|
1749
|
+
}
|
|
1750
|
+
`,
|
|
1751
|
+
},
|
|
1752
|
+
{
|
|
1753
|
+
caminhoRelativo: "contratos/showroom_consumer.sema",
|
|
1754
|
+
conteudo: `module showroom.consumer {
|
|
1755
|
+
task fetch_showroom_ranking {
|
|
1756
|
+
input {
|
|
1757
|
+
}
|
|
1758
|
+
output {
|
|
1759
|
+
ranking: Json
|
|
1760
|
+
}
|
|
1761
|
+
impl {
|
|
1762
|
+
ts: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
|
|
1763
|
+
}
|
|
1764
|
+
vinculos {
|
|
1765
|
+
arquivo: "src/lib/sema_consumer_bridge.ts"
|
|
1766
|
+
simbolo: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
|
|
1767
|
+
superficie: "/ranking"
|
|
1768
|
+
arquivo: "src/app/ranking/page.tsx"
|
|
1769
|
+
arquivo: "src/app/ranking/loading.tsx"
|
|
1770
|
+
arquivo: "src/app/ranking/error.tsx"
|
|
1771
|
+
}
|
|
1772
|
+
guarantees {
|
|
1773
|
+
ranking existe
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
`,
|
|
1778
|
+
},
|
|
1779
|
+
{
|
|
1780
|
+
caminhoRelativo: "src/lib/sema_consumer_bridge.ts",
|
|
1781
|
+
conteudo: `export async function semaFetchShowroomRanking() {
|
|
1782
|
+
return {
|
|
1783
|
+
ranking: [
|
|
1784
|
+
{ clube: "Tigres do Norte", pontos: 33 },
|
|
1785
|
+
{ clube: "Porto Azul", pontos: 31 },
|
|
1786
|
+
{ clube: "Galo de Ouro", pontos: 28 },
|
|
1787
|
+
],
|
|
1788
|
+
};
|
|
1789
|
+
}
|
|
1790
|
+
`,
|
|
1791
|
+
},
|
|
1792
|
+
{
|
|
1793
|
+
caminhoRelativo: "src/app/ranking/page.tsx",
|
|
1794
|
+
conteudo: `import { semaFetchShowroomRanking } from "../../lib/sema_consumer_bridge";
|
|
1795
|
+
|
|
1796
|
+
export default async function RankingPage() {
|
|
1797
|
+
const { ranking } = await semaFetchShowroomRanking();
|
|
1798
|
+
|
|
1799
|
+
return (
|
|
1800
|
+
<main>
|
|
1801
|
+
<h1>Ranking showroom</h1>
|
|
1802
|
+
<ul>
|
|
1803
|
+
{ranking.map((item) => (
|
|
1804
|
+
<li key={item.clube}>
|
|
1805
|
+
{item.clube} - {item.pontos} pts
|
|
1806
|
+
</li>
|
|
1807
|
+
))}
|
|
1808
|
+
</ul>
|
|
1809
|
+
</main>
|
|
1810
|
+
);
|
|
1811
|
+
}
|
|
1812
|
+
`,
|
|
1813
|
+
},
|
|
1814
|
+
{
|
|
1815
|
+
caminhoRelativo: "src/app/ranking/loading.tsx",
|
|
1816
|
+
conteudo: `export default function Loading() {
|
|
1817
|
+
return <p>Carregando ranking...</p>;
|
|
1818
|
+
}
|
|
1819
|
+
`,
|
|
1820
|
+
},
|
|
1821
|
+
{
|
|
1822
|
+
caminhoRelativo: "src/app/ranking/error.tsx",
|
|
1823
|
+
conteudo: `"use client";
|
|
1824
|
+
|
|
1825
|
+
export default function Error({
|
|
1826
|
+
error,
|
|
1827
|
+
reset,
|
|
1828
|
+
}: {
|
|
1829
|
+
error: Error;
|
|
1830
|
+
reset: () => void;
|
|
1831
|
+
}) {
|
|
1832
|
+
return (
|
|
1833
|
+
<main>
|
|
1834
|
+
<h1>Falha ao carregar ranking</h1>
|
|
1835
|
+
<p>{error.message}</p>
|
|
1836
|
+
<button type="button" onClick={reset}>Tentar novamente</button>
|
|
1837
|
+
</main>
|
|
1838
|
+
);
|
|
1839
|
+
}
|
|
1840
|
+
`,
|
|
1841
|
+
},
|
|
1842
|
+
{
|
|
1843
|
+
caminhoRelativo: "README.md",
|
|
1844
|
+
conteudo: `# Starter Next.js Consumer + Sema
|
|
1845
|
+
|
|
1846
|
+
- Contratos em \`contratos/\`
|
|
1847
|
+
- Bridge consumer canonico em \`src/lib/sema_consumer_bridge.ts\`
|
|
1848
|
+
- Superficies App Router em \`src/app/\`
|
|
1849
|
+
- O slice oficial desta fase e \`consumer bridge + App Router surfaces\`
|
|
1850
|
+
- \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
|
|
1851
|
+
`,
|
|
1852
|
+
},
|
|
1853
|
+
];
|
|
1854
|
+
}
|
|
1855
|
+
else if (template === "react-vite-consumer") {
|
|
1856
|
+
arquivos = [
|
|
1857
|
+
{
|
|
1858
|
+
caminhoRelativo: "sema.config.json",
|
|
1859
|
+
conteudo: `{
|
|
1860
|
+
"origens": ["./contratos"],
|
|
1861
|
+
"saida": "./generated",
|
|
1862
|
+
"alvos": ["typescript"],
|
|
1863
|
+
"alvoPadrao": "typescript",
|
|
1864
|
+
"estruturaSaida": "modulos",
|
|
1865
|
+
"framework": "base",
|
|
1866
|
+
"modoEstrito": true,
|
|
1867
|
+
"diretoriosCodigo": ["./src"],
|
|
1868
|
+
"fontesLegado": ["react-vite-consumer", "typescript"],
|
|
1869
|
+
"diretoriosSaidaPorAlvo": {
|
|
1870
|
+
"typescript": "./generated/typescript"
|
|
1871
|
+
},
|
|
1872
|
+
"convencoesGeracaoPorProjeto": "base"
|
|
1873
|
+
}
|
|
1874
|
+
`,
|
|
1875
|
+
},
|
|
1876
|
+
{
|
|
1877
|
+
caminhoRelativo: "contratos/showroom_consumer.sema",
|
|
1878
|
+
conteudo: `module showroom.consumer {
|
|
1879
|
+
task fetch_showroom_ranking {
|
|
1880
|
+
input {
|
|
1881
|
+
}
|
|
1882
|
+
output {
|
|
1883
|
+
ranking: Json
|
|
1884
|
+
}
|
|
1885
|
+
impl {
|
|
1886
|
+
ts: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
|
|
1887
|
+
}
|
|
1888
|
+
vinculos {
|
|
1889
|
+
arquivo: "src/lib/sema_consumer_bridge.ts"
|
|
1890
|
+
simbolo: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
|
|
1891
|
+
superficie: "/ranking"
|
|
1892
|
+
arquivo: "src/router.tsx"
|
|
1893
|
+
arquivo: "src/pages/ranking.tsx"
|
|
1894
|
+
}
|
|
1895
|
+
guarantees {
|
|
1896
|
+
ranking existe
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
`,
|
|
1901
|
+
},
|
|
1902
|
+
{
|
|
1903
|
+
caminhoRelativo: "src/lib/sema_consumer_bridge.ts",
|
|
1904
|
+
conteudo: `export async function semaFetchShowroomRanking() {
|
|
1905
|
+
return {
|
|
1906
|
+
ranking: [
|
|
1907
|
+
{ clube: "Tigres do Norte", pontos: 33 },
|
|
1908
|
+
{ clube: "Porto Azul", pontos: 31 },
|
|
1909
|
+
{ clube: "Galo de Ouro", pontos: 28 },
|
|
1910
|
+
],
|
|
1911
|
+
};
|
|
1912
|
+
}
|
|
1913
|
+
`,
|
|
1914
|
+
},
|
|
1915
|
+
{
|
|
1916
|
+
caminhoRelativo: "src/pages/ranking.tsx",
|
|
1917
|
+
conteudo: `import { useEffect, useState } from "react";
|
|
1918
|
+
import { semaFetchShowroomRanking } from "../lib/sema_consumer_bridge";
|
|
1919
|
+
|
|
1920
|
+
export function RankingPage() {
|
|
1921
|
+
const [ranking, setRanking] = useState<Array<{ clube: string; pontos: number }>>([]);
|
|
1922
|
+
|
|
1923
|
+
useEffect(() => {
|
|
1924
|
+
void semaFetchShowroomRanking().then((payload) => setRanking(payload.ranking ?? []));
|
|
1925
|
+
}, []);
|
|
1926
|
+
|
|
1927
|
+
return (
|
|
1928
|
+
<main>
|
|
1929
|
+
<h1>Ranking showroom</h1>
|
|
1930
|
+
<ul>
|
|
1931
|
+
{ranking.map((item) => (
|
|
1932
|
+
<li key={item.clube}>
|
|
1933
|
+
{item.clube} - {item.pontos} pts
|
|
1934
|
+
</li>
|
|
1935
|
+
))}
|
|
1936
|
+
</ul>
|
|
1937
|
+
</main>
|
|
1938
|
+
);
|
|
1939
|
+
}
|
|
1940
|
+
`,
|
|
1941
|
+
},
|
|
1942
|
+
{
|
|
1943
|
+
caminhoRelativo: "src/router.tsx",
|
|
1944
|
+
conteudo: `import { createBrowserRouter } from "react-router-dom";
|
|
1945
|
+
import { RankingPage } from "./pages/ranking";
|
|
1946
|
+
|
|
1947
|
+
export const appRouter = createBrowserRouter([
|
|
1948
|
+
{
|
|
1949
|
+
path: "/ranking",
|
|
1950
|
+
Component: RankingPage,
|
|
1951
|
+
},
|
|
1952
|
+
]);
|
|
1953
|
+
`,
|
|
1954
|
+
},
|
|
1955
|
+
{
|
|
1956
|
+
caminhoRelativo: "src/App.tsx",
|
|
1957
|
+
conteudo: `import { RouterProvider } from "react-router-dom";
|
|
1958
|
+
import { appRouter } from "./router";
|
|
1959
|
+
|
|
1960
|
+
export default function App() {
|
|
1961
|
+
return <RouterProvider router={appRouter} />;
|
|
1962
|
+
}
|
|
1963
|
+
`,
|
|
1964
|
+
},
|
|
1965
|
+
{
|
|
1966
|
+
caminhoRelativo: "src/main.tsx",
|
|
1967
|
+
conteudo: `import React from "react";
|
|
1968
|
+
import ReactDOM from "react-dom/client";
|
|
1969
|
+
import App from "./App";
|
|
1970
|
+
|
|
1971
|
+
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
|
|
1972
|
+
<React.StrictMode>
|
|
1973
|
+
<App />
|
|
1974
|
+
</React.StrictMode>,
|
|
1975
|
+
);
|
|
1976
|
+
`,
|
|
1977
|
+
},
|
|
1978
|
+
{
|
|
1979
|
+
caminhoRelativo: "README.md",
|
|
1980
|
+
conteudo: `# Starter React Vite Consumer + Sema
|
|
1981
|
+
|
|
1982
|
+
- Contratos em \`contratos/\`
|
|
1983
|
+
- Bridge consumer canonico em \`src/lib/sema_consumer_bridge.ts\`
|
|
1984
|
+
- Rotas explicitas em \`src/router.tsx\`
|
|
1985
|
+
- Superficies consumer em \`src/pages/\`
|
|
1986
|
+
- O slice oficial desta fase e \`consumer bridge + react-router surfaces\`
|
|
1987
|
+
- \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
|
|
1988
|
+
`,
|
|
1989
|
+
},
|
|
1990
|
+
];
|
|
1991
|
+
}
|
|
1992
|
+
else if (template === "angular-consumer") {
|
|
1993
|
+
arquivos = [
|
|
1994
|
+
{
|
|
1995
|
+
caminhoRelativo: "sema.config.json",
|
|
1996
|
+
conteudo: `{
|
|
1997
|
+
"origens": ["./contratos"],
|
|
1998
|
+
"saida": "./generated",
|
|
1999
|
+
"alvos": ["typescript"],
|
|
2000
|
+
"alvoPadrao": "typescript",
|
|
2001
|
+
"estruturaSaida": "modulos",
|
|
2002
|
+
"framework": "base",
|
|
2003
|
+
"modoEstrito": true,
|
|
2004
|
+
"diretoriosCodigo": ["./src"],
|
|
2005
|
+
"fontesLegado": ["angular-consumer", "typescript"],
|
|
2006
|
+
"diretoriosSaidaPorAlvo": {
|
|
2007
|
+
"typescript": "./generated/typescript"
|
|
2008
|
+
},
|
|
2009
|
+
"convencoesGeracaoPorProjeto": "base"
|
|
2010
|
+
}
|
|
2011
|
+
`,
|
|
2012
|
+
},
|
|
2013
|
+
{
|
|
2014
|
+
caminhoRelativo: "contratos/showroom_consumer.sema",
|
|
2015
|
+
conteudo: `module showroom.consumer {
|
|
2016
|
+
task fetch_showroom_ranking {
|
|
2017
|
+
input {
|
|
2018
|
+
}
|
|
2019
|
+
output {
|
|
2020
|
+
ranking: Json
|
|
2021
|
+
}
|
|
2022
|
+
impl {
|
|
2023
|
+
ts: src.app.sema_consumer_bridge.semaFetchShowroomRanking
|
|
2024
|
+
}
|
|
2025
|
+
vinculos {
|
|
2026
|
+
arquivo: "src/app/sema_consumer_bridge.ts"
|
|
2027
|
+
simbolo: src.app.sema_consumer_bridge.semaFetchShowroomRanking
|
|
2028
|
+
superficie: "/ranking"
|
|
2029
|
+
arquivo: "src/app/app.routes.ts"
|
|
2030
|
+
arquivo: "src/app/features/ranking/ranking.routes.ts"
|
|
2031
|
+
arquivo: "src/app/features/ranking/ranking-page.component.ts"
|
|
2032
|
+
}
|
|
2033
|
+
guarantees {
|
|
2034
|
+
ranking existe
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
`,
|
|
2039
|
+
},
|
|
2040
|
+
{
|
|
2041
|
+
caminhoRelativo: "src/app/sema_consumer_bridge.ts",
|
|
2042
|
+
conteudo: `export async function semaFetchShowroomRanking() {
|
|
2043
|
+
return {
|
|
2044
|
+
ranking: [
|
|
2045
|
+
{ clube: "Tigres do Norte", pontos: 33 },
|
|
2046
|
+
{ clube: "Porto Azul", pontos: 31 },
|
|
2047
|
+
{ clube: "Galo de Ouro", pontos: 28 },
|
|
2048
|
+
],
|
|
2049
|
+
};
|
|
2050
|
+
}
|
|
2051
|
+
`,
|
|
2052
|
+
},
|
|
2053
|
+
{
|
|
2054
|
+
caminhoRelativo: "src/app/app.routes.ts",
|
|
2055
|
+
conteudo: `import { Routes } from "@angular/router";
|
|
2056
|
+
|
|
2057
|
+
export const routes: Routes = [
|
|
2058
|
+
{
|
|
2059
|
+
path: "ranking",
|
|
2060
|
+
loadChildren: () => import("./features/ranking/ranking.routes").then((m) => m.RANKING_ROUTES),
|
|
2061
|
+
},
|
|
2062
|
+
];
|
|
2063
|
+
`,
|
|
2064
|
+
},
|
|
2065
|
+
{
|
|
2066
|
+
caminhoRelativo: "src/app/features/ranking/ranking.routes.ts",
|
|
2067
|
+
conteudo: `import { Routes } from "@angular/router";
|
|
2068
|
+
|
|
2069
|
+
export const RANKING_ROUTES: Routes = [
|
|
2070
|
+
{
|
|
2071
|
+
path: "",
|
|
2072
|
+
loadComponent: () => import("./ranking-page.component").then((m) => m.RankingPageComponent),
|
|
2073
|
+
},
|
|
2074
|
+
];
|
|
2075
|
+
`,
|
|
2076
|
+
},
|
|
2077
|
+
{
|
|
2078
|
+
caminhoRelativo: "src/app/features/ranking/ranking-page.component.ts",
|
|
2079
|
+
conteudo: `import { Component, OnInit } from "@angular/core";
|
|
2080
|
+
import { CommonModule } from "@angular/common";
|
|
2081
|
+
import { semaFetchShowroomRanking } from "../../sema_consumer_bridge";
|
|
2082
|
+
|
|
2083
|
+
@Component({
|
|
2084
|
+
selector: "app-ranking-page",
|
|
2085
|
+
standalone: true,
|
|
2086
|
+
imports: [CommonModule],
|
|
2087
|
+
template: \`
|
|
2088
|
+
<main>
|
|
2089
|
+
<h1>Ranking showroom</h1>
|
|
2090
|
+
<ul>
|
|
2091
|
+
<li *ngFor="let item of ranking">
|
|
2092
|
+
{{ item.clube }} - {{ item.pontos }} pts
|
|
2093
|
+
</li>
|
|
2094
|
+
</ul>
|
|
2095
|
+
</main>
|
|
2096
|
+
\`,
|
|
2097
|
+
})
|
|
2098
|
+
export class RankingPageComponent implements OnInit {
|
|
2099
|
+
ranking: Array<{ clube: string; pontos: number }> = [];
|
|
2100
|
+
|
|
2101
|
+
async ngOnInit() {
|
|
2102
|
+
const payload = await semaFetchShowroomRanking();
|
|
2103
|
+
this.ranking = payload.ranking ?? [];
|
|
2104
|
+
}
|
|
2105
|
+
}
|
|
2106
|
+
`,
|
|
2107
|
+
},
|
|
2108
|
+
{
|
|
2109
|
+
caminhoRelativo: "src/app/app.component.ts",
|
|
2110
|
+
conteudo: `import { Component } from "@angular/core";
|
|
2111
|
+
import { RouterOutlet } from "@angular/router";
|
|
2112
|
+
|
|
2113
|
+
@Component({
|
|
2114
|
+
selector: "app-root",
|
|
2115
|
+
standalone: true,
|
|
2116
|
+
imports: [RouterOutlet],
|
|
2117
|
+
template: "<router-outlet />",
|
|
2118
|
+
})
|
|
2119
|
+
export class AppComponent {}
|
|
2120
|
+
`,
|
|
2121
|
+
},
|
|
2122
|
+
{
|
|
2123
|
+
caminhoRelativo: "src/main.ts",
|
|
2124
|
+
conteudo: `import { bootstrapApplication } from "@angular/platform-browser";
|
|
2125
|
+
import { provideRouter } from "@angular/router";
|
|
2126
|
+
import { AppComponent } from "./app/app.component";
|
|
2127
|
+
import { routes } from "./app/app.routes";
|
|
2128
|
+
|
|
2129
|
+
void bootstrapApplication(AppComponent, {
|
|
2130
|
+
providers: [provideRouter(routes)],
|
|
2131
|
+
});
|
|
2132
|
+
`,
|
|
2133
|
+
},
|
|
2134
|
+
{
|
|
2135
|
+
caminhoRelativo: "README.md",
|
|
2136
|
+
conteudo: `# Starter Angular Consumer + Sema
|
|
2137
|
+
|
|
2138
|
+
- Contratos em \`contratos/\`
|
|
2139
|
+
- Bridge consumer canonico em \`src/app/sema_consumer_bridge.ts\`
|
|
2140
|
+
- Rotas lazy em \`src/app/app.routes.ts\`
|
|
2141
|
+
- Feature folders em \`src/app/features/\`
|
|
2142
|
+
- O slice oficial desta fase e \`consumer bridge + route config surfaces\`
|
|
2143
|
+
- \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
|
|
2144
|
+
`,
|
|
2145
|
+
},
|
|
2146
|
+
];
|
|
2147
|
+
}
|
|
2148
|
+
else if (template === "flutter-consumer") {
|
|
2149
|
+
arquivos = [
|
|
2150
|
+
{
|
|
2151
|
+
caminhoRelativo: "sema.config.json",
|
|
2152
|
+
conteudo: `{
|
|
2153
|
+
"origens": ["./contratos"],
|
|
2154
|
+
"saida": "./generated",
|
|
2155
|
+
"alvos": ["dart"],
|
|
2156
|
+
"alvoPadrao": "dart",
|
|
2157
|
+
"estruturaSaida": "modulos",
|
|
2158
|
+
"framework": "base",
|
|
2159
|
+
"modoEstrito": true,
|
|
2160
|
+
"diretoriosCodigo": ["./lib"],
|
|
2161
|
+
"fontesLegado": ["flutter-consumer", "dart"],
|
|
2162
|
+
"diretoriosSaidaPorAlvo": {
|
|
2163
|
+
"dart": "./generated/dart"
|
|
2164
|
+
},
|
|
2165
|
+
"convencoesGeracaoPorProjeto": "base"
|
|
2166
|
+
}
|
|
2167
|
+
`,
|
|
2168
|
+
},
|
|
2169
|
+
{
|
|
2170
|
+
caminhoRelativo: "pubspec.yaml",
|
|
2171
|
+
conteudo: `name: sema_flutter_consumer
|
|
2172
|
+
description: Starter Flutter consumer IA-first com Sema
|
|
2173
|
+
publish_to: "none"
|
|
2174
|
+
|
|
2175
|
+
environment:
|
|
2176
|
+
sdk: ">=3.3.0 <4.0.0"
|
|
2177
|
+
|
|
2178
|
+
dependencies:
|
|
2179
|
+
flutter:
|
|
2180
|
+
sdk: flutter
|
|
2181
|
+
go_router: ^14.0.0
|
|
2182
|
+
`,
|
|
2183
|
+
},
|
|
2184
|
+
{
|
|
2185
|
+
caminhoRelativo: "contratos/showroom_consumer.sema",
|
|
2186
|
+
conteudo: `module showroom.consumer {
|
|
2187
|
+
task fetch_showroom_ranking {
|
|
2188
|
+
input {
|
|
2189
|
+
}
|
|
2190
|
+
output {
|
|
2191
|
+
resultado: Json
|
|
2192
|
+
}
|
|
2193
|
+
impl {
|
|
2194
|
+
dart: lib.sema_consumer_bridge.semaFetchShowroomRanking
|
|
2195
|
+
}
|
|
2196
|
+
vinculos {
|
|
2197
|
+
arquivo: "lib/sema_consumer_bridge.dart"
|
|
2198
|
+
simbolo: lib.sema_consumer_bridge.semaFetchShowroomRanking
|
|
2199
|
+
superficie: "/ranking"
|
|
2200
|
+
arquivo: "lib/router.dart"
|
|
2201
|
+
arquivo: "lib/screens/ranking_screen.dart"
|
|
2202
|
+
}
|
|
2203
|
+
guarantees {
|
|
2204
|
+
resultado existe
|
|
2205
|
+
}
|
|
2206
|
+
}
|
|
2207
|
+
}
|
|
2208
|
+
`,
|
|
2209
|
+
},
|
|
2210
|
+
{
|
|
2211
|
+
caminhoRelativo: "lib/sema_consumer_bridge.dart",
|
|
2212
|
+
conteudo: `Future<Map<String, dynamic>> semaFetchShowroomRanking() async {
|
|
2213
|
+
return {
|
|
2214
|
+
"ranking": [
|
|
2215
|
+
{"clube": "Tigres do Norte", "pontos": 33},
|
|
2216
|
+
{"clube": "Porto Azul", "pontos": 31},
|
|
2217
|
+
{"clube": "Galo de Ouro", "pontos": 28},
|
|
2218
|
+
],
|
|
2219
|
+
};
|
|
2220
|
+
}
|
|
2221
|
+
`,
|
|
2222
|
+
},
|
|
2223
|
+
{
|
|
2224
|
+
caminhoRelativo: "lib/router.dart",
|
|
2225
|
+
conteudo: `import "package:go_router/go_router.dart";
|
|
2226
|
+
import "package:flutter/widgets.dart";
|
|
2227
|
+
import "screens/ranking_screen.dart";
|
|
2228
|
+
|
|
2229
|
+
final appRouter = GoRouter(
|
|
2230
|
+
routes: [
|
|
2231
|
+
GoRoute(
|
|
2232
|
+
path: "/ranking",
|
|
2233
|
+
builder: (BuildContext context, GoRouterState state) => const RankingScreen(),
|
|
2234
|
+
),
|
|
2235
|
+
],
|
|
2236
|
+
);
|
|
2237
|
+
`,
|
|
2238
|
+
},
|
|
2239
|
+
{
|
|
2240
|
+
caminhoRelativo: "lib/screens/ranking_screen.dart",
|
|
2241
|
+
conteudo: `import "package:flutter/widgets.dart";
|
|
2242
|
+
import "../sema_consumer_bridge.dart";
|
|
2243
|
+
|
|
2244
|
+
class RankingScreen extends StatefulWidget {
|
|
2245
|
+
const RankingScreen({super.key});
|
|
2246
|
+
|
|
2247
|
+
@override
|
|
2248
|
+
State<RankingScreen> createState() => _RankingScreenState();
|
|
2249
|
+
}
|
|
2250
|
+
|
|
2251
|
+
class _RankingScreenState extends State<RankingScreen> {
|
|
2252
|
+
List<Map<String, dynamic>> ranking = const [];
|
|
2253
|
+
|
|
2254
|
+
@override
|
|
2255
|
+
void initState() {
|
|
2256
|
+
super.initState();
|
|
2257
|
+
semaFetchShowroomRanking().then((payload) {
|
|
2258
|
+
final itens = (payload["ranking"] as List<dynamic>? ?? const [])
|
|
2259
|
+
.whereType<Map<String, dynamic>>()
|
|
2260
|
+
.toList();
|
|
2261
|
+
if (!mounted) return;
|
|
2262
|
+
setState(() {
|
|
2263
|
+
ranking = itens;
|
|
2264
|
+
});
|
|
2265
|
+
});
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
@override
|
|
2269
|
+
Widget build(BuildContext context) {
|
|
2270
|
+
return ListView(
|
|
2271
|
+
children: [
|
|
2272
|
+
const Padding(
|
|
2273
|
+
padding: EdgeInsets.all(16),
|
|
2274
|
+
child: Text("Ranking showroom"),
|
|
2275
|
+
),
|
|
2276
|
+
...ranking.map((item) => Padding(
|
|
2277
|
+
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
|
2278
|
+
child: Text("\${item["clube"]} - \${item["pontos"]} pts"),
|
|
2279
|
+
)),
|
|
2280
|
+
],
|
|
2281
|
+
);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
`,
|
|
2285
|
+
},
|
|
2286
|
+
{
|
|
2287
|
+
caminhoRelativo: "lib/main.dart",
|
|
2288
|
+
conteudo: `import "package:flutter/material.dart";
|
|
2289
|
+
import "router.dart";
|
|
2290
|
+
|
|
2291
|
+
void main() {
|
|
2292
|
+
runApp(const ShowroomApp());
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
class ShowroomApp extends StatelessWidget {
|
|
2296
|
+
const ShowroomApp({super.key});
|
|
2297
|
+
|
|
2298
|
+
@override
|
|
2299
|
+
Widget build(BuildContext context) {
|
|
2300
|
+
return MaterialApp.router(
|
|
2301
|
+
routerConfig: appRouter,
|
|
2302
|
+
);
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
`,
|
|
2306
|
+
},
|
|
2307
|
+
{
|
|
2308
|
+
caminhoRelativo: "README.md",
|
|
2309
|
+
conteudo: `# Starter Flutter Consumer + Sema
|
|
2310
|
+
|
|
2311
|
+
- Contratos em \`contratos/\`
|
|
2312
|
+
- Bridge consumer canonico em \`lib/sema_consumer_bridge.dart\`
|
|
2313
|
+
- Rotas consumer em \`lib/router.dart\`
|
|
2314
|
+
- Superficies consumer em \`lib/screens/\`
|
|
2315
|
+
- O slice oficial desta fase e \`consumer bridge + router/screen surfaces\`
|
|
2316
|
+
- \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual diff
|
|
1551
2317
|
`,
|
|
1552
2318
|
},
|
|
1553
2319
|
];
|
|
@@ -2106,6 +2872,10 @@ async function comandoInspecionar(entrada, emJson, cwd = process.cwd()) {
|
|
|
2106
2872
|
modoAdocao: contextoProjeto.modoAdocao,
|
|
2107
2873
|
scoreDrift: resultadoDrift.resumo_operacional.scoreMedio,
|
|
2108
2874
|
confiancaGeral: resultadoDrift.resumo_operacional.confiancaGeral,
|
|
2875
|
+
consumerFramework: resultadoDrift.consumerFramework,
|
|
2876
|
+
appRoutes: resultadoDrift.appRoutes,
|
|
2877
|
+
consumerSurfaces: resultadoDrift.consumerSurfaces,
|
|
2878
|
+
consumerBridges: resultadoDrift.consumerBridges,
|
|
2109
2879
|
},
|
|
2110
2880
|
projeto: {
|
|
2111
2881
|
arquivos: contextoProjeto.arquivosProjeto,
|
|
@@ -2440,49 +3210,80 @@ async function comandoStarterIa() {
|
|
|
2440
3210
|
console.log(STARTER_IA);
|
|
2441
3211
|
return 0;
|
|
2442
3212
|
}
|
|
3213
|
+
async function comandoSyncAiEntrypoints(emJson) {
|
|
3214
|
+
const resumoProjeto = await gerarResumoProjetoIa(process.cwd(), undefined, true);
|
|
3215
|
+
const indexJson = JSON.parse(await readFile(path.join(resumoProjeto.pastaSaida, "SEMA_INDEX.json"), "utf8"));
|
|
3216
|
+
const artefatos = [...new Set([
|
|
3217
|
+
...ARQUIVOS_CANONICOS_IA_RAIZ,
|
|
3218
|
+
...resumoProjeto.artefatos,
|
|
3219
|
+
])];
|
|
3220
|
+
if (emJson) {
|
|
3221
|
+
console.log(JSON.stringify({
|
|
3222
|
+
comando: "sync-ai-entrypoints",
|
|
3223
|
+
sucesso: true,
|
|
3224
|
+
baseProjeto: resumoProjeto.baseProjeto,
|
|
3225
|
+
pastaSaida: resumoProjeto.pastaSaida,
|
|
3226
|
+
artefatos,
|
|
3227
|
+
entradaCanonica: indexJson.entradaCanonica,
|
|
3228
|
+
}, null, 2));
|
|
3229
|
+
return 0;
|
|
3230
|
+
}
|
|
3231
|
+
console.log("Entrypoints IA-first sincronizados");
|
|
3232
|
+
console.log("");
|
|
3233
|
+
console.log(`Base do projeto: ${resumoProjeto.baseProjeto}`);
|
|
3234
|
+
console.log(`Ordem canonica: ${indexJson.entradaCanonica.ordemLeitura.join(" -> ")}`);
|
|
3235
|
+
console.log(`IA pequena: ${indexJson.entradaCanonica.porCapacidade.pequena.join(" -> ")}`);
|
|
3236
|
+
console.log(`IA media: ${indexJson.entradaCanonica.porCapacidade.media.join(" -> ")}`);
|
|
3237
|
+
console.log(`IA grande: ${indexJson.entradaCanonica.porCapacidade.grande.join(" -> ")}`);
|
|
3238
|
+
return 0;
|
|
3239
|
+
}
|
|
2443
3240
|
async function comandoAjudaIa() {
|
|
2444
3241
|
const descoberta = await descobrirDocsIa();
|
|
2445
3242
|
console.log("Ajuda de IA da Sema");
|
|
2446
3243
|
console.log("");
|
|
3244
|
+
console.log(renderizarCaixaAscii([
|
|
3245
|
+
"IA-first para greenfield, edicao guiada e legado sem contrato inicial",
|
|
3246
|
+
"use o menor artefato semantico que resolva a tarefa",
|
|
3247
|
+
]));
|
|
3248
|
+
console.log("");
|
|
2447
3249
|
console.log(renderizarCabecalhoDocsIa(descoberta));
|
|
2448
3250
|
console.log("");
|
|
2449
|
-
console.log("
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
console.log("- Usa `vinculos` para ligar contrato a arquivo, simbolo, recurso e superficie real.");
|
|
2455
|
-
console.log("- Usa `execucao` para explicitar timeout, retry, compensacao e criticidade.");
|
|
2456
|
-
console.log("- Usa `drift` para medir divergencia entre contrato e codigo vivo com score, confianca e lacunas.");
|
|
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.");
|
|
3251
|
+
console.log(renderizarSecaoAscii("Tres jeitos de usar a Sema", [
|
|
3252
|
+
"[1] Producao inicial: modele, valide, compile e verifique antes de subir codigo derivado.",
|
|
3253
|
+
"[2] Edicao em projeto com Sema: inspecione, leia resumo, rode drift e gere contexto antes de editar codigo vivo.",
|
|
3254
|
+
"[3] Projeto sem Sema ainda: importe, revise o rascunho, formate, valide e use drift como juiz da adocao incremental.",
|
|
3255
|
+
]));
|
|
2459
3256
|
console.log("");
|
|
2460
|
-
console.log("
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
3257
|
+
console.log(renderizarSecaoAscii("Capacidade de IA", [
|
|
3258
|
+
"pequena: `sema resumo --micro`, `briefing.min.json`, `prompt-curto.txt`",
|
|
3259
|
+
"media: `sema resumo --curto`, `drift.json`, `briefing.min.json`",
|
|
3260
|
+
"grande: `sema contexto-ia`, `briefing.json`, `ir.json`, `ast.json`",
|
|
3261
|
+
]));
|
|
2464
3262
|
console.log("");
|
|
2465
|
-
console.log("Fluxo recomendado"
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
console.log("- Use `sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart> --saida <diretorio>` quando a tarefa pedir codigo derivado.");
|
|
3263
|
+
console.log(renderizarSecaoAscii("Fluxo recomendado", [
|
|
3264
|
+
"Use `sema starter-ia` para um texto curto de onboarding.",
|
|
3265
|
+
"Use `sema sync-ai-entrypoints` para regenerar `SEMA_BRIEF.*` e `SEMA_INDEX.json` na raiz.",
|
|
3266
|
+
"Use `sema resumo <arquivo> --micro --para onboarding` para IA pequena.",
|
|
3267
|
+
"Use `sema prompt-curto <arquivo> --curto --para mudanca` para colar contexto em modelo gratuito.",
|
|
3268
|
+
"Use `sema prompt-ia`, `sema prompt-ia-ui`, `sema prompt-ia-react` e `sema prompt-ia-sema-primeiro` conforme a tarefa.",
|
|
3269
|
+
"Use `sema exemplos-prompt-ia` para pegar modelos prontos de prompt.",
|
|
3270
|
+
"Use `sema inspecionar` para descobrir base, codigo vivo e fontes legado.",
|
|
3271
|
+
"Use `sema drift` para medir impls, vinculos, rotas, score e lacunas.",
|
|
3272
|
+
"Use `sema contexto-ia <arquivo.sema>` para gerar AST, IR, drift, `briefing.json` e `briefing.min.json`.",
|
|
3273
|
+
"Use `sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart> --saida <diretorio>` quando a tarefa pedir codigo derivado.",
|
|
3274
|
+
]));
|
|
2478
3275
|
console.log("");
|
|
2479
|
-
console.log("
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
3276
|
+
console.log(renderizarSecaoAscii("Regras praticas", [
|
|
3277
|
+
"Foi feita para IA operar melhor; leitura humana e consequencia, nao centro de produto.",
|
|
3278
|
+
"Governa contrato, intencao, erro, efeito, garantia, fluxo, vinculos e execucao.",
|
|
3279
|
+
"Nao escreve contrato final sozinho nem substitui decisao arquitetural.",
|
|
3280
|
+
"Se voce quer testar a Sema de verdade, nao peca so HTML solto.",
|
|
3281
|
+
"Peca `.sema` + arquitetura + React + TypeScript, ou use o modo `Sema primeiro`.",
|
|
3282
|
+
"Se o projeto ja existe, trate `importar` como rascunho e `drift` como juiz.",
|
|
3283
|
+
"IA pequena comeca no menor artefato que resolve a tarefa; nao enfie `ast.json` inteiro nela de bobeira.",
|
|
3284
|
+
"Antes de editar software vivo, leia `briefing.min.json` ou `briefing.json` em vez de sair cavando arquivo na fe.",
|
|
3285
|
+
"Trate `route`, `worker`, `evento`, `fila`, `cron`, `webhook`, `cache`, `storage` e `policy` como superficies de primeira classe.",
|
|
3286
|
+
]));
|
|
2486
3287
|
return 0;
|
|
2487
3288
|
}
|
|
2488
3289
|
async function comandoPromptIa() {
|
|
@@ -2897,7 +3698,7 @@ async function principal() {
|
|
|
2897
3698
|
{
|
|
2898
3699
|
const fonte = normalizarFonteImportacao(posicionais[0]);
|
|
2899
3700
|
if (!fonte || !posicionais[1]) {
|
|
2900
|
-
console.error("Uso: sema importar <nestjs|fastapi|flask|nextjs|firebase|dotnet|java|go|rust|cpp|typescript|python|dart> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]");
|
|
3701
|
+
console.error("Uso: 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]");
|
|
2901
3702
|
codigoSaida = 1;
|
|
2902
3703
|
break;
|
|
2903
3704
|
}
|
|
@@ -2916,6 +3717,9 @@ async function principal() {
|
|
|
2916
3717
|
case "starter-ia":
|
|
2917
3718
|
codigoSaida = await comandoStarterIa();
|
|
2918
3719
|
break;
|
|
3720
|
+
case "sync-ai-entrypoints":
|
|
3721
|
+
codigoSaida = await comandoSyncAiEntrypoints(possuiFlag(resto, "--json"));
|
|
3722
|
+
break;
|
|
2919
3723
|
case "resumo":
|
|
2920
3724
|
codigoSaida = await comandoResumo(posicionais[0], resto, possuiFlag(resto, "--json"));
|
|
2921
3725
|
break;
|