@semacode/cli 3.12.2 → 4.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.
Files changed (90) hide show
  1. package/dist/agentEntryPoints.js +9 -9
  2. package/dist/cliGrammar.js +17 -5
  3. package/dist/cliHelpTexto.js +5 -4
  4. package/dist/contextPack.d.ts +75 -0
  5. package/dist/contextPack.js +130 -0
  6. package/dist/drift.contrato.d.ts +1 -0
  7. package/dist/drift.contrato.js +1 -0
  8. package/dist/drift.part01.d.ts +4 -2
  9. package/dist/drift.part11.js +12 -1
  10. package/dist/drift.part14.d.ts +3 -0
  11. package/dist/drift.part14.js +108 -10
  12. package/dist/driftEscopo.d.ts +1 -0
  13. package/dist/driftEscopo.js +6 -0
  14. package/dist/driftPack.d.ts +65 -0
  15. package/dist/driftPack.js +96 -0
  16. package/dist/entrypointPack.d.ts +47 -0
  17. package/dist/entrypointPack.js +79 -0
  18. package/dist/index.part03.d.ts +2 -0
  19. package/dist/index.part03.js +6 -0
  20. package/dist/index.part05.js +14 -1
  21. package/dist/index.part06.js +51 -0
  22. package/dist/index.part07.d.ts +1 -1
  23. package/dist/index.part07.js +16 -2
  24. package/dist/index.part08.js +1 -1
  25. package/dist/indexPack.d.ts +54 -0
  26. package/dist/indexPack.js +140 -0
  27. package/dist/init/templates.part01.js +393 -393
  28. package/dist/init/templates.part02.js +189 -189
  29. package/dist/initCommand.js +38 -2
  30. package/dist/initTemplatesBackend.js +73 -73
  31. package/dist/initTemplatesFlutter.js +137 -137
  32. package/dist/initTemplatesRuntime.js +350 -350
  33. package/dist/initTemplatesWeb.js +309 -309
  34. package/dist/sync/index.js +35 -35
  35. package/docs/ai-workflow.md +1 -1
  36. package/docs/auth.md +26 -26
  37. package/docs/commands.md +3 -3
  38. package/docs/database.md +15 -15
  39. package/docs/env.md +16 -16
  40. package/docs/frontend.md +41 -41
  41. package/docs/i18n.md +15 -15
  42. package/exemplos/agendamento.sema +1 -1
  43. package/exemplos/assinatura.sema +1 -1
  44. package/exemplos/auditoria.sema +1 -1
  45. package/exemplos/autenticacao.sema +1 -1
  46. package/exemplos/author_obra_comum.sema +1 -1
  47. package/exemplos/author_tema_sensivel.sema +1 -1
  48. package/exemplos/automacao.sema +1 -1
  49. package/exemplos/cadastro_usuario.sema +1 -1
  50. package/exemplos/calculadora.sema +1 -1
  51. package/exemplos/crud_simples.sema +1 -1
  52. package/exemplos/estoque.sema +1 -1
  53. package/exemplos/exportacao.sema +1 -1
  54. package/exemplos/fila.sema +1 -1
  55. package/exemplos/integracao_externa.sema +1 -1
  56. package/exemplos/multi_tenant.sema +1 -1
  57. package/exemplos/notificacao.sema +1 -1
  58. package/exemplos/operacao_estrategia.sema +132 -132
  59. package/exemplos/operacao_estrategia_discovery.sema +220 -220
  60. package/exemplos/operacao_estrategia_fluxo.sema +114 -114
  61. package/exemplos/operacao_estrategia_gates.sema +106 -106
  62. package/exemplos/operacao_estrategia_quarentena.sema +133 -133
  63. package/exemplos/operacao_estrategia_rollout.sema +124 -124
  64. package/exemplos/pagamento.sema +1 -1
  65. package/exemplos/pagamento_dominio.sema +1 -1
  66. package/exemplos/pedido.sema +1 -1
  67. package/exemplos/permissao.sema +1 -1
  68. package/exemplos/persistencia_vendor_first.sema +1 -1
  69. package/exemplos/php_crud.sema +170 -170
  70. package/exemplos/profile_conversas.sema +165 -165
  71. package/exemplos/profile_game.sema +1 -1
  72. package/exemplos/profile_legal.sema +1 -1
  73. package/exemplos/profile_ops.sema +1 -1
  74. package/exemplos/profile_research.sema +1 -1
  75. package/exemplos/profile_software.sema +1 -1
  76. package/exemplos/profile_workflow_n8n.sema +1 -1
  77. package/exemplos/relatorio.sema +1 -1
  78. package/exemplos/replica_analitica_erp.sema +1 -1
  79. package/exemplos/testes_embutidos.sema +1 -1
  80. package/exemplos/tratamento_erro.sema +1 -1
  81. package/exemplos/upload_arquivo.sema +1 -1
  82. package/exemplos/webhook.sema +1 -1
  83. package/node_modules/@sema/gerador-cpp/dist/index.js +176 -176
  84. package/node_modules/@sema/gerador-css/dist/index.part01.js +10 -10
  85. package/node_modules/@sema/gerador-dotnet/dist/index.js +169 -169
  86. package/node_modules/@sema/gerador-html/dist/index.js +17 -17
  87. package/node_modules/@sema/gerador-python/dist/index.part02.js +3 -3
  88. package/node_modules/@sema/gerador-typescript/dist/index.part02.js +11 -11
  89. package/node_modules/@sema/nucleo/dist/diagnosticos/melhorador.js +42 -42
  90. package/package.json +1 -1
