@semacode/cli 1.2.0 → 1.2.9

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 (38) hide show
  1. package/README.md +2 -2
  2. package/SEMA_BRIEF.curto.txt +9 -9
  3. package/SEMA_BRIEF.md +49 -49
  4. package/SEMA_BRIEF.micro.txt +7 -7
  5. package/SEMA_INDEX.json +501 -546
  6. package/dist/drift.d.ts +2 -2
  7. package/dist/drift.js +0 -20
  8. package/dist/drift.js.map +1 -1
  9. package/dist/importador.d.ts +1 -1
  10. package/dist/importador.js +0 -60
  11. package/dist/importador.js.map +1 -1
  12. package/dist/index.js +1334 -1360
  13. package/dist/index.js.map +1 -1
  14. package/dist/projeto.js +0 -6
  15. package/dist/projeto.js.map +1 -1
  16. package/dist/tipos.d.ts +1 -1
  17. package/docs/AGENT_STARTER.md +102 -102
  18. package/docs/instalacao-e-primeiro-uso.md +196 -198
  19. package/node_modules/@sema/gerador-dart/package.json +1 -1
  20. package/node_modules/@sema/gerador-lua/dist/index.js +49 -81
  21. package/node_modules/@sema/gerador-lua/dist/index.js.map +1 -1
  22. package/node_modules/@sema/gerador-lua/package.json +1 -1
  23. package/node_modules/@sema/gerador-python/package.json +1 -1
  24. package/node_modules/@sema/gerador-typescript/package.json +1 -1
  25. package/node_modules/@sema/nucleo/dist/ast/tipos.d.ts +1 -1
  26. package/node_modules/@sema/nucleo/dist/ir/conversor.js +0 -4
  27. package/node_modules/@sema/nucleo/dist/ir/conversor.js.map +1 -1
  28. package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +3 -3
  29. package/node_modules/@sema/nucleo/dist/parser/parser.js +0 -2
  30. package/node_modules/@sema/nucleo/dist/parser/parser.js.map +1 -1
  31. package/node_modules/@sema/nucleo/dist/semantico/analisador.d.ts +2 -2
  32. package/node_modules/@sema/nucleo/dist/semantico/analisador.js +1 -3
  33. package/node_modules/@sema/nucleo/dist/semantico/analisador.js.map +1 -1
  34. package/node_modules/@sema/nucleo/package.json +1 -1
  35. package/node_modules/@sema/padroes/dist/index.js +18 -1
  36. package/node_modules/@sema/padroes/dist/index.js.map +1 -1
  37. package/node_modules/@sema/padroes/package.json +1 -1
  38. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -13,303 +13,303 @@ import { gerarTypeScript } from "@sema/gerador-typescript";
13
13
  import { carregarConfiguracaoProjeto, carregarProjeto, resolverAlvoPadrao, resolverAlvosVerificacao, resolverEstruturaSaidaPadrao, resolverFrameworkPadrao, resolverSaidaPadrao, } from "./projeto.js";
14
14
  import { importarProjetoLegado, resumoImportacao } from "./importador.js";
15
15
  import { analisarDriftLegado } from "./drift.js";
16
- const STARTER_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao para IA sobre software vivo em backend e front consumer.
17
-
18
- Importante:
19
- - a Sema se apresenta publicamente como protocolo e funciona tecnicamente como linguagem de intencao
20
- - a Sema e protocolo de governanca semantica desenhado para IA, nao para ergonomia humana
21
- - leitura humana e bonus toleravel, nao objetivo de produto
22
- - a Sema nao e gerador magico que deveria fazer tudo
23
- - a Sema modela contratos, estados, fluxos, erros, efeitos, garantias, vinculos e execucao
24
- - a Sema gera codigo e scaffolding real para TypeScript, Python, Dart e Lua
25
- - a Sema usa \`importar\` para bootstrap revisavel, nao para contrato final automatico
26
- - a Sema usa \`impl\` para ligar task a simbolo real do runtime
27
- - a Sema usa \`vinculos\` para ligar contrato a arquivo, simbolo, recurso e superficie real
28
- - a Sema usa \`execucao\` para explicitar timeout, retry, compensacao e criticidade
29
- - a Sema usa \`drift\` para medir diferenca entre contrato e codigo vivo com score, confianca e lacunas
30
- - a Sema usa \`resumo\` e \`prompt-curto\` para IA pequena ou gratuita
31
- - a Sema usa \`contexto-ia\` para gerar \`ast.json\`, \`ir.json\`, \`drift.json\`, \`briefing.json\` e artefatos compactos antes da edicao
32
- - a Sema pode servir de base para interfaces graficas elegantes e coerentes
33
- - a Sema nao gera uma interface completa sozinha no estado atual
34
- - trate a Sema como cerebro semantico da aplicacao, nao como gerador magico de front-end pronto
35
- - se a tarefa envolver UI, prefira pedir Sema + React + TypeScript ou Sema + arquitetura de front-end
36
- - evite pedir HTML unico solto quando a intencao for testar a Sema de verdade
37
-
38
- Regras:
39
- - nao invente sintaxe fora da gramatica e dos exemplos oficiais
40
- - se a IA for pequena, nao tente abrir tudo de uma vez
41
- - use \`sema resumo\` e \`briefing.min.json\` antes de subir para o pacote completo
42
- - trate \`ir --json\` como fonte de verdade semantica
43
- - trate \`briefing.json\` como plano de intervencao antes de editar projeto vivo
44
- - trate \`diagnosticos --json\` como fonte de correcao
45
- - use \`sema formatar\` como fonte unica de estilo
46
- - preserve a intencao do contrato
47
- - nao cobre da Sema adivinhacao de negocio que nao esta no contrato nem no codigo
48
-
49
- Comandos essenciais:
50
- - resumo compacto por capacidade: \`sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
51
- - prompt curto para IA pequena: \`sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
52
- - descoberta do projeto: \`sema inspecionar [arquivo-ou-pasta] --json\`
53
- - auditoria do contrato vivo: \`sema drift <arquivo-ou-pasta> [--json]\`
54
- - contexto completo do modulo: \`sema contexto-ia <arquivo.sema>\`
55
- - estrutura sintatica: \`sema ast <arquivo.sema> --json\`
56
- - estrutura semantica: \`sema ir <arquivo.sema> --json\`
57
- - validacao: \`sema validar <arquivo.sema> --json\`
58
- - diagnosticos: \`sema diagnosticos <arquivo.sema> --json\`
59
- - formatacao: \`sema formatar <arquivo.sema>\`
60
- - 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|lua> <diretorio> --saida <diretorio>\`
16
+ const STARTER_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao para IA sobre software vivo em backend e front consumer.
17
+
18
+ Importante:
19
+ - a Sema se apresenta publicamente como protocolo e funciona tecnicamente como linguagem de intencao
20
+ - a Sema e protocolo de governanca semantica desenhado para IA, nao para ergonomia humana
21
+ - leitura humana e bonus toleravel, nao objetivo de produto
22
+ - a Sema nao e gerador magico que deveria fazer tudo
23
+ - a Sema modela contratos, estados, fluxos, erros, efeitos, garantias, vinculos e execucao
24
+ - a Sema gera codigo e scaffolding real para TypeScript, Python e Dart
25
+ - a Sema usa \`importar\` para bootstrap revisavel, nao para contrato final automatico
26
+ - a Sema usa \`impl\` para ligar task a simbolo real do runtime
27
+ - a Sema usa \`vinculos\` para ligar contrato a arquivo, simbolo, recurso e superficie real
28
+ - a Sema usa \`execucao\` para explicitar timeout, retry, compensacao e criticidade
29
+ - a Sema usa \`drift\` para medir diferenca entre contrato e codigo vivo com score, confianca e lacunas
30
+ - a Sema usa \`resumo\` e \`prompt-curto\` para IA pequena ou gratuita
31
+ - a Sema usa \`contexto-ia\` para gerar \`ast.json\`, \`ir.json\`, \`drift.json\`, \`briefing.json\` e artefatos compactos antes da edicao
32
+ - a Sema pode servir de base para interfaces graficas elegantes e coerentes
33
+ - a Sema nao gera uma interface completa sozinha no estado atual
34
+ - trate a Sema como cerebro semantico da aplicacao, nao como gerador magico de front-end pronto
35
+ - se a tarefa envolver UI, prefira pedir Sema + React + TypeScript ou Sema + arquitetura de front-end
36
+ - evite pedir HTML unico solto quando a intencao for testar a Sema de verdade
37
+
38
+ Regras:
39
+ - nao invente sintaxe fora da gramatica e dos exemplos oficiais
40
+ - se a IA for pequena, nao tente abrir tudo de uma vez
41
+ - use \`sema resumo\` e \`briefing.min.json\` antes de subir para o pacote completo
42
+ - trate \`ir --json\` como fonte de verdade semantica
43
+ - trate \`briefing.json\` como plano de intervencao antes de editar projeto vivo
44
+ - trate \`diagnosticos --json\` como fonte de correcao
45
+ - use \`sema formatar\` como fonte unica de estilo
46
+ - preserve a intencao do contrato
47
+ - nao cobre da Sema adivinhacao de negocio que nao esta no contrato nem no codigo
48
+
49
+ Comandos essenciais:
50
+ - resumo compacto por capacidade: \`sema resumo <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
51
+ - prompt curto para IA pequena: \`sema prompt-curto <arquivo-ou-pasta> [--micro|--curto|--medio] [--para <resumo|onboarding|review|mudanca|bug|arquitetura>]\`
52
+ - descoberta do projeto: \`sema inspecionar [arquivo-ou-pasta] --json\`
53
+ - auditoria do contrato vivo: \`sema drift <arquivo-ou-pasta> [--json]\`
54
+ - contexto completo do modulo: \`sema contexto-ia <arquivo.sema>\`
55
+ - estrutura sintatica: \`sema ast <arquivo.sema> --json\`
56
+ - estrutura semantica: \`sema ir <arquivo.sema> --json\`
57
+ - validacao: \`sema validar <arquivo.sema> --json\`
58
+ - diagnosticos: \`sema diagnosticos <arquivo.sema> --json\`
59
+ - formatacao: \`sema formatar <arquivo.sema>\`
60
+ - 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>\`
61
61
  - geracao de codigo: \`sema compilar <arquivo-ou-pasta> --alvo <typescript|python|dart|lua> --saida <diretorio>\`
62
- - verificacao final: \`sema verificar <arquivo-ou-pasta> [--json]\`
63
-
64
- Antes de editar:
65
- 1. leia README, docs de IA e um exemplo oficial parecido
66
- 2. se a IA for pequena, rode \`sema resumo <arquivo> --micro\` e leia \`briefing.min.json\`
67
- 3. se a IA aguentar mais, rode \`sema drift\` para medir impls, vinculos, rotas, score e lacunas
68
- 4. se a tarefa for pesada, rode \`sema contexto-ia\` e leia \`briefing.json\`
69
- 5. consulte AST e IR do modulo alvo so quando a capacidade realmente aguentar
70
-
71
- Depois de editar:
72
- 1. rode \`sema formatar\`
73
- 2. rode \`sema validar --json\`
74
- 3. se houver falha, use \`diagnosticos --json\`
75
- 4. rode \`sema drift\` de novo quando mexer em codigo vivo
76
- 5. se a tarefa pedir codigo derivado, rode \`sema compilar\`
77
- 6. feche com \`sema verificar <arquivo-ou-pasta> --json\`
78
-
79
- Priorize sempre:
80
- - exemplos oficiais
81
- - JSON da CLI
82
- - o menor artefato que resolva a tarefa da IA atual
83
- - score, confianca e lacunas do \`drift\`
84
- - \`briefing.json\` como guia de mudanca
85
- - consistencia semantica
86
-
87
- Superficies que a IA deve enxergar como first-class:
88
- - \`route\`
89
- - \`worker\`
90
- - \`evento\`
91
- - \`fila\`
92
- - \`cron\`
93
- - \`webhook\`
94
- - \`cache\`
95
- - \`storage\`
96
- - \`policy\`
97
-
98
- Nao improvise quando faltar contexto.
62
+ - verificacao final: \`sema verificar <arquivo-ou-pasta> [--json]\`
63
+
64
+ Antes de editar:
65
+ 1. leia README, docs de IA e um exemplo oficial parecido
66
+ 2. se a IA for pequena, rode \`sema resumo <arquivo> --micro\` e leia \`briefing.min.json\`
67
+ 3. se a IA aguentar mais, rode \`sema drift\` para medir impls, vinculos, rotas, score e lacunas
68
+ 4. se a tarefa for pesada, rode \`sema contexto-ia\` e leia \`briefing.json\`
69
+ 5. consulte AST e IR do modulo alvo so quando a capacidade realmente aguentar
70
+
71
+ Depois de editar:
72
+ 1. rode \`sema formatar\`
73
+ 2. rode \`sema validar --json\`
74
+ 3. se houver falha, use \`diagnosticos --json\`
75
+ 4. rode \`sema drift\` de novo quando mexer em codigo vivo
76
+ 5. se a tarefa pedir codigo derivado, rode \`sema compilar\`
77
+ 6. feche com \`sema verificar <arquivo-ou-pasta> --json\`
78
+
79
+ Priorize sempre:
80
+ - exemplos oficiais
81
+ - JSON da CLI
82
+ - o menor artefato que resolva a tarefa da IA atual
83
+ - score, confianca e lacunas do \`drift\`
84
+ - \`briefing.json\` como guia de mudanca
85
+ - consistencia semantica
86
+
87
+ Superficies que a IA deve enxergar como first-class:
88
+ - \`route\`
89
+ - \`worker\`
90
+ - \`evento\`
91
+ - \`fila\`
92
+ - \`cron\`
93
+ - \`webhook\`
94
+ - \`cache\`
95
+ - \`storage\`
96
+ - \`policy\`
97
+
98
+ Nao improvise quando faltar contexto.
99
99
  `;
100
- const PROMPT_BASE_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao orientado a contrato, desenhado para operacao por IA.
101
-
102
- Trate a Sema como camada semantica e linguagem de especificacao executavel feita para IA, nao para leitura humana confortavel. Nao invente sintaxe, palavras-chave ou blocos fora da gramatica e dos exemplos oficiais.
103
-
104
- Fontes de verdade, em ordem:
105
- 1. README do projeto
106
- 2. gramatica e documentacao de sintaxe da Sema
107
- 3. especificacao semantica da linguagem
108
- 4. exemplos oficiais, com prioridade para o vertical de pagamento
109
- 5. \`sema resumo\` e \`briefing.min.json\` quando a IA for pequena
110
- 6. AST, IR e diagnosticos exportados pela CLI em JSON quando a capacidade aguentar
111
-
112
- Regras de operacao:
113
- - preserve o significado semantico
114
- - use o formatador oficial da Sema como fonte unica de estilo
115
- - use diagnosticos estruturados como contrato de correcao
116
- - use a IR como fonte de verdade semantica quando houver duvida
117
- - nao conclua uma alteracao sem validar e verificar o modulo
118
- - comece pelo menor artefato semantico que resolva a tarefa
119
-
120
- Antes de editar \`.sema\`, entenda:
121
- - o module alvo
122
- - os contratos de task, route, error, effects, guarantees, state e flow
123
- - os exemplos oficiais relacionados
124
-
125
- Depois de editar \`.sema\`, execute este fluxo:
126
- 1. formatar
127
- 2. validar
128
- 3. diagnosticar, se houver falha
129
- 4. verificar
130
-
131
- Se houver conflito entre texto livre e IR/diagnosticos, priorize a IR e os diagnosticos da CLI.
132
-
133
- Se algo nao estiver claro, siga a forma ja usada nos exemplos oficiais. Nao improvise sem base.
100
+ const PROMPT_BASE_IA = `Voce esta trabalhando com Sema, um Protocolo de Governanca de Intencao orientado a contrato, desenhado para operacao por IA.
101
+
102
+ Trate a Sema como camada semantica e linguagem de especificacao executavel feita para IA, nao para leitura humana confortavel. Nao invente sintaxe, palavras-chave ou blocos fora da gramatica e dos exemplos oficiais.
103
+
104
+ Fontes de verdade, em ordem:
105
+ 1. README do projeto
106
+ 2. gramatica e documentacao de sintaxe da Sema
107
+ 3. especificacao semantica da linguagem
108
+ 4. exemplos oficiais, com prioridade para o vertical de pagamento
109
+ 5. \`sema resumo\` e \`briefing.min.json\` quando a IA for pequena
110
+ 6. AST, IR e diagnosticos exportados pela CLI em JSON quando a capacidade aguentar
111
+
112
+ Regras de operacao:
113
+ - preserve o significado semantico
114
+ - use o formatador oficial da Sema como fonte unica de estilo
115
+ - use diagnosticos estruturados como contrato de correcao
116
+ - use a IR como fonte de verdade semantica quando houver duvida
117
+ - nao conclua uma alteracao sem validar e verificar o modulo
118
+ - comece pelo menor artefato semantico que resolva a tarefa
119
+
120
+ Antes de editar \`.sema\`, entenda:
121
+ - o module alvo
122
+ - os contratos de task, route, error, effects, guarantees, state e flow
123
+ - os exemplos oficiais relacionados
124
+
125
+ Depois de editar \`.sema\`, execute este fluxo:
126
+ 1. formatar
127
+ 2. validar
128
+ 3. diagnosticar, se houver falha
129
+ 4. verificar
130
+
131
+ Se houver conflito entre texto livre e IR/diagnosticos, priorize a IR e os diagnosticos da CLI.
132
+
133
+ Se algo nao estiver claro, siga a forma ja usada nos exemplos oficiais. Nao improvise sem base.
134
134
  `;
