expxdev 0.5.1 → 0.5.2

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 (75) hide show
  1. package/dist/cli/init.js +39 -5
  2. package/dist/cli/init.js.map +1 -1
  3. package/dist/harness/hooks.d.ts +9 -4
  4. package/dist/harness/hooks.js +34 -3
  5. package/dist/harness/hooks.js.map +1 -1
  6. package/dist/harness/instalar.d.ts +19 -0
  7. package/dist/harness/instalar.js +42 -1
  8. package/dist/harness/instalar.js.map +1 -1
  9. package/dist/harness/settings.js +6 -0
  10. package/dist/harness/settings.js.map +1 -1
  11. package/dist/nucleo/busca.d.ts +8 -0
  12. package/dist/nucleo/busca.js +27 -2
  13. package/dist/nucleo/busca.js.map +1 -1
  14. package/dist/nucleo/catalogo.d.ts +7 -1
  15. package/dist/nucleo/catalogo.js +73 -9
  16. package/dist/nucleo/catalogo.js.map +1 -1
  17. package/dist/nucleo/layout.d.ts +8 -0
  18. package/dist/nucleo/layout.js +22 -0
  19. package/dist/nucleo/layout.js.map +1 -1
  20. package/dist/parser/descoberta/trabalhos.d.ts +14 -2
  21. package/dist/parser/descoberta/trabalhos.js +59 -0
  22. package/dist/parser/descoberta/trabalhos.js.map +1 -1
  23. package/dist/parser/esquema/cabecalho.d.ts +21 -5
  24. package/dist/parser/esquema/cabecalho.js +24 -5
  25. package/dist/parser/esquema/cabecalho.js.map +1 -1
  26. package/dist/parser/esquema/enums.d.ts +41 -4
  27. package/dist/parser/esquema/enums.js +39 -9
  28. package/dist/parser/esquema/enums.js.map +1 -1
  29. package/dist/parser/esquema/evento.d.ts +1 -0
  30. package/dist/parser/esquema/kinds.d.ts +288 -0
  31. package/dist/parser/esquema/kinds.js +84 -1
  32. package/dist/parser/esquema/kinds.js.map +1 -1
  33. package/dist/plugin/montagem.d.ts +5 -0
  34. package/dist/plugin/montagem.js +67 -1
  35. package/dist/plugin/montagem.js.map +1 -1
  36. package/dist/servidor/http.d.ts +5 -0
  37. package/dist/servidor/http.js +28 -0
  38. package/dist/servidor/http.js.map +1 -1
  39. package/dist/servidor/observador.d.ts +27 -1
  40. package/dist/servidor/observador.js +152 -19
  41. package/dist/servidor/observador.js.map +1 -1
  42. package/dist/servidor/painel.js +13 -3
  43. package/dist/servidor/painel.js.map +1 -1
  44. package/dist/update/comparar.js +2 -2
  45. package/dist/update/comparar.js.map +1 -1
  46. package/dist/watch/desenho/barra.d.ts +29 -0
  47. package/dist/watch/desenho/barra.js +111 -0
  48. package/dist/watch/desenho/barra.js.map +1 -0
  49. package/dist/watch/desenho/desenhar.d.ts +15 -2
  50. package/dist/watch/desenho/desenhar.js +65 -11
  51. package/dist/watch/desenho/desenhar.js.map +1 -1
  52. package/dist/watch/desenho/painel.d.ts +14 -0
  53. package/dist/watch/desenho/painel.js +260 -0
  54. package/dist/watch/desenho/painel.js.map +1 -0
  55. package/dist/watch/fontes/estado-schema.d.ts +7 -0
  56. package/dist/watch/opcoes.d.ts +2 -0
  57. package/dist/watch/opcoes.js +11 -4
  58. package/dist/watch/opcoes.js.map +1 -1
  59. package/dist/watch/terminal/tela.d.ts +15 -12
  60. package/dist/watch/terminal/tela.js +79 -3
  61. package/dist/watch/terminal/tela.js.map +1 -1
  62. package/dist/watch/visao/atividade.d.ts +70 -0
  63. package/dist/watch/visao/atividade.js +0 -0
  64. package/dist/watch/visao/atividade.js.map +1 -0
  65. package/dist/watch/visao/frota.d.ts +46 -0
  66. package/dist/watch/visao/frota.js +67 -0
  67. package/dist/watch/visao/frota.js.map +1 -0
  68. package/dist/watch/visao/projetar.d.ts +9 -0
  69. package/dist/watch/visao/projetar.js +55 -0
  70. package/dist/watch/visao/projetar.js.map +1 -1
  71. package/dist/watch/watch.d.ts +2 -0
  72. package/dist/watch/watch.js +48 -3
  73. package/dist/watch/watch.js.map +1 -1
  74. package/nucleo/hooks/expx-lembrete.sh +136 -0
  75. package/package.json +1 -1
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Barras de progresso e tempo decorrido — o vocabulário visual do painel.
3
+ *
4
+ * Duas barras, porque o método mede duas coisas diferentes e misturá-las
5
+ * mentiria:
6
+ *
7
+ * - `barra()` é progresso REAL: contagem de tasks concluídas sobre o total.
8
+ * Trabalho, sprint e fase têm isso.
9
+ * - `barraIndeterminada()` é atividade, não progresso: a task em andamento
10
+ * não tem percentual verdadeiro no método (o status é pendente, em
11
+ * andamento, concluída ou bloqueada — nunca "43%"). A estimativa que
12
+ * acompanha essa barra vem do rastro e é rotulada como estimativa em
13
+ * `estimativa.ts`; a barra em si só pulsa, para dizer "isto está vivo".
14
+ *
15
+ * Blocos de oitavo (▏▎▍▌▋▊▉█) dão resolução de 1/8 de coluna sem emoji, que a
16
+ * especificação proíbe. São largura simples em qualquer terminal moderno.
17
+ */
18
+ const CHEIO = "█";
19
+ const VAZIO = "░";
20
+ /** Frações de coluna, de 1/8 a 7/8. */
21
+ const OITAVOS = ["", "▏", "▎", "▍", "▌", "▋", "▊", "▉"];
22
+ /**
23
+ * Uma barra de `largura` colunas representando `feitas` de `total`.
24
+ *
25
+ * Duas regras que evitam mentira visual, e que vieram de olhar a tela:
26
+ * - só está cheia quando `feitas === total`: arredondar 9/10 para cheio faz
27
+ * a pessoa achar que acabou;
28
+ * - qualquer progresso maior que zero acende ao menos um oitavo, para não
29
+ * parecer parado quando já começou.
30
+ */
31
+ export function barra(feitas, total, largura) {
32
+ if (largura <= 0)
33
+ return "";
34
+ if (total <= 0)
35
+ return VAZIO.repeat(largura);
36
+ const fracao = Math.max(0, Math.min(1, feitas / total));
37
+ if (fracao >= 1)
38
+ return CHEIO.repeat(largura);
39
+ // Já começou: acende ao menos um oitavo. Ainda NÃO acabou: sobra ao menos
40
+ // uma CÉLULA vazia — não um oitavo, uma célula. Um `▉` na última posição é
41
+ // lido como barra cheia a um metro de distância, e a pessoa que lê "acabou"
42
+ // para de olhar faltando uma task.
43
+ const maximo = (largura - 1) * 8;
44
+ const oitavos = Math.min(maximo, fracao > 0 ? Math.max(1, Math.floor(fracao * largura * 8)) : 0);
45
+ const cheias = Math.floor(oitavos / 8);
46
+ const resto = oitavos % 8;
47
+ const parcial = OITAVOS[resto] ?? "";
48
+ const usadas = cheias + (parcial === "" ? 0 : 1);
49
+ return CHEIO.repeat(cheias) + parcial + VAZIO.repeat(Math.max(0, largura - usadas));
50
+ }
51
+ /**
52
+ * A barra de atividade: uma onda que anda com o tempo.
53
+ *
54
+ * Não representa quanto falta — representa que algo está acontecendo agora.
55
+ * A fase depende do relógio, então o redesenho a move sozinho, sem estado.
56
+ */
57
+ export function barraIndeterminada(largura, agora) {
58
+ if (largura <= 0)
59
+ return "";
60
+ // Um passo por 400 ms: rápido o bastante para ler como movimento, lento o
61
+ // bastante para não virar ruído numa tela que a pessoa olha por minutos.
62
+ const passo = Math.floor(agora.getTime() / 400);
63
+ const cabeca = passo % (largura + 4);
64
+ let saida = "";
65
+ for (let i = 0; i < largura; i++) {
66
+ const d = cabeca - i;
67
+ saida += d >= 0 && d < 3 ? CHEIO : VAZIO;
68
+ }
69
+ return saida;
70
+ }
71
+ /** O papel de cor de uma barra, pelo que a proporção significa. */
72
+ export function papelDaBarra(feitas, total) {
73
+ if (total > 0 && feitas >= total)
74
+ return "sucesso";
75
+ if (feitas > 0)
76
+ return "atencao";
77
+ return "apagado";
78
+ }
79
+ /** "45%" — inteiro, porque casa decimal em barra de terminal é ruído. */
80
+ export function percentual(feitas, total) {
81
+ if (total <= 0)
82
+ return "0%";
83
+ return `${String(Math.floor((Math.max(0, Math.min(feitas, total)) / total) * 100))}%`;
84
+ }
85
+ const SEGUNDO = 1000;
86
+ const MINUTO = 60 * SEGUNDO;
87
+ const HORA = 60 * MINUTO;
88
+ const DIA = 24 * HORA;
89
+ /**
90
+ * Tempo decorrido, curto: "12s", "2m18s", "1h04", "3d".
91
+ *
92
+ * Segundos aparecem até a hora porque é a escala em que a pessoa percebe que
93
+ * a execução travou. Acima disso viram ruído e somem.
94
+ */
95
+ export function decorrido(ms) {
96
+ const t = Math.max(0, ms);
97
+ if (t < MINUTO)
98
+ return `${String(Math.floor(t / SEGUNDO))}s`;
99
+ if (t < HORA) {
100
+ const m = Math.floor(t / MINUTO);
101
+ const s = Math.floor((t % MINUTO) / SEGUNDO);
102
+ return `${String(m)}m${String(s).padStart(2, "0")}s`;
103
+ }
104
+ if (t < DIA) {
105
+ const h = Math.floor(t / HORA);
106
+ const m = Math.floor((t % HORA) / MINUTO);
107
+ return `${String(h)}h${String(m).padStart(2, "0")}`;
108
+ }
109
+ return `${String(Math.floor(t / DIA))}d`;
110
+ }
111
+ //# sourceMappingURL=barra.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barra.js","sourceRoot":"","sources":["../../../src/watch/desenho/barra.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,29 @@
1
1
  import type { Visao } from "../visao/projetar.js";