@@ -201,7 +201,7 @@ Score composto, \`achados[]\` e \`decisaoAgente\` são sinais para guiar a próx
201
201
  - Consultas honestas: \`resumo\` e \`inspecionar\` usam \`--drift none\` por padrão; score, confiança, implementação, rotas e superfícies não observadas ficam nulos/não avaliados.
202
202
  - Se uma consulta executar drift explicitamente, \`payload.analiseDrift.sucesso\` expõe o resultado e uma falha solicitada retorna exit code diferente de zero.
203
203
  - Cache: \`sema drift\` usa \`fresh\` por padrão. \`--cache none\` ainda executa sem persistência; \`cache\` acelera extrações validadas, mas não é prova final.
204
- - Fechamento governado: se o \`payload\` de \`sema drift --cache fresh --json\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não diga que passou limpo. Corrija e rode drift de novo.
204
+ - Fechamento governado: se o \`payload\` de \`sema drift --cache fresh --json\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não diga que passou limpo. Corrija e rode drift de novo. \`vinculos_fora_do_escopo\` é informativo: o arquivo existe no workspace fora dos \`diretoriosCodigo\`; siga o \`diretorioSugerido\` do registro para incluir o diretório no \`sema.config.json\` — não bloqueia fechamento.
205
205
  - Experiência governada: se a tarefa cria ou altera site, sistema, app, UI, painel, jogo, CLI/TUI ou terminal, prove acabamento moderno, contextual e não genérico. Em UI estreita (ex. 390px), \`document.documentElement.scrollWidth <= document.documentElement.clientWidth\` precisa ser verdadeiro.
206
206
  - Caminho fora do workspace local aberto pelo usuário não substitui a pasta local.
207
207
 
@@ -265,7 +265,7 @@ Leia isto primeiro se você tem pouco contexto, pouca memória, pouco tool use o
265
265
  15. Payload inline acima de ${LIMITE_CARACTERES_PAYLOAD_INLINE} caracteres não é lentidão: divida por responsabilidade; não aumente timeout para tentar passar limite de transporte.
266
266
  16. Se aparecer caminho que não pertence ao workspace local aberto pelo usuário, pare e confirme a fonte antes de agir.
267
267
  17. Se Sema estourar por timeout local: aumente o timeout e tente de novo. Não trate isso como falha do Sema.
268
- 18. Para fechamento, rode \`sema drift --cache fresh --json\`; cache persistente só acelera navegação e não é prova final. Se o \`payload\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não conclua. Na 3.0.0, não procure campos de domínio no topo do envelope \`sema.cli.result/v1\` nem use \`ok\` como substituto do veredito do payload.
268
+ 18. Para fechamento, rode \`sema drift --cache fresh --json\`; cache persistente só acelera navegação e não é prova final. Se o \`payload\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não conclua. \`vinculos_fora_do_escopo\` é informativo com \`diretorioSugerido\` para o \`sema.config.json\`; não bloqueia fechamento. Na 3.0.0, não procure campos de domínio no topo do envelope \`sema.cli.result/v1\` nem use \`ok\` como substituto do veredito do payload.
269
269
  19. Se a tarefa tiver site, sistema, app, UI, painel, jogo, CLI/TUI ou terminal: aplique acabamento moderno, contextual, responsivo/ergonômico, com hierarquia clara, estados e evidência. Em UI, valide mobile/desktop e prove \`scrollWidth <= clientWidth\` em viewport estreito como 390px.
270
270
  20. Não substitua o contexto Sema por AGENTS.md, README.md, busca local, inferência por nome ou bom senso.
271
271
 
@@ -486,7 +486,7 @@ Sinal e evidência:
486
486
  - Score composto, \`achados[]\` e \`decisaoAgente\` orientam a ação; abaixo de 80 bloqueia, alvo evolui 0.5 ponto até 100, e nada substitui evidência concreta.
487
487
  - Palavra-chave ou regex passando não prova governança se contrato, código e comportamento não batem.
488
488
  - \`resumo\` e \`inspecionar\` usam \`--drift none\` por padrão; campos derivados nulos significam não avaliados, nunca zero.
489
- - \`sema drift --cache fresh --json\` com \`payload.sucesso:false\`, \`payload.vinculos_quebrados\`, \`payload.rotas_divergentes\` ou \`payload.impls_quebrados\` bloqueia fechamento. Cache persistente é aceleração, não prova final.
489
+ - \`sema drift --cache fresh --json\` com \`payload.sucesso:false\`, \`payload.vinculos_quebrados\`, \`payload.rotas_divergentes\` ou \`payload.impls_quebrados\` bloqueia fechamento. \`payload.vinculos_fora_do_escopo\` é informativo com \`diretorioSugerido\` para os \`diretoriosCodigo\`; não bloqueia. Cache persistente é aceleração, não prova final.
490
490
  - Caminho fora do workspace local aberto pelo usuário não substitui a pasta local.
491
491
 
492
492
  Acabamento visual e terminal:
@@ -685,9 +685,9 @@ This is the minimum workflow for Codex in a local workspace.
685
685
 
686
686
  Contract edit rule: \`.sema\` has its own size budget. Above ${LIMITE_AVISO_LINHAS_CONTRATO_SEMA} lines, plan a split by domain/capability; above ${LIMITE_BLOQUEIO_LINHAS_CONTRATO_SEMA}, do not create or edit before splitting. Do not use parte_1/parte_2 and do not force a 1:1 contract-to-file relationship; several contracts can govern the same file through \`vinculos\`.
687
687
 
688
- Closing rule: the \`payload\` of \`sema drift --cache fresh --json\` must return \`sucesso:true\`. If it reports \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\`, the task is still blocked. Passing unit tests or a cache hit do not replace fresh green drift. In 3.0.0, \`ok\` describes the CLI result path and never replaces a command-specific domain verdict.
688
+ Closing rule: the \`payload\` of \`sema drift --cache fresh --json\` must return \`sucesso:true\`. If it reports \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\`, the task is still blocked. Passing unit tests or a cache hit do not replace fresh green drift. \`vinculos_fora_do_escopo\` is informational: the file exists in the workspace outside the configured \`diretoriosCodigo\`, and each entry carries a \`diretorioSugerido\` to add to \`sema.config.json\`; it does not block closure. In 3.0.0, \`ok\` describes the CLI result path and never replaces a command-specific domain verdict.
689
689
 
690
- Focused drift rule: file and module scopes plan their physical file set before cataloging. They never fall back to a whole-project walk when no safe anchor exists. All indexers and semantic-budget checks reuse the same in-memory source read; a global walk is reserved for explicit \`--escopo projeto\`. Code discovery is deferred until that plan exists, homonymous candidates fail as ambiguous, and configured contract origins or code roots resolving outside the workspace are rejected before enumeration. \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` preserve the same directed boundary. Missing unambiguous local dependencies make coverage partial and block success. In Python, an unresolved \`name\` from \`from module import name\` is not itself a missing file after \`module\` resolves: it may be an exported symbol, while a real child module is still included whenever its file exists.
690
+ Focused drift rule: file and module scopes plan their physical file set before cataloging. They never fall back to a whole-project walk when no safe anchor exists. All indexers and semantic-budget checks reuse the same in-memory source read; a global walk is reserved for explicit \`--escopo projeto\`. Code discovery is deferred until that plan exists, homonymous candidates fail as ambiguous, and configured contract origins or code roots resolving outside the workspace are rejected before enumeration. \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` preserve the same directed boundary. Missing unambiguous local dependencies make coverage partial and block success. In Python, an unresolved \`name\` from \`from module import name\` is not itself a missing file after \`module\` resolves: it may be an exported symbol, while a real child module is still included whenever its file exists.
691
691
 
692
692
  Cache rule: a closure gate should use \`sema drift <contrato> --escopo modulo --cache fresh --json\`. \`--cache none\` executes the same analysis without persistent-cache I/O, while \`--cache cache\` may reuse only extraction data whose schema, workspace identity, Git HEAD, plan, configuration, contracts, member paths, and strong content digests all match. Cache objects are stored in the operating system's user-cache directory, never below the workspace. A hit is acceleration, not evidence: final links, diagnostics, score, and success are always recalculated. Corruption or an unavailable cache degrades to an in-memory calculation.
693
693
 
@@ -752,7 +752,7 @@ Then read every required doc returned by \`docs-impacto\`.
752
752
 
753
753
  ## Contract and Discovery
754
754
 
755
- - \`sema iniciar --template <base|nestjs|fastapi|nextjs-api|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|node-firebase-worker|aspnet-api|springboot-api|go-http-api|rust-axum-api|cpp-service-bridge> [--force]\`: creates a new Sema project and preserves existing files by default; \`--force\` is the only explicit overwrite path.
755
+ - \`sema iniciar --template <base|nestjs|fastapi|nextjs-api|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|node-firebase-worker|aspnet-api|springboot-api|go-http-api|rust-axum-api|cpp-service-bridge> [--force]\`: creates a new Sema project and preserves existing files by default; \`--force\` is the only explicit overwrite path. Inside a subfolder of an already governed workspace, the subfolder is registered under \`diretoriosCodigo\` of the ancestral \`sema.config.json\` (safe write, deduplicated) instead of creating a local config; if the parent config cannot be written, the scaffold proceeds and prints the exact line to add.
756
756
  - \`sema validar <arquivo-ou-pasta> --json\`: validates \`.sema\` contracts.
757
757
  - \`sema diagnosticos <arquivo.sema> --json\`: details errors and warnings.
758
758
  - \`sema formatar <arquivo-ou-pasta>\`: formats contracts.
@@ -772,9 +772,9 @@ Then read every required doc returned by \`docs-impacto\`.
772
772
  - \`sema verificar <arquivo-ou-pasta> --json\`: runs aggregated final verification.
773
773
  - \`sema finalizar-mudanca --intencao "<acao>" --doc-lida <arquivo> --json\`: proves documentation reading before closure.
774
774
 
775
- Honest closure: unwrap drift JSON and treat its command payload as the source of truth. \`payload.sucesso:false\`, non-empty \`payload.vinculos_quebrados\`, non-empty \`payload.rotas_divergentes\`, or non-empty \`payload.impls_quebrados\` mean the change is not complete yet. Do not report "clean drift" without a green payload.
775
+ Honest closure: unwrap drift JSON and treat its command payload as the source of truth. \`payload.sucesso:false\`, non-empty \`payload.vinculos_quebrados\`, non-empty \`payload.rotas_divergentes\`, or non-empty \`payload.impls_quebrados\` mean the change is not complete yet. Do not report "clean drift" without a green payload. \`payload.vinculos_fora_do_escopo\` is informational: the file exists in the workspace outside \`diretoriosCodigo\`, and each entry carries a \`diretorioSugerido\` for \`sema.config.json\`.
776
776
 
777
- Focused drift exposes its planned, declared, inferred, and missing files plus catalog visit/read metrics in \`escopo_aplicado\`. A missing declared file or a missing unambiguous code-referenced dependency is a blocker reported as \`vinculo_quebrado\`; a missing inferred candidate derived from an \`impl\` symbol is informational under \`arquivosAusentesInferidos\` and never blocks an implementation that resolved. For Python \`from module import name\`, Sema still includes \`name\` when it resolves as a real submodule, but never reports the absent submodule candidate as a broken link after the parent module resolved because \`name\` may be a function, class, or variable. File and module scopes fail closed without a safe anchor, with homonymous implementation candidates, or with missing local dependencies; only \`--escopo projeto\` may walk every configured code root. Logical roots such as \`src\` are probed deterministically without a discovery walk. Configured contract origins and code roots are confined before enumeration, and \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` reuse the same directed boundary without reopening arbitrary external paths.
777
+ Focused drift exposes its planned, declared, inferred, and missing files plus catalog visit/read metrics in \`escopo_aplicado\`. A missing declared file or a missing unambiguous code-referenced dependency is a blocker reported as \`vinculo_quebrado\`; a missing inferred candidate derived from an \`impl\` symbol is informational under \`arquivosAusentesInferidos\` and never blocks an implementation that resolved. For Python \`from module import name\`, Sema still includes \`name\` when it resolves as a real submodule, but never reports the absent submodule candidate as a broken link after the parent module resolved because \`name\` may be a function, class, or variable. File and module scopes fail closed without a safe anchor, with homonymous implementation candidates, or with missing local dependencies; only \`--escopo projeto\` may walk every configured code root. Logical roots such as \`src\` are probed deterministically without a discovery walk. Configured contract origins and code roots are confined before enumeration, and \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` reuse the same directed boundary without reopening arbitrary external paths.
778
778
 