135
- const PROMPT_IA_UI = `Atue como Engenheiro de Software Senior e UX/UI Designer de elite.
136
-
137
- Quero que voce trabalhe com Sema como fonte de verdade semantica do sistema e com React + TypeScript como camada de interface.
138
-
139
- Entregue obrigatoriamente duas partes integradas:
140
- 1. os arquivos \`.sema\` do dominio
141
- 2. a proposta ou implementacao da interface em React + TypeScript
142
-
143
- Regras:
144
- - nao entregue apenas HTML solto em arquivo unico
145
- - nao trate a Sema como enfeite conceitual
146
- - a interface deve nascer do contrato semantico definido em Sema
147
- - use os exemplos oficiais da Sema como referencia de estilo e semantica
148
- - nao invente sintaxe fora da gramatica suportada
149
-
150
- A Sema deve modelar, quando fizer sentido:
151
- - \`module\`
152
- - \`use\`
153
- - \`entity\`
154
- - \`enum\`
155
- - \`state\`
156
- - \`task\`
157
- - \`flow\`
158
- - \`route\`
159
- - \`effects\`
160
- - \`error\`
161
- - \`guarantees\`
162
- - \`tests\`
163
- - \`docs\`
164
-
165
- A interface deve refletir visualmente:
166
- - \`state\` como status e progresso observavel
167
- - \`flow\` como etapas ou orquestracao visivel
168
- - \`error\` como falhas tratadas com clareza
169
- - \`effects\` como operacoes relevantes para usuario ou operacao
170
- - \`guarantees\` como confianca, confirmacao ou consistencia final
171
-
172
- Estruture a entrega assim:
173
- 1. visao do produto
174
- 2. dominio modelado em Sema
175
- 3. arquitetura de pastas em React + TypeScript
176
- 4. componentes principais
177
- 5. estrategia visual
178
- 6. codigo principal da interface
179
- 7. explicacao curta de como a UI conversa com a semantica da Sema
180
-
181
- Se a tarefa envolver app visual, a Sema governa o significado e o React renderiza a experiencia. Nao atropele essa separacao.
135
+ const PROMPT_IA_UI = `Atue como Engenheiro de Software Senior e UX/UI Designer de elite.
136
+
137
+ Quero que voce trabalhe com Sema como fonte de verdade semantica do sistema e com React + TypeScript como camada de interface.
138
+
139
+ Entregue obrigatoriamente duas partes integradas:
140
+ 1. os arquivos \`.sema\` do dominio
141
+ 2. a proposta ou implementacao da interface em React + TypeScript
142
+
143
+ Regras:
144
+ - nao entregue apenas HTML solto em arquivo unico
145
+ - nao trate a Sema como enfeite conceitual
146
+ - a interface deve nascer do contrato semantico definido em Sema
147
+ - use os exemplos oficiais da Sema como referencia de estilo e semantica
148
+ - nao invente sintaxe fora da gramatica suportada
149
+
150
+ A Sema deve modelar, quando fizer sentido:
151
+ - \`module\`
152
+ - \`use\`
153
+ - \`entity\`
154
+ - \`enum\`
155
+ - \`state\`
156
+ - \`task\`
157
+ - \`flow\`
158
+ - \`route\`
159
+ - \`effects\`
160
+ - \`error\`
161
+ - \`guarantees\`
162
+ - \`tests\`
163
+ - \`docs\`
164
+
165
+ A interface deve refletir visualmente:
166
+ - \`state\` como status e progresso observavel
167
+ - \`flow\` como etapas ou orquestracao visivel
168
+ - \`error\` como falhas tratadas com clareza
169
+ - \`effects\` como operacoes relevantes para usuario ou operacao
170
+ - \`guarantees\` como confianca, confirmacao ou consistencia final
171
+
172
+ Estruture a entrega assim:
173
+ 1. visao do produto
174
+ 2. dominio modelado em Sema
175
+ 3. arquitetura de pastas em React + TypeScript
176
+ 4. componentes principais
177
+ 5. estrategia visual
178
+ 6. codigo principal da interface
179
+ 7. explicacao curta de como a UI conversa com a semantica da Sema
180
+
181
+ Se a tarefa envolver app visual, a Sema governa o significado e o React renderiza a experiencia. Nao atropele essa separacao.
182
182
  `;
183
- const PROMPT_IA_REACT = `Crie uma solucao com Sema + React + TypeScript.
184
-
185
- Regras principais:
186
- - a Sema deve ser a fonte de verdade semantica do dominio
187
- - React + TypeScript deve ser a camada de interface e experiencia
188
- - nao entregue HTML unico solto
189
- - nao trate a Sema como enfeite
190
-
191
- Entregue obrigatoriamente:
192
- 1. arquivos \`.sema\` do dominio
193
- 2. arquitetura de pastas do frontend
194
- 3. componentes React principais
195
- 4. contratos e tipos derivados da semantica
196
- 5. interface elegante e implementavel
197
-
198
- A modelagem Sema deve cobrir, quando fizer sentido:
199
- - \`entity\`
200
- - \`enum\`
201
- - \`state\`
202
- - \`task\`
203
- - \`flow\`
204
- - \`route\`
205
- - \`effects\`
206
- - \`error\`
207
- - \`guarantees\`
208
- - \`tests\`
209
-
210
- A interface React deve tornar visiveis:
211
- - estado atual e transicoes relevantes
212
- - fluxo operacional
213
- - erros publicos
214
- - efeitos operacionais importantes
215
- - garantias ou confirmacoes finais
216
-
217
- Estruture a entrega assim:
218
- 1. visao do produto
219
- 2. arquivos \`.sema\`
220
- 3. arquitetura React + TypeScript
221
- 4. componentes e telas
222
- 5. codigo principal
223
- 6. explicacao de como a UI deriva da semantica da Sema
224
-
225
- Se houver duvida, siga os exemplos oficiais e mantenha a separacao:
226
- - Sema governa o significado
227
- - React governa a apresentacao
183
+ const PROMPT_IA_REACT = `Crie uma solucao com Sema + React + TypeScript.
184
+
185
+ Regras principais:
186
+ - a Sema deve ser a fonte de verdade semantica do dominio
187
+ - React + TypeScript deve ser a camada de interface e experiencia
188
+ - nao entregue HTML unico solto
189
+ - nao trate a Sema como enfeite
190
+
191
+ Entregue obrigatoriamente:
192
+ 1. arquivos \`.sema\` do dominio
193
+ 2. arquitetura de pastas do frontend
194
+ 3. componentes React principais
195
+ 4. contratos e tipos derivados da semantica
196
+ 5. interface elegante e implementavel
197
+
198
+ A modelagem Sema deve cobrir, quando fizer sentido:
199
+ - \`entity\`
200
+ - \`enum\`
201
+ - \`state\`
202
+ - \`task\`
203
+ - \`flow\`
204
+ - \`route\`
205
+ - \`effects\`
206
+ - \`error\`
207
+ - \`guarantees\`
208
+ - \`tests\`
209
+
210
+ A interface React deve tornar visiveis:
211
+ - estado atual e transicoes relevantes
212
+ - fluxo operacional
213
+ - erros publicos
214
+ - efeitos operacionais importantes
215
+ - garantias ou confirmacoes finais
216
+
217
+ Estruture a entrega assim:
218
+ 1. visao do produto
219
+ 2. arquivos \`.sema\`
220
+ 3. arquitetura React + TypeScript
221
+ 4. componentes e telas
222
+ 5. codigo principal
223
+ 6. explicacao de como a UI deriva da semantica da Sema
224
+
225
+ Se houver duvida, siga os exemplos oficiais e mantenha a separacao:
226
+ - Sema governa o significado
227
+ - React governa a apresentacao
228
228
  `;
229
- const PROMPT_IA_SEMA_PRIMEIRO = `Quero que voce trabalhe no modo "Sema primeiro".
230
-
231
- Regra principal:
232
- - modele primeiro o dominio em arquivos \`.sema\`
233
- - so depois proponha ou gere codigo de aplicacao derivado disso
234
-
235
- Fluxo obrigatorio:
236
- 1. entender o dominio pedido
237
- 2. modelar o contrato em Sema
238
- 3. validar coerencia entre \`task\`, \`route\`, \`state\`, \`flow\`, \`error\`, \`effects\` e \`guarantees\`
239
- 4. so depois gerar TypeScript, Python, React ou outra camada de implementacao
240
-
241
- Nao entregue apenas codigo de interface ou codigo imperativo direto sem antes entregar a camada semantica.
242
-
243
- A modelagem em Sema deve:
244
- - preservar a intencao do dominio
245
- - explicitar entradas, saidas, erros, efeitos e garantias
246
- - usar apenas blocos e sintaxe oficiais
247
- - incluir testes embutidos quando fizer sentido
248
-
249
- Se houver interface grafica:
250
- - entregue a modelagem Sema primeiro
251
- - depois explique como a interface deve refletir a semantica
252
- - se gerar UI, use React + TypeScript em vez de HTML unico solto
253
-
254
- Se houver backend:
255
- - entregue a modelagem Sema primeiro
256
- - depois gere a borda publica e a implementacao derivada
257
-
258
- Nao pule a etapa semantica. A camada \`.sema\` e a ancora principal da solucao.
229
+ const PROMPT_IA_SEMA_PRIMEIRO = `Quero que voce trabalhe no modo "Sema primeiro".
230
+
231
+ Regra principal:
232
+ - modele primeiro o dominio em arquivos \`.sema\`
233
+ - so depois proponha ou gere codigo de aplicacao derivado disso
234
+
235
+ Fluxo obrigatorio:
236
+ 1. entender o dominio pedido
237
+ 2. modelar o contrato em Sema
238
+ 3. validar coerencia entre \`task\`, \`route\`, \`state\`, \`flow\`, \`error\`, \`effects\` e \`guarantees\`
239
+ 4. so depois gerar TypeScript, Python, React ou outra camada de implementacao
240
+
241
+ Nao entregue apenas codigo de interface ou codigo imperativo direto sem antes entregar a camada semantica.
242
+
243
+ A modelagem em Sema deve:
244
+ - preservar a intencao do dominio
245
+ - explicitar entradas, saidas, erros, efeitos e garantias
246
+ - usar apenas blocos e sintaxe oficiais
247
+ - incluir testes embutidos quando fizer sentido
248
+
249
+ Se houver interface grafica:
250
+ - entregue a modelagem Sema primeiro
251
+ - depois explique como a interface deve refletir a semantica
252
+ - se gerar UI, use React + TypeScript em vez de HTML unico solto
253
+
254
+ Se houver backend:
255
+ - entregue a modelagem Sema primeiro
256
+ - depois gere a borda publica e a implementacao derivada
257
+
258
+ Nao pule a etapa semantica. A camada \`.sema\` e a ancora principal da solucao.
259
259
  `;
260
- const EXEMPLOS_PROMPT_IA = `Exemplos de prompt oficial para trabalhar com Sema
261
-
262
- 1. Sema primeiro
263
-
264
- Crie uma solucao seguindo a estrategia "Sema primeiro".
265
- Entregue primeiro os arquivos \`.sema\` do dominio e so depois a implementacao derivada.
266
- Nao entregue apenas codigo imperativo.
267
- Use Sema como fonte de verdade para contratos, estados, erros, efeitos e garantias.
268
-
269
- 2. Sema + React + TypeScript
270
-
271
- Crie um projeto com Sema + React + TypeScript.
272
- Entregue:
273
- - os arquivos \`.sema\` do dominio
274
- - a arquitetura de pastas do frontend
275
- - componentes React que reflitam \`state\`, \`flow\`, \`error\`, \`effects\` e \`guarantees\`
276
- - uma interface elegante e implementavel
277
- - nao entregue HTML solto em arquivo unico
278
-
279
- 3. Revisar ou corrigir um modulo Sema
280
-
281
- Revise e corrija um modulo \`.sema\`.
282
- Antes de editar:
283
- - leia os exemplos oficiais parecidos
284
- - consulte AST e IR
285
- Depois de editar:
286
- - rode \`sema formatar\`
287
- - rode \`sema validar --json\`
288
- - use \`diagnosticos --json\` se houver falha
289
- - feche com \`sema verificar\`
290
-
291
- 4. Caso de UI sem perder a semantica
292
-
293
- Quero uma interface premium para este dominio, mas a solucao deve continuar ancorada em Sema.
294
- Modele primeiro o dominio em \`.sema\`.
295
- Depois proponha uma interface em React + TypeScript que torne visiveis:
296
- - estado
297
- - fluxo
298
- - erros
299
- - efeitos
300
- - garantias
301
- Nao transforme isso em um \`index.html\` solto.
302
-
303
- Comandos uteis da CLI para esse fluxo:
304
- - \`sema starter-ia\`
305
- - \`sema ajuda-ia\`
306
- - \`sema resumo <arquivo-ou-pasta>\`
307
- - \`sema prompt-curto <arquivo-ou-pasta>\`
308
- - \`sema prompt-ia\`
309
- - \`sema prompt-ia-ui\`
310
- - \`sema prompt-ia-react\`
311
- - \`sema prompt-ia-sema-primeiro\`
312
- - \`sema contexto-ia <arquivo.sema>\`
260
+ const EXEMPLOS_PROMPT_IA = `Exemplos de prompt oficial para trabalhar com Sema
261
+
262
+ 1. Sema primeiro
263
+
264
+ Crie uma solucao seguindo a estrategia "Sema primeiro".
265
+ Entregue primeiro os arquivos \`.sema\` do dominio e so depois a implementacao derivada.
266
+ Nao entregue apenas codigo imperativo.
267
+ Use Sema como fonte de verdade para contratos, estados, erros, efeitos e garantias.
268
+
269
+ 2. Sema + React + TypeScript
270
+
271
+ Crie um projeto com Sema + React + TypeScript.
272
+ Entregue:
273
+ - os arquivos \`.sema\` do dominio
274
+ - a arquitetura de pastas do frontend
275
+ - componentes React que reflitam \`state\`, \`flow\`, \`error\`, \`effects\` e \`guarantees\`
276
+ - uma interface elegante e implementavel
277
+ - nao entregue HTML solto em arquivo unico
278
+
279
+ 3. Revisar ou corrigir um modulo Sema
280
+
281
+ Revise e corrija um modulo \`.sema\`.
282
+ Antes de editar:
283
+ - leia os exemplos oficiais parecidos
284
+ - consulte AST e IR
285
+ Depois de editar:
286
+ - rode \`sema formatar\`
287
+ - rode \`sema validar --json\`
288
+ - use \`diagnosticos --json\` se houver falha
289
+ - feche com \`sema verificar\`
290
+
291
+ 4. Caso de UI sem perder a semantica
292
+
293
+ Quero uma interface premium para este dominio, mas a solucao deve continuar ancorada em Sema.
294
+ Modele primeiro o dominio em \`.sema\`.
295
+ Depois proponha uma interface em React + TypeScript que torne visiveis:
296
+ - estado
297
+ - fluxo
298
+ - erros
299
+ - efeitos
300
+ - garantias
301
+ Nao transforme isso em um \`index.html\` solto.
302
+
303
+ Comandos uteis da CLI para esse fluxo:
304
+ - \`sema starter-ia\`
305
+ - \`sema ajuda-ia\`
306
+ - \`sema resumo <arquivo-ou-pasta>\`
307
+ - \`sema prompt-curto <arquivo-ou-pasta>\`
308
+ - \`sema prompt-ia\`
309
+ - \`sema prompt-ia-ui\`
310
+ - \`sema prompt-ia-react\`
311
+ - \`sema prompt-ia-sema-primeiro\`
312
+ - \`sema contexto-ia <arquivo.sema>\`
313
313
  `;
