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.
Files changed (68) hide show
  1. package/README.md +459 -72
  2. package/dist/cli/expx.d.ts +2 -0
  3. package/dist/cli/expx.js +55 -6
  4. package/dist/cli/expx.js.map +1 -1
  5. package/dist/cli/init.js +6 -2
  6. package/dist/cli/init.js.map +1 -1
  7. package/dist/cli/perguntar.d.ts +37 -0
  8. package/dist/cli/perguntar.js +76 -0
  9. package/dist/cli/perguntar.js.map +1 -0
  10. package/dist/cli/wizard.d.ts +21 -0
  11. package/dist/cli/wizard.js +101 -0
  12. package/dist/cli/wizard.js.map +1 -0
  13. package/dist/doctor/verificadores.js +97 -1
  14. package/dist/doctor/verificadores.js.map +1 -1
  15. package/dist/harness/hooks.d.ts +27 -0
  16. package/dist/harness/hooks.js +36 -0
  17. package/dist/harness/hooks.js.map +1 -0
  18. package/dist/harness/settings.d.ts +2 -1
  19. package/dist/harness/settings.js +40 -2
  20. package/dist/harness/settings.js.map +1 -1
  21. package/dist/nucleo/caminhos.d.ts +1 -1
  22. package/dist/nucleo/catalogo.d.ts +1 -1
  23. package/dist/nucleo/catalogo.js +7 -1
  24. package/dist/nucleo/catalogo.js.map +1 -1
  25. package/dist/nucleo/layout.d.ts +3 -2
  26. package/dist/nucleo/layout.js +37 -1
  27. package/dist/nucleo/layout.js.map +1 -1
  28. package/dist/nucleo/versao.d.ts +1 -1
  29. package/dist/parser/conformidade/regras.d.ts +1 -0
  30. package/dist/parser/conformidade/regras.js +24 -0
  31. package/dist/parser/conformidade/regras.js.map +1 -1
  32. package/dist/parser/esquema/enums.d.ts +19 -0
  33. package/dist/parser/esquema/enums.js +18 -0
  34. package/dist/parser/esquema/enums.js.map +1 -1
  35. package/dist/parser/esquema/evento.d.ts +123 -0
  36. package/dist/parser/esquema/evento.js +141 -0
  37. package/dist/parser/esquema/evento.js.map +1 -0
  38. package/dist/parser/leitura/rejeicao.d.ts +9 -0
  39. package/dist/parser/leitura/rejeicao.js +56 -0
  40. package/dist/parser/leitura/rejeicao.js.map +1 -1
  41. package/dist/parser/memoria/ler.d.ts +38 -0
  42. package/dist/parser/memoria/ler.js +46 -0
  43. package/dist/parser/memoria/ler.js.map +1 -0
  44. package/dist/parser/memoria/projetar.d.ts +3 -0
  45. package/dist/parser/memoria/projetar.js +132 -0
  46. package/dist/parser/memoria/projetar.js.map +1 -0
  47. package/dist/parser/memoria/tipos.d.ts +155 -0
  48. package/dist/parser/memoria/tipos.js +97 -0
  49. package/dist/parser/memoria/tipos.js.map +1 -0
  50. package/dist/parser/projeto/montar.d.ts +17 -0
  51. package/dist/parser/projeto/montar.js +17 -0
  52. package/dist/parser/projeto/montar.js.map +1 -1
  53. package/dist/plugin/montagem.d.ts +7 -0
  54. package/dist/plugin/montagem.js +22 -2
  55. package/dist/plugin/montagem.js.map +1 -1
  56. package/dist/servidor/http.js +5 -0
  57. package/dist/servidor/http.js.map +1 -1
  58. package/dist/servidor/observador.js +5 -1
  59. package/dist/servidor/observador.js.map +1 -1
  60. package/dist/teste/repo-fixture.d.ts +7 -0
  61. package/dist/teste/repo-fixture.js +18 -0
  62. package/dist/teste/repo-fixture.js.map +1 -1
  63. package/nucleo/README.md +79 -0
  64. package/nucleo/hooks/expx-rastro.sh +261 -0
  65. package/package.json +2 -1
  66. package/ui/dist/assets/index-BNE_RJrV.js +15 -0
  67. package/ui/dist/index.html +1 -1
  68. package/ui/dist/assets/index-BmDTogQZ.js +0 -14