779
779
  Drift analysis and cache modes are explicit:
780
780
 
@@ -877,7 +877,7 @@ Spatial model and render mode are orthogonal: \`THREE_D + HEADLESS\` is valid, w
877
877
  - Do not stop after \`sema compilar\` if the contract target files still do not exist.
878
878
  - Do not replace \`sema compilar\` with \`sema testar\` when the contract requires generated code.
879
879
  - Do not create a Markdown report to pretend a gate ran.
880
- - Do not say drift passed when the unwrapped \`sema drift --cache fresh --json\` payload returned \`sucesso:false\`, a non-empty \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\` list.
880
+ - Do not say drift passed when the unwrapped \`sema drift --cache fresh --json\` payload returned \`sucesso:false\`, a non-empty \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\` list. \`vinculos_fora_do_escopo\` entries are informational scope hints, not broken links.
881
881
  - Do not declare a UI responsive without mobile/desktop proof; horizontal scroll at 390px blocks closure.
882
882
 
883
883
  Governed code policy: keep the \`SEMA-GOVERNED\` marker, split large code by real responsibility, preserve contract links, and never treat a generated output directory as the final delivery.
@@ -35,6 +35,7 @@ const ESTRUTURAS = new Set(["flat", "modulos", "backend"]);
35
35
  const ESCOPOS = new Set(["arquivo", "modulo", "projeto"]);
36
36
  const MODOS_CACHE = new Set(["none", "cache", "fresh", "off", "auto", "refresh"]);
37
37
  const MODOS_RESUMO = new Set(["resumo", "onboarding", "review", "mudanca", "bug", "arquitetura"]);
38
+ const CAPACIDADES_IA = new Set(["fraca", "media", "forte"]);
38
39
  const MATURIDADES = new Set([
39
40
  "draft", "rascunho", "prototype", "prototipo", "production", "producao",
40
41
  "critical", "critico", "critica",
@@ -416,15 +417,22 @@ function validarInterativo(args) {
416
417
  }
417
418
  function validarResumo(args, promptCurto) {
418
419
  const parsed = parsearArgumentos(args, {
419
- opcoes: promptCurto ? ["--para"] : ["--para", "--saida", "--drift", "--cache"],
420
- flags: promptCurto ? ["--micro", "--curto", "--medio"] : ["--micro", "--curto", "--medio", "--raiz", "--com-drift"],
420
+ opcoes: promptCurto ? ["--para"] : ["--para", "--saida", "--drift", "--cache", "--pedido"],
421
+ flags: promptCurto ? ["--micro", "--curto", "--medio"] : ["--micro", "--curto", "--medio", "--raiz", "--com-drift", "--pacote", "--somente-pacote"],
421
422
  maxPosicionais: 1,
422
423
  });
423
424
  if (!parsed)
424
425
  return false;
425
426
  const tamanhos = ["--micro", "--curto", "--medio"].filter((flag) => parsed.flags.has(flag));
426
427
  const modo = valorOpcao(parsed, "--para");
427
- return tamanhos.length <= 1 && (!modo || MODOS_RESUMO.has(modo)) && (promptCurto || validarModoCache(parsed, "--drift"));
428
+ const pacote = parsed.flags.has("--pacote");
429
+ const somentePacote = parsed.flags.has("--somente-pacote");
430
+ const pedido = valorOpcao(parsed, "--pedido");
431
+ const combinacaoPacoteValida = pacote === Boolean(pedido);
432
+ return tamanhos.length <= 1
433
+ && (!modo || MODOS_RESUMO.has(modo))
434
+ && (promptCurto || validarModoCache(parsed, "--drift"))
435
+ && (promptCurto ? !pacote && !pedido && !somentePacote : combinacaoPacoteValida && (!somentePacote || pacote));
428
436
  }
429
437
  function validarComandoBasico(comando, args) {
430
438
  const aliasesGeracao = { "-a": "--alvo", "-s": "--saida" };
@@ -433,7 +441,11 @@ function validarComandoBasico(comando, args) {
433
441
  case "ast":
434
442
  case "ir":
435
443
  case "diagnosticos": return parsearArgumentos(args, { minPosicionais: 1, maxPosicionais: 1 }) !== null;
436
- case "contexto-ia": return parsearArgumentos(args, { opcoes: ["--saida"], minPosicionais: 1, maxPosicionais: 1 }) !== null;
444
+ case "contexto-ia": {
445
+ const parsed = parsearArgumentos(args, { opcoes: ["--saida", "--capacidade"], flags: ["--pacote"], minPosicionais: 1, maxPosicionais: 1 });
446
+ const capacidade = parsed ? valorOpcao(parsed, "--capacidade") : undefined;
447
+ return parsed !== null && (!capacidade || CAPACIDADES_IA.has(capacidade));
448
+ }
437
449
  case "compilar":
438
450
  case "testar": {
439
451
  const parsed = parsearArgumentos(args, { opcoes: ["--alvo", "--saida", "--estrutura", "--framework"], aliases: aliasesGeracao, minPosicionais: comando === "testar" ? 1 : 0, maxPosicionais: 1 });
@@ -458,7 +470,7 @@ function validarComandoBasico(comando, args) {
458
470
  return parsed !== null && validarModoCache(parsed, "--drift");
459
471
  }
460
472
  case "drift": {
461
- const parsed = parsearArgumentos(args, { opcoes: ["--escopo", "--cache", "--drift"], flags: ["--incluir-worktrees", "--incluir-consumidores-laterais"], maxPosicionais: 1 });
473
+ const parsed = parsearArgumentos(args, { opcoes: ["--escopo", "--cache", "--drift"], flags: ["--incluir-worktrees", "--incluir-consumidores-laterais", "--pacote"], maxPosicionais: 1 });
462
474
  const escopo = parsed ? valorOpcao(parsed, "--escopo") : undefined;
463
475
  return parsed !== null && (!escopo || ESCOPOS.has(escopo)) && validarModoCache(parsed, "--cache");
464
476
  }
@@ -26,7 +26,7 @@ export function criarAjudaRaiz(versao) {
26
26
  renderizarSecaoAscii("Fluxos rápidos", [
27
27
  "[1] Projeto novo / produção inicial",
28
28
  "sema iniciar --template <base|nestjs|fastapi|nextjs-api|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|node-firebase-worker|aspnet-api|springboot-api|go-http-api|rust-axum-api|cpp-service-bridge> [--force] [--com-exemplos]",
29
- "Arquivos existentes são preservados; use --force somente para sobrescrita explícita. O starter de exemplos vem por padrão; --com-exemplos instala o pacote completo.",
29
+ "Arquivos existentes são preservados; use --force somente para sobrescrita explícita. O starter de exemplos vem por padrão; --com-exemplos instala o pacote completo. Em subpasta de workspace já governado, a subpasta é registrada nos diretoriosCodigo do sema.config.json ancestral em vez de criar config local.",
30
30
  "sema validar contratos/<modulo>.sema --json",
31
31
  "sema compilar <arquivo-ou-pasta> --alvo <typescript|python|php|dart|lua|javascript|html|css|dotnet|cpp> --saida <diretorio>",
32
32
  "sema verificar <arquivo-ou-pasta> [--saida <dir>] [--alvo <alvo>] [--sem-cache] --json",
@@ -102,6 +102,7 @@ export function criarAjudaRaiz(versao) {
102
102
  "fraca: sema resumo <arquivo> --micro --drift none --json (contrato compacto; implementação não avaliada)",
103
103
  "média: sema resumo <arquivo> --curto --drift none --json + sema drift <arquivo> --cache fresh --json",
104
104
  "forte: sema contexto-ia <arquivo.sema> --saida <diretorio> --json",
105
+ "context-pack: sema resumo <arquivo.sema> --micro --para mudanca --drift none --pacote --pedido \"<intenção>\" --json (seleção determinística para a IA)",
105
106
  ]),
106
107
  "",
107
108
  renderizarSecaoAscii("Comandos principais", [
@@ -110,7 +111,7 @@ export function criarAjudaRaiz(versao) {
110
111
  "pipelines: sema pipeline <listar|descrever> [id] [--json]",
111
112
  "todas as capacidades: sema capabilities [--json]",
112
113
  "distribuição global: sema skill <status|sync> [--json] (status é somente leitura; sync repara launcher e skill)",
113
- "auditoria: sema drift <arquivo-ou-pasta> [--escopo <arquivo|modulo|projeto>] [--cache <none|cache|fresh>] [--incluir-worktrees] [--incluir-consumidores-laterais] [--json]",
114
+ "auditoria: sema drift <arquivo-ou-pasta> [--escopo <arquivo|modulo|projeto>] [--cache <none|cache|fresh>] [--incluir-worktrees] [--incluir-consumidores-laterais] [--pacote] [--json]",
114
115
  "modos: drift direto usa fresh por padrão; --cache none ainda executa sem cache persistente; resumo/inspecionar usam --drift none por padrão e não fabricam evidência",
115
116
  "impacto: sema impacto <arquivo-ou-pasta> --alvo <token> [--mudanca <descricao>] [--escopo <arquivo|modulo|projeto>] [--json]",
116
117
  "renomeação: sema renomear-semantico <arquivo-ou-pasta> --de <nome-atual> --para <nome-novo> [--escopo <arquivo|modulo|projeto>] [--json]",
@@ -133,14 +134,14 @@ export function criarAjudaRaiz(versao) {
133
134
  renderizarSecaoAscii("Ajuda IA-first", [
134
135
  "sema ajuda-ia",
135
136
  "sema starter-ia",
136
- "sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>] [--drift <none|cache|fresh>] [--saida <diretorio>] [--raiz] [--json]",
137
+ "sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>] [--drift <none|cache|fresh>] [--saida <diretorio>] [--raiz] [--pacote --somente-pacote --pedido <intencao>] [--json]",
137
138
  "sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>] [--json]",
138
139
  "sema prompt-ia",
139
140
  "sema prompt-ia-ui",
140
141
  "sema prompt-ia-react",
141
142
  "sema prompt-ia-sema-primeiro",
142
143
  "sema exemplos-prompt-ia",
143
- "sema contexto-ia <arquivo.sema> [--saida <diretorio>] [--json]",
144
+ "sema contexto-ia <arquivo.sema> [--saida <diretorio>] [--capacidade <fraca|media|forte>] [--pacote] [--json]",
144
145
  "sema sync-codex [--json]",
145
146
  "sema instalar-exemplos [--json]",
146
147
  "sema sessao [intencao] [entrada] [--json]",
@@ -0,0 +1,75 @@
1
+ import type { ResumoSemanticoModuloIa, TamanhoResumoIa } from "./index.part01.js";
2
+ type ResumoEntrada = Partial<ResumoSemanticoModuloIa>;
3
+ export type ContextPackPayload = {
4
+ geradoEm?: string;
5
+ arquivo?: string;
6
+ modulo?: string;
7
+ modo?: string;
8
+ tamanho?: string;
9
+ analiseDrift?: {
10
+ modo?: string;
11
+ executada?: boolean;
12
+ sucesso?: boolean | null;
13
+ aviso?: string | null;
14
+ };
15
+ guiaPorCapacidade?: unknown;
16
+ texto?: string;
17
+ resumo?: ResumoEntrada;
18
+ };
19
+ export type ContextPack = {
20
+ schema: "sema.ai.context-pack/v1";
21
+ selection: "deterministic_allowlist";
22
+ request: string;
23
+ source: {
24
+ command: "resumo";
25
+ mode: string;
26
+ size: string;
27
+ drift: string;
28
+ generatedAt: string | null;
29
+ contract: string | null;
30
+ };
31
+ context: {
32
+ module: string | null;
33
+ purpose: string | null;
34
+ relevantTasks: string[];
35
+ criticalRules: string[];
36
+ effects: string[];
37
+ entities: string[];
38
+ risks: string[];
39
+ likelyFiles: string[];
40
+ requiredChecks: string[];
41
+ minimumTests: string[];
42
+ compatibilityProfile: string | null;
43
+ knownGaps: string[];
44
+ };
45
+ authority: {
46
+ semaRemainsAuthority: true;
47
+ rawSummaryForwarded: false;
48
+ executionRequiresFreshValidation: true;
49
+ omitted: string[];
50
+ };
51
+ telemetry: {
52
+ packChars: number;
53
+ packEstimatedTokens: number;
54
+ estimateMethod: "chars_div_4";
55
+ selectedFields: string[];
56
+ };
57
+ };
58
+ export type ContextPackResult = {
59
+ pack: ContextPack;
60
+ rawSummaryChars: number;
61
+ rawSummaryEstimatedTokens: number;
62
+ rawSummaryEstimateMethod: "chars_div_4";
63
+ reductionPercent: number;
64
+ };
65
+ export declare function selecionarContexto(payload: ContextPackPayload, request: string): ContextPackResult;
66
+ export declare function criarContextPackAPartirDoResumo(input: {
67
+ resumo: ResumoSemanticoModuloIa;
68
+ pedido: string;
69
+ modo: string;
70
+ tamanho: TamanhoResumoIa;
71
+ analiseDrift: ContextPackPayload["analiseDrift"];
72
+ guiaPorCapacidade: unknown;
73
+ texto: string;
74
+ }): ContextPackResult;
75
+ export {};
@@ -0,0 +1,130 @@
1
+ function list(value) {
2
+ return Array.isArray(value)
3
+ ? value.filter((item) => typeof item === "string" && item.length > 0)
4
+ : [];
5
+ }
6
+ function text(value) {
7
+ return typeof value === "string" && value.length > 0 ? value : null;
8
+ }
9
+ function normalizedTokens(value) {
10
+ return value
11
+ .toLocaleLowerCase("pt-BR")
12
+ .normalize("NFD")
13
+ .replace(/[\u0300-\u036f]/g, "")
14
+ .split(/[^a-z0-9_]+/)
15
+ .filter((token) => token.length >= 4);
16
+ }
17
+ function selectRelevantTasks(tasks, request) {
18
+ const requestTokens = new Set(normalizedTokens(request));
19
+ const intentRoots = ["cancel", "notific", "export", "reagend", "registr", "consult"];
20
+ const rootedMatches = intentRoots
21
+ .filter((root) => [...requestTokens].some((token) => token.startsWith(root)))
22
+ .flatMap((root) => tasks.filter((task) => normalizedTokens(task).some((token) => token.startsWith(root))));
23
+ if (rootedMatches.length > 0)
24
+ return [...new Set(rootedMatches)];
25
+ const scored = tasks.map((task, index) => {
26
+ const taskTokens = normalizedTokens(task);
27
+ const score = taskTokens.reduce((total, token) => total + (requestTokens.has(token) ? 1 : 0), 0);
28
+ return { task, index, score };
29
+ });
30
+ const selected = scored
31
+ .filter((item) => item.score > 0)
32
+ .sort((a, b) => b.score - a.score || a.index - b.index)
33
+ .map((item) => item.task);
34
+ return selected.length > 0 ? selected : tasks.slice(0, 3);
35
+ }
36
+ function estimateTokens(chars) {
37
+ return Math.ceil(chars / 4);
38
+ }
39
+ export function selecionarContexto(payload, request) {
40
+ const resumo = payload.resumo ?? {};
41
+ const context = {
42
+ module: text(resumo.modulo) ?? text(payload.modulo),
43
+ purpose: text(resumo.faz),
44
+ relevantTasks: selectRelevantTasks(list(resumo.tarefasPrincipais), request),
45
+ criticalRules: list(resumo.regrasCriticas),
46
+ effects: list(resumo.efeitos),
47
+ entities: list(resumo.entidadesAfetadas),
48
+ risks: list(resumo.riscosPrincipais),
49
+ likelyFiles: list(resumo.arquivosProvaveis),
50
+ requiredChecks: list(resumo.checksSugeridos),
51
+ minimumTests: list(resumo.testesMinimos),
52
+ compatibilityProfile: text(resumo.perfilCompatibilidade),
53
+ knownGaps: list(resumo.lacunas),
54
+ };
55
+ const packWithoutTelemetry = {
56
+ schema: "sema.ai.context-pack/v1",
57
+ selection: "deterministic_allowlist",
58
+ request,
59
+ source: {
60
+ command: "resumo",
61
+ mode: text(payload.modo) ?? "mudanca",
62
+ size: text(payload.tamanho) ?? "micro",
63
+ drift: text(payload.analiseDrift?.modo) ?? "none",
64
+ generatedAt: text(resumo.geradoEm) ?? text(payload.geradoEm),
65
+ contract: text(resumo.arquivo) ?? text(payload.arquivo),
66
+ },
67
+ context,
68
+ authority: {
69
+ semaRemainsAuthority: true,
70
+ rawSummaryForwarded: false,
71
+ executionRequiresFreshValidation: true,
72
+ omitted: [
73
+ "cli_result_envelope",
74
+ "guiaPorCapacidade",
75
+ "texto_bruto_do_resumo",
76
+ "metadados_fora_do_escopo",
77
+ ],
78
+ },
79
+ };
80
+ const packChars = JSON.stringify(packWithoutTelemetry).length;
81
+ const selectedFields = [
82
+ "request",
83
+ "source.module",
84
+ "source.contract",
85
+ "context.module",
86
+ "context.purpose",
87
+ "context.relevantTasks",
88
+ "context.criticalRules",
89
+ "context.effects",
90
+ "context.entities",
91
+ "context.risks",
92
+ "context.likelyFiles",
93
+ "context.requiredChecks",
94
+ "context.minimumTests",
95
+ "context.compatibilityProfile",
96
+ "context.knownGaps",
97
+ "authority",
98
+ ];
99
+ const pack = {
100
+ ...packWithoutTelemetry,
101
+ telemetry: {
102
+ packChars,
103
+ packEstimatedTokens: estimateTokens(packChars),
104
+ estimateMethod: "chars_div_4",
105
+ selectedFields,
106
+ },
107
+ };
108
+ const rawSummaryChars = JSON.stringify(payload).length;
109
+ return {
110
+ pack,
111
+ rawSummaryChars,
112
+ rawSummaryEstimatedTokens: estimateTokens(rawSummaryChars),
113
+ rawSummaryEstimateMethod: "chars_div_4",
114
+ reductionPercent: rawSummaryChars === 0 ? 0 : Math.round((1 - packChars / rawSummaryChars) * 10000) / 100,
115
+ };
116
+ }
117
+ export function criarContextPackAPartirDoResumo(input) {
118
+ return selecionarContexto({
119
+ geradoEm: input.resumo.geradoEm,
120
+ arquivo: input.resumo.arquivo,
121
+ modulo: input.resumo.modulo,
122
+ modo: input.modo,
123
+ tamanho: input.tamanho,
124
+ analiseDrift: input.analiseDrift,
125
+ guiaPorCapacidade: input.guiaPorCapacidade,
126
+ texto: input.texto,
127
+ resumo: input.resumo,
128
+ }, input.pedido);
129
+ }
130
+ //# sourceMappingURL=contextPack.js.map
@@ -19,6 +19,7 @@ export declare function executarDriftCheck(contratos: string[], codigoVivo: stri
19
19
  impls_quebrados: number;
20
20
  vinculos_validos: number;
21
21
  vinculos_quebrados: number;
22
+ vinculos_fora_do_escopo: number;
22
23
  score: number;
23
24
  piso_operacional: number;
24
25
  alvo_atual: number;
@@ -30,6 +30,7 @@ export function executarDriftCheck(contratos, codigoVivo) {
30
30
  impls_quebrados: implsQuebrados,
31
31
  vinculos_validos: vinculosValidos,
32
32
  vinculos_quebrados: vinculosQuebrados,
33
+ vinculos_fora_do_escopo: 0,
33
34
  score,
34
35
  piso_operacional: avaliacao.pontuacaoMinimaOperacional,
35
36
  alvo_atual: avaliacao.pontuacaoAlvoAtual,
@@ -39,7 +39,7 @@ export interface OpcoesDriftLegado {
39
39
  observador?: ObservadorOperacaoDrift | undefined;
40
40
  }
41
41
  export interface DiagnosticoDrift {
42
- tipo: "impl_quebrado" | "task_sem_impl" | "rota_divergente" | "recurso_divergente" | "vinculo_quebrado" | "seguranca_frouxa" | "pontuacao_semantica_insuficiente" | "contrato_monolitico" | "codigo_monolitico" | "codigo_governado_sem_cabecalho" | "escopo_estreito_sem_vinculos" | "escopo_estreito_ambiguo" | "design_nao_declarado";
42
+ tipo: "impl_quebrado" | "task_sem_impl" | "rota_divergente" | "recurso_divergente" | "vinculo_quebrado" | "vinculo_fora_do_escopo" | "seguranca_frouxa" | "pontuacao_semantica_insuficiente" | "contrato_monolitico" | "codigo_monolitico" | "codigo_governado_sem_cabecalho" | "escopo_estreito_sem_vinculos" | "escopo_estreito_ambiguo" | "design_nao_declarado";
43
43
  modulo: string;
44
44
  task?: string;
45
45
  route?: string;
@@ -149,8 +149,9 @@ export interface RegistroVinculoDrift {
149
149
  valor: string;
150
150
  arquivo?: string;
151
151
  simbolo?: string;
152
- status: "resolvido" | "parcial" | "nao_encontrado";
152
+ status: "resolvido" | "parcial" | "nao_encontrado" | "fora_do_escopo";
153
153
  confianca: NivelConfiancaSemantica;
154
+ diretorioSugerido?: string;
154
155
  }
155
156
  export interface RegistroPersistenciaRealDrift {
156
157
  modulo: string;
@@ -256,6 +257,7 @@ export interface ResultadoDrift {
256
257
  impls_quebrados: RegistroImplDrift[];
257
258
  vinculos_validos: RegistroVinculoDrift[];
258
259
  vinculos_quebrados: RegistroVinculoDrift[];
260
+ vinculos_fora_do_escopo: RegistroVinculoDrift[];
259
261
  rotas_divergentes: RegistroRotaDivergente[];
260
262
  recursos_validos: RegistroRecursoDrift[];
261
263
  recursos_divergentes: RegistroRecursoDrift[];
@@ -10,7 +10,8 @@ import { calcularConfiancaTask, calcularRiscoOperacional, calcularScoreTask, car
10
10
  import { analisarPersistenciaReal, ordenarCandidatos } from "./drift.part09.js";
11
11
  import { simboloEhBridgeConsumer } from "./drift.part05.js";
12
12
  import { prepararIndicesDrift } from "./drift.part13.js";
13
- import { analisarModulosSelecionadosDrift } from "./drift.part14.js";
13
+ import { sondarCaminhosDeclaradosExistentes } from "./driftEscopo.js";
14
+ import { analisarModulosSelecionadosDrift, coletarCaminhosDeclaradosVinculosDrift } from "./drift.part14.js";
14
15
  import { resolverPoliticaPontuacaoSemantica } from "./driftScore.js";
15
16
  function arquivosVinculadosFisicamenteDrift(contexto, modulo, task) {
16
17
  const arquivos = new Set();
@@ -158,6 +159,7 @@ export async function analisarDriftLegado(contexto, opcoes) {
158
159
  const implsQuebrados = [];
159
160
  const vinculosValidos = [];
160
161
  const vinculosQuebrados = [];
162
+ const vinculosForaDoEscopo = [];
161
163
  const rotasDivergentes = [];
162
164
  const recursosValidos = [];
163
165
  const recursosDivergentes = [];
@@ -209,6 +211,12 @@ export async function analisarDriftLegado(contexto, opcoes) {
209
211
  for (const substituicao of substituicoesCaminho) {
210
212
  substituicao.implementacao.caminho = substituicao.temporario;
211
213
  }
214
+ // Sonda previa: distingue vinculo apontando para arquivo inexistente de
215
+ // arquivo existente fora dos diretoriosCodigo (informativo, nao bloqueante).
216
+ const caminhosDeclaradosVinculos = coletarCaminhosDeclaradosVinculosDrift(contexto);
217
+ const arquivosDeclaradosExistentes = caminhosDeclaradosVinculos.length > 0
218
+ ? await sondarCaminhosDeclaradosExistentes(caminhosDeclaradosVinculos, contexto.baseProjeto)
219
+ : new Map();
212
220
  try {
213
221
  analisarModulosSelecionadosDrift({
214
222
  contexto,
@@ -222,6 +230,8 @@ export async function analisarDriftLegado(contexto, opcoes) {
222
230
  implsQuebrados,
223
231
  vinculosValidos,
224
232
  vinculosQuebrados,
233
+ vinculosForaDoEscopo,
234
+ arquivosDeclaradosExistentes,
225
235
  rotasDivergentes,
226
236
  recursosValidos,
227
237
  recursosDivergentes,
@@ -563,6 +573,7 @@ export async function analisarDriftLegado(contexto, opcoes) {
563
573
  impls_quebrados: implsQuebrados,
564
574
  vinculos_validos: vinculosValidos,
565
575
  vinculos_quebrados: vinculosQuebrados,
576
+ vinculos_fora_do_escopo: vinculosForaDoEscopo,
566
577
  rotas_divergentes: rotasDivergentes,
567
578
  recursos_validos: recursosValidos,
568
579
  recursos_divergentes: recursosDivergentes,
@@ -14,6 +14,7 @@ export interface GuardrailsTaskDrift {
14
14
  efeitoPrivilegiado: boolean;
15
15
  exigeSegredos: boolean;
16
16
  }
17
+ export declare function coletarCaminhosDeclaradosVinculosDrift(contexto: ContextoProjetoCarregado): string[];
17
18
  export interface ResumoVinculosTaskDrift {
18
19
  validos: number;
19
20
  quebrados: number;
@@ -31,6 +32,8 @@ export interface EstadoAnaliseModulosDrift {
31
32
  implsQuebrados: RegistroImplDrift[];
32
33
  vinculosValidos: RegistroVinculoDrift[];
33
34
  vinculosQuebrados: RegistroVinculoDrift[];
35
+ vinculosForaDoEscopo: RegistroVinculoDrift[];
36
+ arquivosDeclaradosExistentes: ReadonlyMap<string, boolean>;
34
37
  rotasDivergentes: RegistroRotaDivergente[];
35
38
  recursosValidos: RegistroRecursoDrift[];
36
39
  recursosDivergentes: RegistroRecursoDrift[];