@semacode/cli 4.1.3 → 4.2.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.
@@ -5,10 +5,10 @@ This is the minimum workflow for Codex in a local workspace.
5
5
 
6
6
  1. Read `SEMA_BOOT.md`.
7
7
  2. Run `sema --version`. If the shell cannot find it, use `$HOME/.sema/bin/sema` on macOS/Linux. On Windows, PowerShell resolves `sema.ps1` from PATH and cmd.exe resolves `sema.cmd`; use `& "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\.sema\bin\sema-managed.ps1" --version` as the absolute fallback. Only then declare the CLI unavailable.
8
- 3. Run `sema resumo --drift none` for contract-only orientation; request `--drift cache` or `--drift fresh` only when code evidence is needed.
9
- 4. Run `sema docs-impacto --intencao "<change>" --json`.
8
+ 3. Run `sema sessao "<intenção>" --json`; then `sema resumo <contrato> --micro --drift none --json` only for the selected contract.
9
+ 4. Run `sema docs-impacto --intencao "<change>" --arquivo <contract> --json`.
10
10
  5. Read every required document returned by the command.
11
- 6. Read `docs/commands.md` before selecting a command or interpreting `--saida`.
11
+ 6. Consult command help or the relevant section of `docs/commands.md` when syntax, a gate or `--saida` is unclear.
12
12
  7. If the right capability is unclear, run `sema descobrir recomendar --intencao "<goal>" --json`; do not auto-run ambiguous recommendations.
13
13
  8. Use `exemplos/` and `docs/syntax.md` before creating or editing a contract.
14
14
  9. Run `sema drift --cache fresh` and `sema impacto` before editing existing code.
@@ -30,9 +30,11 @@ UI rule: if the task involves an interface, minimum evidence includes desktop an
30
30
 
31
31
  ## Codex Context Capacity
32
32
 
33
- - Small context: `SEMA_SMALL_MODEL.md`, `SEMA_BRIEF.micro.txt`, `AGENT_CONTEXT_PACK.json`, `SEMA_INDEX.json`.
34
- - Medium context: `SEMA_BOOT.md`, `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.curto.txt`, `SEMA_INDEX.json`, `AGENTS.md`.
35
- - Large context: `SEMA_BOOT.md`, `AGENT_CONTEXT_PACK.json`, `SEMA_BRIEF.md`, `SEMA_INDEX.json`, AST, IR, drift, and impact.
33
+ All capacities use AGENTS.md -> SEMA_BOOT.md -> the contract returned by `sema sessao`.
34
+ The first session asks for the configured token window; declare `--janela-contexto <tokens> --salvar-perfil`.
35
+ Use `--orcamento-contexto` and `--reserva-saida` to allocate space. Counts use characters / 4, not the model tokenizer.
36
+ The CLI reads SEMA_INDEX.json internally. Do not load the full index, global pack, or unrelated modules.
37
+ An explicit `--arquivo` selects its contract and declared dependencies. Word matches are optional references.
36
38
 
37
39
  ## When to Generate Code
38
40
 
package/docs/commands.md CHANGED
@@ -18,7 +18,7 @@ Then read every required doc returned by `docs-impacto`.
18
18
 
19
19
  ## Session Opening
20
20
 
21
- - `sema sessao "<intencao>" --json`: opens a governed session with one compact envelope. It returns workspace identity (`baseProjeto`, `hashContratos`, CLI version), artifact freshness (`frescor.fresco` plus the exact recovery command when stale), the project's contract count and modules, the declared intent's categories with blocking and recommended docs, the four gate commands for the full loop, and concrete next steps. Treat `frescor.fresco:false` as a pre-action blocker: run the suggested `sema sync-codex --json` before editing, because gates protect the consistency that stale artifacts break.
21
+ - `sema sessao "<intencao>" [--arquivo <contrato-ou-codigo>] [--janela-contexto <tokens>] [--orcamento-contexto <tokens>] [--reserva-saida <tokens>] [--salvar-perfil] --json`: asks for the effective window when absent and stores the profile only on explicit request. The compact response contains workspace identity, artifact freshness, matching contracts and linked files, mandatory document paths, scoped gates and next steps. The index stays inside the CLI. The budget estimates the public JSON size using characters/4; it does not measure the conversation or the model's exact tokenizer. Omitted candidates are counted and require scope refinement; mandatory readings are never silently waived. Treat `frescor.fresco:false` as a pre-action blocker and run the suggested `sema sync-codex --json`. Navigation never authorizes execution.
22
22
 
