@semacode/cli 0.9.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +50 -0
- package/README.md +24 -3
- package/SEMA_BRIEF.curto.txt +9 -0
- package/SEMA_BRIEF.md +49 -0
- package/SEMA_BRIEF.micro.txt +7 -0
- package/SEMA_INDEX.json +501 -0
- package/dist/drift.d.ts +15 -0
- package/dist/drift.js +496 -5
- package/dist/drift.js.map +1 -1
- package/dist/importador.d.ts +1 -1
- package/dist/importador.js +681 -3
- package/dist/importador.js.map +1 -1
- package/dist/index.js +1578 -123
- package/dist/index.js.map +1 -1
- package/dist/projeto.js +49 -1
- package/dist/projeto.js.map +1 -1
- package/dist/tipos.d.ts +1 -1
- package/docs/AGENT_STARTER.md +40 -8
- package/docs/como-ensinar-a-sema-para-ia.md +17 -11
- package/docs/fluxo-pratico-ia-sema.md +42 -38
- package/docs/instalacao-e-primeiro-uso.md +196 -0
- package/docs/integracao-com-ia.md +228 -0
- package/docs/pagamento-ponta-a-ponta.md +155 -0
- package/docs/prompt-base-ia-sema.md +10 -3
- package/docs/sintaxe.md +267 -0
- package/exemplos/automacao.sema +107 -0
- package/exemplos/cadastro_usuario.sema +54 -0
- package/exemplos/calculadora.sema +78 -0
- package/exemplos/crud_simples.sema +89 -0
- package/exemplos/operacao_estrategia.sema +402 -0
- package/exemplos/pagamento.sema +222 -0
- package/exemplos/pagamento_dominio.sema +35 -0
- package/exemplos/testes_embutidos.sema +45 -0
- package/exemplos/tratamento_erro.sema +157 -0
- package/llms-full.txt +34 -0
- package/llms.txt +17 -0
- package/node_modules/@sema/gerador-dart/package.json +1 -1
- package/node_modules/@sema/gerador-python/dist/index.js +92 -10
- package/node_modules/@sema/gerador-python/dist/index.js.map +1 -1
- package/node_modules/@sema/gerador-python/package.json +1 -1
- package/node_modules/@sema/gerador-typescript/package.json +1 -1
- package/node_modules/@sema/nucleo/package.json +1 -1
- package/node_modules/@sema/padroes/dist/index.js +47 -1
- package/node_modules/@sema/padroes/dist/index.js.map +1 -1
- package/node_modules/@sema/padroes/package.json +1 -1
- package/package.json +15 -7
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
module exemplos.pagamento {
|
|
2
|
+
docs {
|
|
3
|
+
resumo: "Vertical oficial de pagamento da Sema 0.5,usado como referencia de utilidade real controlada."
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
use exemplos.pagamento.dominio
|
|
7
|
+
|
|
8
|
+
task processar_pagamento {
|
|
9
|
+
input {
|
|
10
|
+
pagamento_id: Id required
|
|
11
|
+
valor: Decimal required
|
|
12
|
+
token: Texto required
|
|
13
|
+
}
|
|
14
|
+
output {
|
|
15
|
+
pagamento: Pagamento
|
|
16
|
+
status: StatusPagamento
|
|
17
|
+
}
|
|
18
|
+
rules {
|
|
19
|
+
valor > 0
|
|
20
|
+
token existe
|
|
21
|
+
token deve_ser valido
|
|
22
|
+
}
|
|
23
|
+
effects {
|
|
24
|
+
consulta gateway_pagamento criticidade = alta
|
|
25
|
+
persistencia Pagamento criticidade = alta
|
|
26
|
+
evento pagamento_autorizado criticidade = media
|
|
27
|
+
notificacao cliente comprovante_pagamento criticidade = media
|
|
28
|
+
auditoria pagamento criticidade = alta
|
|
29
|
+
}
|
|
30
|
+
state ciclo_pagamento {
|
|
31
|
+
transitions {
|
|
32
|
+
PENDENTE -> AUTORIZADO
|
|
33
|
+
AUTORIZADO -> PROCESSADO
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
guarantees {
|
|
37
|
+
pagamento existe
|
|
38
|
+
status em [AUTORIZADO, PROCESSADO]
|
|
39
|
+
pagamento.status == status
|
|
40
|
+
}
|
|
41
|
+
error {
|
|
42
|
+
autorizacao_negada: "A operacao foi recusada pelo gateway."
|
|
43
|
+
saldo_insuficiente: "O saldo nao cobre o valor da cobranca."
|
|
44
|
+
timeout_gateway: "O gateway nao respondeu em tempo habil."
|
|
45
|
+
}
|
|
46
|
+
tests {
|
|
47
|
+
caso "pagamento autorizado" {
|
|
48
|
+
given {
|
|
49
|
+
pagamento_id: "pag_1"
|
|
50
|
+
valor: 199.9
|
|
51
|
+
token: "tok_ok"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
expect {
|
|
55
|
+
sucesso: verdadeiro
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
caso "pagamento recusado por autorizacao" {
|
|
59
|
+
given {
|
|
60
|
+
pagamento_id: "pag_erro"
|
|
61
|
+
valor: 10
|
|
62
|
+
token: "tok_recusado"
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
expect {
|
|
66
|
+
sucesso: falso
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
error {
|
|
70
|
+
tipo: "autorizacao_negada"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
caso "pagamento falha por timeout" {
|
|
74
|
+
given {
|
|
75
|
+
pagamento_id: "pag_timeout"
|
|
76
|
+
valor: 10
|
|
77
|
+
token: "tok_timeout"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
expect {
|
|
81
|
+
sucesso: falso
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
error {
|
|
85
|
+
tipo: "timeout_gateway"
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
task confirmar_pagamento {
|
|
92
|
+
input {
|
|
93
|
+
pagamento_id: Id required
|
|
94
|
+
}
|
|
95
|
+
output {
|
|
96
|
+
status: StatusPagamento
|
|
97
|
+
}
|
|
98
|
+
rules {
|
|
99
|
+
pagamento_id existe
|
|
100
|
+
}
|
|
101
|
+
effects {
|
|
102
|
+
consulta gateway_pagamento criticidade = alta
|
|
103
|
+
persistencia Pagamento criticidade = alta
|
|
104
|
+
evento pagamento_confirmado criticidade = media
|
|
105
|
+
auditoria conciliacao_pagamento criticidade = alta
|
|
106
|
+
}
|
|
107
|
+
state ciclo_pagamento {
|
|
108
|
+
transitions {
|
|
109
|
+
AUTORIZADO -> PROCESSADO
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
guarantees {
|
|
113
|
+
status == PROCESSADO
|
|
114
|
+
}
|
|
115
|
+
tests {
|
|
116
|
+
caso "confirma pagamento autorizado" {
|
|
117
|
+
given {
|
|
118
|
+
pagamento_id: "pag_1"
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
expect {
|
|
122
|
+
sucesso: verdadeiro
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
task notificar_falha_pagamento {
|
|
129
|
+
input {
|
|
130
|
+
pagamento_id: Id required
|
|
131
|
+
motivo: Texto required
|
|
132
|
+
}
|
|
133
|
+
output {
|
|
134
|
+
protocolo_notificacao: Id
|
|
135
|
+
}
|
|
136
|
+
effects {
|
|
137
|
+
notificacao cliente falha_pagamento criticidade = alta
|
|
138
|
+
auditoria falha_pagamento criticidade = media
|
|
139
|
+
}
|
|
140
|
+
guarantees {
|
|
141
|
+
protocolo_notificacao existe
|
|
142
|
+
}
|
|
143
|
+
tests {
|
|
144
|
+
caso "notifica falha por recusa" {
|
|
145
|
+
given {
|
|
146
|
+
pagamento_id: "pag_erro"
|
|
147
|
+
motivo: "autorizacao_negada"
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
expect {
|
|
151
|
+
sucesso: verdadeiro
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
task registrar_timeout_pagamento {
|
|
158
|
+
input {
|
|
159
|
+
pagamento_id: Id required
|
|
160
|
+
}
|
|
161
|
+
output {
|
|
162
|
+
auditoria_id: Id
|
|
163
|
+
}
|
|
164
|
+
effects {
|
|
165
|
+
auditoria timeout_gateway criticidade = alta
|
|
166
|
+
persistencia incidente_pagamento criticidade = media
|
|
167
|
+
}
|
|
168
|
+
guarantees {
|
|
169
|
+
auditoria_id existe
|
|
170
|
+
}
|
|
171
|
+
tests {
|
|
172
|
+
caso "registra timeout" {
|
|
173
|
+
given {
|
|
174
|
+
pagamento_id: "pag_timeout"
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
expect {
|
|
178
|
+
sucesso: verdadeiro
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
flow orquestracao_pagamento {
|
|
185
|
+
pagamento_id: Id
|
|
186
|
+
valor: Decimal
|
|
187
|
+
token: Texto
|
|
188
|
+
etapa autorizar usa processar_pagamento com pagamento_id = pagamento_id, valor = valor, token = token em_sucesso confirmar em_erro registrar_falha por_erro autorizacao_negada = notificar_falha, timeout_gateway = registrar_timeout
|
|
189
|
+
etapa confirmar usa confirmar_pagamento com pagamento_id = pagamento_id depende_de autorizar
|
|
190
|
+
etapa notificar_falha usa notificar_falha_pagamento com pagamento_id = pagamento_id, motivo = autorizacao_negada depende_de autorizar
|
|
191
|
+
etapa registrar_timeout usa registrar_timeout_pagamento com pagamento_id = pagamento_id depende_de autorizar
|
|
192
|
+
etapa registrar_falha usa registrar_timeout_pagamento com pagamento_id = pagamento_id depende_de autorizar
|
|
193
|
+
effects {
|
|
194
|
+
auditoria fluxo_pagamento criticidade = alta
|
|
195
|
+
evento pagamento_em_processamento criticidade = media
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
route processar_pagamento_publico {
|
|
200
|
+
metodo: POST
|
|
201
|
+
caminho: /pagamentos/processar
|
|
202
|
+
task: processar_pagamento
|
|
203
|
+
input {
|
|
204
|
+
pagamento_id: Id required
|
|
205
|
+
valor: Decimal required
|
|
206
|
+
token: Texto required
|
|
207
|
+
}
|
|
208
|
+
output {
|
|
209
|
+
pagamento: Pagamento required
|
|
210
|
+
status: StatusPagamento required
|
|
211
|
+
}
|
|
212
|
+
effects {
|
|
213
|
+
auditoria pagamento_publico criticidade = alta
|
|
214
|
+
evento pagamento_requisitado criticidade = media
|
|
215
|
+
}
|
|
216
|
+
error {
|
|
217
|
+
autorizacao_negada: "Erro publico quando o gateway recusa a operacao."
|
|
218
|
+
saldo_insuficiente: "Erro publico quando nao ha saldo suficiente."
|
|
219
|
+
timeout_gateway: "Erro publico quando o gateway nao responde."
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module exemplos.pagamento.dominio {
|
|
2
|
+
docs {
|
|
3
|
+
resumo: "Contratos de dominio compartilhados pelo vertical oficial de pagamento da Sema 0.5."
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
entity Pagamento {
|
|
7
|
+
fields {
|
|
8
|
+
id: Id
|
|
9
|
+
valor: Decimal
|
|
10
|
+
status: StatusPagamento
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
enum StatusPagamento {
|
|
15
|
+
PENDENTE,
|
|
16
|
+
AUTORIZADO,
|
|
17
|
+
RECUSADO,
|
|
18
|
+
PROCESSADO
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
state ciclo_pagamento {
|
|
22
|
+
fields {
|
|
23
|
+
status: StatusPagamento
|
|
24
|
+
conciliado: Booleano
|
|
25
|
+
}
|
|
26
|
+
invariants {
|
|
27
|
+
status existe
|
|
28
|
+
}
|
|
29
|
+
transitions {
|
|
30
|
+
PENDENTE -> AUTORIZADO
|
|
31
|
+
AUTORIZADO -> PROCESSADO
|
|
32
|
+
PENDENTE -> RECUSADO
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module exemplos.testes.embutidos {
|
|
2
|
+
task validar_documento {
|
|
3
|
+
input {
|
|
4
|
+
documento: Texto required
|
|
5
|
+
}
|
|
6
|
+
output {
|
|
7
|
+
valido: Booleano
|
|
8
|
+
motivo: Texto
|
|
9
|
+
}
|
|
10
|
+
rules {
|
|
11
|
+
documento deve_ser preenchido
|
|
12
|
+
}
|
|
13
|
+
effects {
|
|
14
|
+
auditoria validacao_documento
|
|
15
|
+
}
|
|
16
|
+
guarantees {
|
|
17
|
+
valido existe
|
|
18
|
+
motivo existe
|
|
19
|
+
}
|
|
20
|
+
tests {
|
|
21
|
+
caso "documento valido" {
|
|
22
|
+
given {
|
|
23
|
+
documento: 12345678900
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
expect {
|
|
27
|
+
sucesso: verdadeiro
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
caso "documento vazio" {
|
|
31
|
+
given {
|
|
32
|
+
documento: ""
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
expect {
|
|
36
|
+
sucesso: falso
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
error {
|
|
40
|
+
tipo: "entrada_invalida"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
module exemplos.tratamento.erro {
|
|
2
|
+
task executar_operacao_sensivel {
|
|
3
|
+
input {
|
|
4
|
+
chave: Texto required
|
|
5
|
+
}
|
|
6
|
+
output {
|
|
7
|
+
protocolo: Id
|
|
8
|
+
}
|
|
9
|
+
rules {
|
|
10
|
+
chave existe e chave deve_ser preenchida
|
|
11
|
+
}
|
|
12
|
+
effects {
|
|
13
|
+
consulta cofre
|
|
14
|
+
auditoria falha_operacao_sensivel
|
|
15
|
+
}
|
|
16
|
+
guarantees {
|
|
17
|
+
protocolo existe
|
|
18
|
+
}
|
|
19
|
+
error {
|
|
20
|
+
acesso_negado: "A chave informada nao tem permissao."
|
|
21
|
+
recurso_indisponivel: "O servico esta temporariamente indisponivel."
|
|
22
|
+
auditoria_obrigatoria: "Toda falha precisa ser registrada."
|
|
23
|
+
}
|
|
24
|
+
tests {
|
|
25
|
+
caso "falha por acesso negado" {
|
|
26
|
+
given {
|
|
27
|
+
chave: "sem_permissao"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
expect {
|
|
31
|
+
sucesso: falso
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
error {
|
|
35
|
+
tipo: "acesso_negado"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
task responder_acesso_negado {
|
|
42
|
+
input {
|
|
43
|
+
chave: Texto required
|
|
44
|
+
}
|
|
45
|
+
output {
|
|
46
|
+
protocolo_resposta: Id
|
|
47
|
+
}
|
|
48
|
+
effects {
|
|
49
|
+
notificacao cliente acesso_negado
|
|
50
|
+
auditoria acesso_negado
|
|
51
|
+
}
|
|
52
|
+
guarantees {
|
|
53
|
+
protocolo_resposta existe
|
|
54
|
+
}
|
|
55
|
+
tests {
|
|
56
|
+
caso "responde acesso negado" {
|
|
57
|
+
given {
|
|
58
|
+
chave: "sem_permissao"
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
expect {
|
|
62
|
+
sucesso: verdadeiro
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
task responder_retentativa {
|
|
69
|
+
input {
|
|
70
|
+
chave: Texto required
|
|
71
|
+
}
|
|
72
|
+
output {
|
|
73
|
+
protocolo_resposta: Id
|
|
74
|
+
}
|
|
75
|
+
effects {
|
|
76
|
+
notificacao cliente retentativa_programada
|
|
77
|
+
auditoria retentativa
|
|
78
|
+
}
|
|
79
|
+
guarantees {
|
|
80
|
+
protocolo_resposta existe
|
|
81
|
+
}
|
|
82
|
+
tests {
|
|
83
|
+
caso "agenda retentativa" {
|
|
84
|
+
given {
|
|
85
|
+
chave: "instavel"
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
expect {
|
|
89
|
+
sucesso: verdadeiro
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
task registrar_auditoria_falha {
|
|
96
|
+
input {
|
|
97
|
+
chave: Texto required
|
|
98
|
+
}
|
|
99
|
+
output {
|
|
100
|
+
auditoria_id: Id
|
|
101
|
+
}
|
|
102
|
+
effects {
|
|
103
|
+
auditoria falha_operacional
|
|
104
|
+
persistencia auditoria_falha
|
|
105
|
+
}
|
|
106
|
+
guarantees {
|
|
107
|
+
auditoria_id existe
|
|
108
|
+
}
|
|
109
|
+
tests {
|
|
110
|
+
caso "audita falha" {
|
|
111
|
+
given {
|
|
112
|
+
chave: "sem_permissao"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
expect {
|
|
116
|
+
sucesso: verdadeiro
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
task registrar_sucesso {
|
|
123
|
+
input {
|
|
124
|
+
protocolo: Id required
|
|
125
|
+
}
|
|
126
|
+
output {
|
|
127
|
+
registro_id: Id
|
|
128
|
+
}
|
|
129
|
+
effects {
|
|
130
|
+
auditoria operacao_concluida
|
|
131
|
+
evento operacao_sensivel_concluida
|
|
132
|
+
}
|
|
133
|
+
guarantees {
|
|
134
|
+
registro_id existe
|
|
135
|
+
}
|
|
136
|
+
tests {
|
|
137
|
+
caso "registra sucesso" {
|
|
138
|
+
given {
|
|
139
|
+
protocolo: "prot_1"
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
expect {
|
|
143
|
+
sucesso: verdadeiro
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
flow resposta_segura {
|
|
150
|
+
chave: Texto
|
|
151
|
+
etapa tentar usa executar_operacao_sensivel com chave = chave em_sucesso concluir em_erro registrar_falha por_erro acesso_negado = tratar_acesso_negado, recurso_indisponivel = agendar_retentativa
|
|
152
|
+
etapa tratar_acesso_negado usa responder_acesso_negado com chave = chave depende_de tentar
|
|
153
|
+
etapa agendar_retentativa usa responder_retentativa com chave = chave depende_de tentar
|
|
154
|
+
etapa registrar_falha usa registrar_auditoria_falha com chave = chave depende_de tentar
|
|
155
|
+
etapa concluir usa registrar_sucesso com protocolo = tentar.protocolo depende_de tentar
|
|
156
|
+
}
|
|
157
|
+
}
|
package/llms-full.txt
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
Sema is an AI-first semantic language and tooling stack for explicit software intent, drift analysis, and safer intervention in live backend systems.
|
|
2
|
+
|
|
3
|
+
This repository is not optimized for human-first reading. It is optimized for AI agents that need compressed, canonical semantic context.
|
|
4
|
+
|
|
5
|
+
Canonical entrypoints in the repository root:
|
|
6
|
+
1. `llms.txt`
|
|
7
|
+
2. `SEMA_BRIEF.md`
|
|
8
|
+
3. `SEMA_INDEX.json`
|
|
9
|
+
4. `AGENTS.md`
|
|
10
|
+
5. `README.md`
|
|
11
|
+
6. `docs/AGENT_STARTER.md`
|
|
12
|
+
|
|
13
|
+
Capacity routing:
|
|
14
|
+
- small/free AI: `llms.txt` -> `SEMA_BRIEF.micro.txt` -> `SEMA_INDEX.json` -> `AGENTS.md`
|
|
15
|
+
- medium AI: `llms.txt` -> `SEMA_BRIEF.curto.txt` -> `SEMA_INDEX.json` -> `AGENTS.md` -> `README.md`
|
|
16
|
+
- large/tool-using AI: `llms-full.txt` -> `SEMA_BRIEF.md` -> `SEMA_INDEX.json` -> `AGENTS.md` -> `README.md`
|
|
17
|
+
|
|
18
|
+
Source-of-truth order:
|
|
19
|
+
1. root Sema artifacts
|
|
20
|
+
2. CLI JSON outputs
|
|
21
|
+
3. official docs
|
|
22
|
+
4. official examples
|
|
23
|
+
5. raw implementation code
|
|
24
|
+
|
|
25
|
+
Useful commands:
|
|
26
|
+
- `sema resumo <arquivo-ou-pasta> --micro --para mudanca`
|
|
27
|
+
- `sema prompt-curto <arquivo-ou-pasta> --curto --para review`
|
|
28
|
+
- `sema drift <arquivo-ou-pasta> --json`
|
|
29
|
+
- `sema contexto-ia <arquivo.sema> --saida ./.tmp/contexto --json`
|
|
30
|
+
- `sema validar <arquivo-ou-pasta> --json`
|
|
31
|
+
- `sema verificar <arquivo-ou-pasta> --json`
|
|
32
|
+
|
|
33
|
+
Do not ask the model to infer semantics that are already available in Sema artifacts.
|
|
34
|
+
Do not start from raw source code if `SEMA_BRIEF`, `SEMA_INDEX`, `drift`, or `briefing` are available.
|
package/llms.txt
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Sema is an AI-first semantic language and tooling stack for backend intent.
|
|
2
|
+
|
|
3
|
+
This repository is not human-first. Use the canonical AI entrypoints before raw code.
|
|
4
|
+
|
|
5
|
+
Read in this order:
|
|
6
|
+
1. SEMA_BRIEF.micro.txt or SEMA_BRIEF.md
|
|
7
|
+
2. SEMA_INDEX.json
|
|
8
|
+
3. AGENTS.md
|
|
9
|
+
4. README.md
|
|
10
|
+
|
|
11
|
+
Capacity routing:
|
|
12
|
+
- small models: llms.txt -> SEMA_BRIEF.micro.txt -> SEMA_INDEX.json
|
|
13
|
+
- medium models: llms.txt -> SEMA_BRIEF.curto.txt -> SEMA_INDEX.json -> README.md
|
|
14
|
+
- large models: llms-full.txt -> SEMA_BRIEF.md -> SEMA_INDEX.json -> README.md
|
|
15
|
+
|
|
16
|
+
Prefer Sema artifacts over raw source code when both exist.
|
|
17
|
+
Prefer `drift`, `briefing`, `ir`, and `diagnosticos` over guesswork.
|
|
@@ -1,15 +1,84 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
2
|
import { descreverEstruturaModulo, mapearTipoParaPython, normalizarNomeModulo, normalizarNomeParaSimbolo, } from "@sema/padroes";
|
|
3
3
|
const TIPOS_PRIMITIVOS_SEMA = new Set(["Texto", "Numero", "Inteiro", "Decimal", "Booleano", "Data", "DataHora", "Id", "Email", "Url", "Json", "Vazio"]);
|
|
4
|
+
function dividirTipoNoNivelRaiz(valor, separador) {
|
|
5
|
+
const partes = [];
|
|
6
|
+
let atual = "";
|
|
7
|
+
let profundidade = 0;
|
|
8
|
+
for (const caractere of valor) {
|
|
9
|
+
if (caractere === "<") {
|
|
10
|
+
profundidade += 1;
|
|
11
|
+
atual += caractere;
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
if (caractere === ">") {
|
|
15
|
+
profundidade = Math.max(0, profundidade - 1);
|
|
16
|
+
atual += caractere;
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (caractere === separador && profundidade === 0) {
|
|
20
|
+
if (atual.trim()) {
|
|
21
|
+
partes.push(atual.trim());
|
|
22
|
+
}
|
|
23
|
+
atual = "";
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
atual += caractere;
|
|
27
|
+
}
|
|
28
|
+
if (atual.trim()) {
|
|
29
|
+
partes.push(atual.trim());
|
|
30
|
+
}
|
|
31
|
+
return partes;
|
|
32
|
+
}
|
|
33
|
+
function coletarFolhasTipoPython(tipo) {
|
|
34
|
+
const limpo = tipo.trim();
|
|
35
|
+
if (!limpo) {
|
|
36
|
+
return [];
|
|
37
|
+
}
|
|
38
|
+
if (/^Opcional<.+>$/.test(limpo)) {
|
|
39
|
+
return coletarFolhasTipoPython(limpo.slice("Opcional<".length, -1));
|
|
40
|
+
}
|
|
41
|
+
const uniao = dividirTipoNoNivelRaiz(limpo, "|");
|
|
42
|
+
if (uniao.length > 1) {
|
|
43
|
+
return uniao.flatMap((item) => coletarFolhasTipoPython(item));
|
|
44
|
+
}
|
|
45
|
+
if (/^Lista<.+>$/.test(limpo)) {
|
|
46
|
+
return coletarFolhasTipoPython(limpo.slice("Lista<".length, -1));
|
|
47
|
+
}
|
|
48
|
+
if (/^Mapa<.+>$/.test(limpo)) {
|
|
49
|
+
return dividirTipoNoNivelRaiz(limpo.slice("Mapa<".length, -1), ",")
|
|
50
|
+
.flatMap((item) => coletarFolhasTipoPython(item));
|
|
51
|
+
}
|
|
52
|
+
return [limpo];
|
|
53
|
+
}
|
|
54
|
+
function mapearCampoParaPython(campo) {
|
|
55
|
+
let anotacao;
|
|
56
|
+
if (campo.cardinalidade === "lista") {
|
|
57
|
+
anotacao = `list[${mapearTipoParaPython(campo.tipoItem ?? campo.tipoBase)}]`;
|
|
58
|
+
}
|
|
59
|
+
else if (campo.cardinalidade === "mapa") {
|
|
60
|
+
anotacao = `dict[${mapearTipoParaPython(campo.chaveMapa ?? "Texto")}, ${mapearTipoParaPython(campo.valorMapa ?? "Json")}]`;
|
|
61
|
+
}
|
|
62
|
+
else if (campo.cardinalidade === "uniao") {
|
|
63
|
+
anotacao = campo.tiposAlternativos.map((tipo) => mapearTipoParaPython(tipo)).join(" | ");
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
anotacao = mapearTipoParaPython(campo.tipoBase);
|
|
67
|
+
}
|
|
68
|
+
if (campo.opcional && !/\bNone\b/.test(anotacao)) {
|
|
69
|
+
return `${anotacao} | None`;
|
|
70
|
+
}
|
|
71
|
+
return anotacao;
|
|
72
|
+
}
|
|
4
73
|
function gerarDataclass(nome, campos) {
|
|
5
74
|
const linhas = campos.length === 0
|
|
6
75
|
? " pass"
|
|
7
76
|
: campos.map((campo) => {
|
|
8
|
-
const tipoBase =
|
|
77
|
+
const tipoBase = mapearCampoParaPython(campo);
|
|
9
78
|
if (campo.modificadores.includes("required")) {
|
|
10
79
|
return ` ${campo.nome}: ${tipoBase}`;
|
|
11
80
|
}
|
|
12
|
-
return ` ${campo.nome}: ${tipoBase} | None = None`;
|
|
81
|
+
return ` ${campo.nome}: ${/\bNone\b/.test(tipoBase) ? tipoBase : `${tipoBase} | None`} = None`;
|
|
13
82
|
}).join("\n");
|
|
14
83
|
return `@dataclass\nclass ${nome}:\n${linhas}\n`;
|
|
15
84
|
}
|
|
@@ -39,8 +108,10 @@ function coletarTiposExternos(modulo) {
|
|
|
39
108
|
...modulo.states.flatMap((state) => state.campos),
|
|
40
109
|
];
|
|
41
110
|
for (const campo of campos) {
|
|
42
|
-
|
|
43
|
-
|
|
111
|
+
for (const tipo of coletarFolhasTipoPython(campo.tipo)) {
|
|
112
|
+
if (!TIPOS_PRIMITIVOS_SEMA.has(tipo) && !locais.has(tipo)) {
|
|
113
|
+
referenciados.add(tipo);
|
|
114
|
+
}
|
|
44
115
|
}
|
|
45
116
|
}
|
|
46
117
|
return [...referenciados].sort((a, b) => a.localeCompare(b, "pt-BR"));
|
|
@@ -87,7 +158,18 @@ function resolverExpressaoPython(expressao, camposConhecidos, variavel) {
|
|
|
87
158
|
return `(not ${resolverExpressaoPython(expressao.termo, camposConhecidos, variavel)})`;
|
|
88
159
|
}
|
|
89
160
|
}
|
|
90
|
-
function valorPadraoPython(
|
|
161
|
+
function valorPadraoPython(campo) {
|
|
162
|
+
const tipo = campo.tipoBase;
|
|
163
|
+
const nomeCampo = campo.nome;
|
|
164
|
+
if (campo.cardinalidade === "lista") {
|
|
165
|
+
return "[]";
|
|
166
|
+
}
|
|
167
|
+
if (campo.cardinalidade === "mapa") {
|
|
168
|
+
return "{}";
|
|
169
|
+
}
|
|
170
|
+
if (campo.opcional) {
|
|
171
|
+
return "None";
|
|
172
|
+
}
|
|
91
173
|
switch (tipo) {
|
|
92
174
|
case "Texto":
|
|
93
175
|
case "Id":
|
|
@@ -175,7 +257,7 @@ function paraPascalCase(valor) {
|
|
|
175
257
|
}
|
|
176
258
|
function gerarPreparacaoSaida(task) {
|
|
177
259
|
const camposSaida = new Set(task.output.map((campo) => campo.nome));
|
|
178
|
-
const argumentos = task.output.map((campo) => `${campo.nome}=${valorPadraoPython(campo
|
|
260
|
+
const argumentos = task.output.map((campo) => `${campo.nome}=${valorPadraoPython(campo)}`).join(", ");
|
|
179
261
|
const ajustes = [];
|
|
180
262
|
for (const garantia of task.garantiasEstruturadas) {
|
|
181
263
|
if (garantia.tipo === "pertencimento" && garantia.valores && camposSaida.has(garantia.alvo)) {
|
|
@@ -426,18 +508,18 @@ function gerarFastApiSchemas(modulo, caminhoContrato) {
|
|
|
426
508
|
];
|
|
427
509
|
for (const task of modulo.tasks) {
|
|
428
510
|
linhas.push(`class ${task.nome}EntradaSchema(BaseModel):
|
|
429
|
-
${task.input.length === 0 ? " pass" : task.input.map((campo) => ` ${campo.nome}: ${
|
|
511
|
+
${task.input.length === 0 ? " pass" : task.input.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
|
|
430
512
|
`);
|
|
431
513
|
linhas.push(`class ${task.nome}SaidaSchema(BaseModel):
|
|
432
|
-
${task.output.length === 0 ? " pass" : task.output.map((campo) => ` ${campo.nome}: ${
|
|
514
|
+
${task.output.length === 0 ? " pass" : task.output.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
|
|
433
515
|
`);
|
|
434
516
|
}
|
|
435
517
|
for (const route of modulo.routes) {
|
|
436
518
|
linhas.push(`class ${route.nome}EntradaPublicaSchema(BaseModel):
|
|
437
|
-
${route.inputPublico.length === 0 ? " pass" : route.inputPublico.map((campo) => ` ${campo.nome}: ${
|
|
519
|
+
${route.inputPublico.length === 0 ? " pass" : route.inputPublico.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
|
|
438
520
|
`);
|
|
439
521
|
linhas.push(`class ${route.nome}SaidaPublicaSchema(BaseModel):
|
|
440
|
-
${route.outputPublico.length === 0 ? " pass" : route.outputPublico.map((campo) => ` ${campo.nome}: ${
|
|
522
|
+
${route.outputPublico.length === 0 ? " pass" : route.outputPublico.map((campo) => ` ${campo.nome}: ${mapearCampoParaPython(campo)}`).join("\n")}
|
|
441
523
|
`);
|
|
442
524
|
}
|
|
443
525
|
return linhas.join("\n");
|