@semacode/cli 1.4.0 → 1.5.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
@@ -15,7 +15,7 @@ import { gerarHtml } from "@sema/gerador-html";
15
15
  import { gerarCss } from "@sema/gerador-css";
16
16
  import { carregarConfiguracaoProjeto, carregarProjeto, resolverAlvoPadrao, resolverAlvosVerificacao, resolverEstruturaSaidaPadrao, resolverFrameworkPadrao, resolverSaidaPadrao, } from "./projeto.js";
17
17
  import { importarProjetoLegado, resumoImportacao } from "./importador.js";
18
- import { analisarDriftLegado } from "./drift.js";
18
+ import { analisarDriftLegado, assistirRenomeacaoSemantica, gerarMapaImpactoSemantico, } from "./drift.js";
19
19
  const STARTER_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao para IA sobre software vivo em backend e front consumer.
20
20
 
21
21
  Importante:
@@ -52,8 +52,10 @@ Regras:
52
52
  Comandos essenciais:
53
53
  - resumo compacto por capacidade: \`sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
54
54
  - prompt curto para IA pequena: \`sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
55
- - descoberta do projeto: \`sema inspecionar [arquivo-ou-pasta] --json\`
56
- - auditoria do contrato vivo: \`sema drift <arquivo-ou-pasta> [--json]\`
55
+ - descoberta do projeto: \`sema inspecionar [arquivo-ou-pasta] --json\`
56
+ - auditoria do contrato vivo: \`sema drift <arquivo-ou-pasta> [--escopo <arquivo|modulo|projeto>] [--json]\`
57
+ - mapa de impacto: \`sema impacto <arquivo-ou-pasta> --alvo <token> [--mudanca <descricao>] [--json]\`
58
+ - renomeacao assistida: \`sema renomear-semantico <arquivo-ou-pasta> --de <nome-atual> --para <nome-novo> [--json]\`
57
59
  - contexto completo do modulo: \`sema contexto-ia <arquivo.sema>\`
58
60
  - estrutura sintatica: \`sema ast <arquivo.sema> --json\`
59
61
  - estrutura semantica: \`sema ir <arquivo.sema> --json\`
@@ -373,14 +375,15 @@ function ajuda() {
373
375
  "[2] Editar projeto que ja usa Sema",
374
376
  "sema inspecionar . --json",
375
377
  "sema resumo <arquivo-ou-pasta> --micro --para mudanca",
376
- "sema drift <arquivo-ou-pasta> --json",
378
+ "sema drift <arquivo-ou-pasta> --escopo modulo --json",
379
+ "sema impacto <arquivo-ou-pasta> --alvo <token> --mudanca <descricao> --json",
377
380
  "sema contexto-ia <arquivo.sema> --saida ./.tmp/contexto --json",
378
381
  "",
379
382
  "[3] Adotar Sema em projeto que ainda nao usa",
380
383
  "sema importar <fonte> <diretorio> --saida <diretorio> --json",
381
384
  "sema formatar <arquivo-ou-pasta>",
382
385
  "sema validar <arquivo-ou-pasta> --json",
383
- "sema drift <arquivo-ou-pasta> --json",
386
+ "sema drift <arquivo-ou-pasta> --escopo modulo --json",
384
387
  ]),
385
388
  "",
386
389
  renderizarSecaoAscii("IA por capacidade", [
@@ -391,7 +394,9 @@ function ajuda() {
391
394
  "",
392
395
  renderizarSecaoAscii("Comandos principais", [
393
396
  "descoberta: sema inspecionar [arquivo-ou-pasta] [--json]",
394
- "auditoria: sema drift <arquivo-ou-pasta> [--json]",
397
+ "auditoria: sema drift <arquivo-ou-pasta> [--escopo <arquivo|modulo|projeto>] [--incluir-worktrees] [--incluir-consumidores-laterais] [--json]",
398
+ "impacto: sema impacto <arquivo-ou-pasta> --alvo <token> [--mudanca <descricao>] [--escopo <arquivo|modulo|projeto>] [--json]",
399
+ "renomeacao: sema renomear-semantico <arquivo-ou-pasta> --de <nome-atual> --para <nome-novo> [--escopo <arquivo|modulo|projeto>] [--json]",
395
400
  "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]",
396
401
  "validacao: sema validar <arquivo-ou-pasta> [--json]",
397
402
  "diagnostico: sema diagnosticos <arquivo.sema> [--json]",
@@ -447,10 +452,13 @@ function possuiFlag(args, nome) {
447
452
  const OPCOES_COM_VALOR = new Set([
448
453
  "--template",
449
454
  "--alvo", "-a",
455
+ "--escopo",
450
456
  "--saida", "-s",
451
457
  "--estrutura",
452
458
  "--framework",
453
459
  "--namespace",
460
+ "--mudanca",
461
+ "--de",
454
462
  "--para",
455
463
  ]);
456
464
  const ALIAS_OPCOES = {
@@ -471,6 +479,14 @@ function obterPosicionais(args) {
471
479
  }
472
480
  return posicionais;
473
481
  }
482
+ function resolverOpcoesDriftCli(args) {
483
+ const escopo = obterOpcao(args, "--escopo");
484
+ return {
485
+ escopo: escopo === "arquivo" || escopo === "modulo" || escopo === "projeto" ? escopo : undefined,
486
+ ignorarWorktrees: !possuiFlag(args, "--incluir-worktrees"),
487
+ ignorarConsumidoresLaterais: !possuiFlag(args, "--incluir-consumidores-laterais"),
488
+ };
489
+ }
474
490
  function normalizarTamanhoResumo(args) {
475
491
  const escolhas = [
476
492
  possuiFlag(args, "--micro") ? "micro" : null,
@@ -3058,14 +3074,17 @@ async function comandoInspecionar(entrada, emJson, cwd = process.cwd()) {
3058
3074
  }
3059
3075
  return 0;
3060
3076
  }
3061
- async function comandoDrift(entrada, emJson, cwd = process.cwd()) {
3077
+ async function comandoDrift(entrada, args, emJson, cwd = process.cwd()) {
3062
3078
  const contextoProjeto = await carregarProjeto(entrada, cwd);
3063
- const resultado = await analisarDriftLegado(contextoProjeto);
3079
+ const resultado = await analisarDriftLegado(contextoProjeto, resolverOpcoesDriftCli(args));
3064
3080
  if (emJson) {
3065
3081
  console.log(JSON.stringify(resultado, null, 2));
3066
3082
  return resultado.sucesso ? 0 : 1;
3067
3083
  }
3068
3084
  console.log("Drift entre Sema e codigo legado");
3085
+ console.log(`- Escopo aplicado: ${resultado.escopo_aplicado.escopo}`);
3086
+ console.log(`- Ignorar worktrees: ${resultado.escopo_aplicado.ignorarWorktrees ? "sim" : "nao"}`);
3087
+ console.log(`- Ignorar consumidores laterais: ${resultado.escopo_aplicado.ignorarConsumidoresLaterais ? "sim" : "nao"}`);
3069
3088
  console.log(`- Modulos analisados: ${resultado.modulos.length}`);
3070
3089
  console.log(`- Tasks analisadas: ${resultado.tasks.length}`);
3071
3090
  console.log(`- Impl validos: ${resultado.impls_validos.length}`);
@@ -3075,6 +3094,7 @@ async function comandoDrift(entrada, emJson, cwd = process.cwd()) {
3075
3094
  console.log(`- Rotas divergentes: ${resultado.rotas_divergentes.length}`);
3076
3095
  console.log(`- Recursos vivos validos: ${resultado.recursos_validos.length}`);
3077
3096
  console.log(`- Recursos vivos divergentes: ${resultado.recursos_divergentes.length}`);
3097
+ console.log(`- Persistencia real mapeada: ${resultado.persistencia_real.length}`);
3078
3098
  console.log(`- Score medio: ${resultado.resumo_operacional.scoreMedio}`);
3079
3099
  console.log(`- Confianca geral: ${resultado.resumo_operacional.confiancaGeral}`);
3080
3100
  if (resultado.impls_quebrados.length > 0) {
@@ -3101,6 +3121,13 @@ async function comandoDrift(entrada, emJson, cwd = process.cwd()) {
3101
3121
  console.log(` - ${recurso.modulo}.${recurso.task} :: ${recurso.categoria} ${recurso.alvo}`);
3102
3122
  }
3103
3123
  }
3124
+ const persistenciaDivergente = resultado.persistencia_real.filter((item) => item.status !== "materializado");
3125
+ if (persistenciaDivergente.length > 0) {
3126
+ console.log("- Persistencia que pede revisao:");
3127
+ for (const item of persistenciaDivergente.slice(0, 8)) {
3128
+ console.log(` - ${item.modulo}.${item.task} :: ${item.alvo} :: ${item.status} :: compat=${item.compatibilidade}`);
3129
+ }
3130
+ }
3104
3131
  const semImpl = resultado.tasks.filter((task) => task.semImplementacao);
3105
3132
  if (semImpl.length > 0) {
3106
3133
  console.log("- Tasks sem implementacao vinculada:");
@@ -3137,6 +3164,70 @@ async function comandoDrift(entrada, emJson, cwd = process.cwd()) {
3137
3164
  }
3138
3165
  return resultado.sucesso ? 0 : 1;
3139
3166
  }
3167
+ async function comandoImpacto(entrada, args, emJson, cwd = process.cwd()) {
3168
+ const alvoSemantico = obterOpcao(args, "--alvo");
3169
+ if (!alvoSemantico) {
3170
+ console.error("Uso: sema impacto <arquivo-ou-pasta> --alvo <token-semântico> [--mudanca <descricao>] [--escopo <arquivo|modulo|projeto>] [--incluir-worktrees] [--incluir-consumidores-laterais] [--json]");
3171
+ return 1;
3172
+ }
3173
+ const contextoProjeto = await carregarProjeto(entrada, cwd);
3174
+ const resultado = await gerarMapaImpactoSemantico(contextoProjeto, alvoSemantico, obterOpcao(args, "--mudanca", `avaliar impacto de ${alvoSemantico}`), resolverOpcoesDriftCli(args));
3175
+ if (emJson) {
3176
+ console.log(JSON.stringify(resultado, null, 2));
3177
+ return resultado.sucesso ? 0 : 1;
3178
+ }
3179
+ console.log("Impact map semantico");
3180
+ console.log(`- Escopo: ${resultado.escopo}`);
3181
+ console.log(`- Alvo: ${resultado.alvoSemantico}`);
3182
+ console.log(`- Mudanca: ${resultado.mudancaProposta}`);
3183
+ console.log(`- Arquivos impactados: ${resultado.arquivos.length}`);
3184
+ console.log(`- Tasks afetadas: ${resultado.tasksAfetadas.length}`);
3185
+ console.log(`- Rotas afetadas: ${resultado.routesAfetadas.length}`);
3186
+ console.log(`- Superficies afetadas: ${resultado.superficiesAfetadas.length}`);
3187
+ console.log(`- Persistencia afetada: ${resultado.persistenciaAfetada.length}`);
3188
+ if (resultado.arquivos.length > 0) {
3189
+ console.log("- Arquivos prioritarios:");
3190
+ for (const arquivo of resultado.arquivos.slice(0, 10)) {
3191
+ console.log(` - [${arquivo.prioridade}] ${arquivo.tipo} :: ${arquivo.arquivo}`);
3192
+ }
3193
+ }
3194
+ console.log("- Ordem operacional:");
3195
+ for (const passo of resultado.ordemOperacional) {
3196
+ console.log(` - ${passo}`);
3197
+ }
3198
+ return resultado.sucesso ? 0 : 1;
3199
+ }
3200
+ async function comandoRenomearSemantico(entrada, args, emJson, cwd = process.cwd()) {
3201
+ const nomeAtual = obterOpcao(args, "--de");
3202
+ const nomeNovo = obterOpcao(args, "--para");
3203
+ if (!nomeAtual || !nomeNovo) {
3204
+ console.error("Uso: sema renomear-semantico <arquivo-ou-pasta> --de <nome-atual> --para <nome-novo> [--escopo <arquivo|modulo|projeto>] [--incluir-worktrees] [--incluir-consumidores-laterais] [--json]");
3205
+ return 1;
3206
+ }
3207
+ const contextoProjeto = await carregarProjeto(entrada, cwd);
3208
+ const resultado = await assistirRenomeacaoSemantica(contextoProjeto, nomeAtual, nomeNovo, resolverOpcoesDriftCli(args));
3209
+ if (emJson) {
3210
+ console.log(JSON.stringify(resultado, null, 2));
3211
+ return resultado.sucesso ? 0 : 1;
3212
+ }
3213
+ console.log("Renomeacao semantica assistida");
3214
+ console.log(`- Escopo: ${resultado.escopo}`);
3215
+ console.log(`- De: ${resultado.de}`);
3216
+ console.log(`- Para: ${resultado.para}`);
3217
+ console.log(`- Arquivos afetados: ${resultado.arquivos.length}`);
3218
+ console.log(`- Sugestoes: ${resultado.sugestoes.length}`);
3219
+ if (resultado.sugestoes.length > 0) {
3220
+ console.log("- Primeiras sugestoes:");
3221
+ for (const sugestao of resultado.sugestoes.slice(0, 12)) {
3222
+ console.log(` - ${sugestao.arquivo}:${sugestao.linha} :: ${sugestao.atual} -> ${sugestao.sugerido}`);
3223
+ }
3224
+ }
3225
+ console.log("- Ordem operacional:");
3226
+ for (const passo of resultado.ordemOperacional) {
3227
+ console.log(` - ${passo}`);
3228
+ }
3229
+ return resultado.sucesso ? 0 : 1;
3230
+ }
3140
3231
  async function comandoImportar(fonte, diretorio, saida, namespaceBase, emJson) {
3141
3232
  const resultado = await importarProjetoLegado(fonte, diretorio, namespaceBase);
3142
3233
  const resumo = resumoImportacao(resultado);
@@ -3855,7 +3946,13 @@ async function principal() {
3855
3946
  codigoSaida = await comandoInspecionar(posicionais[0], possuiFlag(resto, "--json"), cwd);
3856
3947
  break;
3857
3948
  case "drift":
3858
- codigoSaida = await comandoDrift(posicionais[0], possuiFlag(resto, "--json"), cwd);
3949
+ codigoSaida = await comandoDrift(posicionais[0], resto, possuiFlag(resto, "--json"), cwd);
3950
+ break;
3951
+ case "impacto":
3952
+ codigoSaida = await comandoImpacto(posicionais[0], resto, possuiFlag(resto, "--json"), cwd);
3953
+ break;
3954
+ case "renomear-semantico":
3955
+ codigoSaida = await comandoRenomearSemantico(posicionais[0], resto, possuiFlag(resto, "--json"), cwd);
3859
3956
  break;
3860
3957
  case "importar":
3861
3958
  {