@semacode/cli 1.5.55 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +50 -7
  2. package/dist/agentContext.d.ts +1 -1
  3. package/dist/agentContext.js +3 -3
  4. package/dist/agentContextPack.js +33 -92
  5. package/dist/agentContextTipos.d.ts +6 -9
  6. package/dist/agentContextTipos.js +5 -4
  7. package/dist/agentEntryPoints.d.ts +22 -2
  8. package/dist/agentEntryPoints.js +229 -126
  9. package/dist/docs.part01.js +1 -1
  10. package/dist/docs.part02.js +21 -10
  11. package/dist/doctorCommand.d.ts +4 -4
  12. package/dist/doctorCommand.js +21 -10
  13. package/dist/exemplosOficiais.d.ts +10 -0
  14. package/dist/exemplosOficiais.js +32 -22
  15. package/dist/fsGovernado.js +8 -6
  16. package/dist/iaPrompts.d.ts +2 -2
  17. package/dist/iaPrompts.js +3 -3
  18. package/dist/index.part01.d.ts +1 -1
  19. package/dist/index.part01.js +6 -6
  20. package/dist/index.part02.js +1 -1
  21. package/dist/index.part03.d.ts +1 -0
  22. package/dist/index.part03.js +26 -12
  23. package/dist/index.part04.d.ts +1 -0
  24. package/dist/index.part04.js +49 -21
  25. package/dist/index.part05.js +1 -1
  26. package/dist/index.part06.d.ts +1 -1
  27. package/dist/index.part06.js +27 -18
  28. package/dist/index.part07.js +20 -20
  29. package/dist/index.part08.js +4 -8
  30. package/dist/initCommand.d.ts +3 -1
  31. package/dist/initCommand.js +41 -12
  32. package/dist/initTemplatesBase.js +8 -10
  33. package/dist/workspaceWrite.d.ts +22 -0
  34. package/dist/workspaceWrite.js +332 -0
  35. package/docs/README.md +10 -4
  36. package/docs/ai-integration.md +31 -12
  37. package/docs/ai-onboarding.md +43 -14
  38. package/docs/ai-workflow.md +22 -39
  39. package/docs/auth.md +13 -3
  40. package/docs/cli.md +21 -8
  41. package/docs/commands.md +9 -10
  42. package/docs/deploy.md +27 -4
  43. package/docs/documentation.md +2 -2
  44. package/docs/env.md +3 -1
  45. package/docs/getting-started.md +27 -3
  46. package/docs/repositories.md +18 -2
  47. package/docs/rollback.md +23 -5
  48. package/docs/security.md +8 -0
  49. package/docs/syntax.md +8 -9
  50. package/docs/testing.md +15 -4
  51. package/docs/vocabulary.md +2 -1
  52. package/package.json +20 -12
  53. package/dist/billing/index.d.ts +0 -17
  54. package/dist/billing/index.js +0 -74
