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