2
+ import { decorrido } from "./barra.js";
2
3
  /**
3
4
  * O painel inteiro, como lista de linhas.
4
5
  *
5
6
  * Função PURA: recebe a visão, a largura e se há cor, e devolve texto. Não
6
7
  * toca em `process.stdout`, não lê TTY, não escreve em disco. É o que torna
7
- * possível testar as dez fixtures da especificação sem nenhum terminal — as
8
- * duas últimas (60 colunas, saída redirecionada) são justamente os parâmetros
8
+ * possível testar as fixtures da especificação sem nenhum terminal — as duas
9
+ * últimas (60 colunas, saída redirecionada) são justamente os parâmetros
9
10
  * `colunas` e `cor` (decisão D-11).
11
+ *
12
+ * A ordem da tela é a ordem da urgência:
13
+ * 1. bloqueios abertos, que exigem decisão humana;
14
+ * 2. a régua do projeto, uma linha só;
15
+ * 3. a frota: cada trabalho com sua barra e suas tasks correndo;
16
+ * 4. a atividade recente, agrupada;
17
+ * 5. o rodapé de saúde da execução.
10
18
  */
11
19
  export type OpcoesDesenho = {
12
20
  colunas: number;
13
21
  cor: boolean;
14
22
  agora: Date;
23
+ /** `--arvore`: mostra a árvore completa do trabalho corrente. */
24
+ arvore?: boolean;
15
25
  };
