theforge-cli 0.2.0 → 0.2.1
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/CHANGELOG.md +8 -0
- package/dist/index.js +2667 -942
- package/docs/registry-state-contract.md +42 -0
- package/docs/solucao-de-problemas.md +46 -0
- package/package.json +1 -1
|
@@ -79,3 +79,45 @@ tolerar campos desconhecidos e tratar campos conhecidos ausentes como
|
|
|
79
79
|
host loopback + sessão, como toda a API do portal).
|
|
80
80
|
- Projeção é whitelist de escalares/containers pequenos — nada de
|
|
81
81
|
objetos arbitrários vindos do disco.
|
|
82
|
+
|
|
83
|
+
## Consistência e recuperação
|
|
84
|
+
|
|
85
|
+
O CLI trata `state.json` + `install.json` + venv como um único fato.
|
|
86
|
+
`installConsistency(home, name)` compara os três e classifica:
|
|
87
|
+
|
|
88
|
+
- `ok` — as três fontes concordam;
|
|
89
|
+
- `not-installed` — nada no state, nada no disco;
|
|
90
|
+
- `orphaned` — diretório/venv presente sem entrada no state
|
|
91
|
+
(típico de kill entre "venv criada" e "state commitado");
|
|
92
|
+
- `missing-receipt` — entrada no state sem `install.json`;
|
|
93
|
+
- `unreadable-receipt` — `install.json` existe mas não parseia;
|
|
94
|
+
- `forge-mismatch` / `version-mismatch` — receipt diverge do state;
|
|
95
|
+
- `missing-venv` — registro coerente, venv ausente.
|
|
96
|
+
|
|
97
|
+
Regras do contrato de consistência:
|
|
98
|
+
|
|
99
|
+
1. Qualquer status diferente de `ok`/`not-installed` é exposto por
|
|
100
|
+
`forge-cli registry` (`consistent: false` + `consistency`) — uma
|
|
101
|
+
instalação pela metade nunca aparece saudável.
|
|
102
|
+
2. `install` recusa com `stage: "incomplete"` sobre estado
|
|
103
|
+
inconsistente; `--clean` é o caminho de reparo (backup da instalação
|
|
104
|
+
anterior até o commit, restauração em qualquer falha).
|
|
105
|
+
3. `uninstall --method registry` remove também órfãs (disco sem state),
|
|
106
|
+
senão o reparo ficaria sem saída.
|
|
107
|
+
4. O commit é a última fronteira: receipt + state são gravados juntos
|
|
108
|
+
sob o lifecycle lock; falha nesse ponto é `stage: "persist"` com o
|
|
109
|
+
errno (EACCES/ENOSPC) no detalhe — o disco pode conter a venv, mas
|
|
110
|
+
a instalação permanece "não saudável" até o reparo.
|
|
111
|
+
5. Escritas são atômicas (tmp + fsync + rename) e varrem `*.tmp`
|
|
112
|
+
órfãos de runs mortos com SIGKILL.
|
|
113
|
+
|
|
114
|
+
## Lifecycle lock
|
|
115
|
+
|
|
116
|
+
`~/.forge-cli/forges/.forge-lifecycle.lock` é um diretório criado com
|
|
117
|
+
`mkdir` (atômico por construção de fs) contendo `info.json`
|
|
118
|
+
(`pid`, `at`). Titular com PID morto é quebrado na hora; lock sem
|
|
119
|
+
metadata legível só é stale após o threshold de idade; a liberação é
|
|
120
|
+
best-effort. O lock serializa install/uninstall/pin/update — quem
|
|
121
|
+
perde a corrida re-checa o state sob o lock antes de recusar, então
|
|
122
|
+
`already-installed`/`incomplete` refletem o estado pós-serialização,
|
|
123
|
+
nunca uma corrida de observação.
|
|
@@ -83,3 +83,49 @@ erro de binário esbuild, rode
|
|
|
83
83
|
spec nova.
|
|
84
84
|
- `vitest` é `^5` para evitar vulnerabilidades do `tinypool` (ver
|
|
85
85
|
`npm audit`).
|
|
86
|
+
|
|
87
|
+
## Instalação registry incompleta ou interrompida
|
|
88
|
+
|
|
89
|
+
Uma instalação morta no meio (SIGKILL, queda de energia, disco cheio)
|
|
90
|
+
nunca se apresenta como saudável: `forge-cli registry` marca a linha
|
|
91
|
+
com `incompleta` e o JSON carrega `consistency` com o motivo exato:
|
|
92
|
+
|
|
93
|
+
| `consistency` | Significado |
|
|
94
|
+
| -------------------- | -------------------------------------------------- |
|
|
95
|
+
| `orphaned` | venv/arquivos no disco sem entrada no `state.json` |
|
|
96
|
+
| `missing-receipt` | entrada no state, mas `install.json` ausente |
|
|
97
|
+
| `unreadable-receipt` | `install.json` não parseia |
|
|
98
|
+
| `forge-mismatch` | `install.json` registra outra Forja |
|
|
99
|
+
| `version-mismatch` | `install.json` e `state.json` divergem na versão |
|
|
100
|
+
| `missing-venv` | state+receipt coerentes, mas a venv sumiu |
|
|
101
|
+
|
|
102
|
+
Reparo documentado (as duas únicas portas de saída honestas):
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
forge-cli reinstall --method registry <forja> --clean # regrava tudo com backup da anterior
|
|
106
|
+
forge-cli uninstall --method registry <forja> # remove venv + state + receipt (inclui órfãs)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
`install` sem `--clean` recusa com `incomplete` — ela nunca sobrescreve
|
|
110
|
+
uma instalação pela metade fingindo que já existia.
|
|
111
|
+
|
|
112
|
+
## Lifecycle lock preso (`busy`)
|
|
113
|
+
|
|
114
|
+
Operações registry (install/uninstall/pin) serializam por
|
|
115
|
+
`~/.forge-cli/forges/.forge-lifecycle.lock`. Se o erro diz `busy`:
|
|
116
|
+
|
|
117
|
+
- **Outra execução em andamento** — espere terminar; o titular é o PID
|
|
118
|
+
gravado em `.forge-lifecycle.lock/info.json`.
|
|
119
|
+
- **Titular morto** (o PID não existe mais) — o próprio CLI detecta e
|
|
120
|
+
quebra o lock automaticamente na próxima execução; nada a fazer.
|
|
121
|
+
- **Lock órfão sem metadata legível** — só é considerado stale depois
|
|
122
|
+
de expirar o threshold de idade; se persistir além disso, remova o
|
|
123
|
+
diretório `.forge-lifecycle.lock` manualmente (seguro: quem cria o
|
|
124
|
+
lock nunca tem trabalho a perder fora dele).
|
|
125
|
+
|
|
126
|
+
## `state.json` corrompido
|
|
127
|
+
|
|
128
|
+
Leitura nunca escreve: um `state.json` que não parseia é tratado como
|
|
129
|
+
vazio (nada é removido nem sobrescrito) e a evidência só vai para
|
|
130
|
+
`state.json.corrupt` no momento em que uma escrita real acontecer —
|
|
131
|
+
assim `--plan`/`--check`/`registry` (list) não têm efeito colateral.
|