@@ -0,0 +1,332 @@
1
+ // SEMA-GOVERNED: sema.produto.escrita_segura_workspace
2
+ // Descrição: valida e executa escritas locais sem atravessar symlink, junction ou a base escolhida.
3
+ import { constants } from "node:fs";
4
+ import { lstat, mkdir, open, realpath, rename, stat, unlink, } from "node:fs/promises";
5
+ import { randomUUID } from "node:crypto";
6
+ import path from "node:path";
7
+ const IDENTIDADE_DESTINO = Symbol("sema.identidade-destino-workspace");
8
+ const IDENTIDADE_BASE_DESTINO = Symbol("sema.identidade-base-workspace");
9
+ class ErroIntegridadeWorkspace extends Error {
10
+ code = "SEMA_WORKSPACE_TOCTOU";
11
+ constructor(mensagem) {
12
+ super(`Integridade do workspace mudou durante a escrita (TOCTOU): ${mensagem}`);
13
+ this.name = "ErroIntegridadeWorkspace";
14
+ }
15
+ }
16
+ function caminhoEstaContido(base, alvo) {
17
+ const relativo = path.relative(base, alvo);
18
+ return relativo === "" || (relativo !== ".." &&
19
+ !relativo.startsWith(`..${path.sep}`) &&
20
+ !path.isAbsolute(relativo));
21
+ }
22
+ function identidadeDe(info) {
23
+ return { dev: info.dev, ino: info.ino };
24
+ }
25
+ function mesmaIdentidade(esquerda, direita) {
26
+ return esquerda.dev === direita.dev && esquerda.ino === direita.ino;
27
+ }
28
+ async function lstatSeguro(caminho) {
29
+ try {
30
+ return await lstat(caminho, { bigint: true });
31
+ }
32
+ catch (erro) {
33
+ if (["ENOENT", "ENOTDIR"].includes(erro.code ?? "")) {
34
+ return null;
35
+ }
36
+ throw erro;
37
+ }
38
+ }
39
+ function validarRelativo(caminhoRelativo) {
40
+ if (!caminhoRelativo.trim() || path.isAbsolute(caminhoRelativo)) {
41
+ throw new Error(`Destino de workspace deve ser relativo: ${caminhoRelativo}`);
42
+ }
43
+ if (caminhoRelativo.includes("\0")) {
44
+ throw new Error("Destino de workspace não pode conter byte nulo.");
45
+ }
46
+ if (caminhoRelativo.split(/[\\/]+/u).includes("..")) {
47
+ throw new Error(`Destino de workspace não pode conter traversal: ${caminhoRelativo}`);
48
+ }
49
+ }
50
+ async function resolverBaseReal(base) {
51
+ const baseAbsoluta = path.resolve(base);
52
+ const baseInfo = await stat(baseAbsoluta).catch(() => null);
53
+ if (!baseInfo?.isDirectory()) {
54
+ throw new Error(`Base de escrita não existe ou não é diretório: ${baseAbsoluta}`);
55
+ }
56
+ const baseReal = await realpath(baseAbsoluta);
57
+ const baseRealInfo = await lstatSeguro(baseReal);
58
+ if (!baseRealInfo?.isDirectory() || baseRealInfo.isSymbolicLink()) {
59
+ throw new Error(`Base real de escrita não é diretório confiável: ${baseReal}`);
60
+ }
61
+ return baseReal;
62
+ }
63
+ function resolverDestino(baseReal, caminhoRelativo) {
64
+ validarRelativo(caminhoRelativo);
65
+ const caminhoAbsoluto = path.resolve(baseReal, caminhoRelativo);
66
+ if (!caminhoEstaContido(baseReal, caminhoAbsoluto)) {
67
+ throw new Error(`Destino escapa da base de escrita: ${caminhoRelativo}`);
68
+ }
69
+ return caminhoAbsoluto;
70
+ }
71
+ async function revalidarGuardasDiretorio(guardas) {
72
+ for (const guarda of guardas) {
73
+ const [porCaminho, porHandle] = await Promise.all([
74
+ lstatSeguro(guarda.caminho),
75
+ guarda.handle.stat({ bigint: true }),
76
+ ]);
77
+ if (!porCaminho?.isDirectory() ||
78
+ porCaminho.isSymbolicLink() ||
79
+ !porHandle.isDirectory() ||
80
+ !mesmaIdentidade(guarda.identidade, identidadeDe(porCaminho)) ||
81
+ !mesmaIdentidade(guarda.identidade, identidadeDe(porHandle))) {
82
+ throw new ErroIntegridadeWorkspace(`diretório substituído: ${guarda.caminho}`);
83
+ }
84
+ }
85
+ }
86
+ async function abrirEGuardarDiretorio(caminho, guardasAnteriores) {
87
+ await revalidarGuardasDiretorio(guardasAnteriores);
88
+ const antes = await lstatSeguro(caminho);
89
+ if (!antes?.isDirectory() || antes.isSymbolicLink()) {
90
+ throw new Error(`Destino atravessa symlink, junction ou não-diretório: ${caminho}`);
91
+ }
92
+ const handle = await open(caminho, constants.O_RDONLY);
93
+ try {
94
+ const [depois, porHandle] = await Promise.all([
95
+ lstatSeguro(caminho),
96
+ handle.stat({ bigint: true }),
97
+ ]);
98
+ const identidadeAntes = identidadeDe(antes);
99
+ if (!depois?.isDirectory() ||
100
+ depois.isSymbolicLink() ||
101
+ !porHandle.isDirectory() ||
102
+ !mesmaIdentidade(identidadeAntes, identidadeDe(depois)) ||
103
+ !mesmaIdentidade(identidadeAntes, identidadeDe(porHandle))) {
104
+ throw new ErroIntegridadeWorkspace(`diretório mudou ao ser aberto: ${caminho}`);
105
+ }
106
+ await revalidarGuardasDiretorio(guardasAnteriores);
107
+ return { caminho, handle, identidade: identidadeAntes };
108
+ }
109
+ catch (erro) {
110
+ await handle.close().catch(() => undefined);
111
+ throw erro;
112
+ }
113
+ }
114
+ async function fecharGuardasDiretorio(guardas) {
115
+ await Promise.all(guardas.map((guarda) => guarda.handle.close().catch(() => undefined)));
116
+ }
117
+ function segmentosEntre(baseReal, alvo) {
118
+ if (!caminhoEstaContido(baseReal, alvo)) {
119
+ throw new Error(`Destino resolve fora da base de escrita: ${alvo}`);
120
+ }
121
+ return path.relative(baseReal, alvo).split(path.sep).filter(Boolean);
122
+ }
123
+ async function garantirDiretoriosDestino(baseReal, diretorioDestino, identidadeBaseEsperada) {
124
+ const guardas = [];
125
+ try {
126
+ guardas.push(await abrirEGuardarDiretorio(baseReal, guardas));
127
+ if (!mesmaIdentidade(guardas[0].identidade, identidadeBaseEsperada)) {
128
+ throw new ErroIntegridadeWorkspace(`base substituída: ${baseReal}`);
129
+ }
130
+ let atual = baseReal;
131
+ for (const segmento of segmentosEntre(baseReal, diretorioDestino)) {
132
+ atual = path.join(atual, segmento);
133
+ await revalidarGuardasDiretorio(guardas);
134
+ let info = await lstatSeguro(atual);
135
+ if (!info) {
136
+ try {
137
+ await mkdir(atual);
138
+ }
139
+ catch (erro) {
140
+ if (erro.code !== "EEXIST") {
141
+ throw erro;
142
+ }
143
+ }
144
+ await revalidarGuardasDiretorio(guardas);
145
+ info = await lstatSeguro(atual);
146
+ }
147
+ if (!info?.isDirectory() || info.isSymbolicLink()) {
148
+ throw new Error(`Destino atravessa symlink, junction ou não-diretório: ${atual}`);
149
+ }
150
+ guardas.push(await abrirEGuardarDiretorio(atual, guardas));
151
+ }
152
+ await revalidarGuardasDiretorio(guardas);
153
+ return guardas;
154
+ }
155
+ catch (erro) {
156
+ await fecharGuardasDiretorio(guardas);
157
+ throw erro;
158
+ }
159
+ }
160
+ async function confirmarArquivoPorHandle(caminho, handle, guardas) {
161
+ await revalidarGuardasDiretorio(guardas);
162
+ const [porCaminho, porHandle] = await Promise.all([
163
+ lstatSeguro(caminho),
164
+ handle.stat({ bigint: true }),
165
+ ]);
166
+ if (!porCaminho?.isFile() ||
167
+ porCaminho.isSymbolicLink() ||
168
+ !porHandle.isFile() ||
169
+ !mesmaIdentidade(identidadeDe(porCaminho), identidadeDe(porHandle)) ||
170
+ porHandle.nlink !== 1n) {
171
+ throw new ErroIntegridadeWorkspace(`arquivo substituído, ocultado ou ligado externamente: ${caminho}`);
172
+ }
173
+ await revalidarGuardasDiretorio(guardas);
174
+ }
175
+ async function confirmarEstadoInicialDestino(destino, guardas) {
176
+ await revalidarGuardasDiretorio(guardas);
177
+ const atual = await lstatSeguro(destino.caminhoAbsoluto);
178
+ const esperada = destino[IDENTIDADE_DESTINO] ?? null;
179
+ if (atual?.isSymbolicLink()) {
180
+ throw new ErroIntegridadeWorkspace(`destino virou symlink ou junction: ${destino.caminhoAbsoluto}`);
181
+ }
182
+ if ((esperada === null && atual !== null) ||
183
+ (esperada !== null && (atual === null || !mesmaIdentidade(esperada, identidadeDe(atual))))) {
184
+ throw new ErroIntegridadeWorkspace(`destino mudou desde a validação: ${destino.caminhoAbsoluto}`);
185
+ }
186
+ }
187
+ async function escreverConteudoConfirmado(caminho, handle, guardas, conteudo) {
188
+ await confirmarArquivoPorHandle(caminho, handle, guardas);
189
+ await handle.writeFile(conteudo, { encoding: "utf8" });
190
+ await handle.sync();
191
+ await confirmarArquivoPorHandle(caminho, handle, guardas);
192
+ }
193
+ async function removerArquivoSeAindaForMesmo(caminho, handle, guardas) {
194
+ try {
195
+ await confirmarArquivoPorHandle(caminho, handle, guardas);
196
+ await unlink(caminho);
197
+ await revalidarGuardasDiretorio(guardas);
198
+ }
199
+ catch {
200
+ // Falha fechada: não removemos um caminho cuja identidade já não pode ser provada.
201
+ }
202
+ }
203
+ export async function validarDestinosEscritaWorkspace(base, caminhosRelativos) {
204
+ const baseReal = await resolverBaseReal(base);
205
+ const destinos = [];
206
+ const guardaBase = await abrirEGuardarDiretorio(baseReal, []);
207
+ try {
208
+ for (const caminhoRelativo of [...new Set(caminhosRelativos)]) {
209
+ const caminhoAbsoluto = resolverDestino(baseReal, caminhoRelativo);
210
+ const segmentos = segmentosEntre(baseReal, caminhoAbsoluto);
211
+ const guardas = [guardaBase];
212
+ let atual = baseReal;
213
+ let infoFinal = null;
214
+ try {
215
+ for (let indice = 0; indice < segmentos.length; indice += 1) {
216
+ atual = path.join(atual, segmentos[indice]);
217
+ await revalidarGuardasDiretorio(guardas);
218
+ const info = await lstatSeguro(atual);
219
+ if (!info) {
220
+ infoFinal = null;
221
+ break;
222
+ }
223
+ if (info.isSymbolicLink()) {
224
+ throw new Error(`Destino atravessa symlink ou junction: ${caminhoRelativo}`);
225
+ }
226
+ const ultimo = indice === segmentos.length - 1;
227
+ if (ultimo) {
228
+ infoFinal = info;
229
+ break;
230
+ }
231
+ if (!info.isDirectory()) {
232
+ // O validador também é usado por migrações que sondam caminhos
233
+ // legados alternativos (arquivo único versus diretório). Um
234
+ // componente regular torna o descendente inexistente; a escrita,
235
+ // se tentada, continua bloqueada em garantirDiretoriosDestino.
236
+ infoFinal = null;
237
+ break;
238
+ }
239
+ guardas.push(await abrirEGuardarDiretorio(atual, guardas));
240
+ }
241
+ await revalidarGuardasDiretorio(guardas);
242
+ }
243
+ finally {
244
+ await fecharGuardasDiretorio(guardas.slice(1));
245
+ }
246
+ const destino = {
247
+ caminhoRelativo,
248
+ caminhoAbsoluto,
249
+ existe: infoFinal !== null,
250
+ };
251
+ destino[IDENTIDADE_DESTINO] = infoFinal ? identidadeDe(infoFinal) : null;
252
+ destino[IDENTIDADE_BASE_DESTINO] = guardaBase.identidade;
253
+ destinos.push(destino);
254
+ }
255
+ }
256
+ finally {
257
+ await fecharGuardasDiretorio([guardaBase]);
258
+ }
259
+ return destinos;
260
+ }
261
+ export async function escreverArquivoWorkspaceSeguro(base, caminhoRelativo, conteudo, opcoes = {}) {
262
+ const [destino] = await validarDestinosEscritaWorkspace(base, [caminhoRelativo]);
263
+ if (destino.existe && !opcoes.sobrescrever) {
264
+ return { status: "preservado", caminho: destino.caminhoAbsoluto };
265
+ }
266
+ const baseReal = await resolverBaseReal(base);
267
+ const identidadeBaseEsperada = destino[IDENTIDADE_BASE_DESTINO];
268
+ if (!identidadeBaseEsperada) {
269
+ throw new ErroIntegridadeWorkspace("a validação inicial não registrou a identidade da base");
270
+ }
271
+ if (!caminhoEstaContido(baseReal, destino.caminhoAbsoluto)) {
272
+ throw new ErroIntegridadeWorkspace("a base real mudou desde a validação inicial");
273
+ }
274
+ const guardas = await garantirDiretoriosDestino(baseReal, path.dirname(destino.caminhoAbsoluto), identidadeBaseEsperada);
275
+ try {
276
+ await confirmarEstadoInicialDestino(destino, guardas);
277
+ if (!opcoes.sobrescrever) {
278
+ let handle;
279
+ try {
280
+ handle = await open(destino.caminhoAbsoluto, "wx", 0o600);
281
+ }
282
+ catch (erro) {
283
+ if (erro.code === "EEXIST") {
284
+ return { status: "preservado", caminho: destino.caminhoAbsoluto };
285
+ }
286
+ throw erro;
287
+ }
288
+ try {
289
+ await escreverConteudoConfirmado(destino.caminhoAbsoluto, handle, guardas, conteudo);
290
+ }
291
+ catch (erro) {
292
+ if (!(erro instanceof ErroIntegridadeWorkspace)) {
293
+ await removerArquivoSeAindaForMesmo(destino.caminhoAbsoluto, handle, guardas);
294
+ }
295
+ throw erro;
296
+ }
297
+ finally {
298
+ await handle.close().catch(() => undefined);
299
+ }
300
+ }
301
+ else {
302
+ const temporario = path.join(path.dirname(destino.caminhoAbsoluto), `.${path.basename(destino.caminhoAbsoluto)}.sema-${randomUUID()}.tmp`);
303
+ const handle = await open(temporario, "wx", 0o600);
304
+ let renomeado = false;
305
+ try {
306
+ await escreverConteudoConfirmado(temporario, handle, guardas, conteudo);
307
+ await confirmarEstadoInicialDestino(destino, guardas);
308
+ await confirmarArquivoPorHandle(temporario, handle, guardas);
309
+ await rename(temporario, destino.caminhoAbsoluto);
310
+ renomeado = true;
311
+ await confirmarArquivoPorHandle(destino.caminhoAbsoluto, handle, guardas);
312
+ }
313
+ catch (erro) {
314
+ if (!renomeado && !(erro instanceof ErroIntegridadeWorkspace)) {
315
+ await removerArquivoSeAindaForMesmo(temporario, handle, guardas);
316
+ }
317
+ throw erro;
318
+ }
319
+ finally {
320
+ await handle.close().catch(() => undefined);
321
+ }
322
+ }
323
+ }
324
+ finally {
325
+ await fecharGuardasDiretorio(guardas);
326
+ }
327
+ return {
328
+ status: destino.existe ? "atualizado" : "criado",
329
+ caminho: destino.caminhoAbsoluto,
330
+ };
331
+ }
332
+ //# sourceMappingURL=workspaceWrite.js.map
package/docs/README.md CHANGED
@@ -1,10 +1,15 @@
1
1
  # Sema Documentation