26
+ /** O tempo desde que o watch subiu, para quem deixa a tela aberta. */
16
27
  export declare function desenhar(v: Visao, op: OpcoesDesenho): string[];
28
+ /** Reexportado para quem desenha o cabeçalho fora do painel. */
29
+ export { decorrido };
@@ -1,9 +1,9 @@
1
1
  import { desenharArvore } from "./arvore.js";
2
+ import { barra, decorrido, papelDaBarra, percentual } from "./barra.js";
2
3
  import { desenharBloqueios } from "./bloqueios.js";
3
- import { desenharCabecalho } from "./cabecalho.js";
4
4
  import { criarPintor } from "./cor.js";
5
- import { desenharEventos } from "./eventos.js";
6
- import { cortar } from "./largura.js";
5
+ import { cortar, largura, preencher } from "./largura.js";
6
+ import { blocoTrabalho, desenharAtividade } from "./painel.js";
7
7
  const MINUTO = 60_000;
8
8
  const HORA = 60 * MINUTO;
9
9
  const DIA = 24 * HORA;
@@ -18,6 +18,46 @@ function desde(quando, agora) {
18
18
  return `há ${String(Math.floor(ms / HORA))} h`;
19
19
  return `há ${String(Math.floor(ms / DIA))} d`;
20
20
  }
21
+ /**
22
+ * A régua do projeto: uma linha dizendo onde o conjunto todo está.
23
+ *
24
+ * Somar as tasks de todos os trabalhos abertos é a única pergunta que a tela
25
+ * antiga não respondia de jeito nenhum — "quanto falta no geral" exigia somar
26
+ * de cabeça as linhas de progresso de cada ocorrência.
27
+ */
28
+ function desenharRegua(v, colunas, pintar) {
29
+ if (v.frota.length === 0)
30
+ return [];
31
+ const feitas = v.frota.reduce((s, t) => s + t.concluidas, 0);
32
+ const total = v.frota.reduce((s, t) => s + t.total, 0);
33
+ const emCurso = v.frota.filter((t) => t.ativas.length > 0).length;
34
+ const paralelas = v.frota.reduce((s, t) => s + t.ativas.length, 0);
35
+ const n = v.frota.length;
36
+ const quantos = n === 1 ? "1 trabalho" : `${String(n)} trabalhos`;
37
+ const detalhe = paralelas > 1
38
+ ? `${quantos} · ${String(emCurso)} em curso · ${String(paralelas)} tasks em paralelo`
39
+ : `${quantos} · ${String(emCurso)} em curso`;
40
+ const b = barra(feitas, total, 20);
41
+ const contagem = `${String(feitas)}/${String(total)} tasks`;
42
+ const pct = percentual(feitas, total);
43
+ const linhas = [];
44
+ if (colunas < 52) {
45
+ linhas.push(pintar(cortar(`${contagem} · ${pct}`, colunas), papelDaBarra(feitas, total)));
46
+ linhas.push(pintar(cortar(detalhe, colunas), "apagado"));
47
+ return linhas;
48
+ }
49
+ const esq = ` ${b} ${preencher(contagem, 12)} ${pct}`;
50
+ const sobra = colunas - largura(esq) - largura(detalhe) - 2;
51
+ linhas.push(" " +
52
+ pintar(b, papelDaBarra(feitas, total)) +
53
+ " " +
54
+ pintar(preencher(contagem, 12), "neutro") +
55
+ " " +
56
+ pintar(pct, "apagado") +
57
+ (sobra >= 1 ? " ".repeat(sobra + 2) + pintar(detalhe, "apagado") : ""));
58
+ return linhas;
59
+ }
60
+ /** O rodapé: saúde da execução em uma linha. */
21
61
  function desenharRodape(v, colunas, pintar, agora) {
22
62
  const partes = [];
23
63
  // Tempo desde o último evento: "se passar muito, a execução travou".
@@ -30,25 +70,39 @@ function desenharRodape(v, colunas, pintar, agora) {
30
70
  const n = v.violacoesAviso;
31
71
  partes.push(n === 1 ? "1 violacao em aviso" : `${String(n)} violacoes em aviso`);
32
72
  }
73
+ if (v.degradado)
74
+ partes.push("sem estado.json: lendo o plano");
33
75
  if (partes.length === 0)
34
76
  return [];
35
77
  const papel = v.violacoesAviso > 0 ? "atencao" : "apagado";
36
78
  return [pintar(cortar(partes.join(" · "), colunas), papel)];
37
79
  }
