expxdev 0.4.0 → 0.5.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 (89) hide show
  1. package/README.md +27 -9
  2. package/dist/cli/expx.js +2 -0
  3. package/dist/cli/expx.js.map +1 -1
  4. package/dist/cli/init.js +9 -3
  5. package/dist/cli/init.js.map +1 -1
  6. package/dist/cli/principal.js +30 -6
  7. package/dist/cli/principal.js.map +1 -1
  8. package/dist/cli/selecao.js +3 -0
  9. package/dist/cli/selecao.js.map +1 -1
  10. package/dist/cli/subcomandos.d.ts +1 -1
  11. package/dist/cli/subcomandos.js +3 -2
  12. package/dist/cli/subcomandos.js.map +1 -1
  13. package/dist/nucleo/caminhos.d.ts +1 -1
  14. package/dist/nucleo/catalogo.d.ts +1 -1
  15. package/dist/nucleo/catalogo.js +7 -1
  16. package/dist/nucleo/catalogo.js.map +1 -1
  17. package/dist/nucleo/layout.d.ts +2 -2
  18. package/dist/nucleo/versao.d.ts +1 -1
  19. package/dist/parser/esquema/enums.d.ts +3 -2
  20. package/dist/parser/esquema/enums.js +3 -2
  21. package/dist/parser/esquema/enums.js.map +1 -1
  22. package/dist/parser/esquema/evento.d.ts +1 -0
  23. package/dist/servidor/http.d.ts +11 -0
  24. package/dist/servidor/http.js +31 -1
  25. package/dist/servidor/http.js.map +1 -1
  26. package/dist/watch/desenho/arvore.d.ts +3 -0
  27. package/dist/watch/desenho/arvore.js +62 -0
  28. package/dist/watch/desenho/arvore.js.map +1 -0
  29. package/dist/watch/desenho/bloqueios.d.ts +5 -0
  30. package/dist/watch/desenho/bloqueios.js +41 -0
  31. package/dist/watch/desenho/bloqueios.js.map +1 -0
  32. package/dist/watch/desenho/cabecalho.d.ts +11 -0
  33. package/dist/watch/desenho/cabecalho.js +49 -0
  34. package/dist/watch/desenho/cabecalho.js.map +1 -0
  35. package/dist/watch/desenho/cor.d.ts +44 -0
  36. package/dist/watch/desenho/cor.js +66 -0
  37. package/dist/watch/desenho/cor.js.map +1 -0
  38. package/dist/watch/desenho/desenhar.d.ts +16 -0
  39. package/dist/watch/desenho/desenhar.js +54 -0
  40. package/dist/watch/desenho/desenhar.js.map +1 -0
  41. package/dist/watch/desenho/eventos.d.ts +3 -0
  42. package/dist/watch/desenho/eventos.js +37 -0
  43. package/dist/watch/desenho/eventos.js.map +1 -0
  44. package/dist/watch/desenho/largura.d.ts +23 -0
  45. package/dist/watch/desenho/largura.js +42 -0
  46. package/dist/watch/desenho/largura.js.map +1 -0
  47. package/dist/watch/desenho/lista.d.ts +9 -0
  48. package/dist/watch/desenho/lista.js +28 -0
  49. package/dist/watch/desenho/lista.js.map +1 -0
  50. package/dist/watch/fontes/cauda.d.ts +14 -0
  51. package/dist/watch/fontes/cauda.js +49 -0
  52. package/dist/watch/fontes/cauda.js.map +1 -0
  53. package/dist/watch/fontes/estado-schema.d.ts +79 -0
  54. package/dist/watch/fontes/estado-schema.js +72 -0
  55. package/dist/watch/fontes/estado-schema.js.map +1 -0
  56. package/dist/watch/fontes/estado.d.ts +18 -0
  57. package/dist/watch/fontes/estado.js +38 -0
  58. package/dist/watch/fontes/estado.js.map +1 -0
  59. package/dist/watch/fontes/observar.d.ts +32 -0
  60. package/dist/watch/fontes/observar.js +101 -0
  61. package/dist/watch/fontes/observar.js.map +1 -0
  62. package/dist/watch/fontes/raiz.d.ts +12 -0
  63. package/dist/watch/fontes/raiz.js +25 -0
  64. package/dist/watch/fontes/raiz.js.map +1 -0
  65. package/dist/watch/fontes/rastro.d.ts +17 -0
  66. package/dist/watch/fontes/rastro.js +43 -0
  67. package/dist/watch/fontes/rastro.js.map +1 -0
  68. package/dist/watch/opcoes.d.ts +25 -0
  69. package/dist/watch/opcoes.js +73 -0
  70. package/dist/watch/opcoes.js.map +1 -0
  71. package/dist/watch/principal.d.ts +12 -0
  72. package/dist/watch/principal.js +49 -0
  73. package/dist/watch/principal.js.map +1 -0
  74. package/dist/watch/terminal/restaurar.d.ts +24 -0
  75. package/dist/watch/terminal/restaurar.js +58 -0
  76. package/dist/watch/terminal/restaurar.js.map +1 -0
  77. package/dist/watch/terminal/tela.d.ts +17 -0
  78. package/dist/watch/terminal/tela.js +64 -0
  79. package/dist/watch/terminal/tela.js.map +1 -0
  80. package/dist/watch/visao/escolher.d.ts +18 -0
  81. package/dist/watch/visao/escolher.js +57 -0
  82. package/dist/watch/visao/escolher.js.map +1 -0
  83. package/dist/watch/visao/projetar.d.ts +51 -0
  84. package/dist/watch/visao/projetar.js +38 -0
  85. package/dist/watch/visao/projetar.js.map +1 -0
  86. package/dist/watch/watch.d.ts +26 -0
  87. package/dist/watch/watch.js +89 -0
  88. package/dist/watch/watch.js.map +1 -0
  89. package/package.json +1 -1
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Devolver o terminal ao estado anterior — sempre, por qualquer caminho.
3
+ *
4
+ * "Nunca deixa o terminal quebrado" é definição de pronto do usuário. O
5
+ * precedente do painel (`src/cli/principal.ts`) cobre `SIGINT` e `SIGTERM`,
6
+ * o que basta para um servidor HTTP; aqui escondemos o cursor, e uma exceção
7
+ * não capturada deixaria o terminal sem cursor até o próximo `reset`. Daí os
8
+ * quatro caminhos (decisão D-21).
9
+ */
10
+ /** Os quatro caminhos pelos quais o watch pode terminar. */
11
+ export declare const CAMINHOS_DE_SAIDA: readonly ["SIGINT", "SIGTERM", "uncaughtException", "exit"];
12
+ export type CaminhoDeSaida = (typeof CAMINHOS_DE_SAIDA)[number];
13
+ export type Ambiente = {
14
+ escrever: (texto: string) => void;
15
+ sair: (codigo: number) => void;
16
+ };
17
+ export type Restaurador = {
18
+ registrar: () => void;
19
+ desregistrar: () => void;
20
+ esconderCursor: () => void;
21
+ /** Executa a restauração. Idempotente. */
22
+ disparar: (caminho: CaminhoDeSaida) => void;
23
+ };
24
+ export declare function criarRestaurador(amb: Ambiente): Restaurador;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Devolver o terminal ao estado anterior — sempre, por qualquer caminho.
3
+ *
4
+ * "Nunca deixa o terminal quebrado" é definição de pronto do usuário. O
5
+ * precedente do painel (`src/cli/principal.ts`) cobre `SIGINT` e `SIGTERM`,
6
+ * o que basta para um servidor HTTP; aqui escondemos o cursor, e uma exceção
7
+ * não capturada deixaria o terminal sem cursor até o próximo `reset`. Daí os
8
+ * quatro caminhos (decisão D-21).
9
+ */
10
+ const ESC = "";
11
+ const MOSTRAR_CURSOR = `${ESC}[?25h`;
12
+ const ESCONDER_CURSOR = `${ESC}[?25l`;
13
+ /** Os quatro caminhos pelos quais o watch pode terminar. */
14
+ export const CAMINHOS_DE_SAIDA = [
15
+ "SIGINT",
16
+ "SIGTERM",
17
+ "uncaughtException",
18
+ "exit",
19
+ ];
20
+ export function criarRestaurador(amb) {
21
+ let restaurado = false;
22
+ const ouvintes = new Map();
23
+ function restaurar() {
24
+ if (restaurado)
25
+ return; // idempotente: dois sinais não restauram duas vezes
26
+ restaurado = true;
27
+ amb.escrever(MOSTRAR_CURSOR + "\n");
28
+ }
29
+ function disparar(caminho) {
30
+ restaurar();
31
+ // `exit` já está saindo, e em `uncaughtException` quem decide é o Node.
32
+ // Só os dois sinais precisam encerrar o processo por conta própria.
33
+ if (caminho === "SIGINT" || caminho === "SIGTERM")
34
+ amb.sair(0);
35
+ }
36
+ return {
37
+ registrar() {
38
+ for (const caminho of CAMINHOS_DE_SAIDA) {
39
+ const ouvinte = () => {
40
+ disparar(caminho);
41
+ };
42
+ ouvintes.set(caminho, ouvinte);
43
+ process.on(caminho, ouvinte);
44
+ }
45
+ },
46
+ desregistrar() {
47
+ for (const [caminho, ouvinte] of ouvintes) {
48
+ process.off(caminho, ouvinte);
49
+ }
50
+ ouvintes.clear();
51
+ },
52
+ esconderCursor() {
53
+ amb.escrever(ESCONDER_CURSOR);
54
+ },
55
+ disparar,
56
+ };
57
+ }
58
+ //# sourceMappingURL=restaurar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restaurar.js","sourceRoot":"","sources":["../../../src/watch/terminal/restaurar.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,GAAG,GAAG,GAAG,CAAC;AAChB,MAAM,cAAc,GAAG,GAAG,GAAG,OAAO,CAAC;AACrC,MAAM,eAAe,GAAG,GAAG,GAAG,OAAO,CAAC;AAEtC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,QAAQ;IACR,SAAS;IACT,mBAAmB;IACnB,MAAM;CACE,CAAC;AAiBX,MAAM,UAAU,gBAAgB,CAAC,GAAa;IAC5C,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAA8B,CAAC;IAEvD,SAAS,SAAS;QAChB,IAAI,UAAU;YAAE,OAAO,CAAC,oDAAoD;QAC5E,UAAU,GAAG,IAAI,CAAC;QAClB,GAAG,CAAC,QAAQ,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,SAAS,QAAQ,CAAC,OAAuB;QACvC,SAAS,EAAE,CAAC;QACZ,wEAAwE;QACxE,oEAAoE;QACpE,IAAI,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,SAAS;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,OAAO;QACL,SAAS;YACP,KAAK,MAAM,OAAO,IAAI,iBAAiB,EAAE,CAAC;gBACxC,MAAM,OAAO,GAAG,GAAS,EAAE;oBACzB,QAAQ,CAAC,OAAO,CAAC,CAAC;gBACpB,CAAC,CAAC;gBACF,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC/B,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,YAAY;YACV,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,QAAQ,EAAE,CAAC;gBAC1C,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAChC,CAAC;YACD,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;QAED,cAAc;YACZ,GAAG,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;QAChC,CAAC;QAED,QAAQ;KACT,CAAC;AACJ,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * A tela: redesenho incremental, sem piscar.
3
+ *
4
+ * "Redesenho não pode piscar a tela inteira." Limpar tudo e reimprimir produz
5
+ * exatamente o piscar que a especificação proíbe, e o buffer alternativo do
6
+ * terminal foi descartado por apagar o que estava na tela quando o watch sai
7
+ * (decisão D-20).
8
+ *
9
+ * A técnica: guardamos as linhas do último desenho, comparamos com as novas e
10
+ * reescrevemos SÓ as que mudaram, movendo o cursor até cada uma.
11
+ */
12
+ export type Tela = {
13
+ desenhar: (linhas: readonly string[]) => void;
14
+ /** Quantas linhas a tela ocupa agora — para quem precisa arrumar o cursor. */
15
+ altura: () => number;
16
+ };
17
+ export declare function criarTela(escrever: (texto: string) => void): Tela;
@@ -0,0 +1,64 @@
1
+ /**
2
+ * A tela: redesenho incremental, sem piscar.
3
+ *
4
+ * "Redesenho não pode piscar a tela inteira." Limpar tudo e reimprimir produz
5
+ * exatamente o piscar que a especificação proíbe, e o buffer alternativo do
6
+ * terminal foi descartado por apagar o que estava na tela quando o watch sai
7
+ * (decisão D-20).
8
+ *
9
+ * A técnica: guardamos as linhas do último desenho, comparamos com as novas e
10
+ * reescrevemos SÓ as que mudaram, movendo o cursor até cada uma.
11
+ */
12
+ const ESC = "";
13
+ /** Move o cursor N linhas para cima. */
14
+ const sobe = (n) => (n > 0 ? `${ESC}[${String(n)}A` : "");
15
+ /** Move o cursor N linhas para baixo. */
16
+ const desce = (n) => (n > 0 ? `${ESC}[${String(n)}B` : "");
17
+ /** Começo da linha. */
18
+ const COLUNA_1 = `${ESC}[G`;
19
+ /** Apaga da posição do cursor até o fim da linha. */
20
+ const LIMPA_LINHA = `${ESC}[K`;
21
+ export function criarTela(escrever) {
22
+ let anteriores = [];
23
+ // Onde o cursor está, contando do topo do bloco desenhado.
24
+ let cursor = 0;
25
+ function irPara(linha) {
26
+ const delta = linha - cursor;
27
+ cursor = linha;
28
+ return delta > 0 ? desce(delta) : sobe(-delta);
29
+ }
30
+ return {
31
+ altura: () => anteriores.length,
32
+ desenhar(linhas) {
33
+ const novas = [...linhas];
34
+ const partes = [];
35
+ const alturaAnterior = anteriores.length;
36
+ const total = Math.max(novas.length, alturaAnterior);
37
+ for (let i = 0; i < total; i++) {
38
+ const nova = novas[i];
39
+ const velha = anteriores[i];
40
+ if (nova === velha)
41
+ continue; // não mudou: não reescreve
42
+ partes.push(irPara(i), COLUNA_1);
43
+ // A tela encolheu? A linha que sobrou é apagada, não deixada para trás.
44
+ partes.push(nova === undefined ? LIMPA_LINHA : nova + LIMPA_LINHA);
45
+ }
46
+ if (partes.length === 0)
47
+ return; // nada mudou: nada a escrever
48
+ // Deixa o cursor logo abaixo do bloco, onde o próximo desenho o espera.
49
+ const fim = Math.max(0, novas.length - 1);
50
+ partes.push(irPara(fim));
51
+ // A primeira renderização precisa das quebras de linha para o bloco
52
+ // existir; a partir daí é só movimento de cursor.
53
+ if (alturaAnterior === 0) {
54
+ escrever(novas.join("\n"));
55
+ cursor = fim;
56
+ }
57
+ else {
58
+ escrever(partes.join(""));
59
+ }
60
+ anteriores = novas;
61
+ },
62
+ };
63
+ }
64
+ //# sourceMappingURL=tela.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tela.js","sourceRoot":"","sources":["../../../src/watch/terminal/tela.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,GAAG,GAAG,GAAG,CAAC;AAChB,wCAAwC;AACxC,MAAM,IAAI,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC1E,yCAAyC;AACzC,MAAM,KAAK,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAC3E,uBAAuB;AACvB,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI,CAAC;AAC5B,qDAAqD;AACrD,MAAM,WAAW,GAAG,GAAG,GAAG,IAAI,CAAC;AAQ/B,MAAM,UAAU,SAAS,CAAC,QAAiC;IACzD,IAAI,UAAU,GAAa,EAAE,CAAC;IAC9B,2DAA2D;IAC3D,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,SAAS,MAAM,CAAC,KAAa;QAC3B,MAAM,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;QAC7B,MAAM,GAAG,KAAK,CAAC;QACf,OAAO,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;IACjD,CAAC;IAED,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM;QAE/B,QAAQ,CAAC,MAAM;YACb,MAAM,KAAK,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAa,EAAE,CAAC;YAE5B,MAAM,cAAc,GAAG,UAAU,CAAC,MAAM,CAAC;YACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;YAErD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;gBACtB,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC5B,IAAI,IAAI,KAAK,KAAK;oBAAE,SAAS,CAAC,2BAA2B;gBAEzD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACjC,wEAAwE;gBACxE,MAAM,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,GAAG,WAAW,CAAC,CAAC;YACrE,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,CAAC,8BAA8B;YAE/D,wEAAwE;YACxE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC1C,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YAEzB,oEAAoE;YACpE,kDAAkD;YAClD,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;gBACzB,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBAC3B,MAAM,GAAG,GAAG,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5B,CAAC;YAED,UAAU,GAAG,KAAK,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { TrabalhoMontado } from "../../parser/projeto/montar.js";
2
+ import type { EstadoExpx } from "../fontes/estado-schema.js";
3
+ /**
4
+ * Qual trabalho o watch segue.
5
+ *
6
+ * O `estado.json` responde isso direto, no campo `trabalho`. O problema é o
7
+ * modo degradado: nenhum campo do plano marca um trabalho como "o atual"
8
+ * (lacuna L-01). A decisão D-05 fixou a derivação, e ela mora aqui.
9
+ *
10
+ * A ordem de precedência é deliberada:
11
+ *
12
+ * 1. o id que a pessoa pediu na linha de comando — se ela nomeou, é esse;
13
+ * 2. o `trabalho` do `estado.json`, quando ele existe e é válido;
14
+ * 3. a derivação do plano: `em_andamento`, desempatado por `atualizado_em`.
15
+ */
16
+ /** Trabalho aberto é todo status diferente de `concluido` (decisão D-16). */
17
+ export declare function abertos(trabalhos: readonly TrabalhoMontado[]): TrabalhoMontado[];
18
+ export declare function escolherTrabalho(trabalhos: readonly TrabalhoMontado[], estado: EstadoExpx | null, pedido?: string): TrabalhoMontado | null;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Qual trabalho o watch segue.
3
+ *
4
+ * O `estado.json` responde isso direto, no campo `trabalho`. O problema é o
5
+ * modo degradado: nenhum campo do plano marca um trabalho como "o atual"
6
+ * (lacuna L-01). A decisão D-05 fixou a derivação, e ela mora aqui.
7
+ *
8
+ * A ordem de precedência é deliberada:
9
+ *
10
+ * 1. o id que a pessoa pediu na linha de comando — se ela nomeou, é esse;
11
+ * 2. o `trabalho` do `estado.json`, quando ele existe e é válido;
12
+ * 3. a derivação do plano: `em_andamento`, desempatado por `atualizado_em`.
13
+ */
14
+ /** Trabalho aberto é todo status diferente de `concluido` (decisão D-16). */
15
+ export function abertos(trabalhos) {
16
+ return trabalhos.filter((t) => t.status !== "concluido");
17
+ }
18
+ /** O mais recentemente atualizado. Empate de data mantém a ordem recebida. */
19
+ function maisRecente(lista) {
20
+ let melhor = null;
21
+ for (const t of lista) {
22
+ // `atualizado_em` é AAAA-MM-DD (R4): comparação lexicográfica é cronológica
23
+ if (melhor === null || t.atualizado_em > melhor.atualizado_em)
24
+ melhor = t;
25
+ }
26
+ return melhor;
27
+ }
28
+ export function escolherTrabalho(trabalhos, estado, pedido) {
29
+ const por = (id) => trabalhos.find((t) => t.trabalho_id === id) ?? null;
30
+ // 1. `expx watch <trabalho_id>`: a pessoa mandou, acabou a discussão.
31
+ if (pedido !== undefined && pedido !== "")
32
+ return por(pedido);
33
+ // 2. O estado.json, quando pôde ser lido.
34
+ if (estado?.trabalho != null) {
35
+ const doEstado = por(estado.trabalho);
36
+ // O estado pode apontar um trabalho que não está no disco observado
37
+ // (pasta apagada, outro repositório). Nesse caso a derivação assume.
38
+ if (doEstado !== null)
39
+ return doEstado;
40
+ }
41
+ // 3. Derivação do plano (D-05): entre os em andamento, o mais recente.
42
+ const emAndamento = trabalhos.filter((t) => t.status === "em_andamento");
43
+ if (emAndamento.length > 0)
44
+ return maisRecente(emAndamento);
45
+ // Nenhum em andamento: o mais recente entre os abertos ainda é melhor
46
+ // resposta que nada — um trabalho bloqueado é exatamente o que a pessoa
47
+ // precisa ver.
48
+ const aberto = maisRecente(abertos(trabalhos));
49
+ if (aberto !== null)
50
+ return aberto;
51
+ // Nada aberto, mas existe trabalho concluído? Mostramos o mais recente.
52
+ // "Nenhum trabalho aberto" (D-19) é sobre a LISTA de acompanhamento; abrir o
53
+ // watch num projeto cujo único trabalho acabou de fechar e ver a tela vazia
54
+ // seria esconder justamente o que a pessoa quer conferir.
55
+ return maisRecente(trabalhos);
56
+ }
57
+ //# sourceMappingURL=escolher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"escolher.js","sourceRoot":"","sources":["../../../src/watch/visao/escolher.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,6EAA6E;AAC7E,MAAM,UAAU,OAAO,CAAC,SAAqC;IAC3D,OAAO,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;AAC3D,CAAC;AAED,8EAA8E;AAC9E,SAAS,WAAW,CAAC,KAAiC;IACpD,IAAI,MAAM,GAA2B,IAAI,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,4EAA4E;QAC5E,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,CAAC,aAAa,GAAG,MAAM,CAAC,aAAa;YAAE,MAAM,GAAG,CAAC,CAAC;IAC5E,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAqC,EACrC,MAAyB,EACzB,MAAe;IAEf,MAAM,GAAG,GAAG,CAAC,EAAU,EAA0B,EAAE,CACjD,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IAEtD,sEAAsE;IACtE,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,EAAE;QAAE,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC;IAE9D,0CAA0C;IAC1C,IAAI,MAAM,EAAE,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACtC,oEAAoE;QACpE,qEAAqE;QACrE,IAAI,QAAQ,KAAK,IAAI;YAAE,OAAO,QAAQ,CAAC;IACzC,CAAC;IAED,uEAAuE;IACvE,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC;IACzE,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,WAAW,CAAC,WAAW,CAAC,CAAC;IAE5D,sEAAsE;IACtE,wEAAwE;IACxE,eAAe;IACf,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;IAC/C,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAEnC,wEAAwE;IACxE,6EAA6E;IAC7E,4EAA4E;IAC5E,0DAA0D;IAC1D,OAAO,WAAW,CAAC,SAAS,CAAC,CAAC;AAChC,CAAC"}
@@ -0,0 +1,51 @@
1
+ import { type BloqueioSituado, type TrabalhoMontado } from "../../parser/projeto/montar.js";
2
+ import type { LinhaEvento } from "../../parser/esquema/evento.js";
3
+ import type { EstadoExpx } from "../fontes/estado-schema.js";
4
+ /**
5
+ * A visão que o desenho consome — as três fontes reunidas numa estrutura só.
6
+ *
7
+ * O parser do painel é reaproveitado inteiro, sem refatoração: `montarProjeto`
8
+ * é função pura de sistema de arquivos, sem acoplamento a HTTP ou websocket
9
+ * (base/parser-de-artefatos.md, decisão D-02). O que se acrescenta aqui é o
10
+ * que ele não sabe: o `estado.json` e o rastro.
11
+ */
12
+ export type Visao = {
13
+ /** O trabalho que o watch está seguindo, ou `null` se não há nenhum. */
14
+ trabalho: TrabalhoMontado | null;
15
+ /** Os trabalhos abertos, para `--todos` e para a tela de "nenhum trabalho". */
16
+ abertos: TrabalhoMontado[];
17
+ /** O `estado.json`, ou `null` quando ausente, inválido ou de versão futura. */
18
+ estado: EstadoExpx | null;
19
+ /**
20
+ * Estamos sem o `estado.json`?
21
+ *
22
+ * NÃO é "o arquivo não existe": a decisão D-12 trata versão ≠ 1 e JSON
23
+ * inválido do mesmo jeito. No modo degradado, `raio`, `orcamento_*`, `branch`
24
+ * e `pr_estado` não têm fonte alguma e não podem ser exibidos — nenhum kind
25
+ * do `expx-schema` os declara (base/estado-json.md, risco 2).
26
+ */
27
+ degradado: boolean;
28
+ /** Tasks concluídas e total, do estado quando há, do plano quando não há. */
29
+ concluidas: number;
30
+ total: number;
31
+ /** Só os bloqueios abertos, que são os que sobem ao topo. */
32
+ bloqueiosAbertos: BloqueioSituado[];
33
+ /** As últimas linhas do rastro, da mais recente para a mais antiga. */
34
+ eventos: LinhaEvento[];
35
+ /** Violações em modo aviso desde que o watch subiu (decisão D-07). */
36
+ violacoesAviso: number;
37
+ /** Instante da leitura, para o rodapé calcular "tempo desde o último evento". */
38
+ lidoEm: Date;
39
+ };
40
+ export type OpcoesVisao = {
41
+ /** Id pedido em `expx watch <trabalho_id>`. */
42
+ trabalhoPedido?: string;
43
+ /**
44
+ * Quando o watch subiu. É a fronteira da "sessão" no rodapé: o rastro é
45
+ * append-only e não marca sessão nenhuma (lacuna L-03, decisão D-07).
46
+ */
47
+ subiuEm?: Date;
48
+ /** Quantas linhas do rastro exibir. */
49
+ linhasRastro?: number;
50
+ };
51
+ export declare function projetarVisao(raizProjeto: string, op?: OpcoesVisao, agora?: Date): Visao;
@@ -0,0 +1,38 @@
1
+ import { montarProjeto } from "../../parser/projeto/montar.js";
2
+ import { lerEstadoExpx } from "../fontes/estado.js";
3
+ import { lerRastro } from "../fontes/rastro.js";
4
+ import { abertos, escolherTrabalho } from "./escolher.js";
5
+ export function projetarVisao(raizProjeto, op = {}, agora = new Date()) {
6
+ const projeto = montarProjeto(raizProjeto, agora);
7
+ const estado = lerEstadoExpx(raizProjeto);
8
+ const trabalho = escolherTrabalho(projeto.trabalhos, estado, op.trabalhoPedido);
9
+ const tasks = trabalho?.sprints.flatMap((s) => s.tasks) ?? [];
10
+ // O par concluídas/total tem duas fontes: o estado.json traz os inteiros
11
+ // prontos, e o plano exige contagem — `progresso` do parser é fração 0..1,
12
+ // não o par (base/parser-de-artefatos.md, risco 4).
13
+ const doEstado = estado !== null && trabalho !== null;
14
+ const concluidas = doEstado
15
+ ? estado.tasks_concluidas
16
+ : tasks.filter((t) => t.status === "concluida").length;
17
+ const total = doEstado ? estado.tasks_total : tasks.length;
18
+ const eventos = trabalho === null ? [] : lerRastro(raizProjeto, trabalho.trabalho_id, op.linhasRastro);
19
+ // "Modo aviso" é vocabulário de hook e só existe no rastro: `regra_violada` é
20
+ // gravado por hook em modo aviso, `acao_bloqueada` em modo bloqueio. Não
21
+ // confundir com as `Violacao` da conformidade, que são defeitos do método nos
22
+ // arquivos do plano (lacuna L-03).
23
+ const fronteira = op.subiuEm?.toISOString().replace(/\.\d{3}Z$/, "Z");
24
+ const violacoesAviso = eventos.filter((e) => e.evento === "regra_violada" && (fronteira === undefined || e.ts >= fronteira)).length;
25
+ return {
26
+ trabalho,
27
+ abertos: abertos(projeto.trabalhos),
28
+ estado,
29
+ degradado: estado === null,
30
+ concluidas,
31
+ total,
32
+ bloqueiosAbertos: (trabalho?.bloqueios ?? []).filter((b) => b.aberto),
33
+ eventos,
34
+ violacoesAviso,
35
+ lidoEm: agora,
36
+ };
37
+ }
38
+ //# sourceMappingURL=projetar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projetar.js","sourceRoot":"","sources":["../../../src/watch/visao/projetar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAA8C,MAAM,gCAAgC,CAAC;AAG3G,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAoD1D,MAAM,UAAU,aAAa,CAC3B,WAAmB,EACnB,KAAkB,EAAE,EACpB,QAAc,IAAI,IAAI,EAAE;IAExB,MAAM,OAAO,GAAG,aAAa,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IAClD,MAAM,MAAM,GAAG,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,CAAC;IAEhF,MAAM,KAAK,GAAG,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAE9D,yEAAyE;IACzE,2EAA2E;IAC3E,oDAAoD;IACpD,MAAM,QAAQ,GAAG,MAAM,KAAK,IAAI,IAAI,QAAQ,KAAK,IAAI,CAAC;IACtD,MAAM,UAAU,GAAG,QAAQ;QACzB,CAAC,CAAC,MAAM,CAAC,gBAAgB;QACzB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;IACzD,MAAM,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IAE3D,MAAM,OAAO,GACX,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC;IAEzF,8EAA8E;IAC9E,yEAAyE;IACzE,8EAA8E;IAC9E,mCAAmC;IACnC,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACtE,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CACnC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,eAAe,IAAI,CAAC,SAAS,KAAK,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,SAAS,CAAC,CACtF,CAAC,MAAM,CAAC;IAET,OAAO;QACL,QAAQ;QACR,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QACnC,MAAM;QACN,SAAS,EAAE,MAAM,KAAK,IAAI;QAC1B,UAAU;QACV,KAAK;QACL,gBAAgB,EAAE,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QACrE,OAAO;QACP,cAAc;QACd,MAAM,EAAE,KAAK;KACd,CAAC;AACJ,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { Opcoes } from "./opcoes.js";
2
+ /**
3
+ * O loop do watch: lê, desenha, observa, redesenha.
4
+ *
5
+ * A promessa que este arquivo existe para cumprir: "a árvore completa vem dos
6
+ * arquivos do plano, relida apenas quando eles mudam — não a cada redesenho".
7
+ * Por isso a visão é guardada e só o gatilho de plano a reconstrói; o gatilho
8
+ * de estado atualiza o barato e redesenha com a árvore que já estava em mãos.
9
+ */
10
+ export type SessaoWatch = {
11
+ parar: () => Promise<void>;
12
+ /** Código de saída, quando o watch terminou sozinho. */
13
+ codigo: number;
14
+ /** O watch encerrou por conta própria (projeto sem Expx)? */
15
+ encerrou: boolean;
16
+ };
17
+ export type OpcoesExecucao = {
18
+ raiz: string;
19
+ opcoes: Opcoes;
20
+ escrever: (texto: string) => void;
21
+ cor: boolean;
22
+ debounceMs?: number;
23
+ /** Gancho de teste: chamado toda vez que o PLANO é relido do disco. */
24
+ aoLerPlano?: () => void;
25
+ };
26
+ export declare function executarWatch(op: OpcoesExecucao): Promise<SessaoWatch>;
@@ -0,0 +1,89 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { desenhar } from "./desenho/desenhar.js";
4
+ import { desenharLista } from "./desenho/lista.js";
5
+ import { lerEstadoExpx } from "./fontes/estado.js";
6
+ import { observarFontes } from "./fontes/observar.js";
7
+ import { lerRastro } from "./fontes/rastro.js";
8
+ import { criarTela } from "./terminal/tela.js";
9
+ import { projetarVisao } from "./visao/projetar.js";
10
+ /** Largura de trabalho: a do terminal, o pedido explícito, ou 80. */
11
+ function larguraDe(op) {
12
+ if (op.opcoes.colunas !== undefined)
13
+ return op.opcoes.colunas;
14
+ const cols = process.stdout.columns;
15
+ // Abaixo de 80 continuamos desenhando: o corte é elegante por construção.
16
+ return typeof cols === "number" && cols > 0 ? cols : 80;
17
+ }
18
+ export async function executarWatch(op) {
19
+ // Sem `.expx/`, o projeto não tem o Expx instalado. Mensagem curta e saída
20
+ // limpa, como manda a tolerância a falha — não é erro, é ausência.
21
+ if (!existsSync(join(op.raiz, ".expx"))) {
22
+ op.escrever([
23
+ "este projeto nao tem o Expx instalado (falta a pasta .expx/).",
24
+ "",
25
+ " npx expxdev init instala as skills neste projeto",
26
+ "",
27
+ ].join("\n"));
28
+ return { parar: async () => undefined, codigo: 0, encerrou: true };
29
+ }
30
+ const subiuEm = new Date();
31
+ const colunas = larguraDe(op);
32
+ const tela = criarTela(op.escrever);
33
+ // A visão fica guardada de propósito: é ela que carrega a árvore, cara de
34
+ // montar. O gatilho de estado NÃO a reconstrói.
35
+ let visao = lerTudo();
36
+ function lerTudo() {
37
+ op.aoLerPlano?.();
38
+ return projetarVisao(op.raiz, {
39
+ ...(op.opcoes.trabalho !== undefined ? { trabalhoPedido: op.opcoes.trabalho } : {}),
40
+ subiuEm,
41
+ });
42
+ }
43
+ function redesenhar() {
44
+ const linhas = op.opcoes.todos
45
+ ? desenharLista(visao, colunas, op.cor)
46
+ : desenhar(visao, { colunas, cor: op.cor, agora: new Date() });
47
+ tela.desenhar(linhas);
48
+ }
49
+ redesenhar();
50
+ const observador = await observarFontes(op.raiz, {
51
+ // O plano mudou: reconstrói tudo. É a releitura cara, e ela só acontece
52
+ // aqui.
53
+ aoMudarPlano: () => {
54
+ visao = lerTudo();
55
+ redesenhar();
56
+ },
57
+ // Só o estado.json mudou: atualiza o barato e redesenha com a árvore
58
+ // que já estava em mãos.
59
+ aoMudarEstado: () => {
60
+ const estado = lerEstadoExpx(op.raiz);
61
+ visao = { ...visao, estado, degradado: estado === null };
62
+ redesenhar();
63
+ },
64
+ // Só o rastro cresceu: relê os eventos, que é leitura de cauda, e
65
+ // preserva a árvore. É o caminho mais percorrido durante uma execução
66
+ // autônoma — cada hook grava uma linha.
67
+ aoMudarRastro: () => {
68
+ if (visao.trabalho === null)
69
+ return;
70
+ const eventos = lerRastro(op.raiz, visao.trabalho.trabalho_id);
71
+ const fronteira = subiuEm.toISOString().replace(/\.\d{3}Z$/, "Z");
72
+ visao = {
73
+ ...visao,
74
+ eventos,
75
+ violacoesAviso: eventos.filter((e) => e.evento === "regra_violada" && e.ts >= fronteira)
76
+ .length,
77
+ };
78
+ redesenhar();
79
+ },
80
+ }, op.debounceMs ?? 150);
81
+ return {
82
+ parar: async () => {
83
+ await observador.parar();
84
+ },
85
+ codigo: 0,
86
+ encerrou: false,
87
+ };
88
+ }
89
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/watch/watch.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expxdev",
3
- "version": "0.4.0",
3
+ "version": "0.5.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": {