2
2
 
3
- These docs describe the public local CLI distribution of Sema.
3
+ These docs describe the public Codex-native local CLI distribution of Sema.
4
4
 
5
- Sema is local-first: agents run the CLI inside a project folder, read `.sema`
6
- contracts, check drift, map impact, and close changes with documentation
7
- evidence. Public docs are written in English.
5
+ Sema is local-first: Codex runs the CLI inside a project folder, reads `.sema`
6
+ contracts, checks drift, maps impact, and closes changes with documentation
7
+ evidence. `AGENTS.md` is the official Codex entrypoint. Public docs are written
8
+ in English.
9
+
10
+ Sema is an independent product and is not affiliated with or endorsed by
11
+ OpenAI. Codex-native describes Sema's product direction, not an official OpenAI
12
+ program or submission.
8
13
 
9
14
  Start here:
10
15
 
@@ -15,5 +20,6 @@ Start here:
15
20
  - [Documentation Governance](./documentation.md)
16
21
  - [Repository Boundary](./repositories.md)
17
22
  - [Security](./security.md)
23
+ - [Codex Integration](./ai-integration.md)
18
24
 
19
25
  Official support: [suporte@otimitare.online](mailto:suporte@otimitare.online)
@@ -1,9 +1,28 @@
1
- # AI Integration
1
+ # Codex Integration
2
2
 