80
+ /** O tempo desde que o watch subiu, para quem deixa a tela aberta. */
38
81
  export function desenhar(v, op) {
39
82
  const pintar = criarPintor(op.cor);
40
83
  const c = op.colunas;
84
+ if (v.frota.length === 0) {
85
+ return [pintar(cortar("nenhum trabalho aberto", c), "apagado")];
86
+ }
41
87
  // A ordem é a prioridade da especificação: bloqueio aberto sobe para o topo,
42
- // acima até do cabeçalho, "porque é a informação que mais precisa de olho
43
- // humano e a que mais passa despercebida quando a execução é autônoma".
88
+ // "porque é a informação que mais precisa de olho humano e a que mais passa
89
+ // despercebida quando a execução é autônoma".
44
90
  const secoes = [
45
91
  desenharBloqueios(v, c, pintar, op.agora),
46
- desenharCabecalho(v, c, pintar),
47
- desenharArvore(v, c, pintar),
48
- desenharEventos(v, c, pintar),
49
- desenharRodape(v, c, pintar, op.agora),
50
- ].filter((s) => s.length > 0);
92
+ desenharRegua(v, c, pintar),
93
+ ];
94
+ // Cada trabalho é um bloco. O corrente vem primeiro (a frota já vem ordenada).
95
+ for (const t of v.frota)
96
+ secoes.push(blocoTrabalho(t, c, pintar, op.agora, v.estado));
97
+ // `--arvore`: a árvore completa do trabalho corrente, para quem quer o detalhe.
98
+ if (op.arvore === true)
99
+ secoes.push(desenharArvore(v, c, pintar));
100
+ secoes.push(desenharAtividade(v, c, pintar));
101
+ secoes.push(desenharRodape(v, c, pintar, op.agora));
102
+ const cheias = secoes.filter((s) => s.length > 0);
51
103
  // Uma linha em branco entre seções, nenhuma no fim.
52
- return secoes.flatMap((s, i) => (i === 0 ? s : ["", ...s]));
104
+ return cheias.flatMap((s, i) => (i === 0 ? s : ["", ...s]));
53
105
  }
106
+ /** Reexportado para quem desenha o cabeçalho fora do painel. */
107
+ export { decorrido };
54
108
  //# sourceMappingURL=desenhar.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"desenhar.js","sourceRoot":"","sources":["../../../src/watch/desenho/desenhar.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"desenhar.js","sourceRoot":"","sources":["../../../src/watch/desenho/desenhar.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAe,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AA2B/D,MAAM,MAAM,GAAG,MAAM,CAAC;AACtB,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC;AACzB,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtB,+DAA+D;AAC/D,SAAS,KAAK,CAAC,MAAY,EAAE,KAAW;IACtC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,IAAI,EAAE,GAAG,MAAM;QAAE,OAAO,cAAc,CAAC;IACvC,IAAI,EAAE,GAAG,IAAI;QAAE,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,MAAM,CAAC,CAAC,MAAM,CAAC;IAClE,IAAI,EAAE,GAAG,GAAG;QAAE,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC,IAAI,CAAC;IAC7D,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,CAAQ,EAAE,OAAe,EAAE,MAAc;IAC9D,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEpC,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;IAClE,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAEnE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IACzB,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;IAClE,MAAM,OAAO,GACX,SAAS,GAAG,CAAC;QACX,CAAC,CAAC,GAAG,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,eAAe,MAAM,CAAC,SAAS,CAAC,oBAAoB;QACrF,CAAC,CAAC,GAAG,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC;IAEjD,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;IACnC,MAAM,QAAQ,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC5D,MAAM,GAAG,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAEtC,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,IAAI,OAAO,GAAG,EAAE,EAAE,CAAC;QACjB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,QAAQ,MAAM,GAAG,EAAE,EAAE,OAAO,CAAC,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;QAC1F,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;QACzD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC;IACvD,MAAM,KAAK,GAAG,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAE5D,MAAM,CAAC,IAAI,CACT,IAAI;QACF,MAAM,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACtC,GAAG;QACH,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,CAAC,EAAE,QAAQ,CAAC;QACzC,GAAG;QACH,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC;QACtB,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CACzE,CAAC;IAEF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gDAAgD;AAChD,SAAS,cAAc,CAAC,CAAQ,EAAE,OAAe,EAAE,MAAc,EAAE,KAAW;IAC5E,MAAM,MAAM,GAAa,EAAE,CAAC;IAE5B,qEAAqE;IACrE,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,CAAC,IAAI,CAAC,iBAAiB,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACpE,CAAC;IAED,uDAAuD;IACvD,IAAI,CAAC,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC,CAAC,cAAc,CAAC;QAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,qBAAqB,CAAC,CAAC;IACnF,CAAC;IAED,IAAI,CAAC,CAAC,SAAS;QAAE,MAAM,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;IAE/D,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,QAAQ,CAAC,CAAQ,EAAE,EAAiB;IAClD,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;IACnC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC;IAErB,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC;IAClE,CAAC;IAED,6EAA6E;IAC7E,4EAA4E;IAC5E,8CAA8C;IAC9C,MAAM,MAAM,GAAe;QACzB,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC;QACzC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;IAEF,+EAA+E;IAC/E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK;QAAE,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAEtF,gFAAgF;IAChF,IAAI,EAAE,CAAC,MAAM,KAAK,IAAI;QAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAElE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;IAEpD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAElD,oDAAoD;IACpD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,gEAAgE;AAChE,OAAO,EAAE,SAAS,EAAE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Visao } from "../visao/projetar.js";