23
23
  ## Public JSON output
24
24
 
@@ -47,3 +47,36 @@ same rule applies to drift and semantic-budget governance: keep a cohesive
47
47
  primary capability in the root contract and move secondary responsibilities to
48
48
  named children. Preserve task names, guarantees, implementations, and
49
49
  `vinculos`; never create numbered part files.
50
+
51
+
52
+ ## Progressive AI Context
53
+
54
+ The mandatory entry is AGENTS.md and SEMA_BOOT.md. SEMA_INDEX.json and
55
+ AGENT_CONTEXT_PACK.json are internal CLI sources, not required full readings.
56
+ The session asks for the effective context window when it is unknown. The local
57
+ `.sema/contexto-ia.json` profile is saved only by `--salvar-perfil` or by `iniciar`
58
+ with a declared window. Reconfigure it after switching models.
59
+
60
+ `sema sessao "<intent>" --janela-contexto 32768 --salvar-perfil --json`
61
+ configures a 32K window. Defaults allocate 4096 estimated tokens to the session
62
+ response and reserve 4096 for output. Other instructions, tools, conversation
63
+ and code need the remaining space. `--orcamento-contexto` and `--reserva-saida`
64
+ adjust this split. The characters/4 estimate includes the public envelope and
65
+ a margin; it is not an exact tokenizer or a measurement of the client's used
66
+ context. The limit applies to the session response, not every legacy command
67
+ or the cumulative conversation. The output reserve does not configure the model.
68
+
69
+ In docs-impacto and finalizar-mudanca, `--arquivo` fixes the target. Explicit
70
+ contracts are included even beyond the 80th catalog entry. Source files resolve
71
+ through `vinculos.arquivo`. Required expansion follows declared `use` dependencies,
72
+ with reasons and originating contracts. Missing or ambiguous dependencies block.
73
+ `docs.arquivo` references are recommendations and do not expand the dependency
74
+ graph. Intent suggestions stay in `leituraRecomendada`, distinct from
75
+ `leituraObrigatoria`, and do not block closure. Pass the same target at closure
76
+ and confirm the selected contracts before editing code.
77
+
78
+ The context-budget and docs-relevancia tests measure actual CLI output, prove
79
+ that the raw index is absent, verify hash invalidation and configuration before
80
+ writes, and cover WhatsApp alongside 85 unrelated contracts. Drift, contract
81
+ and behavioral gates remain required. To roll back, restore the prior generators
82
+ and resolvers and run sync-codex; preserve manual blocks and the local profile.
@@ -1,68 +1,68 @@
1
- module exemplos.python_verificacao {
2
- docs {
3
- resumo: "Regressao executavel Python para garantias numericas, formulario tipado, status e metadados aninhados."
4
- }
5
- entity FormularioEntrega {
6
- fields {
7
- tipo: Texto
8
- }
9
- }
10
- entity MetaTemplate {
11
- fields {
12
- original_campaign_id: Texto
13
- }
14
- }
15
- entity Template {
16
- fields {
17
- _template_meta: MetaTemplate
18
- }
19
- }
20
- entity Status {
21
- fields {
22
- desired_action: Texto
23
- }
24
- }
25
- task preparar {
26
- input {
27
- formulario: FormularioEntrega required
28
- }
29
- output {
30
- poolSize: Inteiro
31
- workersAplicados: Inteiro
32
- template: Template
33
- status: Status
34
- }
35
- rules {
36
- formulario.tipo existe
37
- }
38
- guarantees {
39
- poolSize > 0
40
- workersAplicados >= 2
41
- template._template_meta existe
42
- template._template_meta.original_campaign_id em ["campanha_1"]
43
- status.desired_action em ["iniciar", "parar"]
44
- }
45
- tests {
46
- caso "verifica cada saida" {
47
- given {
48
- formulario {
49
- tipo: "entrega"
50
- }
51
- }
52
- expect {
53
- sucesso: verdadeiro
54
- poolSize: 1
55
- workersAplicados: 2
56
- template {
57
- _template_meta {
58
- original_campaign_id: "campanha_1"
59
- }
60
- }
61
- status {
62
- desired_action: "iniciar"
63
- }
64
- }
65
- }
66
- }
67
- }
68
- }
1
+ module exemplos.python_verificacao {
2
+ docs {
3
+ resumo: "Regressao executavel Python para garantias numericas, formulario tipado, status e metadados aninhados."
4
+ }
5
+ entity FormularioEntrega {
6
+ fields {
7
+ tipo: Texto
8
+ }
9
+ }
10
+ entity MetaTemplate {
11
+ fields {
12
+ original_campaign_id: Texto
13
+ }
14
+ }
15
+ entity Template {
16
+ fields {
17
+ _template_meta: MetaTemplate
18
+ }
19
+ }
20
+ entity Status {
21
+ fields {
22
+ desired_action: Texto
23
+ }
24
+ }
25
+ task preparar {
26
+ input {
27
+ formulario: FormularioEntrega required
28
+ }
29
+ output {
30
+ poolSize: Inteiro
31
+ workersAplicados: Inteiro
32
+ template: Template
33
+ status: Status
34
+ }
35
+ rules {
36
+ formulario.tipo existe
37
+ }
38
+ guarantees {
39
+ poolSize > 0
40
+ workersAplicados >= 2
41
+ template._template_meta existe
42
+ template._template_meta.original_campaign_id em ["campanha_1"]
43
+ status.desired_action em ["iniciar", "parar"]
44
+ }
45
+ tests {
46
+ caso "verifica cada saida" {
47
+ given {
48
+ formulario {
49
+ tipo: "entrega"
50
+ }
51
+ }
52
+ expect {
53
+ sucesso: verdadeiro
54
+ poolSize: 1
55
+ workersAplicados: 2
56
+ template {
57
+ _template_meta {
58
+ original_campaign_id: "campanha_1"
59
+ }
60
+ }
61
+ status {
62
+ desired_action: "iniciar"
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
68
+ }
@@ -1,70 +1,70 @@
1
1
  // SEMA-GOVERNED: sema.produto.gerador_python_verificacao
2
2
  // Contrato: contratos/sema/gerador_python_verificacao.sema
3
3
  // Descrição: acesso uniforme a mapas e entidades e síntese demonstrativa de garantias.
4
- export const RUNTIME_PYTHON = `
5
- import math
6
-
7
- def sema_get(objeto, caminho):
8
- for campo in caminho:
9
- if objeto is None:
10
- return None
11
- objeto = objeto.get(campo) if isinstance(objeto, dict) else getattr(objeto, campo, None)
12
- return objeto
13
-
14
- def sema_set(objeto, caminho, valor):
15
- for campo in caminho[:-1]:
16
- filho = sema_get(objeto, [campo])
17
- if filho is None:
18
- filho = {} if isinstance(objeto, dict) else SimpleNamespace()
19
- if isinstance(objeto, dict):
20
- objeto[campo] = filho
21
- else:
22
- setattr(objeto, campo, filho)
23
- if not isinstance(filho, dict) and not hasattr(filho, "__dict__"):
24
- raise ValueError(f"Caminho de objeto incompatível: {campo}")
25
- objeto = filho
26
- if isinstance(objeto, dict):
27
- objeto[caminho[-1]] = valor
28
- else:
29
- setattr(objeto, caminho[-1], valor)
30
-
31
- def sema_sintetizar(atual, restricoes, inteiro=False):
32
- # Apenas valores demonstrativos: expect nunca participa desta síntese.
33
- def aceita(valor):
34
- for operador, limite in restricoes:
35
- if operador == "existe" and valor is None:
36
- return False
37
- if operador == "in" and valor not in limite:
38
- return False
39
- try:
40
- if operador == "==" and valor != limite: return False
41
- if operador == "!=" and valor == limite: return False
42
- if operador == ">" and not valor > limite: return False
43
- if operador == ">=" and not valor >= limite: return False
44
- if operador == "<" and not valor < limite: return False
45
- if operador == "<=" and not valor <= limite: return False
46
- except TypeError:
47
- return False
48
- return True
49
-
50
- candidatos = [atual]
51
- numeros = []
52
- for operador, limite in restricoes:
53
- if operador == "in":
54
- candidatos.extend(limite)
55
- elif operador != "existe":
56
- candidatos.append(limite)
57
- if isinstance(limite, (int, float)) and not isinstance(limite, bool):
58
- numeros.append(limite)
59
- candidatos.extend([limite - 1, limite + 1, math.floor(limite), math.ceil(limite)])
60
- numeros.sort()
61
- candidatos.extend((a + b) / 2 for a, b in zip(numeros, numeros[1:]))
62
- candidatos.extend([1, 0, -1, True, False, "valor_garantido", "outro_valor"])
63
- for candidato in candidatos:
64
- if inteiro and (not isinstance(candidato, int) or isinstance(candidato, bool)):
65
- continue
66
- if aceita(candidato):
67
- return candidato
68
- raise ValueError("Não foi possível sintetizar saída demonstrativa compatível com as garantias; forneça implementação real.")
4
+ export const RUNTIME_PYTHON = `
5
+ import math
6
+
7
+ def sema_get(objeto, caminho):
8
+ for campo in caminho:
9
+ if objeto is None:
10
+ return None
11
+ objeto = objeto.get(campo) if isinstance(objeto, dict) else getattr(objeto, campo, None)
12
+ return objeto
13
+
14
+ def sema_set(objeto, caminho, valor):
15
+ for campo in caminho[:-1]:
16
+ filho = sema_get(objeto, [campo])
17
+ if filho is None:
18
+ filho = {} if isinstance(objeto, dict) else SimpleNamespace()
19
+ if isinstance(objeto, dict):
20
+ objeto[campo] = filho
21
+ else:
22
+ setattr(objeto, campo, filho)
23
+ if not isinstance(filho, dict) and not hasattr(filho, "__dict__"):
24
+ raise ValueError(f"Caminho de objeto incompatível: {campo}")
25
+ objeto = filho
26
+ if isinstance(objeto, dict):
27
+ objeto[caminho[-1]] = valor
28
+ else:
29
+ setattr(objeto, caminho[-1], valor)
30
+
31
+ def sema_sintetizar(atual, restricoes, inteiro=False):
32
+ # Apenas valores demonstrativos: expect nunca participa desta síntese.
33
+ def aceita(valor):
34
+ for operador, limite in restricoes:
35
+ if operador == "existe" and valor is None:
36
+ return False
37
+ if operador == "in" and valor not in limite:
38
+ return False
39
+ try:
40
+ if operador == "==" and valor != limite: return False
41
+ if operador == "!=" and valor == limite: return False
42
+ if operador == ">" and not valor > limite: return False
43
+ if operador == ">=" and not valor >= limite: return False
44
+ if operador == "<" and not valor < limite: return False
45
+ if operador == "<=" and not valor <= limite: return False
46
+ except TypeError:
47
+ return False
48
+ return True
49
+
50
+ candidatos = [atual]
51
+ numeros = []
52
+ for operador, limite in restricoes:
53
+ if operador == "in":
54
+ candidatos.extend(limite)
55
+ elif operador != "existe":
56
+ candidatos.append(limite)
57
+ if isinstance(limite, (int, float)) and not isinstance(limite, bool):
58
+ numeros.append(limite)
59
+ candidatos.extend([limite - 1, limite + 1, math.floor(limite), math.ceil(limite)])
60
+ numeros.sort()
61
+ candidatos.extend((a + b) / 2 for a, b in zip(numeros, numeros[1:]))
62
+ candidatos.extend([1, 0, -1, True, False, "valor_garantido", "outro_valor"])
63
+ for candidato in candidatos:
64
+ if inteiro and (not isinstance(candidato, int) or isinstance(candidato, bool)):
65
+ continue
66
+ if aceita(candidato):
67
+ return candidato
68
+ raise ValueError("Não foi possível sintetizar saída demonstrativa compatível com as garantias; forneça implementação real.")
69
69
  `;
70
70
  //# sourceMappingURL=runtime.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semacode/cli",
3
- "version": "4.1.3",
3
+ "version": "4.2.0",
4
4
  "description": "Local-first semantic governance CLI for AI agents, proven with Claude, Codex, zCode (GLM) and Kimi: contracts, drift, impact, docs gates, and code generation.",
5
5
  "type": "module",
6
6
  "icon": "logo.png",