3
- Sema is designed for AI agents with different context sizes and discipline
4
- levels. The public repository documents the local CLI flow only: agents run the
5
- CLI inside the project, read contracts, check drift, map impact, and close the
6
- change with evidence.
3
+ The official Sema agent integration is Codex through the repository-level
4
+ `AGENTS.md`. Codex loads that file automatically and runs the local Sema CLI
5
+ inside the project to read contracts, check drift, map impact, and close changes
6
+ with evidence.
7
+
8
+ Sema is an independent project and is not affiliated with or endorsed by OpenAI.
9
+ Codex surfaces and `AGENTS.md` behavior are documented at
10
+ https://learn.chatgpt.com/docs/agent-configuration/agents-md.
11
+
12
+ ## Before AGENTS.md Exists
13
+
14
+ The official Sema skill is the required first-contact bootstrap for Codex in a
15
+ project that does not have Sema yet. Install it explicitly:
16
+
17
+ ```bash
18
+ codex plugin marketplace add gerlanss/Sema
19
+ codex plugin add sema@sema
20
+ ```
21
+
22
+ The skill locates the local CLI, runs `sema iniciar`, generates `AGENTS.md`, and
23
+ then delegates all ongoing workspace governance to that file. It contains no
24
+ MCP server, remote workspace bridge, login, license, billing, token, credit,
25
+ panel, or authorization gate.
7
26
 