2
+ import type { TrabalhoNaFrota } from "../visao/frota.js";
3
+ import type { EstadoExpx } from "../fontes/estado-schema.js";
4
+ import type { Pintor } from "./cor.js";
5
+ /** Um bloco de trabalho: título, progresso e as tasks que rodam agora. */
6
+ export declare function blocoTrabalho(t: TrabalhoNaFrota, colunas: number, pintar: Pintor, agora: Date, estado?: EstadoExpx | null): string[];
7
+ /**
8
+ * A atividade: eventos agrupados, não o rastro cru.
9
+ *
10
+ * Antes eram dez linhas do arquivo `.jsonl` como estavam no disco — sete delas
11
+ * a mesma `suite_executada` com o mesmo comando gigante. Agrupar por (evento,
12
+ * alvo) devolve a informação e libera as linhas para o que de fato aconteceu.
13
+ */
14
+ export declare function desenharAtividade(v: Visao, colunas: number, pintar: Pintor): string[];
@@ -0,0 +1,260 @@
1
+ import { agrupar } from "../visao/atividade.js";
2
+ import { barra, barraIndeterminada, decorrido, papelDaBarra, percentual } from "./barra.js";
3
+ import { cortar, largura, preencher } from "./largura.js";
4
+ /**
5
+ * O painel: a frota de trabalhos, cada um com sua barra e sua task corrente.
6
+ *
7
+ * O desenho antigo era uma árvore inteira despejada mais um dump do rastro:
8
+ * tudo com o mesmo peso visual, e a informação que importa — quem está andando,
9
+ * quanto falta, o que roda em paralelo — enterrada no meio. Aqui cada trabalho
10
+ * ocupa um bloco curto e fixo, e a tela toda cabe de relance.
11
+ *
12
+ * Como todo este diretório: função PURA. Recebe a visão, a largura e se há cor,
13
+ * devolve linhas. Nada de `process.stdout`.
14
+ */
15
+ /** Colunas da barra de progresso de um trabalho. */
16
+ const BARRA_TRABALHO = 16;
17
+ /** Colunas da barra de uma task ativa. */
18
+ const BARRA_TASK = 10;
19
+ /** Colunas reservadas ao detalhe de um evento, na coluna da direita. */
20
+ const COL_DETALHE = 26;
21
+ /** Larguras mínimas para os enfeites: abaixo disso, só texto. */
22
+ const CABE_BARRA = 52;
23
+ const MARCA_ESTAGIO = {
24
+ f1: "ingestao",
25
+ f2: "descoberta",
26
+ f3: "plano",
27
+ f4: "orquestracao",
28
+ f5: "auditoria",
29
+ f6: "execucao",
30
+ e1: "investigacao",
31
+ e2: "plano",
32
+ e3: "correcao",
33
+ e4: "qa",
34
+ e5: "relatorio",
35
+ b1: "concepcao",
36
+ b2: "stack",
37
+ b3: "mapa",
38
+ b4: "features",
39
+ b5: "recursao",
40
+ b6: "validacao",
41
+ };
42
+ /**
43
+ * Uma palavra dizendo em que pé está o trabalho — o que a pessoa lê primeiro.
44
+ *
45
+ * "bloqueado" e "parado" são coisas diferentes de propósito: bloqueado é
46
+ * declarado no plano e exige decisão humana; parado é o rastro em silêncio, e
47
+ * costuma ser execução travada.
48
+ */
49
+ function situacao(t, agora) {
50
+ if (t.bloqueiosAbertos > 0) {
51
+ const n = t.bloqueiosAbertos;
52
+ return { texto: n === 1 ? "1 bloqueio" : `${String(n)} bloqueios`, papel: "erro" };
53
+ }
54
+ if (t.ativas.some((a) => a.bloqueada))
55
+ return { texto: "task bloqueada", papel: "erro" };
56
+ if (t.total > 0 && t.concluidas >= t.total)
57
+ return { texto: "concluido", papel: "sucesso" };
58
+ if (t.ativas.length > 0) {
59
+ // Duas ou mais tasks em andamento é paralelismo REAL acontecendo agora,
60
+ // e é o que a tela precisa gritar.
61
+ const n = t.ativas.length;
62
+ if (n > 1)
63
+ return { texto: `${String(n)} em paralelo`, papel: "destaque" };
64
+ return { texto: "executando", papel: "atencao" };
65
+ }
66
+ if (t.ultimoEventoTs !== null) {
67
+ const ms = agora.getTime() - new Date(t.ultimoEventoTs).getTime();
68
+ // Dez minutos sem evento numa execução autônoma não é pausa, é sintoma.
69
+ if (ms > 10 * 60_000)
70
+ return { texto: `parado ha ${decorrido(ms)}`, papel: "atencao" };
71
+ }
72
+ return { texto: "aguardando", papel: "apagado" };
73
+ }
74
+ /** A linha-título de um trabalho: id, ferramenta e situação. */
75
+ function linhaTitulo(t, colunas, pintar, agora) {
76
+ const s = situacao(t, agora);
77
+ const marca = t.corrente ? "▸ " : " ";
78
+ const cabeca = `${marca}${t.trabalho.trabalho_id} · ${t.trabalho.expx_tool}`;
79
+ const estagio = MARCA_ESTAGIO[t.estagio] ?? t.estagio;
80
+ const cauda = `${t.estagio} ${estagio} · ${s.texto}`;
81
+ // O título alinha à esquerda e a situação à direita: a coluna da direita
82
+ // vira uma faixa que se lê de cima a baixo sem precisar ler o resto.
83
+ const sobra = colunas - largura(cabeca) - largura(cauda) - 2;
84
+ if (sobra < 1) {
85
+ return pintar(cortar(`${cabeca} · ${s.texto}`, colunas), t.corrente ? "destaque" : "neutro");
86
+ }
87
+ return (pintar(cabeca, t.corrente ? "destaque" : "neutro") +
88
+ " ".repeat(sobra + 2) +
89
+ pintar(cauda, s.papel));
90
+ }
91
+ /** A linha de progresso: barra, contagem, percentual e título do trabalho. */
92
+ function linhaProgresso(t, colunas, pintar) {
93
+ const contagem = `${String(t.concluidas)}/${String(t.total)}`;
94
+ const pct = percentual(t.concluidas, t.total).padStart(4);
95
+ if (colunas < CABE_BARRA) {
96
+ return pintar(cortar(` ${contagem} ${pct} · ${t.trabalho.titulo}`, colunas), "apagado");
97
+ }
98
+ const b = barra(t.concluidas, t.total, BARRA_TRABALHO);
99
+ const prefixo = ` ${b} ${preencher(contagem, 6)} ${pct} `;
100
+ const resto = colunas - largura(prefixo);
101
+ return (" " +
102
+ pintar(b, papelDaBarra(t.concluidas, t.total)) +
103
+ " " +
104
+ pintar(preencher(contagem, 6), "neutro") +
105
+ " " +
106
+ pintar(pct, "apagado") +
107
+ " " +
108
+ pintar(cortar(t.trabalho.titulo, Math.max(0, resto)), "apagado"));
109
+ }
110
+ /**
111
+ * A linha de uma task ativa: barra, estimativa, tempo e paralelismo.
112
+ *
113
+ * O percentual aqui é ESTIMADO — o método não mede progresso dentro de uma
114
+ * task — e por isso vem com `~`. A barra de quem não tem sinal nenhum no rastro
115
+ * é indeterminada: pulsa dizendo "vivo", sem afirmar quanto falta.
116
+ */
117
+ function linhaTask(a, colunas, pintar, agora) {
118
+ const marca = a.bloqueada ? "[!]" : "[>]";
119
+ const papel = a.bloqueada ? "erro" : "destaque";
120
+ // Paralelismo: a fase declarou rodar junto com outras, ou a task pode rodar
121
+ // junto com as irmãs. O plano declara; a execução nunca decide isso sozinha.
122
+ const par = a.paralelaCom.length > 0 ? ` ‖ ${a.paralelaCom.join(",")}` : a.paralelizavel ? " ‖" : "";
123
+ const dep = a.dependeDe.length > 0 ? ` ← ${a.dependeDe.join(",")}` : "";
124
+ const tempo = a.progresso.iniciadaEm !== null
125
+ ? decorrido(agora.getTime() - a.progresso.iniciadaEm.getTime())
126
+ : "";
127
+ const cabeca = ` ${marca} ${a.id} ${a.titulo}${par}${dep}`;
128
+ if (colunas < CABE_BARRA)
129
+ return pintar(cortar(cabeca, colunas), papel);
130
+ // Sem sinal no rastro não há o que estimar: a barra pulsa em vez de mentir.
131
+ const temSinal = a.progresso.sinais > 0 || a.progresso.fracao > 0.1;
132
+ const b = temSinal
133
+ ? barra(Math.round(a.progresso.fracao * 100), 100, BARRA_TASK)
134
+ : barraIndeterminada(BARRA_TASK, agora);
135
+ const est = temSinal ? `~${String(Math.round(a.progresso.fracao * 100))}%`.padStart(5) : " ";
136
+ const cauda = `${b} ${est} ${preencher(tempo, 6)}`;
137
+ const sobra = colunas - largura(cabeca) - largura(cauda) - 2;
138
+ if (sobra < 1) {
139
+ return pintar(cortar(cabeca, colunas - largura(cauda) - 1), papel) + " " + pintar(cauda, "apagado");
140
+ }
141
+ return (pintar(cabeca, papel) +
142
+ " ".repeat(sobra + 2) +
143
+ pintar(b, a.bloqueada ? "erro" : "atencao") +
144
+ " " +
145
+ pintar(est, "apagado") +
146
+ " " +
147
+ pintar(preencher(tempo, 6), "apagado"));
148
+ }
149
+ /**
150
+ * A linha de contexto do trabalho corrente: branch, raio do legado e orçamento.
151
+ *
152
+ * Só o corrente tem: esses campos vêm do `estado.json`, que descreve UM
153
+ * trabalho, e repeti-los nos outros mostraria o dado de um no lugar do outro.
154
+ * Ausentes no modo degradado, porque nenhum kind do plano os declara
155
+ * (base/estado-json.md, risco 2).
156
+ */
157
+ function linhaContexto(t, estado, colunas, pintar) {
158
+ if (!t.corrente || estado === null)
159
+ return [];
160
+ const partes = [];
161
+ if (estado.branch !== null)
162
+ partes.push(estado.branch);
163
+ if (estado.pr_estado !== null)
164
+ partes.push(`pr ${estado.pr_estado}`);
165
+ if (estado.raio !== null)
166
+ partes.push(`raio ${estado.raio}`);
167
+ if (estado.orcamento_arquivos !== null)
168
+ partes.push(`arq ${estado.orcamento_arquivos}`);
169
+ if (estado.orcamento_linhas !== null)
170
+ partes.push(`lin ${estado.orcamento_linhas}`);
171
+ if (partes.length === 0)
172
+ return [];
173
+ // Raio alto é a única parte que grita: é o aviso de que a mudança pode
174
+ // quebrar coisa distante, e é o que o modo legado existe para sinalizar.
175
+ const papel = estado.raio === "alto" ? "erro" : "apagado";
176
+ return [pintar(cortar(` ${partes.join(" · ")}`, colunas), papel)];
177
+ }
178
+ /** Um bloco de trabalho: título, progresso e as tasks que rodam agora. */
179
+ export function blocoTrabalho(t, colunas, pintar, agora, estado = null) {
180
+ const linhas = [
181
+ linhaTitulo(t, colunas, pintar, agora),
182
+ linhaProgresso(t, colunas, pintar),
183
+ ...linhaContexto(t, estado, colunas, pintar),
184
+ ];
185
+ // Só as tasks ATIVAS entram: a árvore inteira é o que fazia a tela virar
186
+ // um despejo. Quem quer a árvore completa pede `--arvore`.
187
+ for (const a of t.ativas)
188
+ linhas.push(linhaTask(a, colunas, pintar, agora));
189
+ return linhas;
190
+ }
191
+ /** Rótulo curto e legível de um evento — sem o vocabulário de máquina. */
192
+ const ROTULO_EVENTO = {
193
+ fase_iniciada: "fase iniciada",
194
+ fase_concluida: "fase concluida",
195
+ task_iniciada: "task iniciada",
196
+ task_concluida: "task concluida",
197
+ task_bloqueada: "task bloqueada",
198
+ suite_executada: "suite",
199
+ arquivo_alterado: "arquivos",
200
+ regra_violada: "regra violada",
201
+ acao_bloqueada: "acao bloqueada",
202
+ agente_iniciado: "agente iniciado",
203
+ agente_concluido: "agente concluido",
204
+ veredito_emitido: "veredito",
205
+ commit_criado: "commit",
206
+ pr_aberto: "pr aberto",
207
+ };
208
+ /** O sinal de um grupo: o que a pessoa lê antes de ler a linha. */
209
+ function sinalDe(g) {
210
+ if (g.houveFalha)
211
+ return { marca: "!", papel: "erro" };
212
+ if (g.evento === "task_concluida" || g.evento === "fase_concluida") {
213
+ return { marca: "✓", papel: "sucesso" };
214
+ }
215
+ if (g.evento === "suite_executada")
216
+ return { marca: "✓", papel: "sucesso" };
217
+ return { marca: "·", papel: "apagado" };
218
+ }
219
+ /**
220
+ * A atividade: eventos agrupados, não o rastro cru.
221
+ *
222
+ * Antes eram dez linhas do arquivo `.jsonl` como estavam no disco — sete delas
223
+ * a mesma `suite_executada` com o mesmo comando gigante. Agrupar por (evento,
224
+ * alvo) devolve a informação e libera as linhas para o que de fato aconteceu.
225
+ */
226
+ export function desenharAtividade(v, colunas, pintar) {
227
+ const grupos = agrupar(v.eventos, 6);
228
+ if (grupos.length === 0)
229
+ return [];
230
+ const linhas = [pintar(cortar("atividade", colunas), "apagado")];
231
+ for (const g of grupos) {
232
+ const s = sinalDe(g);
233
+ const rotulo = ROTULO_EVENTO[g.evento] ?? g.evento;
234
+ // "×12" diz que repetiu; "×12, 8 sem resultado" diz que repetiu APANHANDO,
235
+ // que é o sintoma de execução em laço — e era o que a tela antiga escondia
236
+ // atrás de doze linhas idênticas.
237
+ const vezes = g.vezes > 1 ? ` ×${String(g.vezes)}` : "";
238
+ const insucesso = g.falhas > 0 && !g.houveFalha ? ` (${String(g.falhas)} sem exito)` : "";
239
+ const alvo = g.alvo !== "" ? ` ${g.alvo}` : "";
240
+ const cabeca = ` ${s.marca} ${rotulo}${vezes}${alvo}${insucesso}`;
241
+ const hora = g.ts.slice(11, 16);
242
+ // O detalhe é cortado ANTES de medir: cortar depois de calcular a sobra
243
+ // desalinha a coluna da direita justamente nas linhas mais longas, que é
244
+ // quando o alinhamento mais ajuda a varrer a tela.
245
+ const detalhe = cortar(g.detalhe !== "" ? g.detalhe : g.resultado, COL_DETALHE);
246
+ const cauda = `${preencher(detalhe, COL_DETALHE)} ${hora}`;
247
+ const sobra = colunas - largura(cabeca) - largura(cauda) - 2;
248
+ if (sobra < 1) {
249
+ linhas.push(pintar(cortar(`${cabeca} · ${detalhe} ${hora}`, colunas), s.papel));
250
+ continue;
251
+ }
252
+ linhas.push(pintar(cortar(cabeca, colunas), s.papel) +
253
+ " ".repeat(sobra + 2) +
254
+ pintar(preencher(detalhe, COL_DETALHE), g.houveFalha ? "erro" : "apagado") +
255
+ " " +
256
+ pintar(hora, "apagado"));
257
+ }
258
+ return linhas;
259
+ }
260
+ //# sourceMappingURL=painel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"painel.js","sourceRoot":"","sources":["../../../src/watch/desenho/painel.ts"],"names":[],"mappings":"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"}
@@ -42,6 +42,7 @@ export declare const EstadoExpx: z.ZodObject<{
42
42
  ferramenta: z.ZodNullable<z.ZodEnum<{
43
43
  sprintx: "sprintx";
44
44
  runx: "runx";
45
+ buildx: "buildx";
45
46
  mergex: "mergex";
46
47
  legadox: "legadox";
47
48
  stackx: "stackx";
@@ -61,6 +62,12 @@ export declare const EstadoExpx: z.ZodObject<{
61
62
  e3: "e3";
62
63
  e4: "e4";
63
64
  e5: "e5";
65
+ b1: "b1";
66
+ b2: "b2";
67
+ b3: "b3";
68
+ b4: "b4";
69
+ b5: "b5";
70
+ b6: "b6";
64
71
  }>>;
65
72
  task: z.ZodNullable<z.ZodString>;
66
73
  tasks_concluidas: z.ZodNumber;
@@ -10,6 +10,8 @@ export type Opcoes = {
10
10
  trabalho: string | undefined;
11
11
  /** `--todos` — lista os trabalhos abertos, um por linha, sem a árvore. */
12
12
  todos: boolean;
13
+ /** `--arvore` — mostra a árvore completa do trabalho corrente. */
14
+ arvore: boolean;
13
15
  ajuda: boolean;
14
16
  /** Largura fixa, para teste e para quem quer saída estável. */
15
17
  colunas: number | undefined;
@@ -6,11 +6,14 @@
6
6
  * painel não tem.
7
7
  */
8
8
  const AJUDA = `
9
- expx watch — acompanha um trabalho no terminal, ao vivo (somente leitura)
9
+ expx watch — painel dos trabalhos no terminal, ao vivo (somente leitura)
10
10
 
11
- expx watch segue o trabalho atual, lido do .expx/estado.json
12
- expx watch <trabalho_id> segue um trabalho especifico
13
- expx watch --todos lista os trabalhos abertos, um por linha, sem arvore
11
+ expx watch painel de todos os trabalhos abertos, com barra de
12
+ progresso, task em execucao e atividade recente
13
+ expx watch <trabalho_id> destaca um trabalho como o corrente, no topo
14
+ expx watch --todos uma linha por trabalho, sem detalhe
15
+
16
+ --arvore acrescenta a arvore completa (sprints, fases, tasks)
14
17
 
15
18
  --colunas <n> largura fixa, em vez da largura do terminal
16
19
  --ajuda mostra esta ajuda
@@ -25,6 +28,7 @@ export function interpretarOpcoes(argv) {
25
28
  const opcoes = {
26
29
  trabalho: undefined,
27
30
  todos: false,
31
+ arvore: false,
28
32
  ajuda: false,
29
33
  colunas: undefined,
30
34
  };
@@ -38,6 +42,9 @@ export function interpretarOpcoes(argv) {
38
42
  case "--todos":
39
43
  opcoes.todos = true;
40
44
  break;
45
+ case "--arvore":
46
+ opcoes.arvore = true;
47
+ break;
41
48
  case "--colunas": {
42
49
  const v = embutido ?? argv[++i];
43
50
  const n = Number(v);