314
314
  const DIRETORIO_CLI_ATUAL = path.dirname(fileURLToPath(import.meta.url));
315
315
  const VERSAO_CLI = pacoteCli.version;
@@ -385,7 +385,7 @@ function ajuda() {
385
385
  renderizarSecaoAscii("Comandos principais", [
386
386
  "descoberta: sema inspecionar [arquivo-ou-pasta] [--json]",
387
387
  "auditoria: sema drift <arquivo-ou-pasta> [--json]",
388
- "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|lua> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]",
388
+ "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]",
389
389
  "validacao: sema validar <arquivo-ou-pasta> [--json]",
390
390
  "diagnostico: sema diagnosticos <arquivo.sema> [--json]",
391
391
  "geracao: sema compilar <arquivo-ou-pasta> --alvo <python|typescript|dart|lua> --saida <diretorio> [--estrutura <flat|modulos|backend>] [--framework <base|nestjs|fastapi>]",
@@ -484,22 +484,11 @@ function comandoDisponivel(comando, argumentos = ["--version"]) {
484
484
  const execucao = spawnSync(comando, argumentos, { stdio: "ignore", shell: process.platform === "win32" });
485
485
  return (execucao.status ?? 1) === 0;
486
486
  }
487
- function resolverComandoLua() {
488
- if (comandoDisponivel("lua", ["-v"])) {
489
- return "lua";
490
- }
491
- if (comandoDisponivel("luajit", ["-v"])) {
492
- return "luajit";
493
- }
494
- return undefined;
495
- }
496
487
  async function comandoDoctor() {
497
- const comandoLua = resolverComandoLua();
498
488
  const checks = [
499
489
  { nome: "node", ok: comandoDisponivel("node") },
500
490
  { nome: "npm", ok: comandoDisponivel("npm") },
501
491
  { nome: "python", ok: comandoDisponivel("python") || comandoDisponivel("py") },
502
- { nome: "lua", ok: comandoLua !== undefined },
503
492
  { nome: "dotnet", ok: comandoDisponivel("dotnet") },
504
493
  { nome: "go", ok: comandoDisponivel("go") },
505
494
  { nome: "cargo", ok: comandoDisponivel("cargo") },
@@ -577,9 +566,6 @@ function normalizarFonteImportacao(valor) {
577
566
  if (valor === "rust" || valor === "rs") {
578
567
  return "rust";
579
568
  }
580
- if (valor === "lua" || valor === "luajit") {
581
- return "lua";
582
- }
583
569
  if (valor === "cpp" || valor === "cxx" || valor === "cc" || valor === "c++") {
584
570
  return "cpp";
585
571
  }
@@ -599,8 +585,7 @@ function normalizarFonteImportacao(valor) {
599
585
  || valor === "cpp"
600
586
  || valor === "typescript"
601
587
  || valor === "python"
602
- || valor === "dart"
603
- || valor === "lua") {
588
+ || valor === "dart") {
604
589
  return valor;
605
590
  }
606
591
  return undefined;
@@ -675,6 +660,7 @@ function aplicarEstruturaSaida(arquivos, ir, estrutura) {
675
660
  }
676
661
  else if (basename === `test_${nomeBaseAntigo}.lua`) {
677
662
  novoBasename = `test_${nomeArquivo}.lua`;
663
+ conteudo = conteudo.replace(`${nomeBaseAntigo}.lua`, `${nomeArquivo}.lua`);
678
664
  }
679
665
  return {
680
666
  caminhoRelativo: pastaModulo ? path.join(pastaModulo, novoBasename) : novoBasename,
@@ -686,19 +672,19 @@ function contarCasosDeTesteGerados(alvo, arquivos) {
686
672
  if (alvo === "dart") {
687
673
  return 0;
688
674
  }
689
- if (alvo === "typescript") {
690
- const arquivoTeste = arquivos.find((item) => item.caminhoRelativo.endsWith(".test.ts"));
675
+ if (alvo === "lua") {
676
+ const arquivoTeste = arquivos.find((item) => path.basename(item.caminhoRelativo).startsWith("test_") && item.caminhoRelativo.endsWith(".lua"));
691
677
  if (!arquivoTeste) {
692
678
  return 0;
693
679
  }
694
- return (arquivoTeste.conteudo.match(/\btest\(/g) ?? []).length;
680
+ return (arquivoTeste.conteudo.match(/\blocal function test_/g) ?? []).length;
695
681
  }
696
- if (alvo === "lua") {
697
- const arquivoTeste = arquivos.find((item) => path.basename(item.caminhoRelativo).startsWith("test_") && item.caminhoRelativo.endsWith(".lua"));
682
+ if (alvo === "typescript") {
683
+ const arquivoTeste = arquivos.find((item) => item.caminhoRelativo.endsWith(".test.ts"));
698
684
  if (!arquivoTeste) {
699
685
  return 0;
700
686
  }
701
- return (arquivoTeste.conteudo.match(/\blocal function test_/g) ?? []).length;
687
+ return (arquivoTeste.conteudo.match(/\btest\(/g) ?? []).length;
702
688
  }
703
689
  const arquivoTeste = arquivos.find((item) => path.basename(item.caminhoRelativo).startsWith("test_"));
704
690
  if (!arquivoTeste) {
@@ -710,8 +696,14 @@ function executarTestesGerados(alvo, baseSaida, arquivos, silencioso = false) {
710
696
  const quantidadeTestes = contarCasosDeTesteGerados(alvo, arquivos);
711
697
  if (quantidadeTestes === 0) {
712
698
  if (!silencioso) {
713
- const rotulo = alvo === "typescript" ? "TypeScript" : alvo === "python" ? "Python" : alvo === "dart" ? "Dart" : "Lua";
714
- console.log(`Nenhum teste ${rotulo} foi gerado.`);
699
+ const nomeAlvo = alvo === "typescript"
700
+ ? "TypeScript"
701
+ : alvo === "python"
702
+ ? "Python"
703
+ : alvo === "lua"
704
+ ? "Lua"
705
+ : "Dart";
706
+ console.log(`Nenhum teste ${nomeAlvo} foi gerado.`);
715
707
  }
716
708
  return { codigoSaida: 0, quantidadeTestes, saidaPadrao: "", saidaErro: "" };
717
709
  }
@@ -742,16 +734,7 @@ function executarTestesGerados(alvo, baseSaida, arquivos, silencioso = false) {
742
734
  }
743
735
  return { codigoSaida: 0, quantidadeTestes, saidaPadrao: "", saidaErro: "" };
744
736
  }
745
- const comandoLua = resolverComandoLua();
746
- if (!comandoLua) {
747
- return {
748
- codigoSaida: 1,
749
- quantidadeTestes,
750
- saidaPadrao: "",
751
- saidaErro: "Interpretador Lua nao encontrado. Instale `lua` ou `luajit` para rodar testes gerados.",
752
- };
753
- }
754
- const execucao = spawnSync(comandoLua, [arquivoTeste], {
737
+ const execucao = spawnSync("lua", [arquivoTeste], {
755
738
  stdio: silencioso ? "pipe" : "inherit",
756
739
  cwd: baseSaida,
757
740
  encoding: silencioso ? "utf8" : undefined,
@@ -1139,23 +1122,23 @@ function criarBriefingMinimo(resumo, modo, tamanho) {
1139
1122
  }
1140
1123
  function criarPromptCurtoModulo(resumo, modo, tamanho, capacidade) {
1141
1124
  const resumoTexto = renderizarResumoModuloTexto(resumo, tamanho, modo).trim();
1142
- return `Voce esta operando Sema em modo IA-first.
1143
-
1144
- Esta linguagem nao foi desenhada para agradar humano; ela existe para reduzir ambiguidade para IA.
1145
-
1146
- Capacidade alvo: ${capacidade}
1147
- Modo da tarefa: ${modo}
1148
-
1149
- Regras:
1150
- - nao invente sintaxe nem bloco fora da gramatica oficial
1151
- - preserve a intencao do contrato
1152
- - use este resumo como fonte compacta inicial
1153
- - se a tarefa pedir mais contexto, suba para \`briefing.min.json\`, \`drift.json\` e depois \`ir.json\`
1154
- - nao saia editando software vivo sem olhar risco, lacuna e checks sugeridos
1155
- ${resumo.consumerFramework ? "- se for tarefa visual consumer, priorize `appRoutes`, `consumerSurfaces` e `consumerBridges` antes de abrir arquivos aleatorios" : ""}
1156
-
1157
- Contexto compacto:
1158
- ${resumoTexto}
1125
+ return `Voce esta operando Sema em modo IA-first.
1126
+
1127
+ Esta linguagem nao foi desenhada para agradar humano; ela existe para reduzir ambiguidade para IA.
1128
+
1129
+ Capacidade alvo: ${capacidade}
1130
+ Modo da tarefa: ${modo}
1131
+
1132
+ Regras:
1133
+ - nao invente sintaxe nem bloco fora da gramatica oficial
1134
+ - preserve a intencao do contrato
1135
+ - use este resumo como fonte compacta inicial
1136
+ - se a tarefa pedir mais contexto, suba para \`briefing.min.json\`, \`drift.json\` e depois \`ir.json\`
1137
+ - nao saia editando software vivo sem olhar risco, lacuna e checks sugeridos
1138
+ ${resumo.consumerFramework ? "- se for tarefa visual consumer, priorize `appRoutes`, `consumerSurfaces` e `consumerBridges` antes de abrir arquivos aleatorios" : ""}
1139
+
1140
+ Contexto compacto:
1141
+ ${resumoTexto}
1159
1142
  `;
1160
1143
  }
1161
1144
  function renderizarResumoProjetoMarkdown(geradoEm, modulos, guiaPorCapacidade) {
@@ -1539,65 +1522,65 @@ async function gerarContextoIa(arquivoEntrada, pastaSaidaOpcional) {
1539
1522
  await writeFile(path.join(pastaBase, "drift.json"), `${JSON.stringify(contexto.drift, null, 2)}\n`, "utf8");
1540
1523
  await writeFile(path.join(pastaBase, "briefing.json"), `${JSON.stringify(contexto.briefing, null, 2)}\n`, "utf8");
1541
1524
  const resumoGerado = await gerarArquivosResumoModuloIa(contexto, pastaBase);
1542
- const resumo = `# Contexto de IA para ${contexto.modulo}
1543
-
1544
- - Arquivo alvo: \`${contexto.arquivo}\`
1545
- - Modulo: \`${contexto.modulo}\`
1546
- - Sucesso em validar: \`${contexto.sucesso}\`
1547
- - Quantidade de diagnosticos: \`${contexto.diagnosticos.length}\`
1548
- - Gerado em: \`${contexto.geradoEm}\`
1549
-
1550
- ## Arquivos gerados neste pacote
1551
-
1552
- - \`resumo.micro.txt\`
1553
- - \`resumo.curto.txt\`
1554
- - \`resumo.md\`
1555
- - \`briefing.min.json\`
1556
- - \`prompt-curto.txt\`
1557
- - \`validar.json\`
1558
- - \`diagnosticos.json\`
1559
- - \`ast.json\`
1560
- - \`ir.json\`
1561
- - \`drift.json\`
1562
- - \`briefing.json\`
1563
-
1564
- ## Fluxo recomendado para o agente
1565
-
1566
- ### IA pequena ou gratuita
1567
-
1568
- 1. Ler \`resumo.micro.txt\`.
1569
- 2. Ler \`briefing.min.json\`.
1570
- 3. Se ainda couber contexto, ler \`resumo.curto.txt\`.
1571
-
1572
- ### IA media
1573
-
1574
- 1. Ler \`resumo.curto.txt\`.
1575
- 2. Ler \`briefing.min.json\`.
1576
- 3. Ler \`drift.json\`.
1577
- 4. Se precisar, subir para \`resumo.md\`.
1578
-
1579
- ### IA grande ou com tool use
1580
-
1581
- 1. Ler \`README.md\`.
1582
- 2. Ler \`resumo.md\`.
1583
- 3. Ler \`briefing.json\`.
1584
- 4. Ler \`drift.json\`.
1585
- 5. So depois abrir \`ir.json\` e \`ast.json\`.
1586
-
1587
- ## Fechamento
1588
-
1589
- 1. Editar o arquivo \`.sema\`.
1590
- 2. Rodar \`sema formatar "${contexto.arquivo}"\`.
1591
- 3. Rodar \`sema validar "${contexto.arquivo}" --json\`.
1592
- 4. Rodar \`sema drift "${contexto.arquivo}" --json\`.
1593
- 5. Fechar com \`sema verificar <arquivo-ou-pasta> --json --saida ./.tmp/verificacao-ia\`.
1594
-
1595
- ## Textos base para onboarding do agente
1596
-
1597
- - \`sema starter-ia\`
1598
- - \`sema resumo "${contexto.arquivo}" --micro --para onboarding\`
1599
- - \`sema prompt-curto "${contexto.arquivo}" --para mudanca\`
1600
- - \`sema prompt-ia\`
1525
+ const resumo = `# Contexto de IA para ${contexto.modulo}
1526
+
1527
+ - Arquivo alvo: \`${contexto.arquivo}\`
1528
+ - Modulo: \`${contexto.modulo}\`
1529
+ - Sucesso em validar: \`${contexto.sucesso}\`
1530
+ - Quantidade de diagnosticos: \`${contexto.diagnosticos.length}\`
1531
+ - Gerado em: \`${contexto.geradoEm}\`
1532
+
1533
+ ## Arquivos gerados neste pacote
1534
+
1535
+ - \`resumo.micro.txt\`
1536
+ - \`resumo.curto.txt\`
1537
+ - \`resumo.md\`
1538
+ - \`briefing.min.json\`
1539
+ - \`prompt-curto.txt\`
1540
+ - \`validar.json\`
1541
+ - \`diagnosticos.json\`
1542
+ - \`ast.json\`
1543
+ - \`ir.json\`
1544
+ - \`drift.json\`
1545
+ - \`briefing.json\`
1546
+
1547
+ ## Fluxo recomendado para o agente
1548
+
1549
+ ### IA pequena ou gratuita
1550
+
1551
+ 1. Ler \`resumo.micro.txt\`.
1552
+ 2. Ler \`briefing.min.json\`.
1553
+ 3. Se ainda couber contexto, ler \`resumo.curto.txt\`.
1554
+
1555
+ ### IA media
1556
+
1557
+ 1. Ler \`resumo.curto.txt\`.
1558
+ 2. Ler \`briefing.min.json\`.
1559
+ 3. Ler \`drift.json\`.
1560
+ 4. Se precisar, subir para \`resumo.md\`.
1561
+
1562
+ ### IA grande ou com tool use
1563
+
1564
+ 1. Ler \`README.md\`.
1565
+ 2. Ler \`resumo.md\`.
1566
+ 3. Ler \`briefing.json\`.
1567
+ 4. Ler \`drift.json\`.
1568
+ 5. So depois abrir \`ir.json\` e \`ast.json\`.
1569
+
1570
+ ## Fechamento
1571
+
1572
+ 1. Editar o arquivo \`.sema\`.
1573
+ 2. Rodar \`sema formatar "${contexto.arquivo}"\`.
1574
+ 3. Rodar \`sema validar "${contexto.arquivo}" --json\`.
1575
+ 4. Rodar \`sema drift "${contexto.arquivo}" --json\`.
1576
+ 5. Fechar com \`sema verificar <arquivo-ou-pasta> --json --saida ./.tmp/verificacao-ia\`.
1577
+
1578
+ ## Textos base para onboarding do agente
1579
+
1580
+ - \`sema starter-ia\`
1581
+ - \`sema resumo "${contexto.arquivo}" --micro --para onboarding\`
1582
+ - \`sema prompt-curto "${contexto.arquivo}" --para mudanca\`
1583
+ - \`sema prompt-ia\`
1601
1584
  `;
1602
1585
  await writeFile(path.join(pastaBase, "README.md"), resumo, "utf8");
1603
1586
  return {
@@ -1624,54 +1607,54 @@ async function comandoIniciar(cwd, template) {
1624
1607
  const arquivosBase = [
1625
1608
  {
1626
1609
  caminhoRelativo: "contratos/pedidos.sema",
1627
- conteudo: `module app.pedidos {
1628
- entity Pedido {
1629
- fields {
1630
- id: Id
1631
- status: Texto
1632
- total: Decimal
1633
- }
1634
- }
1635
-
1636
- task criar_pedido {
1637
- input {
1638
- cliente_id: Id required
1639
- total: Decimal required
1640
- }
1641
- output {
1642
- pedido_id: Id
1643
- status: Texto
1644
- }
1645
- rules {
1646
- total > 0
1647
- }
1648
- effects {
1649
- persistencia Pedido criticidade=alta
1650
- auditoria pedidos
1651
- }
1652
- guarantees {
1653
- pedido_id existe
1654
- status existe
1655
- }
1656
- tests {
1657
- caso "pedido valido" {
1658
- given {
1659
- cliente_id: "cli-1"
1660
- total: 10
1661
- }
1662
- expect {
1663
- sucesso: verdadeiro
1664
- }
1665
- }
1666
- }
1667
- }
1668
-
1669
- route criar_pedido_publico {
1670
- metodo: POST
1671
- caminho: /pedidos
1672
- task: criar_pedido
1673
- }
1674
- }
1610
+ conteudo: `module app.pedidos {
1611
+ entity Pedido {
1612
+ fields {
1613
+ id: Id
1614
+ status: Texto
1615
+ total: Decimal
1616
+ }
1617
+ }
1618
+
1619
+ task criar_pedido {
1620
+ input {
1621
+ cliente_id: Id required
1622
+ total: Decimal required
1623
+ }
1624
+ output {
1625
+ pedido_id: Id
1626
+ status: Texto
1627
+ }
1628
+ rules {
1629
+ total > 0
1630
+ }
1631
+ effects {
1632
+ persistencia Pedido criticidade=alta
1633
+ auditoria pedidos
1634
+ }
1635
+ guarantees {
1636
+ pedido_id existe
1637
+ status existe
1638
+ }
1639
+ tests {
1640
+ caso "pedido valido" {
1641
+ given {
1642
+ cliente_id: "cli-1"
1643
+ total: 10
1644
+ }
1645
+ expect {
1646
+ sucesso: verdadeiro
1647
+ }
1648
+ }
1649
+ }
1650
+ }
1651
+
1652
+ route criar_pedido_publico {
1653
+ metodo: POST
1654
+ caminho: /pedidos
1655
+ task: criar_pedido
1656
+ }
1657
+ }
1675
1658
  `,
1676
1659
  },
1677
1660
  ];
@@ -1680,19 +1663,19 @@ async function comandoIniciar(cwd, template) {
1680
1663
  arquivos = [
1681
1664
  {
1682
1665
  caminhoRelativo: "sema.config.json",
1683
- conteudo: `{
1684
- "origens": ["./contratos"],
1685
- "saida": "./generated/nestjs",
1686
- "alvos": ["typescript"],
1687
- "alvoPadrao": "typescript",
1688
- "estruturaSaida": "backend",
1689
- "framework": "nestjs",
1690
- "modoEstrito": true,
1691
- "diretoriosSaidaPorAlvo": {
1692
- "typescript": "./generated/nestjs"
1693
- },
1694
- "convencoesGeracaoPorProjeto": "backend"
1695
- }
1666
+ conteudo: `{
1667
+ "origens": ["./contratos"],
1668
+ "saida": "./generated/nestjs",
1669
+ "alvos": ["typescript"],
1670
+ "alvoPadrao": "typescript",
1671
+ "estruturaSaida": "backend",
1672
+ "framework": "nestjs",
1673
+ "modoEstrito": true,
1674
+ "diretoriosSaidaPorAlvo": {
1675
+ "typescript": "./generated/nestjs"
1676
+ },
1677
+ "convencoesGeracaoPorProjeto": "backend"
1678
+ }
1696
1679
  `,
1697
1680
  },
1698
1681
  { caminhoRelativo: "src/.gitkeep", conteudo: "" },
@@ -1704,19 +1687,19 @@ async function comandoIniciar(cwd, template) {
1704
1687
  arquivos = [
1705
1688
  {
1706
1689
  caminhoRelativo: "sema.config.json",
1707
- conteudo: `{
1708
- "origens": ["./contratos"],
1709
- "saida": "./generated/fastapi",
1710
- "alvos": ["python"],
1711
- "alvoPadrao": "python",
1712
- "estruturaSaida": "backend",
1713
- "framework": "fastapi",
1714
- "modoEstrito": true,
1715
- "diretoriosSaidaPorAlvo": {
1716
- "python": "./generated/fastapi"
1717
- },
1718
- "convencoesGeracaoPorProjeto": "backend"
1719
- }
1690
+ conteudo: `{
1691
+ "origens": ["./contratos"],
1692
+ "saida": "./generated/fastapi",
1693
+ "alvos": ["python"],
1694
+ "alvoPadrao": "python",
1695
+ "estruturaSaida": "backend",
1696
+ "framework": "fastapi",
1697
+ "modoEstrito": true,
1698
+ "diretoriosSaidaPorAlvo": {
1699
+ "python": "./generated/fastapi"
1700
+ },
1701
+ "convencoesGeracaoPorProjeto": "backend"
1702
+ }
1720
1703
  `,
1721
1704
  },
1722
1705
  { caminhoRelativo: "app/.gitkeep", conteudo: "" },
@@ -1728,65 +1711,65 @@ async function comandoIniciar(cwd, template) {
1728
1711
  arquivos = [
1729
1712
  {
1730
1713
  caminhoRelativo: "sema.config.json",
1731
- conteudo: `{
1732
- "origens": ["./contratos"],
1733
- "saida": "./generated",
1734
- "alvos": ["typescript"],
1735
- "alvoPadrao": "typescript",
1736
- "estruturaSaida": "modulos",
1737
- "framework": "base",
1738
- "modoEstrito": true,
1739
- "diretoriosCodigo": ["./src"],
1740
- "fontesLegado": ["nextjs", "typescript"],
1741
- "diretoriosSaidaPorAlvo": {
1742
- "typescript": "./generated/typescript"
1743
- },
1744
- "convencoesGeracaoPorProjeto": "base"
1745
- }
1714
+ conteudo: `{
1715
+ "origens": ["./contratos"],
1716
+ "saida": "./generated",
1717
+ "alvos": ["typescript"],
1718
+ "alvoPadrao": "typescript",
1719
+ "estruturaSaida": "modulos",
1720
+ "framework": "base",
1721
+ "modoEstrito": true,
1722
+ "diretoriosCodigo": ["./src"],
1723
+ "fontesLegado": ["nextjs", "typescript"],
1724
+ "diretoriosSaidaPorAlvo": {
1725
+ "typescript": "./generated/typescript"
1726
+ },
1727
+ "convencoesGeracaoPorProjeto": "base"
1728
+ }
1746
1729
  `,
1747
1730
  },
1748
1731
  {
1749
1732
  caminhoRelativo: "contratos/health.sema",
1750
- conteudo: `module app.health {
1751
- task get_api_health {
1752
- output {
1753
- status: Texto
1754
- runtime: Texto
1755
- }
1756
- impl {
1757
- ts: src.app.api.health.route.GET
1758
- }
1759
- guarantees {
1760
- status existe
1761
- runtime existe
1762
- }
1763
- }
1764
-
1765
- route get_api_health_publico {
1766
- metodo: GET
1767
- caminho: /api/health
1768
- task: get_api_health
1769
- }
1770
- }
1733
+ conteudo: `module app.health {
1734
+ task get_api_health {
1735
+ output {
1736
+ status: Texto
1737
+ runtime: Texto
1738
+ }
1739
+ impl {
1740
+ ts: src.app.api.health.route.GET
1741
+ }
1742
+ guarantees {
1743
+ status existe
1744
+ runtime existe
1745
+ }
1746
+ }
1747
+
1748
+ route get_api_health_publico {
1749
+ metodo: GET
1750
+ caminho: /api/health
1751
+ task: get_api_health
1752
+ }
1753
+ }
1771
1754
  `,
1772
1755
  },
1773
1756
  {
1774
1757
  caminhoRelativo: "src/app/api/health/route.ts",
1775
- conteudo: `export async function GET() {
1776
- return Response.json({
1777
- status: "ok",
1778
- runtime: "nextjs",
1779
- });
1780
- }
1758
+ conteudo: `export async function GET() {
1759
+ return Response.json({
1760
+ status: "ok",
1761
+ runtime: "nextjs",
1762
+ });
1763
+ }
1781
1764
  `,
1782
1765
  },
1783
1766
  {
1784
1767
  caminhoRelativo: "README.md",
1785
- conteudo: `# Starter Next.js API + Sema
1786
-
1787
- - Contratos em \`contratos/\`
1788
- - Handlers App Router em \`src/app/api/\`
1789
- - Rota de exemplo validada por \`drift\`
1768
+ conteudo: `# Starter Next.js API + Sema
1769
+
1770
+ - Contratos em \`contratos/\`
1771
+ - Handlers App Router em \`src/app/api/\`
1772
+ - Rota de exemplo validada por \`drift\`
1790
1773
  `,
1791
1774
  },
1792
1775
  ];
@@ -1795,122 +1778,122 @@ async function comandoIniciar(cwd, template) {
1795
1778
  arquivos = [
1796
1779
  {
1797
1780
  caminhoRelativo: "sema.config.json",
1798
- conteudo: `{
1799
- "origens": ["./contratos"],
1800
- "saida": "./generated",
1801
- "alvos": ["typescript"],
1802
- "alvoPadrao": "typescript",
1803
- "estruturaSaida": "modulos",
1804
- "framework": "base",
1805
- "modoEstrito": true,
1806
- "diretoriosCodigo": ["./src"],
1807
- "fontesLegado": ["nextjs-consumer", "typescript"],
1808
- "diretoriosSaidaPorAlvo": {
1809
- "typescript": "./generated/typescript"
1810
- },
1811
- "convencoesGeracaoPorProjeto": "base"
1812
- }
1781
+ conteudo: `{
1782
+ "origens": ["./contratos"],
1783
+ "saida": "./generated",
1784
+ "alvos": ["typescript"],
1785
+ "alvoPadrao": "typescript",
1786
+ "estruturaSaida": "modulos",
1787
+ "framework": "base",
1788
+ "modoEstrito": true,
1789
+ "diretoriosCodigo": ["./src"],
1790
+ "fontesLegado": ["nextjs-consumer", "typescript"],
1791
+ "diretoriosSaidaPorAlvo": {
1792
+ "typescript": "./generated/typescript"
1793
+ },
1794
+ "convencoesGeracaoPorProjeto": "base"
1795
+ }
1813
1796
  `,
1814
1797
  },
1815
1798
  {
1816
1799
  caminhoRelativo: "contratos/showroom_consumer.sema",
1817
- conteudo: `module showroom.consumer {
1818
- task fetch_showroom_ranking {
1819
- input {
1820
- }
1821
- output {
1822
- ranking: Json
1823
- }
1824
- impl {
1825
- ts: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1826
- }
1827
- vinculos {
1828
- arquivo: "src/lib/sema_consumer_bridge.ts"
1829
- simbolo: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1830
- superficie: "/ranking"
1831
- arquivo: "src/app/ranking/page.tsx"
1832
- arquivo: "src/app/ranking/loading.tsx"
1833
- arquivo: "src/app/ranking/error.tsx"
1834
- }
1835
- guarantees {
1836
- ranking existe
1837
- }
1838
- }
1839
- }
1800
+ conteudo: `module showroom.consumer {
1801
+ task fetch_showroom_ranking {
1802
+ input {
1803
+ }
1804
+ output {
1805
+ ranking: Json
1806
+ }
1807
+ impl {
1808
+ ts: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1809
+ }
1810
+ vinculos {
1811
+ arquivo: "src/lib/sema_consumer_bridge.ts"
1812
+ simbolo: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1813
+ superficie: "/ranking"
1814
+ arquivo: "src/app/ranking/page.tsx"
1815
+ arquivo: "src/app/ranking/loading.tsx"
1816
+ arquivo: "src/app/ranking/error.tsx"
1817
+ }
1818
+ guarantees {
1819
+ ranking existe
1820
+ }
1821
+ }
1822
+ }
1840
1823
  `,
1841
1824
  },
1842
1825
  {
1843
1826
  caminhoRelativo: "src/lib/sema_consumer_bridge.ts",
1844
- conteudo: `export async function semaFetchShowroomRanking() {
1845
- return {
1846
- ranking: [
1847
- { clube: "Tigres do Norte", pontos: 33 },
1848
- { clube: "Porto Azul", pontos: 31 },
1849
- { clube: "Galo de Ouro", pontos: 28 },
1850
- ],
1851
- };
1852
- }
1827
+ conteudo: `export async function semaFetchShowroomRanking() {
1828
+ return {
1829
+ ranking: [
1830
+ { clube: "Tigres do Norte", pontos: 33 },
1831
+ { clube: "Porto Azul", pontos: 31 },
1832
+ { clube: "Galo de Ouro", pontos: 28 },
1833
+ ],
1834
+ };
1835
+ }
1853
1836
  `,
1854
1837
  },
1855
1838
  {
1856
1839
  caminhoRelativo: "src/app/ranking/page.tsx",
1857
- conteudo: `import { semaFetchShowroomRanking } from "../../lib/sema_consumer_bridge";
1858
-
1859
- export default async function RankingPage() {
1860
- const { ranking } = await semaFetchShowroomRanking();
1861
-
1862
- return (
1863
- <main>
1864
- <h1>Ranking showroom</h1>
1865
- <ul>
1866
- {ranking.map((item) => (
1867
- <li key={item.clube}>
1868
- {item.clube} - {item.pontos} pts
1869
- </li>
1870
- ))}
1871
- </ul>
1872
- </main>
1873
- );
1874
- }
1840
+ conteudo: `import { semaFetchShowroomRanking } from "../../lib/sema_consumer_bridge";
1841
+
1842
+ export default async function RankingPage() {
1843
+ const { ranking } = await semaFetchShowroomRanking();
1844
+
1845
+ return (
1846
+ <main>
1847
+ <h1>Ranking showroom</h1>
1848
+ <ul>
1849
+ {ranking.map((item) => (
1850
+ <li key={item.clube}>
1851
+ {item.clube} - {item.pontos} pts
1852
+ </li>
1853
+ ))}
1854
+ </ul>
1855
+ </main>
1856
+ );
1857
+ }
1875
1858
  `,
1876
1859
  },
1877
1860
  {
1878
1861
  caminhoRelativo: "src/app/ranking/loading.tsx",
1879
- conteudo: `export default function Loading() {
1880
- return <p>Carregando ranking...</p>;
1881
- }
1862
+ conteudo: `export default function Loading() {
1863
+ return <p>Carregando ranking...</p>;
1864
+ }
1882
1865
  `,
1883
1866
  },
1884
1867
  {
1885
1868
  caminhoRelativo: "src/app/ranking/error.tsx",
1886
- conteudo: `"use client";
1887
-
1888
- export default function Error({
1889
- error,
1890
- reset,
1891
- }: {
1892
- error: Error;
1893
- reset: () => void;
1894
- }) {
1895
- return (
1896
- <main>
1897
- <h1>Falha ao carregar ranking</h1>
1898
- <p>{error.message}</p>
1899
- <button type="button" onClick={reset}>Tentar novamente</button>
1900
- </main>
1901
- );
1902
- }
1869
+ conteudo: `"use client";
1870
+
1871
+ export default function Error({
1872
+ error,
1873
+ reset,
1874
+ }: {
1875
+ error: Error;
1876
+ reset: () => void;
1877
+ }) {
1878
+ return (
1879
+ <main>
1880
+ <h1>Falha ao carregar ranking</h1>
1881
+ <p>{error.message}</p>
1882
+ <button type="button" onClick={reset}>Tentar novamente</button>
1883
+ </main>
1884
+ );
1885
+ }
1903
1886
  `,
1904
1887
  },
1905
1888
  {
1906
1889
  caminhoRelativo: "README.md",
1907
- conteudo: `# Starter Next.js Consumer + Sema
1908
-
1909
- - Contratos em \`contratos/\`
1910
- - Bridge consumer canonico em \`src/lib/sema_consumer_bridge.ts\`
1911
- - Superficies App Router em \`src/app/\`
1912
- - O slice oficial desta fase e \`consumer bridge + App Router surfaces\`
1913
- - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
1890
+ conteudo: `# Starter Next.js Consumer + Sema
1891
+
1892
+ - Contratos em \`contratos/\`
1893
+ - Bridge consumer canonico em \`src/lib/sema_consumer_bridge.ts\`
1894
+ - Superficies App Router em \`src/app/\`
1895
+ - O slice oficial desta fase e \`consumer bridge + App Router surfaces\`
1896
+ - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
1914
1897
  `,
1915
1898
  },
1916
1899
  ];
@@ -1919,135 +1902,135 @@ export default function Error({
1919
1902
  arquivos = [
1920
1903
  {
1921
1904
  caminhoRelativo: "sema.config.json",
1922
- conteudo: `{
1923
- "origens": ["./contratos"],
1924
- "saida": "./generated",
1925
- "alvos": ["typescript"],
1926
- "alvoPadrao": "typescript",
1927
- "estruturaSaida": "modulos",
1928
- "framework": "base",
1929
- "modoEstrito": true,
1930
- "diretoriosCodigo": ["./src"],
1931
- "fontesLegado": ["react-vite-consumer", "typescript"],
1932
- "diretoriosSaidaPorAlvo": {
1933
- "typescript": "./generated/typescript"
1934
- },
1935
- "convencoesGeracaoPorProjeto": "base"
1936
- }
1905
+ conteudo: `{
1906
+ "origens": ["./contratos"],
1907
+ "saida": "./generated",
1908
+ "alvos": ["typescript"],
1909
+ "alvoPadrao": "typescript",
1910
+ "estruturaSaida": "modulos",
1911
+ "framework": "base",
1912
+ "modoEstrito": true,
1913
+ "diretoriosCodigo": ["./src"],
1914
+ "fontesLegado": ["react-vite-consumer", "typescript"],
1915
+ "diretoriosSaidaPorAlvo": {
1916
+ "typescript": "./generated/typescript"
1917
+ },
1918
+ "convencoesGeracaoPorProjeto": "base"
1919
+ }
1937
1920
  `,
1938
1921
  },
1939
1922
  {
1940
1923
  caminhoRelativo: "contratos/showroom_consumer.sema",
1941
- conteudo: `module showroom.consumer {
1942
- task fetch_showroom_ranking {
1943
- input {
1944
- }
1945
- output {
1946
- ranking: Json
1947
- }
1948
- impl {
1949
- ts: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1950
- }
1951
- vinculos {
1952
- arquivo: "src/lib/sema_consumer_bridge.ts"
1953
- simbolo: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1954
- superficie: "/ranking"
1955
- arquivo: "src/router.tsx"
1956
- arquivo: "src/pages/ranking.tsx"
1957
- }
1958
- guarantees {
1959
- ranking existe
1960
- }
1961
- }
1962
- }
1924
+ conteudo: `module showroom.consumer {
1925
+ task fetch_showroom_ranking {
1926
+ input {
1927
+ }
1928
+ output {
1929
+ ranking: Json
1930
+ }
1931
+ impl {
1932
+ ts: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1933
+ }
1934
+ vinculos {
1935
+ arquivo: "src/lib/sema_consumer_bridge.ts"
1936
+ simbolo: src.lib.sema_consumer_bridge.semaFetchShowroomRanking
1937
+ superficie: "/ranking"
1938
+ arquivo: "src/router.tsx"
1939
+ arquivo: "src/pages/ranking.tsx"
1940
+ }
1941
+ guarantees {
1942
+ ranking existe
1943
+ }
1944
+ }
1945
+ }
1963
1946
  `,
1964
1947
  },
1965
1948
  {
1966
1949
  caminhoRelativo: "src/lib/sema_consumer_bridge.ts",
1967
- conteudo: `export async function semaFetchShowroomRanking() {
1968
- return {
1969
- ranking: [
1970
- { clube: "Tigres do Norte", pontos: 33 },
1971
- { clube: "Porto Azul", pontos: 31 },
1972
- { clube: "Galo de Ouro", pontos: 28 },
1973
- ],
1974
- };
1975
- }
1950
+ conteudo: `export async function semaFetchShowroomRanking() {
1951
+ return {
1952
+ ranking: [
1953
+ { clube: "Tigres do Norte", pontos: 33 },
1954
+ { clube: "Porto Azul", pontos: 31 },
1955
+ { clube: "Galo de Ouro", pontos: 28 },
1956
+ ],
1957
+ };
1958
+ }
1976
1959
  `,
1977
1960
  },
1978
1961
  {
1979
1962
  caminhoRelativo: "src/pages/ranking.tsx",
1980
- conteudo: `import { useEffect, useState } from "react";
1981
- import { semaFetchShowroomRanking } from "../lib/sema_consumer_bridge";
1982
-
1983
- export function RankingPage() {
1984
- const [ranking, setRanking] = useState<Array<{ clube: string; pontos: number }>>([]);
1985
-
1986
- useEffect(() => {
1987
- void semaFetchShowroomRanking().then((payload) => setRanking(payload.ranking ?? []));
1988
- }, []);
1989
-
1990
- return (
1991
- <main>
1992
- <h1>Ranking showroom</h1>
1993
- <ul>
1994
- {ranking.map((item) => (
1995
- <li key={item.clube}>
1996
- {item.clube} - {item.pontos} pts
1997
- </li>
1998
- ))}
1999
- </ul>
2000
- </main>
2001
- );
2002
- }
1963
+ conteudo: `import { useEffect, useState } from "react";
1964
+ import { semaFetchShowroomRanking } from "../lib/sema_consumer_bridge";
1965
+
1966
+ export function RankingPage() {
1967
+ const [ranking, setRanking] = useState<Array<{ clube: string; pontos: number }>>([]);
1968
+
1969
+ useEffect(() => {
1970
+ void semaFetchShowroomRanking().then((payload) => setRanking(payload.ranking ?? []));
1971
+ }, []);
1972
+
1973
+ return (
1974
+ <main>
1975
+ <h1>Ranking showroom</h1>
1976
+ <ul>
1977
+ {ranking.map((item) => (
1978
+ <li key={item.clube}>
1979
+ {item.clube} - {item.pontos} pts
1980
+ </li>
1981
+ ))}
1982
+ </ul>
1983
+ </main>
1984
+ );
1985
+ }
2003
1986
  `,
2004
1987
  },
2005
1988
  {
2006
1989
  caminhoRelativo: "src/router.tsx",
2007
- conteudo: `import { createBrowserRouter } from "react-router-dom";
2008
- import { RankingPage } from "./pages/ranking";
2009
-
2010
- export const appRouter = createBrowserRouter([
2011
- {
2012
- path: "/ranking",
2013
- Component: RankingPage,
2014
- },
2015
- ]);
1990
+ conteudo: `import { createBrowserRouter } from "react-router-dom";
1991
+ import { RankingPage } from "./pages/ranking";
1992
+
1993
+ export const appRouter = createBrowserRouter([
1994
+ {
1995
+ path: "/ranking",
1996
+ Component: RankingPage,
1997
+ },
1998
+ ]);
2016
1999
  `,
2017
2000
  },
2018
2001
  {
2019
2002
  caminhoRelativo: "src/App.tsx",
2020
- conteudo: `import { RouterProvider } from "react-router-dom";
2021
- import { appRouter } from "./router";
2022
-
2023
- export default function App() {
2024
- return <RouterProvider router={appRouter} />;
2025
- }
2003
+ conteudo: `import { RouterProvider } from "react-router-dom";
2004
+ import { appRouter } from "./router";
2005
+
2006
+ export default function App() {
2007
+ return <RouterProvider router={appRouter} />;
2008
+ }
2026
2009
  `,
2027
2010
  },
2028
2011
  {
2029
2012
  caminhoRelativo: "src/main.tsx",
2030
- conteudo: `import React from "react";
2031
- import ReactDOM from "react-dom/client";
2032
- import App from "./App";
2033
-
2034
- ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
2035
- <React.StrictMode>
2036
- <App />
2037
- </React.StrictMode>,
2038
- );
2013
+ conteudo: `import React from "react";
2014
+ import ReactDOM from "react-dom/client";
2015
+ import App from "./App";
2016
+
2017
+ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
2018
+ <React.StrictMode>
2019
+ <App />
2020
+ </React.StrictMode>,
2021
+ );
2039
2022
  `,
2040
2023
  },
2041
2024
  {
2042
2025
  caminhoRelativo: "README.md",
2043
- conteudo: `# Starter React Vite Consumer + Sema
2044
-
2045
- - Contratos em \`contratos/\`
2046
- - Bridge consumer canonico em \`src/lib/sema_consumer_bridge.ts\`
2047
- - Rotas explicitas em \`src/router.tsx\`
2048
- - Superficies consumer em \`src/pages/\`
2049
- - O slice oficial desta fase e \`consumer bridge + react-router surfaces\`
2050
- - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
2026
+ conteudo: `# Starter React Vite Consumer + Sema
2027
+
2028
+ - Contratos em \`contratos/\`
2029
+ - Bridge consumer canonico em \`src/lib/sema_consumer_bridge.ts\`
2030
+ - Rotas explicitas em \`src/router.tsx\`
2031
+ - Superficies consumer em \`src/pages/\`
2032
+ - O slice oficial desta fase e \`consumer bridge + react-router surfaces\`
2033
+ - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
2051
2034
  `,
2052
2035
  },
2053
2036
  ];
@@ -2056,154 +2039,154 @@ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
2056
2039
  arquivos = [
2057
2040
  {
2058
2041
  caminhoRelativo: "sema.config.json",
2059
- conteudo: `{
2060
- "origens": ["./contratos"],
2061
- "saida": "./generated",
2062
- "alvos": ["typescript"],
2063
- "alvoPadrao": "typescript",
2064
- "estruturaSaida": "modulos",
2065
- "framework": "base",
2066
- "modoEstrito": true,
2067
- "diretoriosCodigo": ["./src"],
2068
- "fontesLegado": ["angular-consumer", "typescript"],
2069
- "diretoriosSaidaPorAlvo": {
2070
- "typescript": "./generated/typescript"
2071
- },
2072
- "convencoesGeracaoPorProjeto": "base"
2073
- }
2042
+ conteudo: `{
2043
+ "origens": ["./contratos"],
2044
+ "saida": "./generated",
2045
+ "alvos": ["typescript"],
2046
+ "alvoPadrao": "typescript",
2047
+ "estruturaSaida": "modulos",
2048
+ "framework": "base",
2049
+ "modoEstrito": true,
2050
+ "diretoriosCodigo": ["./src"],
2051
+ "fontesLegado": ["angular-consumer", "typescript"],
2052
+ "diretoriosSaidaPorAlvo": {
2053
+ "typescript": "./generated/typescript"
2054
+ },
2055
+ "convencoesGeracaoPorProjeto": "base"
2056
+ }
2074
2057
  `,
2075
2058
  },
2076
2059
  {
2077
2060
  caminhoRelativo: "contratos/showroom_consumer.sema",
2078
- conteudo: `module showroom.consumer {
2079
- task fetch_showroom_ranking {
2080
- input {
2081
- }
2082
- output {
2083
- ranking: Json
2084
- }
2085
- impl {
2086
- ts: src.app.sema_consumer_bridge.semaFetchShowroomRanking
2087
- }
2088
- vinculos {
2089
- arquivo: "src/app/sema_consumer_bridge.ts"
2090
- simbolo: src.app.sema_consumer_bridge.semaFetchShowroomRanking
2091
- superficie: "/ranking"
2092
- arquivo: "src/app/app.routes.ts"
2093
- arquivo: "src/app/features/ranking/ranking.routes.ts"
2094
- arquivo: "src/app/features/ranking/ranking-page.component.ts"
2095
- }
2096
- guarantees {
2097
- ranking existe
2098
- }
2099
- }
2100
- }
2061
+ conteudo: `module showroom.consumer {
2062
+ task fetch_showroom_ranking {
2063
+ input {
2064
+ }
2065
+ output {
2066
+ ranking: Json
2067
+ }
2068
+ impl {
2069
+ ts: src.app.sema_consumer_bridge.semaFetchShowroomRanking
2070
+ }
2071
+ vinculos {
2072
+ arquivo: "src/app/sema_consumer_bridge.ts"
2073
+ simbolo: src.app.sema_consumer_bridge.semaFetchShowroomRanking
2074
+ superficie: "/ranking"
2075
+ arquivo: "src/app/app.routes.ts"
2076
+ arquivo: "src/app/features/ranking/ranking.routes.ts"
2077
+ arquivo: "src/app/features/ranking/ranking-page.component.ts"
2078
+ }
2079
+ guarantees {
2080
+ ranking existe
2081
+ }
2082
+ }
2083
+ }
2101
2084
  `,
2102
2085
  },
2103
2086
  {
2104
2087
  caminhoRelativo: "src/app/sema_consumer_bridge.ts",
2105
- conteudo: `export async function semaFetchShowroomRanking() {
2106
- return {
2107
- ranking: [
2108
- { clube: "Tigres do Norte", pontos: 33 },
2109
- { clube: "Porto Azul", pontos: 31 },
2110
- { clube: "Galo de Ouro", pontos: 28 },
2111
- ],
2112
- };
2113
- }
2088
+ conteudo: `export async function semaFetchShowroomRanking() {
2089
+ return {
2090
+ ranking: [
2091
+ { clube: "Tigres do Norte", pontos: 33 },
2092
+ { clube: "Porto Azul", pontos: 31 },
2093
+ { clube: "Galo de Ouro", pontos: 28 },
2094
+ ],
2095
+ };
2096
+ }
2114
2097
  `,
2115
2098
  },
2116
2099
  {
2117
2100
  caminhoRelativo: "src/app/app.routes.ts",
2118
- conteudo: `import { Routes } from "@angular/router";
2119
-
2120
- export const routes: Routes = [
2121
- {
2122
- path: "ranking",
2123
- loadChildren: () => import("./features/ranking/ranking.routes").then((m) => m.RANKING_ROUTES),
2124
- },
2125
- ];
2101
+ conteudo: `import { Routes } from "@angular/router";
2102
+
2103
+ export const routes: Routes = [
2104
+ {
2105
+ path: "ranking",
2106
+ loadChildren: () => import("./features/ranking/ranking.routes").then((m) => m.RANKING_ROUTES),
2107
+ },
2108
+ ];
2126
2109
  `,
2127
2110
  },
2128
2111
  {
2129
2112
  caminhoRelativo: "src/app/features/ranking/ranking.routes.ts",
2130
- conteudo: `import { Routes } from "@angular/router";
2131
-
2132
- export const RANKING_ROUTES: Routes = [
2133
- {
2134
- path: "",
2135
- loadComponent: () => import("./ranking-page.component").then((m) => m.RankingPageComponent),
2136
- },
2137
- ];
2113
+ conteudo: `import { Routes } from "@angular/router";
2114
+
2115
+ export const RANKING_ROUTES: Routes = [
2116
+ {
2117
+ path: "",
2118
+ loadComponent: () => import("./ranking-page.component").then((m) => m.RankingPageComponent),
2119
+ },
2120
+ ];
2138
2121
  `,
2139
2122
  },
2140
2123
  {
2141
2124
  caminhoRelativo: "src/app/features/ranking/ranking-page.component.ts",
2142
- conteudo: `import { Component, OnInit } from "@angular/core";
2143
- import { CommonModule } from "@angular/common";
2144
- import { semaFetchShowroomRanking } from "../../sema_consumer_bridge";
2145
-
2146
- @Component({
2147
- selector: "app-ranking-page",
2148
- standalone: true,
2149
- imports: [CommonModule],
2150
- template: \`
2151
- <main>
2152
- <h1>Ranking showroom</h1>
2153
- <ul>
2154
- <li *ngFor="let item of ranking">
2155
- {{ item.clube }} - {{ item.pontos }} pts
2156
- </li>
2157
- </ul>
2158
- </main>
2159
- \`,
2160
- })
2161
- export class RankingPageComponent implements OnInit {
2162
- ranking: Array<{ clube: string; pontos: number }> = [];
2163
-
2164
- async ngOnInit() {
2165
- const payload = await semaFetchShowroomRanking();
2166
- this.ranking = payload.ranking ?? [];
2167
- }
2168
- }
2125
+ conteudo: `import { Component, OnInit } from "@angular/core";
2126
+ import { CommonModule } from "@angular/common";
2127
+ import { semaFetchShowroomRanking } from "../../sema_consumer_bridge";
2128
+
2129
+ @Component({
2130
+ selector: "app-ranking-page",
2131
+ standalone: true,
2132
+ imports: [CommonModule],
2133
+ template: \`
2134
+ <main>
2135
+ <h1>Ranking showroom</h1>
2136
+ <ul>
2137
+ <li *ngFor="let item of ranking">
2138
+ {{ item.clube }} - {{ item.pontos }} pts
2139
+ </li>
2140
+ </ul>
2141
+ </main>
2142
+ \`,
2143
+ })
2144
+ export class RankingPageComponent implements OnInit {
2145
+ ranking: Array<{ clube: string; pontos: number }> = [];
2146
+
2147
+ async ngOnInit() {
2148
+ const payload = await semaFetchShowroomRanking();
2149
+ this.ranking = payload.ranking ?? [];
2150
+ }
2151
+ }
2169
2152
  `,
2170
2153
  },
2171
2154
  {
2172
2155
  caminhoRelativo: "src/app/app.component.ts",
2173
- conteudo: `import { Component } from "@angular/core";
2174
- import { RouterOutlet } from "@angular/router";
2175
-
2176
- @Component({
2177
- selector: "app-root",
2178
- standalone: true,
2179
- imports: [RouterOutlet],
2180
- template: "<router-outlet />",
2181
- })
2182
- export class AppComponent {}
2156
+ conteudo: `import { Component } from "@angular/core";
2157
+ import { RouterOutlet } from "@angular/router";
2158
+
2159
+ @Component({
2160
+ selector: "app-root",
2161
+ standalone: true,
2162
+ imports: [RouterOutlet],
2163
+ template: "<router-outlet />",
2164
+ })
2165
+ export class AppComponent {}
2183
2166
  `,
2184
2167
  },
2185
2168
  {
2186
2169
  caminhoRelativo: "src/main.ts",
2187
- conteudo: `import { bootstrapApplication } from "@angular/platform-browser";
2188
- import { provideRouter } from "@angular/router";
2189
- import { AppComponent } from "./app/app.component";
2190
- import { routes } from "./app/app.routes";
2191
-
2192
- void bootstrapApplication(AppComponent, {
2193
- providers: [provideRouter(routes)],
2194
- });
2170
+ conteudo: `import { bootstrapApplication } from "@angular/platform-browser";
2171
+ import { provideRouter } from "@angular/router";
2172
+ import { AppComponent } from "./app/app.component";
2173
+ import { routes } from "./app/app.routes";
2174
+
2175
+ void bootstrapApplication(AppComponent, {
2176
+ providers: [provideRouter(routes)],
2177
+ });
2195
2178
  `,
2196
2179
  },
2197
2180
  {
2198
2181
  caminhoRelativo: "README.md",
2199
- conteudo: `# Starter Angular Consumer + Sema
2200
-
2201
- - Contratos em \`contratos/\`
2202
- - Bridge consumer canonico em \`src/app/sema_consumer_bridge.ts\`
2203
- - Rotas lazy em \`src/app/app.routes.ts\`
2204
- - Feature folders em \`src/app/features/\`
2205
- - O slice oficial desta fase e \`consumer bridge + route config surfaces\`
2206
- - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
2182
+ conteudo: `# Starter Angular Consumer + Sema
2183
+
2184
+ - Contratos em \`contratos/\`
2185
+ - Bridge consumer canonico em \`src/app/sema_consumer_bridge.ts\`
2186
+ - Rotas lazy em \`src/app/app.routes.ts\`
2187
+ - Feature folders em \`src/app/features/\`
2188
+ - O slice oficial desta fase e \`consumer bridge + route config surfaces\`
2189
+ - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual drift
2207
2190
  `,
2208
2191
  },
2209
2192
  ];
@@ -2212,171 +2195,171 @@ void bootstrapApplication(AppComponent, {
2212
2195
  arquivos = [
2213
2196
  {
2214
2197
  caminhoRelativo: "sema.config.json",
2215
- conteudo: `{
2216
- "origens": ["./contratos"],
2217
- "saida": "./generated",
2218
- "alvos": ["dart"],
2219
- "alvoPadrao": "dart",
2220
- "estruturaSaida": "modulos",
2221
- "framework": "base",
2222
- "modoEstrito": true,
2223
- "diretoriosCodigo": ["./lib"],
2224
- "fontesLegado": ["flutter-consumer", "dart"],
2225
- "diretoriosSaidaPorAlvo": {
2226
- "dart": "./generated/dart"
2227
- },
2228
- "convencoesGeracaoPorProjeto": "base"
2229
- }
2198
+ conteudo: `{
2199
+ "origens": ["./contratos"],
2200
+ "saida": "./generated",
2201
+ "alvos": ["dart"],
2202
+ "alvoPadrao": "dart",
2203
+ "estruturaSaida": "modulos",
2204
+ "framework": "base",
2205
+ "modoEstrito": true,
2206
+ "diretoriosCodigo": ["./lib"],
2207
+ "fontesLegado": ["flutter-consumer", "dart"],
2208
+ "diretoriosSaidaPorAlvo": {
2209
+ "dart": "./generated/dart"
2210
+ },
2211
+ "convencoesGeracaoPorProjeto": "base"
2212
+ }
2230
2213
  `,
2231
2214
  },
2232
2215
  {
2233
2216
  caminhoRelativo: "pubspec.yaml",
2234
- conteudo: `name: sema_flutter_consumer
2235
- description: Starter Flutter consumer IA-first com Sema
2236
- publish_to: "none"
2237
-
2238
- environment:
2239
- sdk: ">=3.3.0 <4.0.0"
2240
-
2241
- dependencies:
2242
- flutter:
2243
- sdk: flutter
2244
- go_router: ^14.0.0
2217
+ conteudo: `name: sema_flutter_consumer
2218
+ description: Starter Flutter consumer IA-first com Sema
2219
+ publish_to: "none"
2220
+
2221
+ environment:
2222
+ sdk: ">=3.3.0 <4.0.0"
2223
+
2224
+ dependencies:
2225
+ flutter:
2226
+ sdk: flutter
2227
+ go_router: ^14.0.0
2245
2228
  `,
2246
2229
  },
2247
2230
  {
2248
2231
  caminhoRelativo: "contratos/showroom_consumer.sema",
2249
- conteudo: `module showroom.consumer {
2250
- task fetch_showroom_ranking {
2251
- input {
2252
- }
2253
- output {
2254
- resultado: Json
2255
- }
2256
- impl {
2257
- dart: lib.sema_consumer_bridge.semaFetchShowroomRanking
2258
- }
2259
- vinculos {
2260
- arquivo: "lib/sema_consumer_bridge.dart"
2261
- simbolo: lib.sema_consumer_bridge.semaFetchShowroomRanking
2262
- superficie: "/ranking"
2263
- arquivo: "lib/router.dart"
2264
- arquivo: "lib/screens/ranking_screen.dart"
2265
- }
2266
- guarantees {
2267
- resultado existe
2268
- }
2269
- }
2270
- }
2232
+ conteudo: `module showroom.consumer {
2233
+ task fetch_showroom_ranking {
2234
+ input {
2235
+ }
2236
+ output {
2237
+ resultado: Json
2238
+ }
2239
+ impl {
2240
+ dart: lib.sema_consumer_bridge.semaFetchShowroomRanking
2241
+ }
2242
+ vinculos {
2243
+ arquivo: "lib/sema_consumer_bridge.dart"
2244
+ simbolo: lib.sema_consumer_bridge.semaFetchShowroomRanking
2245
+ superficie: "/ranking"
2246
+ arquivo: "lib/router.dart"
2247
+ arquivo: "lib/screens/ranking_screen.dart"
2248
+ }
2249
+ guarantees {
2250
+ resultado existe
2251
+ }
2252
+ }
2253
+ }
2271
2254
  `,
2272
2255
  },
2273
2256
  {
2274
2257
  caminhoRelativo: "lib/sema_consumer_bridge.dart",
2275
- conteudo: `Future<Map<String, dynamic>> semaFetchShowroomRanking() async {
2276
- return {
2277
- "ranking": [
2278
- {"clube": "Tigres do Norte", "pontos": 33},
2279
- {"clube": "Porto Azul", "pontos": 31},
2280
- {"clube": "Galo de Ouro", "pontos": 28},
2281
- ],
2282
- };
2283
- }
2258
+ conteudo: `Future<Map<String, dynamic>> semaFetchShowroomRanking() async {
2259
+ return {
2260
+ "ranking": [
2261
+ {"clube": "Tigres do Norte", "pontos": 33},
2262
+ {"clube": "Porto Azul", "pontos": 31},
2263
+ {"clube": "Galo de Ouro", "pontos": 28},
2264
+ ],
2265
+ };
2266
+ }
2284
2267
  `,
2285
2268
  },
2286
2269
  {
2287
2270
  caminhoRelativo: "lib/router.dart",
2288
- conteudo: `import "package:go_router/go_router.dart";
2289
- import "package:flutter/widgets.dart";
2290
- import "screens/ranking_screen.dart";
2291
-
2292
- final appRouter = GoRouter(
2293
- routes: [
2294
- GoRoute(
2295
- path: "/ranking",
2296
- builder: (BuildContext context, GoRouterState state) => const RankingScreen(),
2297
- ),
2298
- ],
2299
- );
2271
+ conteudo: `import "package:go_router/go_router.dart";
2272
+ import "package:flutter/widgets.dart";
2273
+ import "screens/ranking_screen.dart";
2274
+
2275
+ final appRouter = GoRouter(
2276
+ routes: [
2277
+ GoRoute(
2278
+ path: "/ranking",
2279
+ builder: (BuildContext context, GoRouterState state) => const RankingScreen(),
2280
+ ),
2281
+ ],
2282
+ );
2300
2283
  `,
2301
2284
  },
2302
2285
  {
2303
2286
  caminhoRelativo: "lib/screens/ranking_screen.dart",
2304
- conteudo: `import "package:flutter/widgets.dart";
2305
- import "../sema_consumer_bridge.dart";
2306
-
2307
- class RankingScreen extends StatefulWidget {
2308
- const RankingScreen({super.key});
2309
-
2310
- @override
2311
- State<RankingScreen> createState() => _RankingScreenState();
2312
- }
2313
-
2314
- class _RankingScreenState extends State<RankingScreen> {
2315
- List<Map<String, dynamic>> ranking = const [];
2316
-
2317
- @override
2318
- void initState() {
2319
- super.initState();
2320
- semaFetchShowroomRanking().then((payload) {
2321
- final itens = (payload["ranking"] as List<dynamic>? ?? const [])
2322
- .whereType<Map<String, dynamic>>()
2323
- .toList();
2324
- if (!mounted) return;
2325
- setState(() {
2326
- ranking = itens;
2327
- });
2328
- });
2329
- }
2330
-
2331
- @override
2332
- Widget build(BuildContext context) {
2333
- return ListView(
2334
- children: [
2335
- const Padding(
2336
- padding: EdgeInsets.all(16),
2337
- child: Text("Ranking showroom"),
2338
- ),
2339
- ...ranking.map((item) => Padding(
2340
- padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
2341
- child: Text("\${item["clube"]} - \${item["pontos"]} pts"),
2342
- )),
2343
- ],
2344
- );
2345
- }
2346
- }
2287
+ conteudo: `import "package:flutter/widgets.dart";
2288
+ import "../sema_consumer_bridge.dart";
2289
+
2290
+ class RankingScreen extends StatefulWidget {
2291
+ const RankingScreen({super.key});
2292
+
2293
+ @override
2294
+ State<RankingScreen> createState() => _RankingScreenState();
2295
+ }
2296
+
2297
+ class _RankingScreenState extends State<RankingScreen> {
2298
+ List<Map<String, dynamic>> ranking = const [];
2299
+
2300
+ @override
2301
+ void initState() {
2302
+ super.initState();
2303
+ semaFetchShowroomRanking().then((payload) {
2304
+ final itens = (payload["ranking"] as List<dynamic>? ?? const [])
2305
+ .whereType<Map<String, dynamic>>()
2306
+ .toList();
2307
+ if (!mounted) return;
2308
+ setState(() {
2309
+ ranking = itens;
2310
+ });
2311
+ });
2312
+ }
2313
+
2314
+ @override
2315
+ Widget build(BuildContext context) {
2316
+ return ListView(
2317
+ children: [
2318
+ const Padding(
2319
+ padding: EdgeInsets.all(16),
2320
+ child: Text("Ranking showroom"),
2321
+ ),
2322
+ ...ranking.map((item) => Padding(
2323
+ padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
2324
+ child: Text("\${item["clube"]} - \${item["pontos"]} pts"),
2325
+ )),
2326
+ ],
2327
+ );
2328
+ }
2329
+ }
2347
2330
  `,
2348
2331
  },
2349
2332
  {
2350
2333
  caminhoRelativo: "lib/main.dart",
2351
- conteudo: `import "package:flutter/material.dart";
2352
- import "router.dart";
2353
-
2354
- void main() {
2355
- runApp(const ShowroomApp());
2356
- }
2357
-
2358
- class ShowroomApp extends StatelessWidget {
2359
- const ShowroomApp({super.key});
2360
-
2361
- @override
2362
- Widget build(BuildContext context) {
2363
- return MaterialApp.router(
2364
- routerConfig: appRouter,
2365
- );
2366
- }
2367
- }
2334
+ conteudo: `import "package:flutter/material.dart";
2335
+ import "router.dart";
2336
+
2337
+ void main() {
2338
+ runApp(const ShowroomApp());
2339
+ }
2340
+
2341
+ class ShowroomApp extends StatelessWidget {
2342
+ const ShowroomApp({super.key});
2343
+
2344
+ @override
2345
+ Widget build(BuildContext context) {
2346
+ return MaterialApp.router(
2347
+ routerConfig: appRouter,
2348
+ );
2349
+ }
2350
+ }
2368
2351
  `,
2369
2352
  },
2370
2353
  {
2371
2354
  caminhoRelativo: "README.md",
2372
- conteudo: `# Starter Flutter Consumer + Sema
2373
-
2374
- - Contratos em \`contratos/\`
2375
- - Bridge consumer canonico em \`lib/sema_consumer_bridge.dart\`
2376
- - Rotas consumer em \`lib/router.dart\`
2377
- - Superficies consumer em \`lib/screens/\`
2378
- - O slice oficial desta fase e \`consumer bridge + router/screen surfaces\`
2379
- - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual diff
2355
+ conteudo: `# Starter Flutter Consumer + Sema
2356
+
2357
+ - Contratos em \`contratos/\`
2358
+ - Bridge consumer canonico em \`lib/sema_consumer_bridge.dart\`
2359
+ - Rotas consumer em \`lib/router.dart\`
2360
+ - Superficies consumer em \`lib/screens/\`
2361
+ - O slice oficial desta fase e \`consumer bridge + router/screen surfaces\`
2362
+ - \`drift\` valida \`impl\`, \`vinculos\`, bridge e superficies, sem prometer visual diff
2380
2363
  `,
2381
2364
  },
2382
2365
  ];
@@ -2385,126 +2368,126 @@ class ShowroomApp extends StatelessWidget {
2385
2368
  arquivos = [
2386
2369
  {
2387
2370
  caminhoRelativo: "sema.config.json",
2388
- conteudo: `{
2389
- "origens": ["./contratos"],
2390
- "saida": "./generated",
2391
- "alvos": ["typescript"],
2392
- "alvoPadrao": "typescript",
2393
- "estruturaSaida": "modulos",
2394
- "framework": "base",
2395
- "modoEstrito": true,
2396
- "diretoriosCodigo": ["./src"],
2397
- "fontesLegado": ["firebase", "typescript"],
2398
- "diretoriosSaidaPorAlvo": {
2399
- "typescript": "./generated/typescript"
2400
- },
2401
- "convencoesGeracaoPorProjeto": "base"
2402
- }
2371
+ conteudo: `{
2372
+ "origens": ["./contratos"],
2373
+ "saida": "./generated",
2374
+ "alvos": ["typescript"],
2375
+ "alvoPadrao": "typescript",
2376
+ "estruturaSaida": "modulos",
2377
+ "framework": "base",
2378
+ "modoEstrito": true,
2379
+ "diretoriosCodigo": ["./src"],
2380
+ "fontesLegado": ["firebase", "typescript"],
2381
+ "diretoriosSaidaPorAlvo": {
2382
+ "typescript": "./generated/typescript"
2383
+ },
2384
+ "convencoesGeracaoPorProjeto": "base"
2385
+ }
2403
2386
  `,
2404
2387
  },
2405
2388
  {
2406
2389
  caminhoRelativo: "contratos/worker_runtime.sema",
2407
- conteudo: `module worker.runtime {
2408
- task publicar_payload_health {
2409
- output {
2410
- status: Texto
2411
- timestamp: Texto
2412
- }
2413
- effects {
2414
- evento payload_health criticidade = alta
2415
- }
2416
- impl {
2417
- ts: src.sema_contract_bridge.semaWorkerHealthPayload
2418
- }
2419
- guarantees {
2420
- status existe
2421
- timestamp existe
2422
- }
2423
- }
2424
-
2425
- task inventariar_colecoes {
2426
- output {
2427
- collections: Json
2428
- }
2429
- effects {
2430
- consulta runtime criticidade = baixa
2431
- }
2432
- impl {
2433
- ts: src.sema_contract_bridge.semaCollectionNames
2434
- }
2435
- guarantees {
2436
- collections existe
2437
- }
2438
- }
2439
-
2440
- route get_health_worker {
2441
- metodo: GET
2442
- caminho: /health
2443
- task: publicar_payload_health
2444
- }
2445
- }
2390
+ conteudo: `module worker.runtime {
2391
+ task publicar_payload_health {
2392
+ output {
2393
+ status: Texto
2394
+ timestamp: Texto
2395
+ }
2396
+ effects {
2397
+ evento payload_health criticidade = alta
2398
+ }
2399
+ impl {
2400
+ ts: src.sema_contract_bridge.semaWorkerHealthPayload
2401
+ }
2402
+ guarantees {
2403
+ status existe
2404
+ timestamp existe
2405
+ }
2406
+ }
2407
+
2408
+ task inventariar_colecoes {
2409
+ output {
2410
+ collections: Json
2411
+ }
2412
+ effects {
2413
+ consulta runtime criticidade = baixa
2414
+ }
2415
+ impl {
2416
+ ts: src.sema_contract_bridge.semaCollectionNames
2417
+ }
2418
+ guarantees {
2419
+ collections existe
2420
+ }
2421
+ }
2422
+
2423
+ route get_health_worker {
2424
+ metodo: GET
2425
+ caminho: /health
2426
+ task: publicar_payload_health
2427
+ }
2428
+ }
2446
2429
  `,
2447
2430
  },
2448
2431
  {
2449
2432
  caminhoRelativo: "src/config/collections.ts",
2450
- conteudo: `export const COLLECTIONS = {
2451
- worker_status: "worker_status",
2452
- audit_log: "audit_log",
2453
- } as const;
2433
+ conteudo: `export const COLLECTIONS = {
2434
+ worker_status: "worker_status",
2435
+ audit_log: "audit_log",
2436
+ } as const;
2454
2437
  `,
2455
2438
  },
2456
2439
  {
2457
2440
  caminhoRelativo: "src/services/health-check.ts",
2458
- conteudo: `import http from "node:http";
2459
-
2460
- export type HealthStatus = {
2461
- status: "healthy" | "degraded" | "unhealthy" | "initializing";
2462
- timestamp: string;
2463
- };
2464
-
2465
- export type HealthProvider = () => HealthStatus;
2466
-
2467
- export function startHealthCheckServer(port: number, provider: HealthProvider) {
2468
- const server = http.createServer((req, res) => {
2469
- if (req.url === "/health" && req.method === "GET") {
2470
- res.writeHead(200, { "Content-Type": "application/json" });
2471
- res.end(JSON.stringify(provider()));
2472
- return;
2473
- }
2474
- res.writeHead(404);
2475
- res.end();
2476
- });
2477
-
2478
- server.listen(port);
2479
- return server;
2480
- }
2441
+ conteudo: `import http from "node:http";
2442
+
2443
+ export type HealthStatus = {
2444
+ status: "healthy" | "degraded" | "unhealthy" | "initializing";
2445
+ timestamp: string;
2446
+ };
2447
+
2448
+ export type HealthProvider = () => HealthStatus;
2449
+
2450
+ export function startHealthCheckServer(port: number, provider: HealthProvider) {
2451
+ const server = http.createServer((req, res) => {
2452
+ if (req.url === "/health" && req.method === "GET") {
2453
+ res.writeHead(200, { "Content-Type": "application/json" });
2454
+ res.end(JSON.stringify(provider()));
2455
+ return;
2456
+ }
2457
+ res.writeHead(404);
2458
+ res.end();
2459
+ });
2460
+
2461
+ server.listen(port);
2462
+ return server;
2463
+ }
2481
2464
  `,
2482
2465
  },
2483
2466
  {
2484
2467
  caminhoRelativo: "src/sema_contract_bridge.ts",
2485
- conteudo: `import { COLLECTIONS } from "./config/collections";
2486
- import { startHealthCheckServer, type HealthProvider, type HealthStatus } from "./services/health-check";
2487
-
2488
- export function semaStartWorkerHealthServer(port: number, provider: HealthProvider) {
2489
- return startHealthCheckServer(port, provider);
2490
- }
2491
-
2492
- export function semaWorkerHealthPayload(payload: HealthStatus): HealthStatus {
2493
- return payload;
2494
- }
2495
-
2496
- export function semaCollectionNames() {
2497
- return COLLECTIONS;
2498
- }
2468
+ conteudo: `import { COLLECTIONS } from "./config/collections";
2469
+ import { startHealthCheckServer, type HealthProvider, type HealthStatus } from "./services/health-check";
2470
+
2471
+ export function semaStartWorkerHealthServer(port: number, provider: HealthProvider) {
2472
+ return startHealthCheckServer(port, provider);
2473
+ }
2474
+
2475
+ export function semaWorkerHealthPayload(payload: HealthStatus): HealthStatus {
2476
+ return payload;
2477
+ }
2478
+
2479
+ export function semaCollectionNames() {
2480
+ return COLLECTIONS;
2481
+ }
2499
2482
  `,
2500
2483
  },
2501
2484
  {
2502
2485
  caminhoRelativo: "README.md",
2503
- conteudo: `# Starter Node Firebase Worker + Sema
2504
-
2505
- - Contratos em \`contratos/\`
2506
- - Worker e bridges em \`src/\`
2507
- - \`drift\` valida impl, endpoint de health e recursos Firestore declarados
2486
+ conteudo: `# Starter Node Firebase Worker + Sema
2487
+
2488
+ - Contratos em \`contratos/\`
2489
+ - Worker e bridges em \`src/\`
2490
+ - \`drift\` valida impl, endpoint de health e recursos Firestore declarados
2508
2491
  `,
2509
2492
  },
2510
2493
  ];
@@ -2513,71 +2496,71 @@ export function semaCollectionNames() {
2513
2496
  arquivos = [
2514
2497
  {
2515
2498
  caminhoRelativo: "sema.config.json",
2516
- conteudo: `{
2517
- "origens": ["./contratos"],
2518
- "saida": "./generated",
2519
- "alvos": ["typescript"],
2520
- "alvoPadrao": "typescript",
2521
- "estruturaSaida": "modulos",
2522
- "framework": "base",
2523
- "modoEstrito": true,
2524
- "diretoriosCodigo": ["./src"],
2525
- "fontesLegado": ["dotnet"],
2526
- "diretoriosSaidaPorAlvo": {
2527
- "typescript": "./generated/typescript"
2528
- },
2529
- "convencoesGeracaoPorProjeto": "base"
2530
- }
2499
+ conteudo: `{
2500
+ "origens": ["./contratos"],
2501
+ "saida": "./generated",
2502
+ "alvos": ["typescript"],
2503
+ "alvoPadrao": "typescript",
2504
+ "estruturaSaida": "modulos",
2505
+ "framework": "base",
2506
+ "modoEstrito": true,
2507
+ "diretoriosCodigo": ["./src"],
2508
+ "fontesLegado": ["dotnet"],
2509
+ "diretoriosSaidaPorAlvo": {
2510
+ "typescript": "./generated/typescript"
2511
+ },
2512
+ "convencoesGeracaoPorProjeto": "base"
2513
+ }
2531
2514
  `,
2532
2515
  },
2533
2516
  {
2534
2517
  caminhoRelativo: "contratos/health.sema",
2535
- conteudo: `module app.health {
2536
- task get_health {
2537
- output {
2538
- status: Texto
2539
- runtime: Texto
2540
- }
2541
- impl {
2542
- cs: src.Controllers.HealthController.Get
2543
- }
2544
- guarantees {
2545
- status existe
2546
- runtime existe
2547
- }
2548
- }
2549
-
2550
- route get_health_publico {
2551
- metodo: GET
2552
- caminho: /api/health
2553
- task: get_health
2554
- }
2555
- }
2518
+ conteudo: `module app.health {
2519
+ task get_health {
2520
+ output {
2521
+ status: Texto
2522
+ runtime: Texto
2523
+ }
2524
+ impl {
2525
+ cs: src.Controllers.HealthController.Get
2526
+ }
2527
+ guarantees {
2528
+ status existe
2529
+ runtime existe
2530
+ }
2531
+ }
2532
+
2533
+ route get_health_publico {
2534
+ metodo: GET
2535
+ caminho: /api/health
2536
+ task: get_health
2537
+ }
2538
+ }
2556
2539
  `,
2557
2540
  },
2558
2541
  {
2559
2542
  caminhoRelativo: "src/Controllers/HealthController.cs",
2560
- conteudo: `using Microsoft.AspNetCore.Mvc;
2561
-
2562
- [ApiController]
2563
- [Route("api/health")]
2564
- public class HealthController : ControllerBase
2565
- {
2566
- [HttpGet]
2567
- public object Get()
2568
- {
2569
- return new { status = "ok", runtime = "aspnet" };
2570
- }
2571
- }
2543
+ conteudo: `using Microsoft.AspNetCore.Mvc;
2544
+
2545
+ [ApiController]
2546
+ [Route("api/health")]
2547
+ public class HealthController : ControllerBase
2548
+ {
2549
+ [HttpGet]
2550
+ public object Get()
2551
+ {
2552
+ return new { status = "ok", runtime = "aspnet" };
2553
+ }
2554
+ }
2572
2555
  `,
2573
2556
  },
2574
2557
  {
2575
2558
  caminhoRelativo: "README.md",
2576
- conteudo: `# Starter ASP.NET Core API + Sema
2577
-
2578
- - Contratos em \`contratos/\`
2579
- - Controllers/Minimal API em \`src/\`
2580
- - \`drift\` valida impl e rota publica
2559
+ conteudo: `# Starter ASP.NET Core API + Sema
2560
+
2561
+ - Contratos em \`contratos/\`
2562
+ - Controllers/Minimal API em \`src/\`
2563
+ - \`drift\` valida impl e rota publica
2581
2564
  `,
2582
2565
  },
2583
2566
  ];
@@ -2586,74 +2569,74 @@ public class HealthController : ControllerBase
2586
2569
  arquivos = [
2587
2570
  {
2588
2571
  caminhoRelativo: "sema.config.json",
2589
- conteudo: `{
2590
- "origens": ["./contratos"],
2591
- "saida": "./generated",
2592
- "alvos": ["typescript"],
2593
- "alvoPadrao": "typescript",
2594
- "estruturaSaida": "modulos",
2595
- "framework": "base",
2596
- "modoEstrito": true,
2597
- "diretoriosCodigo": ["./src"],
2598
- "fontesLegado": ["java"],
2599
- "diretoriosSaidaPorAlvo": {
2600
- "typescript": "./generated/typescript"
2601
- },
2602
- "convencoesGeracaoPorProjeto": "base"
2603
- }
2572
+ conteudo: `{
2573
+ "origens": ["./contratos"],
2574
+ "saida": "./generated",
2575
+ "alvos": ["typescript"],
2576
+ "alvoPadrao": "typescript",
2577
+ "estruturaSaida": "modulos",
2578
+ "framework": "base",
2579
+ "modoEstrito": true,
2580
+ "diretoriosCodigo": ["./src"],
2581
+ "fontesLegado": ["java"],
2582
+ "diretoriosSaidaPorAlvo": {
2583
+ "typescript": "./generated/typescript"
2584
+ },
2585
+ "convencoesGeracaoPorProjeto": "base"
2586
+ }
2604
2587
  `,
2605
2588
  },
2606
2589
  {
2607
2590
  caminhoRelativo: "contratos/health.sema",
2608
- conteudo: `module app.health {
2609
- task get_health {
2610
- output {
2611
- status: Texto
2612
- runtime: Texto
2613
- }
2614
- impl {
2615
- java: src.main.java.com.acme.health.HealthController.health
2616
- }
2617
- guarantees {
2618
- status existe
2619
- runtime existe
2620
- }
2621
- }
2622
-
2623
- route get_health_publico {
2624
- metodo: GET
2625
- caminho: /api/health
2626
- task: get_health
2627
- }
2628
- }
2591
+ conteudo: `module app.health {
2592
+ task get_health {
2593
+ output {
2594
+ status: Texto
2595
+ runtime: Texto
2596
+ }
2597
+ impl {
2598
+ java: src.main.java.com.acme.health.HealthController.health
2599
+ }
2600
+ guarantees {
2601
+ status existe
2602
+ runtime existe
2603
+ }
2604
+ }
2605
+
2606
+ route get_health_publico {
2607
+ metodo: GET
2608
+ caminho: /api/health
2609
+ task: get_health
2610
+ }
2611
+ }
2629
2612
  `,
2630
2613
  },
2631
2614
  {
2632
2615
  caminhoRelativo: "src/main/java/com/acme/health/HealthController.java",
2633
- conteudo: `package com.acme.health;
2634
-
2635
- import java.util.Map;
2636
- import org.springframework.web.bind.annotation.GetMapping;
2637
- import org.springframework.web.bind.annotation.RequestMapping;
2638
- import org.springframework.web.bind.annotation.RestController;
2639
-
2640
- @RestController
2641
- @RequestMapping("/api/health")
2642
- public class HealthController {
2643
- @GetMapping
2644
- public Map<String, String> health() {
2645
- return Map.of("status", "ok", "runtime", "spring");
2646
- }
2647
- }
2616
+ conteudo: `package com.acme.health;
2617
+
2618
+ import java.util.Map;
2619
+ import org.springframework.web.bind.annotation.GetMapping;
2620
+ import org.springframework.web.bind.annotation.RequestMapping;
2621
+ import org.springframework.web.bind.annotation.RestController;
2622
+
2623
+ @RestController
2624
+ @RequestMapping("/api/health")
2625
+ public class HealthController {
2626
+ @GetMapping
2627
+ public Map<String, String> health() {
2628
+ return Map.of("status", "ok", "runtime", "spring");
2629
+ }
2630
+ }
2648
2631
  `,
2649
2632
  },
2650
2633
  {
2651
2634
  caminhoRelativo: "README.md",
2652
- conteudo: `# Starter Spring Boot API + Sema
2653
-
2654
- - Contratos em \`contratos/\`
2655
- - Controllers REST em \`src/main/java/\`
2656
- - \`drift\` valida impl e rota publica
2635
+ conteudo: `# Starter Spring Boot API + Sema
2636
+
2637
+ - Contratos em \`contratos/\`
2638
+ - Controllers REST em \`src/main/java/\`
2639
+ - \`drift\` valida impl e rota publica
2657
2640
  `,
2658
2641
  },
2659
2642
  ];
@@ -2662,68 +2645,68 @@ public class HealthController {
2662
2645
  arquivos = [
2663
2646
  {
2664
2647
  caminhoRelativo: "sema.config.json",
2665
- conteudo: `{
2666
- "origens": ["./contratos"],
2667
- "saida": "./generated",
2668
- "alvos": ["typescript"],
2669
- "alvoPadrao": "typescript",
2670
- "estruturaSaida": "modulos",
2671
- "framework": "base",
2672
- "modoEstrito": true,
2673
- "diretoriosCodigo": ["./internal"],
2674
- "fontesLegado": ["go"],
2675
- "diretoriosSaidaPorAlvo": {
2676
- "typescript": "./generated/typescript"
2677
- },
2678
- "convencoesGeracaoPorProjeto": "base"
2679
- }
2648
+ conteudo: `{
2649
+ "origens": ["./contratos"],
2650
+ "saida": "./generated",
2651
+ "alvos": ["typescript"],
2652
+ "alvoPadrao": "typescript",
2653
+ "estruturaSaida": "modulos",
2654
+ "framework": "base",
2655
+ "modoEstrito": true,
2656
+ "diretoriosCodigo": ["./internal"],
2657
+ "fontesLegado": ["go"],
2658
+ "diretoriosSaidaPorAlvo": {
2659
+ "typescript": "./generated/typescript"
2660
+ },
2661
+ "convencoesGeracaoPorProjeto": "base"
2662
+ }
2680
2663
  `,
2681
2664
  },
2682
2665
  {
2683
2666
  caminhoRelativo: "contratos/health.sema",
2684
- conteudo: `module app.health {
2685
- task get_health {
2686
- output {
2687
- resultado: Json
2688
- }
2689
- impl {
2690
- go: internal.health.getHealth
2691
- }
2692
- guarantees {
2693
- resultado existe
2694
- }
2695
- }
2696
-
2697
- route get_health_publico {
2698
- metodo: GET
2699
- caminho: /health
2700
- task: get_health
2701
- }
2702
- }
2667
+ conteudo: `module app.health {
2668
+ task get_health {
2669
+ output {
2670
+ resultado: Json
2671
+ }
2672
+ impl {
2673
+ go: internal.health.getHealth
2674
+ }
2675
+ guarantees {
2676
+ resultado existe
2677
+ }
2678
+ }
2679
+
2680
+ route get_health_publico {
2681
+ metodo: GET
2682
+ caminho: /health
2683
+ task: get_health
2684
+ }
2685
+ }
2703
2686
  `,
2704
2687
  },
2705
2688
  {
2706
2689
  caminhoRelativo: "internal/health.go",
2707
- conteudo: `package internal
2708
-
2709
- import "github.com/gin-gonic/gin"
2710
-
2711
- func registerRoutes(router *gin.Engine) {
2712
- router.GET("/health", getHealth)
2713
- }
2714
-
2715
- func getHealth(ctx *gin.Context) {
2716
- ctx.JSON(200, gin.H{"status": "ok", "runtime": "go"})
2717
- }
2690
+ conteudo: `package internal
2691
+
2692
+ import "github.com/gin-gonic/gin"
2693
+
2694
+ func registerRoutes(router *gin.Engine) {
2695
+ router.GET("/health", getHealth)
2696
+ }
2697
+
2698
+ func getHealth(ctx *gin.Context) {
2699
+ ctx.JSON(200, gin.H{"status": "ok", "runtime": "go"})
2700
+ }
2718
2701
  `,
2719
2702
  },
2720
2703
  {
2721
2704
  caminhoRelativo: "README.md",
2722
- conteudo: `# Starter Go HTTP API + Sema
2723
-
2724
- - Contratos em \`contratos/\`
2725
- - Handlers em \`internal/\`
2726
- - \`drift\` valida impl e rota publica
2705
+ conteudo: `# Starter Go HTTP API + Sema
2706
+
2707
+ - Contratos em \`contratos/\`
2708
+ - Handlers em \`internal/\`
2709
+ - \`drift\` valida impl e rota publica
2727
2710
  `,
2728
2711
  },
2729
2712
  ];
@@ -2732,71 +2715,71 @@ func getHealth(ctx *gin.Context) {
2732
2715
  arquivos = [
2733
2716
  {
2734
2717
  caminhoRelativo: "sema.config.json",
2735
- conteudo: `{
2736
- "origens": ["./contratos"],
2737
- "saida": "./generated",
2738
- "alvos": ["typescript"],
2739
- "alvoPadrao": "typescript",
2740
- "estruturaSaida": "modulos",
2741
- "framework": "base",
2742
- "modoEstrito": true,
2743
- "diretoriosCodigo": ["./src"],
2744
- "fontesLegado": ["rust"],
2745
- "diretoriosSaidaPorAlvo": {
2746
- "typescript": "./generated/typescript"
2747
- },
2748
- "convencoesGeracaoPorProjeto": "base"
2749
- }
2718
+ conteudo: `{
2719
+ "origens": ["./contratos"],
2720
+ "saida": "./generated",
2721
+ "alvos": ["typescript"],
2722
+ "alvoPadrao": "typescript",
2723
+ "estruturaSaida": "modulos",
2724
+ "framework": "base",
2725
+ "modoEstrito": true,
2726
+ "diretoriosCodigo": ["./src"],
2727
+ "fontesLegado": ["rust"],
2728
+ "diretoriosSaidaPorAlvo": {
2729
+ "typescript": "./generated/typescript"
2730
+ },
2731
+ "convencoesGeracaoPorProjeto": "base"
2732
+ }
2750
2733
  `,
2751
2734
  },
2752
2735
  {
2753
2736
  caminhoRelativo: "contratos/health.sema",
2754
- conteudo: `module app.health {
2755
- task get_health {
2756
- output {
2757
- resultado: Json
2758
- }
2759
- impl {
2760
- rust: src.handlers.health
2761
- }
2762
- guarantees {
2763
- resultado existe
2764
- }
2765
- }
2766
-
2767
- route get_health_publico {
2768
- metodo: GET
2769
- caminho: /health
2770
- task: get_health
2771
- }
2772
- }
2737
+ conteudo: `module app.health {
2738
+ task get_health {
2739
+ output {
2740
+ resultado: Json
2741
+ }
2742
+ impl {
2743
+ rust: src.handlers.health
2744
+ }
2745
+ guarantees {
2746
+ resultado existe
2747
+ }
2748
+ }
2749
+
2750
+ route get_health_publico {
2751
+ metodo: GET
2752
+ caminho: /health
2753
+ task: get_health
2754
+ }
2755
+ }
2773
2756
  `,
2774
2757
  },
2775
2758
  {
2776
2759
  caminhoRelativo: "src/main.rs",
2777
- conteudo: `use axum::{routing::get, Router};
2778
-
2779
- mod handlers;
2780
-
2781
- fn app() -> Router {
2782
- Router::new().route("/health", get(handlers::health))
2783
- }
2760
+ conteudo: `use axum::{routing::get, Router};
2761
+
2762
+ mod handlers;
2763
+
2764
+ fn app() -> Router {
2765
+ Router::new().route("/health", get(handlers::health))
2766
+ }
2784
2767
  `,
2785
2768
  },
2786
2769
  {
2787
2770
  caminhoRelativo: "src/handlers.rs",
2788
- conteudo: `pub async fn health() -> &'static str {
2789
- "ok"
2790
- }
2771
+ conteudo: `pub async fn health() -> &'static str {
2772
+ "ok"
2773
+ }
2791
2774
  `,
2792
2775
  },
2793
2776
  {
2794
2777
  caminhoRelativo: "README.md",
2795
- conteudo: `# Starter Rust Axum API + Sema
2796
-
2797
- - Contratos em \`contratos/\`
2798
- - Handlers em \`src/\`
2799
- - \`drift\` valida impl e rota publica
2778
+ conteudo: `# Starter Rust Axum API + Sema
2779
+
2780
+ - Contratos em \`contratos/\`
2781
+ - Handlers em \`src/\`
2782
+ - \`drift\` valida impl e rota publica
2800
2783
  `,
2801
2784
  },
2802
2785
  ];
@@ -2805,60 +2788,60 @@ fn app() -> Router {
2805
2788
  arquivos = [
2806
2789
  {
2807
2790
  caminhoRelativo: "sema.config.json",
2808
- conteudo: `{
2809
- "origens": ["./contratos"],
2810
- "saida": "./generated",
2811
- "alvos": ["typescript"],
2812
- "alvoPadrao": "typescript",
2813
- "estruturaSaida": "modulos",
2814
- "framework": "base",
2815
- "modoEstrito": true,
2816
- "diretoriosCodigo": ["./src"],
2817
- "fontesLegado": ["cpp"],
2818
- "diretoriosSaidaPorAlvo": {
2819
- "typescript": "./generated/typescript"
2820
- },
2821
- "convencoesGeracaoPorProjeto": "base"
2822
- }
2791
+ conteudo: `{
2792
+ "origens": ["./contratos"],
2793
+ "saida": "./generated",
2794
+ "alvos": ["typescript"],
2795
+ "alvoPadrao": "typescript",
2796
+ "estruturaSaida": "modulos",
2797
+ "framework": "base",
2798
+ "modoEstrito": true,
2799
+ "diretoriosCodigo": ["./src"],
2800
+ "fontesLegado": ["cpp"],
2801
+ "diretoriosSaidaPorAlvo": {
2802
+ "typescript": "./generated/typescript"
2803
+ },
2804
+ "convencoesGeracaoPorProjeto": "base"
2805
+ }
2823
2806
  `,
2824
2807
  },
2825
2808
  {
2826
2809
  caminhoRelativo: "contratos/runtime_bridge.sema",
2827
- conteudo: `module app.runtime_bridge {
2828
- task processar_snapshot {
2829
- input {
2830
- payload: Json required
2831
- }
2832
- output {
2833
- resultado: Json
2834
- }
2835
- impl {
2836
- cpp: src.runtime.RuntimeBridge.processSnapshot
2837
- }
2838
- guarantees {
2839
- resultado existe
2840
- }
2841
- }
2842
- }
2810
+ conteudo: `module app.runtime_bridge {
2811
+ task processar_snapshot {
2812
+ input {
2813
+ payload: Json required
2814
+ }
2815
+ output {
2816
+ resultado: Json
2817
+ }
2818
+ impl {
2819
+ cpp: src.runtime.RuntimeBridge.processSnapshot
2820
+ }
2821
+ guarantees {
2822
+ resultado existe
2823
+ }
2824
+ }
2825
+ }
2843
2826
  `,
2844
2827
  },
2845
2828
  {
2846
2829
  caminhoRelativo: "src/runtime.cpp",
2847
- conteudo: `class RuntimeBridge {
2848
- public:
2849
- int processSnapshot(int payload) {
2850
- return payload;
2851
- }
2852
- };
2830
+ conteudo: `class RuntimeBridge {
2831
+ public:
2832
+ int processSnapshot(int payload) {
2833
+ return payload;
2834
+ }
2835
+ };
2853
2836
  `,
2854
2837
  },
2855
2838
  {
2856
2839
  caminhoRelativo: "README.md",
2857
- conteudo: `# Starter C++ Service Bridge + Sema
2858
-
2859
- - Contratos em \`contratos/\`
2860
- - Symbols e bridges em \`src/\`
2861
- - \`drift\` valida impl de simbolos, sem prometer rota HTTP
2840
+ conteudo: `# Starter C++ Service Bridge + Sema
2841
+
2842
+ - Contratos em \`contratos/\`
2843
+ - Symbols e bridges em \`src/\`
2844
+ - \`drift\` valida impl de simbolos, sem prometer rota HTTP
2862
2845
  `,
2863
2846
  },
2864
2847
  ];
@@ -2867,21 +2850,21 @@ public:
2867
2850
  arquivos = [
2868
2851
  {
2869
2852
  caminhoRelativo: "sema.config.json",
2870
- conteudo: `{
2871
- "origens": ["./contratos"],
2872
- "saida": "./generated",
2873
- "alvos": ["typescript", "python", "dart"],
2874
- "alvoPadrao": "typescript",
2875
- "estruturaSaida": "modulos",
2876
- "framework": "base",
2877
- "modoEstrito": true,
2878
- "diretoriosSaidaPorAlvo": {
2879
- "typescript": "./generated/typescript",
2880
- "python": "./generated/python",
2881
- "dart": "./generated/dart"
2882
- },
2883
- "convencoesGeracaoPorProjeto": "base"
2884
- }
2853
+ conteudo: `{
2854
+ "origens": ["./contratos"],
2855
+ "saida": "./generated",
2856
+ "alvos": ["typescript", "python", "dart"],
2857
+ "alvoPadrao": "typescript",
2858
+ "estruturaSaida": "modulos",
2859
+ "framework": "base",
2860
+ "modoEstrito": true,
2861
+ "diretoriosSaidaPorAlvo": {
2862
+ "typescript": "./generated/typescript",
2863
+ "python": "./generated/python",
2864
+ "dart": "./generated/dart"
2865
+ },
2866
+ "convencoesGeracaoPorProjeto": "base"
2867
+ }
2885
2868
  `,
2886
2869
  },
2887
2870
  ...arquivosBase,
@@ -3498,21 +3481,21 @@ async function comandoPromptCurto(entrada, args, emJson) {
3498
3481
  : "SEMA_BRIEF.md";
3499
3482
  const contextoProjeto = await readFile(path.join(resumoProjeto.pastaSaida, arquivoResumo), "utf8");
3500
3483
  const capacidade = tamanho === "micro" ? "pequena" : tamanho === "curto" ? "media" : "grande";
3501
- const prompt = `Voce esta operando Sema em modo IA-first.
3502
-
3503
- Isto nao e material feito para humano; e contexto comprimido para IA.
3504
-
3505
- Capacidade alvo: ${capacidade}
3506
- Modo da tarefa: ${modo}
3507
-
3508
- Regras:
3509
- - comece pelo resumo compacto abaixo
3510
- - se a tarefa pedir mais contexto, abra \`SEMA_INDEX.json\`
3511
- - nao tente ler o repo inteiro se o resumo ja disser onde tocar
3512
- - preserve contrato, risco, lacuna e checks sugeridos
3513
-
3514
- Contexto do projeto:
3515
- ${contextoProjeto.trim()}
3484
+ const prompt = `Voce esta operando Sema em modo IA-first.
3485
+
3486
+ Isto nao e material feito para humano; e contexto comprimido para IA.
3487
+
3488
+ Capacidade alvo: ${capacidade}
3489
+ Modo da tarefa: ${modo}
3490
+
3491
+ Regras:
3492
+ - comece pelo resumo compacto abaixo
3493
+ - se a tarefa pedir mais contexto, abra \`SEMA_INDEX.json\`
3494
+ - nao tente ler o repo inteiro se o resumo ja disser onde tocar
3495
+ - preserve contrato, risco, lacuna e checks sugeridos
3496
+
3497
+ Contexto do projeto:
3498
+ ${contextoProjeto.trim()}
3516
3499
  `;
3517
3500
  if (emJson) {
3518
3501
  console.log(JSON.stringify({
@@ -3561,16 +3544,7 @@ async function comandoTestar(arquivo, alvo, saida, estrutura, framework) {
3561
3544
  console.log(`Scaffold ${framework} gerado em ${saida}. A execucao automatica de testes continua focada no framework base da Sema.`);
3562
3545
  return 0;
3563
3546
  }
3564
- const execucao = executarTestesGerados(alvo, saida, arquivos);
3565
- if (execucao.codigoSaida !== 0) {
3566
- if (execucao.saidaPadrao) {
3567
- console.log(execucao.saidaPadrao);
3568
- }
3569
- if (execucao.saidaErro) {
3570
- console.error(execucao.saidaErro);
3571
- }
3572
- }
3573
- return execucao.codigoSaida;
3547
+ return executarTestesGerados(alvo, saida, arquivos).codigoSaida;
3574
3548
  }
3575
3549
  function imprimirResumoVerificacao(resumos) {
3576
3550
  console.log("\nResumo da verificacao:");
@@ -3770,7 +3744,7 @@ async function principal() {
3770
3744
  {
3771
3745
  const fonte = normalizarFonteImportacao(posicionais[0]);
3772
3746
  if (!fonte || !posicionais[1]) {
3773
- 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|lua> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]");
3747
+ 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]");
3774
3748
  codigoSaida = 1;
3775
3749
  break;
3776
3750
  }