8
27
  Supported capacity labels: fraca, pequena, media, forte, grande.
9
28
 
@@ -13,12 +32,12 @@ For a local workspace, use the local CLI:
13
32
 
14
33
  ```bash
15
34
  sema --version
16
- sema preflight resumo --json
17
35
  sema resumo
18
36
  ```
19
37
 
20
- Continue only when preflight returns `use_cli_local`. Do not replace the local
21
- CLI with an external workspace source, external sync, or project-name guessing.
38
+ A successful `sema --version` is enough to use the local CLI directly. Local
39
+ commands require no login, activation key, license check, token, credits, billing
40
+ service, control panel, or external authorization request.
22
41
 
23
42
  ## Before Editing
24
43
 
@@ -32,19 +51,19 @@ sema impacto contratos/example.sema --alvo app.example --mudanca "describe the c
32
51
  Read every document listed by `docs-impacto` before changing code, contracts,
33
52
  operational docs, generated artifacts, workflows, profiles, or release material.
34
53
 
35
- ## Capacity Tiers
54
+ ## Codex Context Tiers
36
55
 
37
- Weak agents should start with `SEMA_BOOT.md`,
56
+ Codex with a small context budget should start with `SEMA_BOOT.md`,
38
57
  `SEMA_SMALL_MODEL.md`, `SEMA_BRIEF.micro.txt`,