@@ -0,0 +1,261 @@
1
+ #!/usr/bin/env bash
2
+ # expx-rastro.sh — o rastro de eventos do metodo Expx, uma vez so.
3
+ #
4
+ # Implementa o contrato `expx-eventos` v1 e as convencoes R1-R14
5
+ # (docs/contrato/CONVENCOES.md e CONTRATO-expx-eventos.md).
6
+ #
7
+ # NAO E EXECUTAVEL: os hooks fazem `source` deste arquivo.
8
+ #
9
+ # ---------------------------------------------------------------------------
10
+ # Por que este arquivo existe
11
+ #
12
+ # Cada skill tinha a sua propria implementacao do rastro — quatro no total, em
13
+ # duas linguagens. Nao eram copias que divergiram: eram reescritas, porque o
14
+ # `comum/rastro.sh` de cada repo trazia o nome da ferramenta CRAVADO no codigo
15
+ # (`"ferramenta":"sprintx"`) e por isso nao dava para compartilhar. Elas ja
16
+ # divergiam em producao: chave extra no meio do objeto, `agente` ora null ora
17
+ # "principal", tres estrategias de trabalho_id, dois conjuntos de modos.
18
+ #
19
+ # Aqui a ferramenta e PARAMETRO. Defina `EXPX_FERRAMENTA` antes do source:
20
+ #
21
+ # EXPX_FERRAMENTA=mergex
22
+ # . "$(dirname "$0")/expx-rastro.sh"
23
+ #
24
+ # ---------------------------------------------------------------------------
25
+ # Como este arquivo chega ate um projeto
26
+ #
27
+ # Por COPIA, nunca por dependencia. O `expx init` copia; cada repositorio
28
+ # continua rodando sozinho, com o que tem em disco, sem `npm install` e sem
29
+ # runtime compartilhado. A fonte e o plugin; a copia e versionada com a skill.
30
+ #
31
+ # ---------------------------------------------------------------------------
32
+ # Regras do contrato que este arquivo materializa
33
+ # 1. Rapido — sem rede, sem parser externo pesado.
34
+ # 3. Falha aberta — toda funcao retorna 0 mesmo sem conseguir gravar.
35
+ # 6. Sem estado — tudo sai de arquivo que ja existe.
36
+ # 7. Sempre grava — inclusive quando permite.
37
+
38
+ # A ferramenta e obrigatoria, mas a ausencia NAO derruba o hook (regra 3):
39
+ # cai para "desconhecida", que o validador aponta em vez de sumir em silencio.
40
+ : "${EXPX_FERRAMENTA:=desconhecida}"
41
+
42
+ # ---------------------------------------------------------------- util basica
43
+
44
+ # Raiz do repositorio: sobe ate achar .git; sem .git, o cwd.
45
+ expx_raiz() {
46
+ local d="${1:-$PWD}"
47
+ while [ "$d" != "/" ]; do
48
+ [ -d "$d/.git" ] && { printf '%s' "$d"; return 0; }
49
+ d="$(dirname "$d")"
50
+ done
51
+ printf '%s' "${1:-$PWD}"
52
+ }
53
+
54
+ # Escapa uma string para caber num JSON string literal.
55
+ # A barra invertida vem primeiro, senao escapamos o que ja foi escapado.
56
+ expx_json_escape() {
57
+ local s="$1"
58
+ s="${s//\\/\\\\}"
59
+ s="${s//\"/\\\"}"
60
+ s="${s// /\\t}"
61
+ s="${s//$'\r'/\\r}"
62
+ s="${s//$'\n'/\\n}"
63
+ printf '%s' "$s"
64
+ }
65
+
66
+ # Le uma chave de topo do JSON que o harness manda no stdin do hook.
67
+ # Com jq quando existe; sem jq, um grep tolerante. Nunca falha.
68
+ expx_json_get() {
69
+ local json="$1" chave="$2"
70
+ if command -v jq >/dev/null 2>&1; then
71
+ printf '%s' "$json" | jq -r --arg k "$chave" '.[$k] // empty' 2>/dev/null
72
+ return 0
73
+ fi
74
+ printf '%s' "$json" \
75
+ | grep -o "\"$chave\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" \
76
+ | head -1 | sed 's/.*:[[:space:]]*"//; s/"$//'
77
+ }
78
+
79
+ # Le uma chave aninhada em tool_input (ex.: file_path).
80
+ expx_tool_input_get() {
81
+ local json="$1" chave="$2"
82
+ if command -v jq >/dev/null 2>&1; then
83
+ printf '%s' "$json" | jq -r --arg k "$chave" '.tool_input[$k] // empty' 2>/dev/null
84
+ return 0
85
+ fi
86
+ printf '%s' "$json" \
87
+ | grep -o "\"$chave\"[[:space:]]*:[[:space:]]*\"[^\"]*\"" \
88
+ | head -1 | sed 's/.*:[[:space:]]*"//; s/"$//'
89
+ }
90
+
91
+ # ------------------------------------------------------------- trabalho_id
92
+
93
+ # O trabalho corrente.
94
+ #
95
+ # UMA estrategia, em ordem de autoridade — antes eram tres, uma por skill, que
96
+ # davam respostas diferentes no mesmo repositorio na mesma execucao:
97
+ #
98
+ # 1. EXPX_TRABALHO_ID, quando a skill ja sabe qual e
99
+ # 2. .expx/expx-lock.json, que o CLI mantem
100
+ # 3. o ORQUESTRADOR.md mais recente, nos dois layouts de pasta
101
+ # 4. "sem-trabalho"
102
+ #
103
+ # O nome do lock e `expx-lock.json` (src/nucleo/lock.ts). Ler `lock.json` sem
104
+ # o prefixo devolve "sem-trabalho" para sempre, em silencio — a falha aqui e
105
+ # aberta por desenho, entao o erro nunca se anuncia.
106
+ expx_trabalho_id() {
107
+ local raiz="$1" v=""
108
+
109
+ if [ -n "${EXPX_TRABALHO_ID:-}" ]; then
110
+ printf '%s' "$EXPX_TRABALHO_ID" | tr -c 'A-Za-z0-9._-' '-' | cut -c1-64
111
+ return 0
112
+ fi
113
+
114
+ local lock="$raiz/.expx/expx-lock.json"
115
+ if [ -f "$lock" ]; then
116
+ if command -v jq >/dev/null 2>&1; then
117
+ v="$(jq -r '.trabalho_id // empty' "$lock" 2>/dev/null)"
118
+ else
119
+ v="$(grep -o '"trabalho_id"[[:space:]]*:[[:space:]]*"[^"]*"' "$lock" 2>/dev/null \
120
+ | head -1 | sed 's/.*:[[:space:]]*"//; s/"$//')"
121
+ fi
122
+ if [ -n "$v" ]; then
123
+ printf '%s' "$v" | tr -c 'A-Za-z0-9._-' '-' | cut -c1-64
124
+ return 0
125
+ fi
126
+ fi
127
+
128
+ # Os dois layouts: o novo (docs/<skill>/features|ocorrencias/<slug>/) e o
129
+ # antigo (docs/<slug>/), que as skills declaram continuar suportando.
130
+ #
131
+ # `find` em vez de glob: no zsh um padrao sem match ABORTA a funcao (nomatch),
132
+ # e o hook perderia o trabalho_id no shell de metade dos usuarios. O -maxdepth
133
+ # 4 cobre os dois layouts sem varrer o repositorio inteiro.
134
+ local f mais_novo=""
135
+ while IFS= read -r f; do
136
+ [ -f "$f" ] || continue
137
+ if [ -z "$mais_novo" ] || [ "$f" -nt "$mais_novo" ]; then mais_novo="$f"; fi
138
+ done <<EOF
139
+ $(find "$raiz/docs" -maxdepth 4 -name ORQUESTRADOR.md -type f 2>/dev/null)
140
+ EOF
141
+ if [ -n "$mais_novo" ]; then
142
+ basename "$(dirname "$mais_novo")"
143
+ return 0
144
+ fi
145
+
146
+ printf 'sem-trabalho'
147
+ }
148
+
149
+ # ------------------------------------------------------------------ modo
150
+
151
+ # Modo de um hook: aviso | bloqueio | desligado.
152
+ #
153
+ # Uso: expx_modo <raiz> <hook> [tipo] tipo: metodo (padrao) | seguranca
154
+ #
155
+ # Os TRES modos sao obrigatorios. Reconhecer so dois e cair no padrao diante do
156
+ # terceiro faz o hook continuar rodando depois de alguem pedir para desliga-lo.
157
+ #
158
+ # O padrao sai do `tipo`: hook de seguranca nasce em bloqueio e NUNCA e
159
+ # rebaixado por ausencia de configuracao; hook de metodo nasce em aviso. So um
160
+ # "desligado" explicito desliga um hook de seguranca.
161
+ expx_modo() {
162
+ local raiz="$1" hook="$2" tipo="${3:-metodo}" m=""
163
+ local cfg="$raiz/.expx/hooks.json"
164
+ local padrao='aviso'
165
+ [ "$tipo" = "seguranca" ] && padrao='bloqueio'
166
+
167
+ [ -f "$cfg" ] || { printf '%s' "$padrao"; return 0; }
168
+
169
+ if command -v jq >/dev/null 2>&1; then
170
+ # `.modos[...]` e a forma antiga, aceita para nao quebrar quem escreveu o
171
+ # arquivo a mao antes do formato atual.
172
+ m="$(jq -r --arg h "$hook" '.hooks[$h].modo // .modos[$h] // empty' "$cfg" 2>/dev/null)"
173
+ else
174
+ m="$(grep -o "\"$hook\"[[:space:]]*:[[:space:]]*{[^}]*}" "$cfg" 2>/dev/null \
175
+ | grep -o '"modo"[[:space:]]*:[[:space:]]*"[^"]*"' \
176
+ | head -1 | sed 's/.*:[[:space:]]*"//; s/"$//')"
177
+ fi
178
+
179
+ case "$m" in
180
+ aviso|bloqueio|desligado) printf '%s' "$m" ;;
181
+ *) printf '%s' "$padrao" ;;
182
+ esac
183
+ }
184
+
185
+ # ---------------------------------------------------------------- gravacao
186
+
187
+ # expx_rastro_grava <raiz> <evento> <origem> <resultado> <detalhe> [arquivos_json] [extras_json]
188
+ #
189
+ # Grava UMA linha em docs/eventos/<trabalho_id>.jsonl.
190
+ #
191
+ # As DOZE chaves obrigatorias saem sempre todas, na ordem do contrato, e chave
192
+ # sem valor vai como null — nunca omitida (R6). As extras declaradas (`hook`,
193
+ # `faixa`) vao DEPOIS das doze, em `extras_json`, nunca no meio: quem valida
194
+ # procura as doze por contencao, e uma chave no meio do objeto ja quebrou a
195
+ # verificacao de uma skill irma.
196
+ #
197
+ # Falha aberta: erro aqui e engolido. Um hook nunca trava o trabalho por nao
198
+ # conseguir escrever o proprio rastro.
199
+ expx_rastro_grava() {
200
+ local raiz="$1" evento="$2" origem="$3" resultado="$4" detalhe="$5"
201
+ local arquivos="${6:-[]}" extras="${7:-}"
202
+
203
+ {
204
+ local dir="$raiz/docs/eventos"
205
+ mkdir -p "$dir" 2>/dev/null || return 0
206
+
207
+ local tid; tid="$(expx_trabalho_id "$raiz")"
208
+ local arq="$dir/$tid.jsonl"
209
+
210
+ # Rotacao: acima de 5 MB o arquivo vira <trabalho_id>.1.jsonl (contrato).
211
+ if [ -f "$arq" ]; then
212
+ local tam
213
+ tam=$(wc -c < "$arq" 2>/dev/null | tr -d ' ')
214
+ if [ -n "$tam" ] && [ "$tam" -gt 5242880 ] 2>/dev/null; then
215
+ mv -f "$arq" "$dir/$tid.1.jsonl" 2>/dev/null || true
216
+ fi
217
+ fi
218
+
219
+ local ts; ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
220
+ local linha
221
+ linha="{\"ts\":\"$ts\""
222
+ linha="$linha,\"expx_eventos\":1"
223
+ linha="$linha,\"trabalho_id\":\"$(expx_json_escape "$tid")\""
224
+ linha="$linha,\"ferramenta\":\"$EXPX_FERRAMENTA\""
225
+ linha="$linha,\"origem\":\"$origem\""
226
+ linha="$linha,\"evento\":\"$evento\""
227
+ linha="$linha,\"fase\":${EXPX_FASE:-null}"
228
+ linha="$linha,\"task\":${EXPX_TASK:-null}"
229
+ # Sem subagente o valor e "principal", nunca null: "foi o principal" e
230
+ # informacao, nao ausencia.
231
+ linha="$linha,\"agente\":\"${EXPX_AGENTE:-principal}\""
232
+ linha="$linha,\"resultado\":\"$resultado\""
233
+ linha="$linha,\"detalhe\":\"$(expx_json_escape "$detalhe")\""
234
+ linha="$linha,\"arquivos\":$arquivos"
235
+ [ -n "$extras" ] && linha="$linha,$extras"
236
+ linha="$linha}"
237
+
238
+ printf '%s\n' "$linha" >> "$arq" 2>/dev/null || true
239
+ } 2>/dev/null || true
240
+ return 0
241
+ }
242
+
243
+ # ------------------------------------------------------------------- saida
244
+
245
+ # Aviso que CHEGA ao modelo em PostToolUse.
246
+ #
247
+ # Ali o exit 2 nao bloqueia e o stderr NAO volta ao modelo — verificado na
248
+ # documentacao oficial. O unico canal e JSON no stdout. Escrever em stderr num
249
+ # PostToolUse e falha silenciosa.
250
+ expx_aviso_ao_modelo() {
251
+ printf '{"hookSpecificOutput":{"hookEventName":"%s","additionalContext":"%s"}}\n' \
252
+ "$1" "$(expx_json_escape "$2")"
253
+ }
254
+
255
+ # Bloqueio em PreToolUse: exit 2 com o motivo no stderr, que vira a mensagem
256
+ # que o modelo le. Mensagem acionavel: diga o que fazer, nao so o que esta
257
+ # errado.
258
+ expx_bloqueia() {
259
+ printf '%s\n' "$1" >&2
260
+ exit 2
261
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expxdev",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "description": "CLI do metodo Expx: instala, atualiza e opera o ecossistema de skills, e sobe o painel de operacao",
5
5
  "type": "module",
6
6
  "bin": {
@@ -23,6 +23,7 @@
23
23
  "files": [
24
24
  "dist",
25
25
  "ui/dist",
26
+ "nucleo",
26
27
  "README.md",
27
28
  "LICENSE"
28
29
  ],