expxdev 0.1.1 → 0.3.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/README.md +459 -72
- package/dist/cli/expx.d.ts +2 -0
- package/dist/cli/expx.js +55 -6
- package/dist/cli/expx.js.map +1 -1
- package/dist/cli/init.js +6 -2
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/perguntar.d.ts +37 -0
- package/dist/cli/perguntar.js +76 -0
- package/dist/cli/perguntar.js.map +1 -0
- package/dist/cli/wizard.d.ts +21 -0
- package/dist/cli/wizard.js +101 -0
- package/dist/cli/wizard.js.map +1 -0
- package/dist/doctor/verificadores.js +97 -1
- package/dist/doctor/verificadores.js.map +1 -1
- package/dist/harness/hooks.d.ts +27 -0
- package/dist/harness/hooks.js +36 -0
- package/dist/harness/hooks.js.map +1 -0
- package/dist/harness/settings.d.ts +2 -1
- package/dist/harness/settings.js +40 -2
- package/dist/harness/settings.js.map +1 -1
- package/dist/nucleo/caminhos.d.ts +1 -1
- package/dist/nucleo/catalogo.d.ts +1 -1
- package/dist/nucleo/catalogo.js +7 -1
- package/dist/nucleo/catalogo.js.map +1 -1
- package/dist/nucleo/layout.d.ts +3 -2
- package/dist/nucleo/layout.js +37 -1
- package/dist/nucleo/layout.js.map +1 -1
- package/dist/nucleo/versao.d.ts +1 -1
- package/dist/parser/conformidade/regras.d.ts +1 -0
- package/dist/parser/conformidade/regras.js +24 -0
- package/dist/parser/conformidade/regras.js.map +1 -1
- package/dist/parser/esquema/enums.d.ts +19 -0
- package/dist/parser/esquema/enums.js +18 -0
- package/dist/parser/esquema/enums.js.map +1 -1
- package/dist/parser/esquema/evento.d.ts +123 -0
- package/dist/parser/esquema/evento.js +141 -0
- package/dist/parser/esquema/evento.js.map +1 -0
- package/dist/parser/leitura/rejeicao.d.ts +9 -0
- package/dist/parser/leitura/rejeicao.js +56 -0
- package/dist/parser/leitura/rejeicao.js.map +1 -1
- package/dist/parser/memoria/ler.d.ts +38 -0
- package/dist/parser/memoria/ler.js +46 -0
- package/dist/parser/memoria/ler.js.map +1 -0
- package/dist/parser/memoria/projetar.d.ts +3 -0
- package/dist/parser/memoria/projetar.js +132 -0
- package/dist/parser/memoria/projetar.js.map +1 -0
- package/dist/parser/memoria/tipos.d.ts +155 -0
- package/dist/parser/memoria/tipos.js +97 -0
- package/dist/parser/memoria/tipos.js.map +1 -0
- package/dist/parser/projeto/montar.d.ts +17 -0
- package/dist/parser/projeto/montar.js +17 -0
- package/dist/parser/projeto/montar.js.map +1 -1
- package/dist/plugin/montagem.d.ts +7 -0
- package/dist/plugin/montagem.js +22 -2
- package/dist/plugin/montagem.js.map +1 -1
- package/dist/servidor/http.js +5 -0
- package/dist/servidor/http.js.map +1 -1
- package/dist/servidor/observador.js +5 -1
- package/dist/servidor/observador.js.map +1 -1
- package/dist/teste/repo-fixture.d.ts +7 -0
- package/dist/teste/repo-fixture.js +18 -0
- package/dist/teste/repo-fixture.js.map +1 -1
- package/nucleo/README.md +79 -0
- package/nucleo/hooks/expx-rastro.sh +261 -0
- package/package.json +2 -1
- package/ui/dist/assets/index-BNE_RJrV.js +15 -0
- package/ui/dist/index.html +1 -1
- package/ui/dist/assets/index-BmDTogQZ.js +0 -14
package/README.md
CHANGED
|
@@ -36,14 +36,58 @@ com namespace no Claude Code (`/expx:sprintx-sprints`) e sem namespace no OpenCo
|
|
|
36
36
|
|
|
37
37
|
---
|
|
38
38
|
|
|
39
|
-
##
|
|
39
|
+
## Índice
|
|
40
|
+
|
|
41
|
+
| | |
|
|
42
|
+
|---|---|
|
|
43
|
+
| **[O problema que o método resolve](#o-problema-que-o-método-resolve)** | por que existe um método, e não só um prompt melhor |
|
|
44
|
+
| **[O ecossistema](#o-ecossistema)** | as seis skills, o que cada uma faz e quando usar |
|
|
45
|
+
| **[Como as peças se encaixam](#como-as-peças-se-encaixam)** | o fluxo de ponta a ponta, com o diagrama |
|
|
46
|
+
| **[As três camadas de garantia](#as-três-camadas-de-garantia)** | skill, hook e agente — da mais fraca à mais forte |
|
|
47
|
+
| **[Os dois contratos](#os-dois-contratos-compartilhados)** | `expx-schema` e `expx-eventos`, o que faz tudo se encaixar |
|
|
48
|
+
| **[O que fica no seu projeto](#o-que-fica-no-seu-projeto)** | cada pasta, quem escreve e quem lê |
|
|
49
|
+
| **[Subcomandos](#subcomandos)** · **[Lock e atualização](#versão-lock-e-atualização)** · **[Doctor](#o-que-o-doctor-verifica)** · **[Painel](#o-painel)** | a referência do CLI |
|
|
50
|
+
| **[Anatomia do `init`](#anatomia-do-init-passo-a-passo)** | o que roda, em que ordem, e por quê |
|
|
51
|
+
| **[A memória do projeto](#a-memória-do-projeto)** | o que já se sabe sobre este arquivo, antes de mexer nele |
|
|
52
|
+
| **[Segurança](#segurança-e-limites)** · **[Desenvolvimento](#desenvolvimento)** | limites e arquitetura interna |
|
|
53
|
+
|
|
54
|
+
---
|
|
40
55
|
|
|
41
|
-
O
|
|
56
|
+
## O problema que o método resolve
|
|
57
|
+
|
|
58
|
+
Pedir a um agente de IA para construir uma feature funciona — até a segunda hora. O plano era
|
|
59
|
+
vago o bastante para o agente ter que decidir sozinho no meio da implementação, então ele
|
|
60
|
+
decide: escolhe um padrão que não é o do projeto, escreve o teste na pasta que o runner não
|
|
61
|
+
olha, refatora três arquivos que ninguém pediu, e entrega um diff de 600 linhas em que as
|
|
62
|
+
quatro que importam estão perdidas. Nada disso exige um modelo ruim — exige um modelo
|
|
63
|
+
prestativo trabalhando sem as restrições que um desenvolvedor experiente aplicaria por
|
|
64
|
+
instinto.
|
|
65
|
+
|
|
66
|
+
O método Expx é o conjunto dessas restrições, escrito. Ele parte de quatro apostas:
|
|
67
|
+
|
|
68
|
+
1. **Todo o esforço vai para o planejamento.** Uma pergunta feita durante a execução é sempre
|
|
69
|
+
uma falha da fase de planejamento. Se a ambiguidade foi eliminada antes, a execução pode
|
|
70
|
+
ser autônoma sem virar aposta.
|
|
71
|
+
2. **Nada avança sem critério verificável.** Task, fase e sprint têm portão de aceite binário,
|
|
72
|
+
sem adjetivo. TDD não é sugestão: o teste vem antes, e a task só fecha com a suíte inteira
|
|
73
|
+
verde.
|
|
74
|
+
3. **O escopo é travado no que a investigação provou.** O que não está no plano não é tocado.
|
|
75
|
+
Melhoria avulsa vira registro de dívida, nunca um brinde no diff.
|
|
76
|
+
4. **Quem implementa não aprova.** O QA e a auditoria são papéis distintos, e os agentes que
|
|
77
|
+
os executam têm acesso somente de leitura — o que transforma "aponta, não corrige" de
|
|
78
|
+
promessa em impossibilidade técnica.
|
|
79
|
+
|
|
80
|
+
Este repositório é o **centro** do ecossistema: o CLI que instala e mantém as skills, e o
|
|
81
|
+
painel que lê o que elas gravam.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## O ecossistema
|
|
42
86
|
|
|
43
87
|
<picture>
|
|
44
88
|
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/ecossistema-dark.svg">
|
|
45
89
|
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/ecossistema-light.svg">
|
|
46
|
-
<img alt="O CLI busca as
|
|
90
|
+
<img alt="O CLI busca as seis skills, empacota como plugin e configura os dois harnesses" src="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/ecossistema-light.svg" width="100%">
|
|
47
91
|
</picture>
|
|
48
92
|
|
|
49
93
|
| Skill | O que faz | Quando usar |
|
|
@@ -53,9 +97,178 @@ O método Expx é um conjunto de skills que se compõem. O CLI é quem as instal
|
|
|
53
97
|
| **[legadox](https://github.com/bittencourtthulio/legadox)** | **Camada** que endurece o trabalho em projetos legados. Não acrescenta fase: muda o *rigor* de cada uma, proporcional ao raio de impacto da mudança. | Mexer em código sem testes ou sem dono |
|
|
54
98
|
| **[stackx](https://github.com/bittencourtthulio/stackx)** | **Camada** que descobre o dialeto técnico do repositório — convenções, padrões e aderência — para o código novo parecer com o que já existe. | Entrar em base desconhecida |
|
|
55
99
|
| **[mergex](https://github.com/bittencourtthulio/mergex)** | Versionamento, entrega e revisão: branch, um commit por task, portão de prontidão, descrição de PR, pacote de QA e abertura do pull request. | Levar o trabalho pronto até o merge |
|
|
100
|
+
| **[memox](https://github.com/bittencourtthulio/MemoX)** | **Camada** de memória: indexa os artefatos já fechados — relatórios, causas raiz, decisões, QA, entregas — e responde o que já se sabe sobre um arquivo antes de alguém mexer nele. | Saber se este arquivo já quebrou antes |
|
|
101
|
+
|
|
102
|
+
**Camadas** (`legadox`, `stackx`, `memox`) sozinhas não fazem nada — elas modificam o
|
|
103
|
+
comportamento de `sprintx` e `runx`. O CLI avisa se você selecionar uma camada sem base, mas
|
|
104
|
+
nunca impede.
|
|
105
|
+
|
|
106
|
+
### Build e Run são a mesma disciplina
|
|
107
|
+
|
|
108
|
+
`sprintx` e `runx` não são dois métodos: são o mesmo método com gatilhos diferentes.
|
|
109
|
+
|
|
110
|
+
| | **sprintx** (Build) | **runx** (Run) |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| **Gatilho** | feature nova, planejada do zero | ocorrência num sistema em produção |
|
|
113
|
+
| **Entrada** | uma ideia, um requisito | um chamado, ticket ou relato de cliente |
|
|
114
|
+
| **Estágios** | F1…F6 (ingestão → execução) | E1…E5 (investigação → relatório) |
|
|
115
|
+
| **Saída** | a feature entregue | a ocorrência encerrada, com dois relatórios |
|
|
116
|
+
|
|
117
|
+
As duas compartilham **exatamente** os mesmos contratos: base de conhecimento antes de
|
|
118
|
+
qualquer plano, hierarquia sprint → fase → task, TDD obrigatório com no mínimo dois testes por
|
|
119
|
+
task, critério de aceite verificável em toda transição, paralelismo declarado no plano e
|
|
120
|
+
execução autônoma guiada por um arquivo orquestrador.
|
|
121
|
+
|
|
122
|
+
**Muda o gatilho e o tamanho. Nunca o rigor.**
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## Como as peças se encaixam
|
|
127
|
+
|
|
128
|
+
<picture>
|
|
129
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/metodo-dark.svg">
|
|
130
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/metodo-light.svg">
|
|
131
|
+
<img alt="O metodo Expx de ponta a ponta: o gatilho escolhe entre sprintx e runx, as camadas stackx e legadox modificam as duas, a mergex entrega e o painel le tudo" src="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/metodo-light.svg" width="100%">
|
|
132
|
+
</picture>
|
|
133
|
+
|
|
134
|
+
Em uma frase: **`stackx` diz como este projeto escreve código, `legadox` diz o quanto ter
|
|
135
|
+
medo, `sprintx` e `runx` fazem o trabalho, `mergex` entrega, e o `expxdev` instala todos e
|
|
136
|
+
mostra o andamento.**
|
|
137
|
+
|
|
138
|
+
A composição concreta, skill a skill:
|
|
139
|
+
|
|
140
|
+
| Quando a camada existe | O que muda na `sprintx` | O que muda na `runx` |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| **`docs/stack/CONVENCOES.md`** *(stackx)* | a ingestão lê as convenções; a descoberta transforma cada PROPOSTA em pergunta; o plano define caminho do teste, camada e padrão de erro **por task**, em vez de deixar para o executor; a auditoria roda a verificação de aderência | a investigação consulta o cartucho conforme o sintoma; o fix obedece o padrão de teste e o isolamento de banco |
|
|
143
|
+
| **`docs/legado/PERFIL.md`** *(legadox)* | cada fase ganha rigor proporcional ao raio: caracterização antes de alterar, orçamento de diff por task, plano de reversão, aprovação humana em raio ALTO | idem, sobre os cinco estágios |
|
|
144
|
+
| **`mergex` instalada** | abre a branch no início da F6, commita cada task, e entrega ao fim | abre a branch no início do E3, e entrega entre o E4 e o E5 |
|
|
145
|
+
|
|
146
|
+
> **A ausência nunca quebra.** Sem `CONVENCOES.md`, sem `PERFIL.md` ou sem a `mergex`, as
|
|
147
|
+
> outras skills se comportam exatamente como se comportariam sem elas. Insumo que não existe
|
|
148
|
+
> vira aviso do que falta — nunca invenção, e nunca um erro que trava o trabalho.
|
|
149
|
+
|
|
150
|
+
### Uma regra de precedência que evita o pior colateral
|
|
151
|
+
|
|
152
|
+
`stackx` descreve **o que deve ser seguido daqui pra frente**. `legadox` descreve **o que
|
|
153
|
+
existe hoje**, incluindo os dialetos conflitantes. Em projeto novo, só o `stackx` governa. **Em
|
|
154
|
+
projeto legado, na área tocada manda o padrão local descrito no `PERFIL.md`; o `stackx` governa
|
|
155
|
+
apenas código novo, em arquivo novo.**
|
|
156
|
+
|
|
157
|
+
Sem essa regra, a IA "moderniza" arquivo antigo achando que está obedecendo convenção — o
|
|
158
|
+
colateral mais perigoso que existe, porque vem com a justificativa de estar seguindo uma regra.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## As três camadas de garantia
|
|
163
|
+
|
|
164
|
+
<picture>
|
|
165
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/camadas-dark.svg">
|
|
166
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/camadas-light.svg">
|
|
167
|
+
<img alt="As tres camadas que garantem o metodo: a skill instrui, o hook barra de forma deterministica, e o agente julga em contexto proprio" src="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/camadas-light.svg" width="100%">
|
|
168
|
+
</picture>
|
|
169
|
+
|
|
170
|
+
Uma regra escrita na skill é uma instrução — e instrução é coisa que o modelo pode esquecer na
|
|
171
|
+
task 14 de uma execução longa, justamente quando o trabalho é grande e o risco é maior. Por
|
|
172
|
+
isso o método tem três camadas, e cada uma cobre o que a anterior não garante:
|
|
173
|
+
|
|
174
|
+
- **A skill instrui.** É o método escrito: fases, contratos, regras invioláveis, templates.
|
|
175
|
+
- **O hook barra.** Script determinístico, executado pelo harness e não pelo modelo. Roda
|
|
176
|
+
sempre, porque não depende de ninguém lembrar.
|
|
177
|
+
- **O agente julga.** Roda em contexto próprio, com ferramentas restritas — não vê o raciocínio
|
|
178
|
+
de quem produziu o trabalho, e não tem como corrigir o que encontra.
|
|
179
|
+
|
|
180
|
+
### Todo hook de método nasce em modo aviso
|
|
181
|
+
|
|
182
|
+
| Modo | Comportamento | Quando promover |
|
|
183
|
+
|---|---|---|
|
|
184
|
+
| `aviso` | registra no rastro, não bloqueia | estado inicial de todo hook de método |
|
|
185
|
+
| `bloqueio` | barra a ação e devolve o motivo ao modelo | só depois de rodar semanas sem falso positivo |
|
|
186
|
+
|
|
187
|
+
A razão é prática: **hook que dá falso positivo é desinstalado, e junto com ele vão os que
|
|
188
|
+
funcionavam.** A exceção são os hooks de segurança, que nascem em `bloqueio` e falham fechados
|
|
189
|
+
— segredo commitado não tem volta, e o falso positivo ali é raro.
|
|
190
|
+
|
|
191
|
+
A promoção é decisão humana, tomada olhando as violações que o rastro acumulou. O modo de cada
|
|
192
|
+
hook vive em `.expx/hooks.json`, e cada skill traz um `doctor` que mostra o estado atual.
|
|
193
|
+
|
|
194
|
+
### Os agentes do ecossistema
|
|
195
|
+
|
|
196
|
+
| Agente | Usado por | Ferramentas | Papel |
|
|
197
|
+
|---|---|---|---|
|
|
198
|
+
| `auditor-plano` | sprintx F5 | **leitura apenas** | Fura o plano antes de ele virar código |
|
|
199
|
+
| `revisor-testes` | sprintx, runx | **leitura apenas** | Responde: esse teste passaria com a implementação errada? |
|
|
200
|
+
| `qa` | runx E4 | leitura + rodar suíte | Valida contra os critérios; não corrige |
|
|
201
|
+
| `investigador` | runx E1, legadox | leitura + busca | Monta a base e prova a causa raiz |
|
|
202
|
+
| `cartografo` | stackx, legadox | leitura + histórico | Varre o repositório e extrai convenção ou perfil |
|
|
203
|
+
|
|
204
|
+
> Os agentes de veredito — `auditor-plano`, `revisor-testes`, `qa` — têm acesso **somente de
|
|
205
|
+
> leitura**. Um agente sem restrição declarada **herda todas as ferramentas** no Claude Code,
|
|
206
|
+
> o que destruiria exatamente a garantia que justifica o agente existir.
|
|
207
|
+
|
|
208
|
+
**Hooks e agentes vivem hoje nos repositórios das skills**, instalados a partir de cada um. O
|
|
209
|
+
`init` monta o plugin com as skills e os comandos; a camada determinística de cada skill segue
|
|
210
|
+
o contrato `expx-eventos`, documentado abaixo.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Os dois contratos compartilhados
|
|
215
|
+
|
|
216
|
+
As seis skills não se conhecem por código: elas se encontram em dois contratos escritos. É
|
|
217
|
+
isso que permite instalar três delas e não as outras duas, atualizar uma sem tocar nas demais,
|
|
218
|
+
ou escrever uma sexta amanhã.
|
|
219
|
+
|
|
220
|
+
| Contrato | O que padroniza | Quem escreve | Quem lê hoje |
|
|
221
|
+
|---|---|---|---|
|
|
222
|
+
| **[`expx-schema` v1](docs/contrato/CONTRATO-expx-schema-v1.md)** | o frontmatter YAML de todo arquivo de estado — plano, tasks, bloqueios, QA, relatórios | as skills | **o painel** |
|
|
223
|
+
| **[`expx-eventos` v1](docs/contrato/CONTRATO-expx-eventos.md)** | o rastro append-only `docs/eventos/<trabalho_id>.jsonl`, e o comportamento de hooks e agentes | as skills e os hooks | as próprias skills e o `doctor` de cada uma |
|
|
224
|
+
|
|
225
|
+
> O painel desta versão lê **apenas o `expx-schema`** — o estado. A leitura do rastro de
|
|
226
|
+
> eventos está especificada no contrato e ainda não implementada no painel.
|
|
227
|
+
|
|
228
|
+
**O estado responde "onde está"; o rastro responde "o que aconteceu e quando".**
|
|
229
|
+
|
|
230
|
+
```yaml
|
|
231
|
+
---
|
|
232
|
+
expx_schema: 1
|
|
233
|
+
expx_tool: runx # sprintx | runx — quem escreveu
|
|
234
|
+
kind: tasks
|
|
235
|
+
trabalho_id: OC-2026-0142
|
|
236
|
+
atualizado_em: 2026-08-29
|
|
237
|
+
tasks:
|
|
238
|
+
- id: T-01.01
|
|
239
|
+
status: concluida
|
|
240
|
+
criterio_aceite: O teste falha antes do fix e passa depois
|
|
241
|
+
suite: verde
|
|
242
|
+
---
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
```json
|
|
246
|
+
{"ts":"2026-08-29T14:32:10Z","expx_eventos":1,"trabalho_id":"OC-2026-0142",
|
|
247
|
+
"ferramenta":"runx","origem":"hook","evento":"task_concluida","fase":"e3",
|
|
248
|
+
"task":"T-01.02","agente":"principal","resultado":"ok","detalhe":"suite verde, 14 testes"}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Os kinds compartilhados entre `sprintx` e `runx` — `orquestrador`, `sprint`, `fases`, `tasks`,
|
|
252
|
+
`bloqueios`, `base_indice` — são **idênticos campo por campo**; o campo `expx_tool` diz qual
|
|
253
|
+
das duas escreveu. A máquina lê o YAML e o JSONL; a pessoa lê a prosa abaixo deles.
|
|
254
|
+
|
|
255
|
+
Uma consequência que não estava prevista: o rastro dá o **esforço real por task sem ninguém
|
|
256
|
+
anotar nada**, e é isso que calibra a estimativa da `sprintx` nas features seguintes.
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## O que fica no seu projeto
|
|
261
|
+
|
|
262
|
+
<picture>
|
|
263
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/disco-dark.svg">
|
|
264
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/disco-light.svg">
|
|
265
|
+
<img alt="O que cada skill grava no seu projeto e quem le o que: as skills escrevem, os hooks acrescentam o rastro, e o painel apenas le" src="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/disco-light.svg" width="100%">
|
|
266
|
+
</picture>
|
|
56
267
|
|
|
57
|
-
|
|
58
|
-
|
|
268
|
+
`<trabalho_id>` é o mesmo identificador em todas as skills: o `<slug-da-feature>` da `sprintx`
|
|
269
|
+
ou o `<OC-ID>-<slug>` da `runx`. **Um trabalho, um nome, do plano até a entrega** — é o que
|
|
270
|
+
permite ao painel juntar o plano, o raio de impacto, a entrega e o rastro numa linha do tempo
|
|
271
|
+
só.
|
|
59
272
|
|
|
60
273
|
---
|
|
61
274
|
|
|
@@ -72,9 +285,10 @@ O método Expx é um conjunto de skills que se compõem. O CLI é quem as instal
|
|
|
72
285
|
|
|
73
286
|
O painel funciona **sem `init`**: ele não precisa de nada instalado.
|
|
74
287
|
|
|
75
|
-
###
|
|
288
|
+
### Flags do `init`
|
|
76
289
|
|
|
77
|
-
|
|
290
|
+
A seleção é feita por flag — a escolha é declarativa, o que faz a mesma linha servir ao seu
|
|
291
|
+
terminal e ao CI:
|
|
78
292
|
|
|
79
293
|
```bash
|
|
80
294
|
npx expxdev init --skills sprintx,runx,mergex --harness claude,opencode --yes
|
|
@@ -82,12 +296,67 @@ npx expxdev init --skills sprintx,runx,mergex --harness claude,opencode --yes
|
|
|
82
296
|
|
|
83
297
|
| Flag | Efeito |
|
|
84
298
|
|---|---|
|
|
85
|
-
| `--skills <lista>` | Skills a instalar, separadas por vírgula |
|
|
86
|
-
| `--harness <lista>` | `claude`, `opencode`, ou os dois |
|
|
87
|
-
| `--
|
|
88
|
-
| `--yes` | Pula confirmações |
|
|
299
|
+
| `--skills <lista>` | Skills a instalar, separadas por vírgula. Repetível |
|
|
300
|
+
| `--harness <lista>` | `claude`, `opencode`, ou os dois. Padrão: `claude` |
|
|
301
|
+
| `--yes` / `--sim` | Aplica sem exigir terminal interativo |
|
|
89
302
|
|
|
90
|
-
|
|
303
|
+
Todas aceitam também a forma `--flag=valor`.
|
|
304
|
+
|
|
305
|
+
**Sem terminal interativo e sem `--yes`**, o `init` imprime o que instalaria e sai **sem
|
|
306
|
+
escrever nada** — é o modo de simulação, e é o que protege um CI de escrever por engano.
|
|
307
|
+
|
|
308
|
+
> A seleção interativa — escolher as skills numa lista, em vez de digitá-las — está planejada
|
|
309
|
+
> e ainda não implementada; o plano vive em [`docs/selecao-interativa-init/`](docs/selecao-interativa-init/).
|
|
310
|
+
> Hoje o `init` não faz nenhuma pergunta: com `--yes` ou com TTY, ele aplica direto.
|
|
311
|
+
|
|
312
|
+
---
|
|
313
|
+
|
|
314
|
+
## Anatomia do `init`, passo a passo
|
|
315
|
+
|
|
316
|
+
<picture>
|
|
317
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/plugin-dark.svg">
|
|
318
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/plugin-light.svg">
|
|
319
|
+
<img alt="Anatomia do que o expx init monta: o marketplace local, o plugin expx com so as skills escolhidas, e o lock que trava versao e hash de cada arquivo" src="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/plugin-light.svg" width="100%">
|
|
320
|
+
</picture>
|
|
321
|
+
|
|
322
|
+
Para cada skill selecionada, em ordem:
|
|
323
|
+
|
|
324
|
+
1. **Resolve a versão alvo.** Busca a **maior tag de versão semântica** do repositório —
|
|
325
|
+
comparando número a número, porque ordenar como texto colocaria `v1.10.0` antes de
|
|
326
|
+
`v1.2.0`. Pré-lançamento (`-rc.1`) é ignorado: não é versão publicada. Sem nenhuma tag, cai
|
|
327
|
+
para a branch padrão e **avisa explicitamente** que aquela skill não está travada.
|
|
328
|
+
2. **Busca o conteúdo** com `git clone --depth 1 --branch <referência>` — clone raso, usando o
|
|
329
|
+
`git` do sistema. É de propósito: assim ele aproveita a credencial já configurada na
|
|
330
|
+
máquina (repositório privado funciona sem CLI nenhum saber de token) e não esbarra em
|
|
331
|
+
limite de requisição de API.
|
|
332
|
+
3. **Detecta o layout.** Os repositórios das skills não têm todos a mesma forma: alguns trazem
|
|
333
|
+
a skill embutida em `.claude/skills/<nome>/`, outros numa pasta `skill/` na raiz. O CLI não
|
|
334
|
+
assume caminho: procura o **`SKILL.md` mais raso** e adota a pasta dele como raiz, depois
|
|
335
|
+
confere que o `name:` do frontmatter é mesmo a skill pedida. Um layout novo passa a
|
|
336
|
+
funcionar sem tocar nesta camada.
|
|
337
|
+
4. **Verifica os caminhos.** Recusa qualquer skill que referencie caminho **fora da própria
|
|
338
|
+
pasta** — a razão está logo abaixo.
|
|
339
|
+
5. **Calcula o hash de cada arquivo** e registra no lock, junto com repositório, referência,
|
|
340
|
+
commit e a data de resolução.
|
|
341
|
+
|
|
342
|
+
**Uma skill que falha não derruba as outras**: o erro dela é reportado nominalmente e o `init`
|
|
343
|
+
segue com as demais. Você fica sabendo exatamente qual não entrou e por quê.
|
|
344
|
+
|
|
345
|
+
Só depois do loop é que a escrita acontece, e ela é **atômica**: a montagem inteira ocorre numa
|
|
346
|
+
pasta temporária **ao lado do destino** — não em `/tmp`, porque `rename` só é atômico dentro do
|
|
347
|
+
mesmo sistema de arquivos — e é trocada por `rename` ao final. Se falhar no meio, o `.expx/`
|
|
348
|
+
anterior é devolvido ao lugar e permanece intacto.
|
|
349
|
+
|
|
350
|
+
Por fim, o harness é configurado: `.claude/settings.json` é **mesclado** — com backup datado,
|
|
351
|
+
preservando todo o resto, e recusando-se a "consertar" JSON inválido — e o `.opencode/` é
|
|
352
|
+
materializado se você escolheu o OpenCode.
|
|
353
|
+
|
|
354
|
+
> **Sobre o registro do plugin.** Declarar o marketplace no `settings.json` do projeto **não
|
|
355
|
+
> instala** o plugin — isso foi verificado em execução, não presumido da documentação. O `init`
|
|
356
|
+
> chama `claude plugin marketplace add` e `claude plugin install`. Como esse registro grava um
|
|
357
|
+
> caminho absoluto na configuração do usuário, ele não viaja no commit: cada pessoa roda
|
|
358
|
+
> `expx init` na própria máquina. Sem o binário `claude` no PATH, o `.expx/` é montado
|
|
359
|
+
> normalmente e o CLI imprime os dois comandos para você rodar à mão.
|
|
91
360
|
|
|
92
361
|
---
|
|
93
362
|
|
|
@@ -99,10 +368,9 @@ Sem terminal interativo e sem `--yes`, o `init` mostra o que faria e sai **sem e
|
|
|
99
368
|
<img alt="Instalacao travada por lock; atualizacao explicita que nunca sobrescreve trabalho local" src="https://raw.githubusercontent.com/bittencourtthulio/expxdev/main/.github/assets/lock-light.svg" width="100%">
|
|
100
369
|
</picture>
|
|
101
370
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
quando existe tag.
|
|
371
|
+
O `expx-lock.json` guarda, por skill: o repositório, a referência resolvida, se ela está
|
|
372
|
+
travada em versão publicada, o commit exato, a data e **o hash de cada arquivo**. É esse
|
|
373
|
+
último campo que permite detectar modificação local sem consultar a rede.
|
|
106
374
|
|
|
107
375
|
### O que o `update` faz
|
|
108
376
|
|
|
@@ -119,42 +387,18 @@ quando existe tag.
|
|
|
119
387
|
| *(sem argumento)* | Atualiza todas as skills instaladas |
|
|
120
388
|
| `<skill...>` | Atualiza apenas as nomeadas |
|
|
121
389
|
| `--check` | Só mostra o que mudaria, não aplica nada |
|
|
122
|
-
| `--to <ref>` | Fixa uma skill numa tag ou commit específico |
|
|
123
|
-
| `--
|
|
124
|
-
| `--yes` | Pula confirmações |
|
|
125
|
-
|
|
126
|
-
> **Rollback.** Como `.expx/` é commitado, desfazer uma atualização é revertê-lo pelo
|
|
127
|
-
> versionador (`git checkout -- .expx`). O `update` diz isso em toda execução que aplica.
|
|
390
|
+
| `--to <ref>` | Fixa uma skill numa tag ou commit específico — exige nomear exatamente uma skill |
|
|
391
|
+
| `--yes` / `--sim` | Aplica sem exigir terminal interativo |
|
|
128
392
|
|
|
129
|
-
|
|
393
|
+
A aplicação **remonta o plugin do zero** com a seleção inteira do lock, em vez de editar a
|
|
394
|
+
árvore montada. É mais lento e é de propósito: editar no lugar deixa arquivo órfão quando uma
|
|
395
|
+
skill encolhe entre versões.
|
|
130
396
|
|
|
131
|
-
|
|
397
|
+
> `--latest` é aceito pelo parser mas hoje **não altera o comportamento** — a resolução segue
|
|
398
|
+
> sempre a maior tag, ou a branch padrão quando não há tag.
|
|
132
399
|
|
|
133
|
-
|
|
134
|
-
.expx
|
|
135
|
-
expx-lock.json versão exata de cada skill + hash por arquivo
|
|
136
|
-
marketplace/
|
|
137
|
-
.claude-plugin/marketplace.json
|
|
138
|
-
plugins/expx/
|
|
139
|
-
.claude-plugin/plugin.json name: "expx"
|
|
140
|
-
skills/<só as selecionadas>/
|
|
141
|
-
commands/<só os correspondentes>/
|
|
142
|
-
.claude/settings.json mesclado, nunca sobrescrito
|
|
143
|
-
.opencode/commands/ se OpenCode for escolhido
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
**Todo o `.expx/` é commitado** — é isso que faz quem clona receber as mesmas skills. O CLI
|
|
147
|
-
verifica que nenhuma regra de `.gitignore` o esteja ignorando.
|
|
148
|
-
|
|
149
|
-
O merge do `.claude/settings.json` faz backup datado antes de tocar, mescla apenas as chaves
|
|
150
|
-
necessárias e preserva todo o resto. JSON inválido não é consertado: o CLI avisa e sai.
|
|
151
|
-
|
|
152
|
-
> **Sobre o registro do plugin.** Declarar o marketplace no `settings.json` do projeto **não
|
|
153
|
-
> instala** o plugin — isso foi verificado em execução, não presumido da documentação. O `init`
|
|
154
|
-
> chama `claude plugin marketplace add` e `claude plugin install`. Como esse registro grava um
|
|
155
|
-
> caminho absoluto na configuração do usuário, ele não viaja no commit: cada pessoa roda
|
|
156
|
-
> `expx init` na própria máquina. Sem o binário `claude` no PATH, o `.expx/` é montado
|
|
157
|
-
> normalmente e o CLI imprime os dois comandos para você rodar à mão.
|
|
400
|
+
> **Rollback.** Como `.expx/` é commitado, desfazer uma atualização é revertê-lo pelo
|
|
401
|
+
> versionador (`git checkout -- .expx`). O `update` diz isso em toda execução que aplica.
|
|
158
402
|
|
|
159
403
|
---
|
|
160
404
|
|
|
@@ -164,22 +408,36 @@ necessárias e preserva todo o resto. JSON inválido não é consertado: o CLI a
|
|
|
164
408
|
npx expxdev doctor
|
|
165
409
|
```
|
|
166
410
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
- skill não travada em versão publicada
|
|
170
|
-
- `plugin.json` e `marketplace.json` válidos, com name `expx`
|
|
171
|
-
- nenhuma skill referenciando caminho **fora da própria pasta**
|
|
172
|
-
- `settings.json` válido e com o plugin habilitado
|
|
173
|
-
- colisão de nome de skill entre Claude Code e OpenCode
|
|
174
|
-
- compatibilidade entre a versão do CLI e a estrutura em `.expx/`
|
|
175
|
-
- `.gitignore` ignorando `.expx/` indevidamente
|
|
411
|
+
Quatorze verificações, cada uma com severidade e correção sugerida. Achado de severidade `aviso`
|
|
412
|
+
não derruba a saída; `erro` sim.
|
|
176
413
|
|
|
177
|
-
|
|
414
|
+
| Verificação | Severidade |
|
|
415
|
+
|---|---|
|
|
416
|
+
| `.expx/` existe | erro |
|
|
417
|
+
| lock legível | erro |
|
|
418
|
+
| lock não é de uma versão futura do CLI | erro |
|
|
419
|
+
| `plugin.json` válido | erro |
|
|
420
|
+
| `marketplace.json` válido | erro |
|
|
421
|
+
| skill do lock presente em disco | erro |
|
|
422
|
+
| nenhuma skill referencia caminho **fora da própria pasta** | erro |
|
|
423
|
+
| `.claude/settings.json` presente | erro |
|
|
424
|
+
| plugin habilitado no `settings.json` | erro |
|
|
425
|
+
| sem colisão de nome entre Claude Code e OpenCode | erro |
|
|
426
|
+
| hook instalado tem o motor da skill ao lado | erro |
|
|
427
|
+
| `.gitignore` não ignora o `.expx/` | erro |
|
|
428
|
+
| disco não divergiu do lock (modificação local) | aviso |
|
|
429
|
+
| skill travada em versão publicada | aviso |
|
|
430
|
+
|
|
431
|
+
> **Por que "hook sem motor" é erro.** Todo caminho de falha dos hooks do memox termina em
|
|
432
|
+
> `exit 0`, de propósito: falha aberta nunca trava o prompt de quem está trabalhando. O preço é
|
|
433
|
+
> que uma instalação quebrada fica indistinguível de um projeto sem artefatos — silêncio dos
|
|
434
|
+
> dois lados. O `doctor` é o único lugar onde a diferença aparece.
|
|
178
435
|
|
|
179
436
|
> **Por que "caminho fora da própria pasta" importa.** Ao instalar, o Claude Code **copia** o
|
|
180
437
|
> plugin para `~/.claude/plugins/cache/<marketplace>/<plugin>/<versão>/`, e só a pasta do
|
|
181
438
|
> plugin vai junto. Qualquer `../` dentro de uma skill sai da árvore copiada e deixa de
|
|
182
|
-
> resolver — silenciosamente. O CLI recusa instalar uma skill assim
|
|
439
|
+
> resolver — silenciosamente. O CLI recusa instalar uma skill assim, tanto no `init` quanto no
|
|
440
|
+
> `doctor`.
|
|
183
441
|
|
|
184
442
|
---
|
|
185
443
|
|
|
@@ -189,12 +447,64 @@ Cada achado vem com a correção sugerida. Achado de severidade `aviso` não der
|
|
|
189
447
|
npx expxdev panel
|
|
190
448
|
```
|
|
191
449
|
|
|
192
|
-
Lê a pasta `docs/` do projeto, descobre os trabalhos gravados
|
|
193
|
-
|
|
194
|
-
|
|
450
|
+
Lê a pasta `docs/` do projeto, descobre os trabalhos gravados pelas skills e mostra no
|
|
451
|
+
navegador o que foi planejado, o que está em execução, o que travou e o histórico do que já foi
|
|
452
|
+
entregue. Ele lê o **estado** gravado sob o contrato `expx-schema`: o frontmatter YAML de cada
|
|
453
|
+
arquivo de plano, task, bloqueio, QA e relatório.
|
|
195
454
|
|
|
196
|
-
**Somente leitura
|
|
197
|
-
|
|
455
|
+
**Somente leitura, e não só por convenção.** Qualquer requisição que não seja `GET` recebe
|
|
456
|
+
`405` com a mensagem `o painel e somente leitura`. O servidor escuta exclusivamente em
|
|
457
|
+
`127.0.0.1` — o host é constante no código, sem flag, opção ou variável de ambiente que mude
|
|
458
|
+
isso.
|
|
459
|
+
|
|
460
|
+
Ele observa o `docs/` e atualiza sozinho: quando um arquivo muda, o navegador recebe o estado
|
|
461
|
+
novo por websocket, sem recarregar a página. A cada mudança o projeto é **relido inteiro**, não
|
|
462
|
+
em pedaços — as regras de conformidade cruzam referências entre arquivos, e uma leitura parcial
|
|
463
|
+
produziria violação falsa.
|
|
464
|
+
|
|
465
|
+
### O que ele reconhece
|
|
466
|
+
|
|
467
|
+
O painel não varre todo `.md` do projeto: procura **os nomes de arquivo do contrato** —
|
|
468
|
+
`ORQUESTRADOR.md`, `tasks.md`, `fases.md`, `sprint.md`, `01-CAUSA-RAIZ.md`, `QA.md`,
|
|
469
|
+
`tecnico.md`, `uso.md` e os demais. A razão é que muitos `.md` legítimos não têm frontmatter, e
|
|
470
|
+
varrer por extensão encheria a tela de "fora do schema" com ruído.
|
|
471
|
+
|
|
472
|
+
Um trabalho é uma pasta com `ORQUESTRADOR.md` de frontmatter válido — a regra é sobre o
|
|
473
|
+
conteúdo, não sobre o caminho. Pasta sem orquestrador é ignorada em silêncio.
|
|
474
|
+
|
|
475
|
+
Além do estado, o painel lê o índice da [`memox`](#a-memória-do-projeto), quando ele existe, e
|
|
476
|
+
o mostra na seção **Memória** — o que já se sabe sobre cada arquivo antes de alguém mexer nele.
|
|
477
|
+
Ele **não** observa `.expx/`: é lá que o índice é gravado, e observá-lo faria a reindexação
|
|
478
|
+
realimentar a recarga da tela sem dado novo nenhum.
|
|
479
|
+
|
|
480
|
+
### Ele também aponta violações do método
|
|
481
|
+
|
|
482
|
+
Além de mostrar o andamento, o painel confere o que leu contra as regras do método e lista o
|
|
483
|
+
que não bate:
|
|
484
|
+
|
|
485
|
+
| Violação | O que significa |
|
|
486
|
+
|---|---|
|
|
487
|
+
| `teste_ausente` | task sem teste de integração ou funcional declarado |
|
|
488
|
+
| `regressao_ausente` | ocorrência do tipo `bug` sem o teste que reproduz |
|
|
489
|
+
| `concluida_sem_verde` | task marcada como concluída sem a suíte verde |
|
|
490
|
+
| `paralela_com_dependencia` | task declarada paralelizável mas com dependência aberta |
|
|
491
|
+
| `sem_criterio_saida` | fase ou sprint sem critério de saída |
|
|
492
|
+
| `dependencia_inexistente` | task que depende de um id que não existe |
|
|
493
|
+
| `ciclo_dependencia` | duas ou mais tasks que se esperam em círculo |
|
|
494
|
+
| `estagio_incoerente` | estágio declarado que não combina com o estado dos arquivos |
|
|
495
|
+
| `bloqueio_antigo` | bloqueio parado há mais dias que o limite configurado |
|
|
496
|
+
|
|
497
|
+
A distinção importa e tem duas telas separadas:
|
|
498
|
+
|
|
499
|
+
- **Violação** — o painel *leu* o arquivo, e o conteúdo desobedece uma regra do método. Isso é
|
|
500
|
+
um achado sobre o trabalho.
|
|
501
|
+
- **Rejeição** — o painel *não conseguiu* ler: sem frontmatter, YAML inválido, `kind`
|
|
502
|
+
desconhecido, ou versão de schema mais nova que a suportada. Isso é um achado sobre o
|
|
503
|
+
arquivo, e ele fica de fora do painel até ser corrigido.
|
|
504
|
+
|
|
505
|
+
Cada regra tem escopo estreito de propósito, porque violação falsa é pior que violação
|
|
506
|
+
ausente: regressão não é cobrada de trabalho da `sprintx` nem de ocorrência que não é bug, e
|
|
507
|
+
critério de saída não é exigido de fase que não o declara por não existir.
|
|
198
508
|
|
|
199
509
|
| Flag | Padrão | O que faz |
|
|
200
510
|
|---|---|---|
|
|
@@ -205,6 +515,60 @@ algum. O servidor escuta exclusivamente em `127.0.0.1` — não há flag que mud
|
|
|
205
515
|
|
|
206
516
|
---
|
|
207
517
|
|
|
518
|
+
## A memória do projeto
|
|
519
|
+
|
|
520
|
+
Uma software house resolve o mesmo tipo de problema repetidamente. Bug de arredondamento numa
|
|
521
|
+
faixa de peso hoje; bug parecido no cálculo de comissão em três meses. Quem lembra do primeiro
|
|
522
|
+
resolve o segundo em vinte minutos — e quem não lembra não sabe que deveria perguntar.
|
|
523
|
+
|
|
524
|
+
A [`memox`](https://github.com/bittencourtthulio/MemoX) resolve isso indexando o que as outras
|
|
525
|
+
skills já gravaram. Ela é um **índice invertido**, não uma busca semântica: a pergunta real não
|
|
526
|
+
é "o que é parecido com isto", é "quem já mexeu neste arquivo e por quê" — e isso é uma string
|
|
527
|
+
exata. Resposta de índice aponta artefato e data, então dá para abrir e conferir; recuperação
|
|
528
|
+
semântica erra em silêncio, devolvendo algo plausível com a mesma confiança do certo.
|
|
529
|
+
|
|
530
|
+
O índice fica em `.expx/memoria/indice.json`, é **local e gitignorado**, e se reconstrói do
|
|
531
|
+
zero a qualquer momento:
|
|
532
|
+
|
|
533
|
+
```bash
|
|
534
|
+
python3 .claude/skills/memox/assets/memox.py indexar
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
### O que o painel mostra
|
|
538
|
+
|
|
539
|
+
A seção **Memória** do painel lê esse índice e mostra quatro coisas:
|
|
540
|
+
|
|
541
|
+
| Seção | O que responde |
|
|
542
|
+
|---|---|
|
|
543
|
+
| **Arquivos de risco** | quais arquivos acumulam sinal, ordenados por **regressões**, depois reprovações de QA, depois número de trabalhos |
|
|
544
|
+
| **Regressões** | onde um trabalho reabriu o que outro já tinha alterado — com a evidência e os dois artefatos de origem |
|
|
545
|
+
| **Coincidências de arquivo** | vínculos que **não** viraram regressão, com o motivo |
|
|
546
|
+
| **Artefatos contaminados** | onde o memox detectou segredo, para você ir corrigir na origem |
|
|
547
|
+
|
|
548
|
+
A ordenação por regressão, e não por movimento, é deliberada: um arquivo central é tocado por
|
|
549
|
+
dezenas de trabalhos sem nunca ter falhado. Ordenar por contagem colocaria justamente ele no
|
|
550
|
+
topo, enterrando embaixo o arquivo que já quebrou duas vezes.
|
|
551
|
+
|
|
552
|
+
**Coincidência não vira regressão por parecer plausível.** Um vínculo só é registrado como
|
|
553
|
+
regressão quando as três condições valem juntas: um arquivo apontado pela causa raiz do
|
|
554
|
+
trabalho posterior está entre os que o anterior alterou; a ordem cronológica está estabelecida;
|
|
555
|
+
e a causa do posterior é **comprovada**, não hipótese. Faltando qualquer uma, o vínculo aparece
|
|
556
|
+
na tabela de coincidências com o motivo escrito — é isso que impede o sinal mais valioso do
|
|
557
|
+
índice de virar ruído.
|
|
558
|
+
|
|
559
|
+
**Esta seção não respeita o filtro de período**, ao contrário das demais. O valor do sinal é
|
|
560
|
+
justamente o antigo: um arquivo que regrediu há dois anos continua sendo um arquivo que regride.
|
|
561
|
+
|
|
562
|
+
### Quando não há índice
|
|
563
|
+
|
|
564
|
+
Este é o caso **comum**, não um erro: o índice é local e não vai para o repositório, então um
|
|
565
|
+
clone recém-feito não tem nenhum. A tela mostra o comando que o gera e não reclama de nada. O
|
|
566
|
+
painel nunca invoca o motor — ele é Python, roda fora do painel, e o painel é somente leitura.
|
|
567
|
+
|
|
568
|
+
Índice corrompido (lido no instante em que o motor o reescreve) ou gravado numa versão de
|
|
569
|
+
formato desconhecida cai no mesmo estado: a memória fica vazia, o resto do painel segue
|
|
570
|
+
funcionando. Degradar mostrando, nunca quebrar.
|
|
571
|
+
|
|
208
572
|
## Segurança e limites
|
|
209
573
|
|
|
210
574
|
- **Nunca pede nem armazena credencial.** Repositório privado usa a credencial de git já
|
|
@@ -213,6 +577,7 @@ algum. O servidor escuta exclusivamente em `127.0.0.1` — não há flag que mud
|
|
|
213
577
|
- **Nunca escreve uma skill.** O CLI busca e empacota; jamais edita conteúdo de skill.
|
|
214
578
|
- **Escrita atômica.** A montagem acontece em pasta temporária e é trocada por `rename` ao
|
|
215
579
|
final: se falhar no meio, o `.expx/` anterior permanece intacto.
|
|
580
|
+
- **O painel é somente leitura**, e escuta apenas em `127.0.0.1`.
|
|
216
581
|
- Toda escrita destrutiva pede confirmação, com flag para pular em ambiente não interativo.
|
|
217
582
|
|
|
218
583
|
---
|
|
@@ -221,26 +586,48 @@ algum. O servidor escuta exclusivamente em `127.0.0.1` — não há flag que mud
|
|
|
221
586
|
|
|
222
587
|
```bash
|
|
223
588
|
npm install
|
|
224
|
-
npm test #
|
|
589
|
+
npm test # 295 testes, sem acesso à rede
|
|
225
590
|
npm run typecheck
|
|
226
591
|
npm run build
|
|
227
592
|
```
|
|
228
593
|
|
|
229
594
|
TypeScript strict + ESM, Node ≥ 20.19, Vitest em três projetos (`servidor`, `ui`, `cli`). A
|
|
230
|
-
suíte roda contra repositórios git locais criados em tempo de teste — nenhum teste depende
|
|
231
|
-
|
|
595
|
+
suíte roda contra repositórios git locais criados em tempo de teste — nenhum teste depende de
|
|
596
|
+
rede nem do estado do GitHub.
|
|
597
|
+
|
|
598
|
+
Arquitetura em camadas isoladas, uma pasta por responsabilidade. **Nenhuma regra de negócio
|
|
599
|
+
vive no código de linha de comando:**
|
|
232
600
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
601
|
+
```
|
|
602
|
+
src/
|
|
603
|
+
nucleo/ catálogo das skills, resolução de versão, busca, layout, lock, integridade
|
|
604
|
+
plugin/ montagem do plugin e dos manifestos, com escrita atômica
|
|
605
|
+
harness/ configuração de Claude Code e OpenCode, merge de settings, backup
|
|
606
|
+
doctor/ os quatorze verificadores e o efeito de cada achado
|
|
607
|
+
update/ comparação com o lock, detecção de modificação local, compatibilidade de schema
|
|
608
|
+
parser/ leitura do expx-schema — frontmatter, kinds, enums, descoberta e conformidade
|
|
609
|
+
e a leitura do índice da memox (memoria/), com falha aberta
|
|
610
|
+
servidor/ o painel: HTTP, websocket e o observador de arquivos (somente leitura)
|
|
611
|
+
cli/ linha de comando: roteamento de subcomando, flags e seleção interativa
|
|
612
|
+
ui/ a interface do painel (React + Vite)
|
|
613
|
+
docs/contrato/ os dois contratos compartilhados pelas seis skills
|
|
614
|
+
```
|
|
236
615
|
|
|
237
616
|
Este projeto foi planejado e executado com o próprio método — o plano completo, a base de
|
|
238
|
-
conhecimento e as decisões estão em [`docs/expx-cli/`](docs/expx-cli/)
|
|
617
|
+
conhecimento e as decisões estão em [`docs/expx-cli/`](docs/expx-cli/), e a integração da
|
|
618
|
+
memória em [`docs/memox-painel/`](docs/memox-painel/).
|
|
619
|
+
|
|
620
|
+
---
|
|
621
|
+
|
|
622
|
+
## Licença
|
|
623
|
+
|
|
624
|
+
MIT
|
|
239
625
|
|
|
240
626
|
---
|
|
241
627
|
|
|
242
628
|
<div align="center">
|
|
243
629
|
<sub>Parte do método <strong>Expx</strong> ·
|
|
630
|
+
expxdev ·
|
|
244
631
|
<a href="https://github.com/bittencourtthulio/sprintx">sprintx</a> ·
|
|
245
632
|
<a href="https://github.com/bittencourtthulio/runx">runx</a> ·
|
|
246
633
|
<a href="https://github.com/bittencourtthulio/legadox">legadox</a> ·
|
package/dist/cli/expx.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type Perguntador } from "./perguntar.js";
|
|
1
2
|
/**
|
|
2
3
|
* O entrypoint do binário `expx`.
|
|
3
4
|
*
|
|
@@ -10,4 +11,5 @@ export type Saida = {
|
|
|
10
11
|
escreverErro?: (texto: string) => void;
|
|
11
12
|
};
|
|
12
13
|
export type Executor = (resto: readonly string[], saida: Required<Saida>) => Promise<number>;
|
|
14
|
+
export declare function usarPerguntador(fabrica: () => Perguntador): void;
|
|
13
15
|
export declare function executarExpx(argv: readonly string[], saida?: Saida): Promise<number>;
|