39
58
  `AGENT_CONTEXT_PACK.json`, and `SEMA_INDEX.json`. They should stop early
40
59
  when a gate is unclear.
41
60
 
42
- Medium agents should start with `SEMA_BOOT.md`,
61
+ Codex with a medium context budget should start with `SEMA_BOOT.md`,
43
62
  `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.curto.txt`,
44
63
  `SEMA_INDEX.json`, and `AGENTS.md`. They must run docs-impact, drift, and
45
64
  impact before edits.
46
65
 
47
- Strong agents may consume `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.md`,
66
+ Codex with a large context budget may consume `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.md`,
48
67
  `SEMA_INDEX.json`, AST, IR, drift, and impact outputs, but larger context does
49
68
  not remove the contract-first rule.
50
69
 
@@ -1,7 +1,29 @@
1
- # Teaching Sema To AI Agents
1
+ # Codex Onboarding
2
2
 
3
- Give agents a short rule: contracts come first, and the local CLI is the source
4
- of truth.
3
+ The official Sema skill is required for Codex to recognize and initialize Sema
4
+ before a project has its own protocol:
5
+
6
+ ```bash
7
+ codex plugin marketplace add gerlanss/Sema
8
+ codex plugin add sema@sema
9
+ ```
10
+
11
+ Open a new Codex task in the target repository after installation. Codex loads
12
+ the plugin/skill catalog at task start, so `$sema` is not added retroactively to
13
+ an already-open task. Invoke `$sema` in the new task; it bootstraps the project,
14
+ reads the generated `AGENTS.md`, and later tasks load that protocol
15
+ automatically.
16
+
17
+ `AGENTS.md` is the official Sema entrypoint for Codex. It gives Codex the durable
18
+ repository rule that contracts come first and the local CLI is the source of
19
+ truth. Once the file exists, the skill delegates to it instead of carrying a
20
+ second copy of the governed workflow.
21
+
22
+ Create or refresh the entrypoint with:
23
+
24
+ ```bash
25
+ sema sync-codex --json
26
+ ```
5
27
 
6
28
  ## Minimal Prompt
7
29
 
@@ -10,19 +32,19 @@ This workspace is governed by Sema. Before editing code, contracts, docs,
10
32
  workflows, profiles, or release scripts, run:
11
33
 
12
34
  1. sema --version
13
- 2. sema preflight resumo --json
14
- 3. sema resumo
15
- 4. sema docs-impacto --intencao "<change>" --json
16
- 5. sema inspecionar on the applicable .sema contract
17
- 6. sema drift before editing existing code
18
- 7. sema impacto before changing behavior
19
- 8. sema finalizar-mudanca before closing
20
-
21
- If the CLI is unavailable or preflight does not return use_cli_local, stop.
22
- Do not replace Sema with manual search or guessed contracts.
35
+ 2. sema resumo
36
+ 3. sema docs-impacto --intencao "<change>" --json
37
+ 4. sema inspecionar on the applicable .sema contract
38
+ 5. sema drift before editing existing code
39
+ 6. sema impacto before changing behavior
40
+ 7. sema finalizar-mudanca before closing
41
+
42
+ If the CLI is unavailable, stop and install or repair @semacode/cli. There is
43
+ no separate Sema login, license activation, or authorization gate. Do not
44
+ replace Sema with manual search or guessed contracts.
23
45
  ```
24
46
 
25
- ## What Agents Should Not Do
47
+ ## What Codex Should Not Do
26
48
 
27
49
  - Do not invent `.sema` contracts.
28
50
  - Do not implement code without an applicable contract.
@@ -30,4 +52,11 @@ Do not replace Sema with manual search or guessed contracts.
30
52
  - Do not publish private or sensitive operational material.
31
53
  - Do not replace the local CLI when the local workspace is available.
32
54
 
55
+ Other AI clients can invoke the public CLI manually, but Sema does not ship or
56
+ manage an official repository entrypoint for them. The supported product path
57
+ is Codex plus `AGENTS.md`.
58
+
59
+ Sema is an independent product and is not affiliated with or endorsed by
60
+ OpenAI.
61
+
33
62
  Support: suporte@otimitare.online
@@ -1,19 +1,18 @@
1
1
  <!-- sema:agent-entrypoint:start -->
2
- # Practical AI + Sema Workflow
3
-
4
- This is the minimum workflow for agents in a local workspace.
5
-
6
- 1. Leia `SEMA_BOOT.md`.
7
- 2. Rode `sema --version`.
8
- 3. Rode `sema preflight resumo --json` e continue apenas se retornar `use_cli_local`.
9
- 4. Rode `sema resumo`.
10
- 5. Rode `sema docs-impacto --intencao "<acao>" --json`.
11
- 6. Leia a documentacao obrigatoria retornada.
12
- 7. Antes de escolher comando ou interpretar `--saida`, leia `docs/commands.md`.
13
- 8. Antes de criar ou editar contrato, use `exemplos/` e `docs/syntax.md`.
14
- 9. Antes de editar codigo existente, rode `sema drift` e `sema impacto`.
15
- 10. Depois de alterar `.sema`, rode `sema formatar` e `sema validar`.
16
- 11. Antes de concluir, rode `sema finalizar-mudanca` com as docs lidas.
2
+ # Practical Codex + Sema Workflow
3
+
4
+ This is the minimum workflow for Codex in a local workspace.
5
+
6
+ 1. Read `SEMA_BOOT.md`.
7
+ 2. Run `sema --version`. Success enables direct local execution; there is no login, license, token, billing, panel, or authorization gate.
8
+ 3. Run `sema resumo`.
9
+ 4. Run `sema docs-impacto --intencao "<change>" --json`.
10
+ 5. Read every required document returned by the command.
11
+ 6. Read `docs/commands.md` before selecting a command or interpreting `--saida`.
12
+ 7. Use `exemplos/` and `docs/syntax.md` before creating or editing a contract.
13
+ 8. Run `sema drift` and `sema impacto` before editing existing code.
14
+ 9. Run `sema formatar` and `sema validar` after changing a `.sema` contract.
15
+ 10. Run `sema finalizar-mudanca` with the documents read before closure.
17
16
 
18
17
  Contract edit rule: `.sema` has its own size budget. Above 300 lines, plan a split by domain/capability; above 500, do not create or edit before splitting. Do not use parte_1/parte_2 and do not force a 1:1 contract-to-file relationship; several contracts can govern the same file through `vinculos`.
19
18
 
@@ -21,11 +20,11 @@ Closing rule: `sema drift --json` must return `sucesso:true`. If it reports `suc
21
20
 
22
21
  UI rule: if the task involves an interface, minimum evidence includes desktop and mobile. On a narrow viewport such as 390px, `document.documentElement.scrollWidth <= document.documentElement.clientWidth` must pass; horizontal scroll blocks closure.
23
22
 
24
- ## Agent Capacity
23
+ ## Codex Context Capacity
25
24
 
26
- - Weak agent: `SEMA_SMALL_MODEL.md`, `SEMA_BRIEF.micro.txt`, `AGENT_CONTEXT_PACK.json`, `SEMA_INDEX.json`.
27
- - Medium agent: `SEMA_BOOT.md`, `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.curto.txt`, `SEMA_INDEX.json`, `AGENTS.md`.
28
- - Strong agent: `SEMA_BOOT.md`, `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.md`, `SEMA_INDEX.json`, AST, IR, drift, and impact.
25
+ - Small context: `SEMA_SMALL_MODEL.md`, `SEMA_BRIEF.micro.txt`, `AGENT_CONTEXT_PACK.json`, `SEMA_INDEX.json`.
26
+ - Medium context: `SEMA_BOOT.md`, `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.curto.txt`, `SEMA_INDEX.json`, `AGENTS.md`.
27
+ - Large context: `SEMA_BOOT.md`, `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.md`, `SEMA_INDEX.json`, AST, IR, drift, and impact.
29
28
 
30
29
  ## When to Generate Code
31
30
 
@@ -39,24 +38,8 @@ Replace `javascript` with `typescript`, `python`, `php`, `dart`, `lua`, `html`,
39
38
 
40
39
  ## Fail Closed
41
40
 
42
- - Se não conseguir chamar Sema, pare e declare bloqueio em vez de editar código ou contrato.
43
- - Se não houver contrato aplicável ou vínculo semântico do arquivo, inspecione o arquivo, descubra ou crie o .sema aplicável e vincule antes do código.
44
- - Em IDE local, rode sema --version; se falhar, pare. A IA não acessa o painel Sema: peça ao humano para instalar a CLI pelo painel. Depois rode sema preflight <comando> --json; só continue com use_cli_local; não use fonte externa de workspace para substituir a CLI local.
45
- - Se não houver workspace local em disco, pare bloqueado e peça o fluxo apropriado; não invente caminho nem substitua a CLI local por ferramenta paralela.
46
- - Se arquivos_codigo.conteudo ou conteudo inline passar de 262144 caracteres, não aumente timeout para forçar: divida por responsabilidade ou use anexo/caminho de servidor autorizado.
47
- - Se for criar ou corrigir .sema, use sema_exemplos antes de escrever sintaxe.
48
- - Se a resposta humana estiver em PT-BR, use vocabulário Sema canônico e preserve acentos mesmo que a DSL use ASCII.
49
- - Se um arquivo de código tiver SEMA-GOVERNED, consulte Sema e o contrato aplicável antes de editar.
50
- - Se codigo governado passar de 1000 linhas, planeje divisao; se passar de 2000, pare e divida antes de concluir. Documentacao Markdown nao entra nesse limite de codigo.
51
- - Se contrato .sema passar de 300 linhas, planeje split por dominio/capacidade; acima de 500, criacao e edicao ficam bloqueadas. Nao use parte_1/parte_2 e nao remova guarantees, tests ou vinculos so para caber.
52
- - Um mesmo arquivo de codigo pode ser governado por varios contratos .sema via vinculos; Sema Codigo deve preservar essa rastreabilidade.
53
- - Se score, achados ou decisaoAgente parecerem bons, trate como sinal de triagem e confira evidência concreta no contrato e no código.
54
- - Se validar artefato inline com 100/100, ainda preserve cabeçalho SEMA-GOVERNED no arquivo físico sincronizado.
55
- - Se `sema drift` retornar sucesso:false, `vinculos_quebrados`, `rotas_divergentes` ou impls quebradas, a mudanca nao pode ser declarada concluida; corrija contrato/codigo e rode drift de novo.
56
- - Se a tarefa tiver site, sistema, app, UI, painel, jogo, CLI/TUI ou terminal, nao conclua sem acabamento moderno, contextual e evidenciado; em UI mobile estreita (ex. 390px), `document.documentElement.scrollWidth <= document.documentElement.clientWidth` precisa ser verdadeiro.
57
- - Se texto visivel PT-BR perder acento ou cedilha em termos como descricao, lancamentos, saude ou alimentacao, trate como defeito bloqueante quando houver i18n/idioma declarado.
58
- - Se aparecer caminho que não pertence ao workspace local aberto pelo usuário, pare e confirme a fonte antes de agir.
59
- - Se uma chamada Sema estourar por timeout local, aumente o timeout e tente de novo; timeout do agente não libera ação sem Sema.
60
- - Se a plataforma bloquear ou alertar política, trate como bloqueio externo ou falso positivo possível; explique sem tentar contornar filtro.
61
- - Se a tarefa tiver experiência de uso e você não conseguir garantir padrão moderno, contextual e não genérico, pare e peça revisão em vez de entregar coisa engessada.
41
+ - If the local CLI is unavailable, stop before editing governed code or contracts and ask for `@semacode/cli` installation.
42
+ - If the applicable contract or semantic link is missing, create or repair it before code.
43
+ - If validation or drift reports failure, broken links, divergent routes, or broken implementations, fix the evidence and run the gate again.
44
+ - A local timeout is not authorization to skip Sema; retry with a larger timeout or a narrower scope.
62
45
  <!-- sema:agent-entrypoint:end -->
package/docs/auth.md CHANGED
@@ -1,15 +1,25 @@
1
- # Authentication Boundary
1
+ # Local Runtime Boundary
2
2
 
3
- The public Sema CLI does not require authentication.
3
+ The public Sema CLI executes directly against the local workspace. It does not
4
+ require a Sema login, user authentication, product authorization, license
5
+ activation, install key, token, credits, billing service, control panel, or an
6
+ external request.
4
7
 
5
8
  Use local commands:
6
9
 
7
10
  ```bash
8
11
  sema --version
9
- sema preflight resumo --json
12
+ sema resumo
10
13
  sema validar contratos/example.sema --json
11
14
  ```
12
15
 
16
+ The repository license governs use and redistribution. It is not checked as a
17
+ runtime activation mechanism.
18
+
19
+ An `authz` block inside a `.sema` contract describes authorization in the
20
+ application being governed. It does not authenticate a person before the Sema
21
+ CLI can run.
22
+
13
23
  Do not put private or sensitive operational material in this repository.
14
24
 
15
25
  Application-specific authentication belongs in the application repository that