expxdev 0.1.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 (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +137 -0
  3. package/dist/cli/argumentos.d.ts +22 -0
  4. package/dist/cli/argumentos.js +85 -0
  5. package/dist/cli/argumentos.js.map +1 -0
  6. package/dist/cli/expx-bin.d.ts +2 -0
  7. package/dist/cli/expx-bin.js +40 -0
  8. package/dist/cli/expx-bin.js.map +1 -0
  9. package/dist/cli/expx.d.ts +13 -0
  10. package/dist/cli/expx.js +123 -0
  11. package/dist/cli/expx.js.map +1 -0
  12. package/dist/cli/init-flags.d.ts +34 -0
  13. package/dist/cli/init-flags.js +83 -0
  14. package/dist/cli/init-flags.js.map +1 -0
  15. package/dist/cli/init.d.ts +34 -0
  16. package/dist/cli/init.js +103 -0
  17. package/dist/cli/init.js.map +1 -0
  18. package/dist/cli/principal.d.ts +2 -0
  19. package/dist/cli/principal.js +107 -0
  20. package/dist/cli/principal.js.map +1 -0
  21. package/dist/cli/projeto.d.ts +19 -0
  22. package/dist/cli/projeto.js +28 -0
  23. package/dist/cli/projeto.js.map +1 -0
  24. package/dist/cli/selecao.d.ts +19 -0
  25. package/dist/cli/selecao.js +28 -0
  26. package/dist/cli/selecao.js.map +1 -0
  27. package/dist/cli/selecionar.d.ts +23 -0
  28. package/dist/cli/selecionar.js +45 -0
  29. package/dist/cli/selecionar.js.map +1 -0
  30. package/dist/cli/subcomandos.d.ts +25 -0
  31. package/dist/cli/subcomandos.js +43 -0
  32. package/dist/cli/subcomandos.js.map +1 -0
  33. package/dist/doctor/efeito.d.ts +17 -0
  34. package/dist/doctor/efeito.js +18 -0
  35. package/dist/doctor/efeito.js.map +1 -0
  36. package/dist/doctor/verificadores.d.ts +21 -0
  37. package/dist/doctor/verificadores.js +158 -0
  38. package/dist/doctor/verificadores.js.map +1 -0
  39. package/dist/harness/backup.d.ts +15 -0
  40. package/dist/harness/backup.js +29 -0
  41. package/dist/harness/backup.js.map +1 -0
  42. package/dist/harness/instalar.d.ts +31 -0
  43. package/dist/harness/instalar.js +43 -0
  44. package/dist/harness/instalar.js.map +1 -0
  45. package/dist/harness/opencode.d.ts +18 -0
  46. package/dist/harness/opencode.js +32 -0
  47. package/dist/harness/opencode.js.map +1 -0
  48. package/dist/harness/settings.d.ts +36 -0
  49. package/dist/harness/settings.js +66 -0
  50. package/dist/harness/settings.js.map +1 -0
  51. package/dist/index.d.ts +8 -0
  52. package/dist/index.js +9 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/nucleo/busca.d.ts +28 -0
  55. package/dist/nucleo/busca.js +29 -0
  56. package/dist/nucleo/busca.js.map +1 -0
  57. package/dist/nucleo/caminhos.d.ts +21 -0
  58. package/dist/nucleo/caminhos.js +64 -0
  59. package/dist/nucleo/caminhos.js.map +1 -0
  60. package/dist/nucleo/catalogo.d.ts +20 -0
  61. package/dist/nucleo/catalogo.js +50 -0
  62. package/dist/nucleo/catalogo.js.map +1 -0
  63. package/dist/nucleo/integridade.d.ts +20 -0
  64. package/dist/nucleo/integridade.js +75 -0
  65. package/dist/nucleo/integridade.js.map +1 -0
  66. package/dist/nucleo/layout.d.ts +23 -0
  67. package/dist/nucleo/layout.js +73 -0
  68. package/dist/nucleo/layout.js.map +1 -0
  69. package/dist/nucleo/lock.d.ts +61 -0
  70. package/dist/nucleo/lock.js +96 -0
  71. package/dist/nucleo/lock.js.map +1 -0
  72. package/dist/nucleo/versao.d.ts +35 -0
  73. package/dist/nucleo/versao.js +63 -0
  74. package/dist/nucleo/versao.js.map +1 -0
  75. package/dist/parser/conformidade/regras.d.ts +41 -0
  76. package/dist/parser/conformidade/regras.js +209 -0
  77. package/dist/parser/conformidade/regras.js.map +1 -0
  78. package/dist/parser/descoberta/trabalhos.d.ts +35 -0
  79. package/dist/parser/descoberta/trabalhos.js +28 -0
  80. package/dist/parser/descoberta/trabalhos.js.map +1 -0
  81. package/dist/parser/descoberta/varredura.d.ts +4 -0
  82. package/dist/parser/descoberta/varredura.js +79 -0
  83. package/dist/parser/descoberta/varredura.js.map +1 -0
  84. package/dist/parser/esquema/cabecalho.d.ts +60 -0
  85. package/dist/parser/esquema/cabecalho.js +57 -0
  86. package/dist/parser/esquema/cabecalho.js.map +1 -0
  87. package/dist/parser/esquema/enums.d.ts +114 -0
  88. package/dist/parser/esquema/enums.js +64 -0
  89. package/dist/parser/esquema/enums.js.map +1 -0
  90. package/dist/parser/esquema/kinds.d.ts +768 -0
  91. package/dist/parser/esquema/kinds.js +231 -0
  92. package/dist/parser/esquema/kinds.js.map +1 -0
  93. package/dist/parser/leitura/arquivo.d.ts +9 -0
  94. package/dist/parser/leitura/arquivo.js +25 -0
  95. package/dist/parser/leitura/arquivo.js.map +1 -0
  96. package/dist/parser/leitura/frontmatter.d.ts +31 -0
  97. package/dist/parser/leitura/frontmatter.js +77 -0
  98. package/dist/parser/leitura/frontmatter.js.map +1 -0
  99. package/dist/parser/leitura/rejeicao.d.ts +43 -0
  100. package/dist/parser/leitura/rejeicao.js +73 -0
  101. package/dist/parser/leitura/rejeicao.js.map +1 -0
  102. package/dist/parser/projeto/montar.d.ts +62 -0
  103. package/dist/parser/projeto/montar.js +149 -0
  104. package/dist/parser/projeto/montar.js.map +1 -0
  105. package/dist/plugin/atomico.d.ts +13 -0
  106. package/dist/plugin/atomico.js +42 -0
  107. package/dist/plugin/atomico.js.map +1 -0
  108. package/dist/plugin/manifestos.d.ts +38 -0
  109. package/dist/plugin/manifestos.js +57 -0
  110. package/dist/plugin/manifestos.js.map +1 -0
  111. package/dist/plugin/montagem.d.ts +22 -0
  112. package/dist/plugin/montagem.js +30 -0
  113. package/dist/plugin/montagem.js.map +1 -0
  114. package/dist/relatorio/markdown.d.ts +22 -0
  115. package/dist/relatorio/markdown.js +0 -0
  116. package/dist/relatorio/markdown.js.map +1 -0
  117. package/dist/relatorio/pagina.d.ts +22 -0
  118. package/dist/relatorio/pagina.js +338 -0
  119. package/dist/relatorio/pagina.js.map +1 -0
  120. package/dist/servidor/estado.d.ts +16 -0
  121. package/dist/servidor/estado.js +16 -0
  122. package/dist/servidor/estado.js.map +1 -0
  123. package/dist/servidor/http.d.ts +22 -0
  124. package/dist/servidor/http.js +164 -0
  125. package/dist/servidor/http.js.map +1 -0
  126. package/dist/servidor/observador.d.ts +12 -0
  127. package/dist/servidor/observador.js +37 -0
  128. package/dist/servidor/observador.js.map +1 -0
  129. package/dist/servidor/painel.d.ts +24 -0
  130. package/dist/servidor/painel.js +49 -0
  131. package/dist/servidor/painel.js.map +1 -0
  132. package/dist/teste/layouts-fixture.d.ts +16 -0
  133. package/dist/teste/layouts-fixture.js +9 -0
  134. package/dist/teste/layouts-fixture.js.map +1 -0
  135. package/dist/teste/projeto-temporario.d.ts +14 -0
  136. package/dist/teste/projeto-temporario.js +16 -0
  137. package/dist/teste/projeto-temporario.js.map +1 -0
  138. package/dist/teste/repo-fixture.d.ts +27 -0
  139. package/dist/teste/repo-fixture.js +49 -0
  140. package/dist/teste/repo-fixture.js.map +1 -0
  141. package/dist/update/comparar.d.ts +33 -0
  142. package/dist/update/comparar.js +67 -0
  143. package/dist/update/comparar.js.map +1 -0
  144. package/dist/update/compatibilidade.d.ts +19 -0
  145. package/dist/update/compatibilidade.js +36 -0
  146. package/dist/update/compatibilidade.js.map +1 -0
  147. package/dist/update/flags.d.ts +47 -0
  148. package/dist/update/flags.js +123 -0
  149. package/dist/update/flags.js.map +1 -0
  150. package/dist/update/modificacao.d.ts +23 -0
  151. package/dist/update/modificacao.js +36 -0
  152. package/dist/update/modificacao.js.map +1 -0
  153. package/package.json +73 -0
  154. package/ui/dist/assets/index-BmDTogQZ.js +14 -0
  155. package/ui/dist/assets/index-DUzbt2M7.css +1 -0
  156. package/ui/dist/index.html +13 -0
@@ -0,0 +1,49 @@
1
+ import { WebSocketServer } from "ws";
2
+ import { criarServidor } from "./http.js";
3
+ import { observar } from "./observador.js";
4
+ /**
5
+ * Junta servidor, observador e websocket.
6
+ *
7
+ * O websocket envia o ESTADO INTEIRO a cada atualização (decisão D-28), não
8
+ * um delta. O estado de um projeto documental é pequeno, e mandar tudo
9
+ * elimina a classe de bug em que servidor e tela discordam depois de uma
10
+ * mensagem perdida.
11
+ */
12
+ export async function iniciarPainel(op) {
13
+ const servidor = await criarServidor({
14
+ raiz: op.raiz,
15
+ porta: op.porta,
16
+ ...(op.diasBloqueio !== undefined ? { diasBloqueio: op.diasBloqueio } : {}),
17
+ ...(op.estaticos !== undefined ? { estaticos: op.estaticos } : {}),
18
+ });
19
+ const wss = new WebSocketServer({ server: servidor.http, path: "/ws" });
20
+ function difundir(estado) {
21
+ const corpo = JSON.stringify({ tipo: "estado", estado });
22
+ for (const cliente of wss.clients) {
23
+ if (cliente.readyState === 1)
24
+ cliente.send(corpo);
25
+ }
26
+ }
27
+ // todo cliente recebe o estado atual assim que conecta
28
+ wss.on("connection", (cliente) => {
29
+ cliente.send(JSON.stringify({ tipo: "estado", estado: servidor.estado() }));
30
+ });
31
+ servidor.aoAtualizar(difundir);
32
+ const observador = await observar(op.raiz, () => {
33
+ servidor.recarregar();
34
+ }, op.debounceMs ?? 300);
35
+ return {
36
+ url: () => servidor.url(),
37
+ urlWebsocket: () => `${servidor.url().replace("http://", "ws://")}/ws`,
38
+ porta: () => servidor.endereco().port,
39
+ estado: () => servidor.estado(),
40
+ parar: async () => {
41
+ await observador.parar();
42
+ for (const c of wss.clients)
43
+ c.terminate();
44
+ await new Promise((ok) => wss.close(() => ok()));
45
+ await servidor.fechar();
46
+ },
47
+ };
48
+ }
49
+ //# sourceMappingURL=painel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"painel.js","sourceRoot":"","sources":["../../src/servidor/painel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AACrD,OAAO,EAAE,aAAa,EAAuB,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAmB,MAAM,iBAAiB,CAAC;AAmB5D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAgB;IAClD,MAAM,QAAQ,GAAmB,MAAM,aAAa,CAAC;QACnD,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,KAAK,EAAE,EAAE,CAAC,KAAK;QACf,GAAG,CAAC,EAAE,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3E,GAAG,CAAC,EAAE,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnE,CAAC,CAAC;IAEH,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAExE,SAAS,QAAQ,CAAC,MAAoB;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;QACzD,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;YAClC,IAAI,OAAO,CAAC,UAAU,KAAK,CAAC;gBAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,uDAAuD;IACvD,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,OAAkB,EAAE,EAAE;QAC1C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAE/B,MAAM,UAAU,GAAe,MAAM,QAAQ,CAC3C,EAAE,CAAC,IAAI,EACP,GAAG,EAAE;QACH,QAAQ,CAAC,UAAU,EAAE,CAAC;IACxB,CAAC,EACD,EAAE,CAAC,UAAU,IAAI,GAAG,CACrB,CAAC;IAEF,OAAO;QACL,GAAG,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE;QACzB,YAAY,EAAE,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK;QACtE,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,IAAI;QACrC,MAAM,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE;QAC/B,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,UAAU,CAAC,KAAK,EAAE,CAAC;YACzB,KAAK,MAAM,CAAC,IAAI,GAAG,CAAC,OAAO;gBAAE,CAAC,CAAC,SAAS,EAAE,CAAC;YAC3C,MAAM,IAAI,OAAO,CAAO,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACvD,MAAM,QAAQ,CAAC,MAAM,EAAE,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * O trio de repositórios que a suíte usa para exercitar layout e versão.
3
+ *
4
+ * Os repositórios reais têm dois layouts distintos e nenhuma tag (ver
5
+ * `base/08-repositorios-reais.md`). O trio cobre os dois layouts e o caso sem
6
+ * tag, que hoje é o de TODAS as skills reais.
7
+ */
8
+ export type Trio = {
9
+ /** Layout do sprintx/stackx/mergex: `.claude/skills/<nome>/`. */
10
+ embutido: string;
11
+ /** Layout do runx/legadox: `skill/` na raiz. */
12
+ plano: string;
13
+ /** Repositório sem nenhuma tag — o caso real de hoje. */
14
+ semTag: string;
15
+ };
16
+ export declare function criarTrioDeLayouts(): Trio;
@@ -0,0 +1,9 @@
1
+ import { criarRepoSkill } from "./repo-fixture.js";
2
+ export function criarTrioDeLayouts() {
3
+ return {
4
+ embutido: criarRepoSkill({ nome: "sprintx", tags: ["v1.0.0", "v1.2.0"], layout: "embutido" }),
5
+ plano: criarRepoSkill({ nome: "runx", tags: ["v0.9.0"], layout: "plano" }),
6
+ semTag: criarRepoSkill({ nome: "stackx", tags: [], layout: "embutido" }),
7
+ };
8
+ }
9
+ //# sourceMappingURL=layouts-fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layouts-fixture.js","sourceRoot":"","sources":["../../src/teste/layouts-fixture.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAkBnD,MAAM,UAAU,kBAAkB;IAChC,OAAO;QACL,QAAQ,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;QAC7F,KAAK,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC1E,MAAM,EAAE,cAAc,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;KACzE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Pasta isolada para testes que escrevem em disco.
3
+ *
4
+ * O CLI escreve de verdade (`.expx/`, `.claude/settings.json`), então testá-lo
5
+ * exige um projeto real, não um mock de fs. Copiar a fixture para uma pasta
6
+ * temporária mantém as fixtures do repositório intactas: um teste que
7
+ * sobrescreve a origem contamina todos os outros.
8
+ */
9
+ export type ProjetoTemporario = {
10
+ raiz: string;
11
+ descartar: () => void;
12
+ };
13
+ /** Cria a pasta; com `origem`, copia o conteúdo dela para dentro. */
14
+ export declare function projetoTemporario(origem?: string): ProjetoTemporario;
@@ -0,0 +1,16 @@
1
+ import { cpSync, mkdtempSync, rmSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ /** Cria a pasta; com `origem`, copia o conteúdo dela para dentro. */
5
+ export function projetoTemporario(origem) {
6
+ const raiz = mkdtempSync(join(tmpdir(), "expx-projeto-"));
7
+ if (origem !== undefined)
8
+ cpSync(origem, raiz, { recursive: true });
9
+ return {
10
+ raiz,
11
+ descartar: () => {
12
+ rmSync(raiz, { recursive: true, force: true });
13
+ },
14
+ };
15
+ }
16
+ //# sourceMappingURL=projeto-temporario.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projeto-temporario.js","sourceRoot":"","sources":["../../src/teste/projeto-temporario.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAejC,qEAAqE;AACrE,MAAM,UAAU,iBAAiB,CAAC,MAAe;IAC/C,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,eAAe,CAAC,CAAC,CAAC;IAC1D,IAAI,MAAM,KAAK,SAAS;QAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,OAAO;QACL,IAAI;QACJ,SAAS,EAAE,GAAG,EAAE;YACd,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Repositórios git locais no lugar da rede.
3
+ *
4
+ * A suíte precisa exercitar resolução de versão e busca de skill sem tocar o
5
+ * GitHub: sem rede a suíte não roda em CI offline, e com rede ela depende do
6
+ * estado de um repositório que ninguém controla. Um repositório local de
7
+ * verdade — não um mock — exercita o mesmo `git` que a implementação usa.
8
+ */
9
+ /** Os dois layouts reais dos repositórios de skill (ver base/08-repositorios-reais.md). */
10
+ export type Layout = "embutido" | "plano";
11
+ export type OpcoesRepo = {
12
+ nome: string;
13
+ tags: readonly string[];
14
+ layout?: Layout;
15
+ /** Conteúdo extra do SKILL.md, para fixtures que precisam de um corpo específico. */
16
+ corpo?: string;
17
+ };
18
+ /**
19
+ * Onde o SKILL.md e os comandos ficam em cada layout. `embutido` é o do
20
+ * sprintx/stackx/mergex; `plano` é o do runx/legadox.
21
+ */
22
+ export declare function caminhosDoLayout(nome: string, layout: Layout): {
23
+ skill: string;
24
+ comandos: string;
25
+ };
26
+ /** Cria um repositório git local com a skill e as tags pedidas. Devolve o caminho. */
27
+ export declare function criarRepoSkill(op: OpcoesRepo): string;
@@ -0,0 +1,49 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { mkdtempSync, mkdirSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ function git(cwd, ...args) {
6
+ execFileSync("git", [...args], {
7
+ cwd,
8
+ stdio: "ignore",
9
+ env: {
10
+ ...process.env,
11
+ GIT_AUTHOR_NAME: "expx",
12
+ GIT_AUTHOR_EMAIL: "expx@example.invalid",
13
+ GIT_COMMITTER_NAME: "expx",
14
+ GIT_COMMITTER_EMAIL: "expx@example.invalid",
15
+ },
16
+ });
17
+ }
18
+ /**
19
+ * Onde o SKILL.md e os comandos ficam em cada layout. `embutido` é o do
20
+ * sprintx/stackx/mergex; `plano` é o do runx/legadox.
21
+ */
22
+ export function caminhosDoLayout(nome, layout) {
23
+ return layout === "embutido"
24
+ ? { skill: join(".claude", "skills", nome), comandos: join(".claude", "commands") }
25
+ : { skill: "skill", comandos: "commands" };
26
+ }
27
+ /** Cria um repositório git local com a skill e as tags pedidas. Devolve o caminho. */
28
+ export function criarRepoSkill(op) {
29
+ const layout = op.layout ?? "embutido";
30
+ const raiz = mkdtempSync(join(tmpdir(), `expx-repo-${op.nome}-`));
31
+ const { skill, comandos } = caminhosDoLayout(op.nome, layout);
32
+ mkdirSync(join(raiz, skill, "references"), { recursive: true });
33
+ mkdirSync(join(raiz, comandos), { recursive: true });
34
+ writeFileSync(join(raiz, skill, "SKILL.md"), op.corpo ??
35
+ `---\nname: ${op.nome}\ndescription: Skill de fixture ${op.nome} para a suite do expx-cli\n---\n\n# ${op.nome}\n\nDetalhe em \`references/01.md\`.\n`);
36
+ writeFileSync(join(raiz, skill, "references", "01.md"), `# referencia de ${op.nome}\n`);
37
+ writeFileSync(join(raiz, comandos, `${op.nome}.md`), `---\ndescription: comando ${op.nome}\n---\n\nInvoque a skill \`${op.nome}\`.\n`);
38
+ git(raiz, "init", "-q", "-b", "main");
39
+ git(raiz, "add", "-A");
40
+ git(raiz, "commit", "-q", "-m", `${op.nome}: commit inicial`);
41
+ for (const tag of op.tags) {
42
+ writeFileSync(join(raiz, skill, "references", "01.md"), `# referencia de ${op.nome} em ${tag}\n`);
43
+ git(raiz, "add", "-A");
44
+ git(raiz, "commit", "-q", "-m", `${op.nome}: ${tag}`);
45
+ git(raiz, "tag", tag);
46
+ }
47
+ return raiz;
48
+ }
49
+ //# sourceMappingURL=repo-fixture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo-fixture.js","sourceRoot":"","sources":["../../src/teste/repo-fixture.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * O que mudaria num `update`, antes de aplicar qualquer coisa.
3
+ *
4
+ * Separar a comparação da aplicação é o que permite o `--check` e o resumo
5
+ * mostrado antes da confirmação: o usuário decide vendo o que vai acontecer, e
6
+ * não descobrindo depois.
7
+ */
8
+ export type ItemComparacao = {
9
+ nome: string;
10
+ atual: string;
11
+ nova: string;
12
+ emDia: boolean;
13
+ travado: boolean;
14
+ /** CHANGELOG quando existir; senão, títulos dos commits entre as referências. */
15
+ mudancas: string[];
16
+ erro?: string;
17
+ };
18
+ export type Comparacao = {
19
+ ok: true;
20
+ itens: ItemComparacao[];
21
+ aAplicar: ItemComparacao[];
22
+ } | {
23
+ ok: false;
24
+ erro: string;
25
+ };
26
+ export type OpcoesComparar = {
27
+ raiz: string;
28
+ /** Limita a comparação a estas skills; vazio compara todas as instaladas. */
29
+ somente?: readonly string[];
30
+ origens?: Record<string, string>;
31
+ referencias?: Record<string, string>;
32
+ };
33
+ export declare function compararComRemoto(op: OpcoesComparar): Promise<Comparacao>;
@@ -0,0 +1,67 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { CATALOGO } from "../nucleo/catalogo.js";
4
+ import { lerLock } from "../nucleo/lock.js";
5
+ import { resolverAlvo } from "../nucleo/versao.js";
6
+ const exec = promisify(execFile);
7
+ function origemDe(nome, lockRepo, origens) {
8
+ return origens?.[nome] ?? lockRepo ?? CATALOGO.find((s) => s.nome === nome)?.repositorio ?? "";
9
+ }
10
+ /**
11
+ * Os títulos dos commits entre duas referências.
12
+ *
13
+ * Lê do repositório remoto por clone raso do intervalo. Falha aqui nunca
14
+ * derruba o update: sem o resumo, o usuário ainda pode decidir pela versão.
15
+ */
16
+ async function mudancasEntre(repositorio, de, para) {
17
+ try {
18
+ const { stdout } = await exec("git", [
19
+ "-c", "core.pager=cat",
20
+ "log", "--format=%s", `${de}..${para}`,
21
+ ], { cwd: repositorio });
22
+ return stdout.split("\n").map((l) => l.trim()).filter((l) => l !== "");
23
+ }
24
+ catch {
25
+ return [];
26
+ }
27
+ }
28
+ export async function compararComRemoto(op) {
29
+ const l = lerLock(op.raiz);
30
+ if (!l.ok)
31
+ return { ok: false, erro: l.erro };
32
+ if (l.incompativel) {
33
+ return {
34
+ ok: false,
35
+ erro: "o .expx/ deste projeto foi criado por uma versao MAIS NOVA do CLI: atualize o expx antes de continuar",
36
+ };
37
+ }
38
+ const itens = [];
39
+ const alvos = Object.entries(l.lock.skills).filter(([nome]) => op.somente === undefined || op.somente.length === 0 || op.somente.includes(nome));
40
+ for (const [nome, travada] of alvos) {
41
+ const repositorio = origemDe(nome, travada.repositorio, op.origens);
42
+ const alvo = await resolverAlvo(repositorio, op.referencias?.[nome]);
43
+ if (!alvo.ok) {
44
+ itens.push({
45
+ nome,
46
+ atual: travada.referencia,
47
+ nova: travada.referencia,
48
+ emDia: true,
49
+ travado: travada.travado,
50
+ mudancas: [],
51
+ erro: alvo.erro ?? "repositorio inacessivel",
52
+ });
53
+ continue;
54
+ }
55
+ const emDia = alvo.referencia === travada.referencia;
56
+ itens.push({
57
+ nome,
58
+ atual: travada.referencia,
59
+ nova: alvo.referencia,
60
+ emDia,
61
+ travado: alvo.travado,
62
+ mudancas: emDia ? [] : await mudancasEntre(repositorio, travada.referencia, alvo.referencia),
63
+ });
64
+ }
65
+ return { ok: true, itens, aAplicar: itens.filter((i) => !i.emDia && i.erro === undefined) };
66
+ }
67
+ //# sourceMappingURL=comparar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparar.js","sourceRoot":"","sources":["../../src/update/comparar.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Recusa skill que exija uma versão de `expx-schema` que este CLI não entende.
3
+ *
4
+ * Nenhuma das cinco skills declara essa versão hoje: o frontmatter delas tem só
5
+ * `name` e `description`. Como o CLI nunca escreve skill, ele não pode
6
+ * acrescentar a chave — então a AUSÊNCIA precisa ser válida e significar a
7
+ * versão 1, a única publicada. Uma skill futura que precise de mais passa a
8
+ * declarar `expx_schema:` e este CLI a bloqueia em vez de instalar algo que o
9
+ * painel não sabe ler.
10
+ */
11
+ export type Compatibilidade = {
12
+ compativel: boolean;
13
+ exigido: number;
14
+ suportado: number;
15
+ motivo?: string;
16
+ };
17
+ /** Lê `expx_schema` do frontmatter do SKILL.md. Ausente ou ilegível = 1. */
18
+ export declare function lerSchemaDaSkill(raizSkill: string): number;
19
+ export declare function avaliarCompatibilidade(raizSkill: string, suportado?: number): Compatibilidade;
@@ -0,0 +1,36 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { VERSAO_SCHEMA_SUPORTADA } from "../index.js";
4
+ /** Lê `expx_schema` do frontmatter do SKILL.md. Ausente ou ilegível = 1. */
5
+ export function lerSchemaDaSkill(raizSkill) {
6
+ const caminho = join(raizSkill, "SKILL.md");
7
+ if (!existsSync(caminho))
8
+ return 1;
9
+ let bruto;
10
+ try {
11
+ bruto = readFileSync(caminho, "utf8");
12
+ }
13
+ catch {
14
+ return 1;
15
+ }
16
+ const bloco = /^---\r?\n([\s\S]*?)\r?\n---/.exec(bruto);
17
+ if (bloco === null)
18
+ return 1;
19
+ const linha = /^expx_schema:\s*(\d+)\s*$/m.exec(bloco[1] ?? "");
20
+ if (linha === null)
21
+ return 1;
22
+ const n = Number(linha[1]);
23
+ return Number.isInteger(n) && n > 0 ? n : 1;
24
+ }
25
+ export function avaliarCompatibilidade(raizSkill, suportado = VERSAO_SCHEMA_SUPORTADA) {
26
+ const exigido = lerSchemaDaSkill(raizSkill);
27
+ if (exigido <= suportado)
28
+ return { compativel: true, exigido, suportado };
29
+ return {
30
+ compativel: false,
31
+ exigido,
32
+ suportado,
33
+ motivo: `a skill exige expx-schema ${String(exigido)} e este CLI suporta ate ${String(suportado)}: e preciso atualizar o CLI antes de instalar esta versao`,
34
+ };
35
+ }
36
+ //# sourceMappingURL=compatibilidade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compatibilidade.js","sourceRoot":"","sources":["../../src/update/compatibilidade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAoBtD,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,CAAC;IACnC,IAAI,KAAa,CAAC;IAClB,IAAI,CAAC;QACH,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,6BAA6B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC;IAC7B,MAAM,KAAK,GAAG,4BAA4B,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAChE,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,CAAC,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3B,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,SAAiB,EACjB,YAAoB,uBAAuB;IAE3C,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,OAAO,IAAI,SAAS;QAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC;IAC1E,OAAO;QACL,UAAU,EAAE,KAAK;QACjB,OAAO;QACP,SAAS;QACT,MAAM,EAAE,6BAA6B,MAAM,CAAC,OAAO,CAAC,2BAA2B,MAAM,CAAC,SAAS,CAAC,2DAA2D;KAC5J,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * O `update`: descobre, mostra, confirma e aplica — nessa ordem.
3
+ *
4
+ * Rollback ficou por conta do versionador, e não por cópia da versão anterior
5
+ * dentro de `.expx/`. Como `.expx/` é commitado, `git checkout` devolve a
6
+ * versão antiga; em troca dessa simplificação, o CLI é OBRIGADO a dizer isso em
7
+ * toda execução que aplica alguma coisa, para que ninguém descubra a ausência
8
+ * do comando de desfazer no pior momento.
9
+ */
10
+ export declare const AVISO_ROLLBACK = "para desfazer esta atualizacao, reverta o .expx/ pelo versionador (ex.: git checkout -- .expx)";
11
+ export type OpcoesUpdateCli = {
12
+ skills: string[];
13
+ check: boolean;
14
+ to?: string;
15
+ latest: boolean;
16
+ sim: boolean;
17
+ };
18
+ export type ResultadoFlagsUpdate = {
19
+ ok: true;
20
+ opcoes: OpcoesUpdateCli;
21
+ } | {
22
+ ok: false;
23
+ erro: string;
24
+ };
25
+ export declare function interpretarFlagsUpdate(argv: readonly string[]): ResultadoFlagsUpdate;
26
+ export type OpcoesUpdate = {
27
+ raiz: string;
28
+ skills?: readonly string[];
29
+ check?: boolean;
30
+ to?: string;
31
+ latest?: boolean;
32
+ sim?: boolean;
33
+ interativo?: boolean;
34
+ origens?: Record<string, string>;
35
+ };
36
+ export type ResultadoUpdate = {
37
+ ok: boolean;
38
+ aplicou: boolean;
39
+ atualizadas: string[];
40
+ emDia: string[];
41
+ bloqueadas: Array<{
42
+ nome: string;
43
+ motivo: string;
44
+ }>;
45
+ mensagens: string[];
46
+ };
47
+ export declare function executarUpdate(op: OpcoesUpdate): Promise<ResultadoUpdate>;
@@ -0,0 +1,123 @@
1
+ import { lerLock } from "../nucleo/lock.js";
2
+ import { executarInit } from "../cli/init.js";
3
+ import { compararComRemoto } from "./comparar.js";
4
+ import { verificarModificacaoLocal } from "./modificacao.js";
5
+ /**
6
+ * O `update`: descobre, mostra, confirma e aplica — nessa ordem.
7
+ *
8
+ * Rollback ficou por conta do versionador, e não por cópia da versão anterior
9
+ * dentro de `.expx/`. Como `.expx/` é commitado, `git checkout` devolve a
10
+ * versão antiga; em troca dessa simplificação, o CLI é OBRIGADO a dizer isso em
11
+ * toda execução que aplica alguma coisa, para que ninguém descubra a ausência
12
+ * do comando de desfazer no pior momento.
13
+ */
14
+ export const AVISO_ROLLBACK = "para desfazer esta atualizacao, reverta o .expx/ pelo versionador (ex.: git checkout -- .expx)";
15
+ export function interpretarFlagsUpdate(argv) {
16
+ const opcoes = { skills: [], check: false, latest: false, sim: false };
17
+ for (let i = 0; i < argv.length; i++) {
18
+ const bruto = argv[i] ?? "";
19
+ const igual = bruto.indexOf("=");
20
+ const nome = igual === -1 ? bruto : bruto.slice(0, igual);
21
+ const embutido = igual === -1 ? undefined : bruto.slice(igual + 1);
22
+ const proximo = () => embutido ?? argv[++i];
23
+ switch (nome) {
24
+ case "--check":
25
+ opcoes.check = true;
26
+ break;
27
+ case "--latest":
28
+ opcoes.latest = true;
29
+ break;
30
+ case "--yes":
31
+ case "--sim":
32
+ opcoes.sim = true;
33
+ break;
34
+ case "--to": {
35
+ const v = proximo();
36
+ if (v === undefined || v === "")
37
+ return { ok: false, erro: "--to exige uma tag ou commit" };
38
+ opcoes.to = v;
39
+ break;
40
+ }
41
+ default:
42
+ if (nome.startsWith("-"))
43
+ return { ok: false, erro: `opcao desconhecida em update: ${nome}` };
44
+ opcoes.skills.push(nome);
45
+ }
46
+ }
47
+ if (opcoes.to !== undefined && opcoes.skills.length !== 1) {
48
+ return { ok: false, erro: "--to exige exatamente uma skill nomeada" };
49
+ }
50
+ return { ok: true, opcoes };
51
+ }
52
+ export async function executarUpdate(op) {
53
+ const mensagens = [];
54
+ const bloqueadas = [];
55
+ const l = lerLock(op.raiz);
56
+ if (!l.ok) {
57
+ return { ok: false, aplicou: false, atualizadas: [], emDia: [], bloqueadas: [], mensagens: [l.erro] };
58
+ }
59
+ const referencias = op.to !== undefined && op.skills?.[0] !== undefined ? { [op.skills[0]]: op.to } : undefined;
60
+ const comparacao = await compararComRemoto({
61
+ raiz: op.raiz,
62
+ ...(op.skills !== undefined ? { somente: op.skills } : {}),
63
+ ...(op.origens !== undefined ? { origens: op.origens } : {}),
64
+ ...(referencias !== undefined ? { referencias } : {}),
65
+ });
66
+ if (!comparacao.ok) {
67
+ return { ok: false, aplicou: false, atualizadas: [], emDia: [], bloqueadas: [], mensagens: [comparacao.erro] };
68
+ }
69
+ const emDia = comparacao.itens.filter((i) => i.emDia).map((i) => i.nome);
70
+ const candidatas = [];
71
+ for (const item of comparacao.aAplicar) {
72
+ // Trabalho manual nunca é sobrescrito por um comando de rotina.
73
+ const mod = verificarModificacaoLocal(op.raiz, item.nome);
74
+ if (mod.temModificacao) {
75
+ bloqueadas.push({
76
+ nome: item.nome,
77
+ motivo: `modificacao local em: ${[...mod.alterados, ...mod.removidos].join(", ")}`,
78
+ });
79
+ continue;
80
+ }
81
+ candidatas.push(item);
82
+ }
83
+ for (const i of comparacao.itens) {
84
+ if (i.erro !== undefined)
85
+ bloqueadas.push({ nome: i.nome, motivo: i.erro });
86
+ }
87
+ for (const i of candidatas) {
88
+ mensagens.push(`${i.nome}: ${i.atual} → ${i.nova}${i.mudancas.length > 0 ? ` (${String(i.mudancas.length)} mudanca(s))` : ""}`);
89
+ }
90
+ const podeAplicar = (op.sim ?? false) || (op.interativo ?? false);
91
+ if (op.check === true || candidatas.length === 0 || !podeAplicar) {
92
+ if (op.check !== true && candidatas.length > 0 && !podeAplicar) {
93
+ mensagens.push("sem confirmacao disponivel: nada foi aplicado (use --yes para aplicar sem perguntar)");
94
+ }
95
+ return { ok: true, aplicou: false, atualizadas: [], emDia, bloqueadas, mensagens };
96
+ }
97
+ // Remonta do zero com as versões novas, mantendo a seleção e o harness.
98
+ const selecao = Object.keys(l.lock.skills);
99
+ const alvos = {};
100
+ for (const c of candidatas)
101
+ alvos[c.nome] = c.nova;
102
+ for (const [nome, travada] of Object.entries(l.lock.skills)) {
103
+ if (alvos[nome] === undefined)
104
+ alvos[nome] = travada.referencia;
105
+ }
106
+ const init = await executarInit({
107
+ raiz: op.raiz,
108
+ skills: selecao,
109
+ harness: l.lock.harness,
110
+ referencias: alvos,
111
+ ...(op.origens !== undefined ? { origens: op.origens } : {}),
112
+ });
113
+ mensagens.push(AVISO_ROLLBACK);
114
+ return {
115
+ ok: init.ok,
116
+ aplicou: true,
117
+ atualizadas: candidatas.map((c) => c.nome),
118
+ emDia,
119
+ bloqueadas,
120
+ mensagens,
121
+ };
122
+ }
123
+ //# sourceMappingURL=flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.js","sourceRoot":"","sources":["../../src/update/flags.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Impede que o `update` apague trabalho manual.
3
+ *
4
+ * Quem ajustou uma skill à mão não pode perder o ajuste por rodar um comando de
5
+ * rotina. Quando o disco diverge do lock, o update NÃO sobrescreve: lista os
6
+ * arquivos e devolve a decisão para quem está no comando.
7
+ */
8
+ export type OpcaoDecisao = {
9
+ id: string;
10
+ rotulo: string;
11
+ };
12
+ /** As três saídas oferecidas quando há modificação local. */
13
+ export declare const OPCOES_DE_DECISAO: readonly OpcaoDecisao[];
14
+ export type Verificacao = {
15
+ temModificacao: boolean;
16
+ alterados: string[];
17
+ removidos: string[];
18
+ novos: string[];
19
+ erro?: string;
20
+ };
21
+ /** A pasta onde a skill instalada vive dentro do projeto. */
22
+ export declare function pastaDaSkill(raizProjeto: string, nome: string): string;
23
+ export declare function verificarModificacaoLocal(raizProjeto: string, nome: string): Verificacao;
@@ -0,0 +1,36 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { lerLock } from "../nucleo/lock.js";
4
+ import { compararComHashes } from "../nucleo/integridade.js";
5
+ import { ORIGEM_DO_PLUGIN } from "../plugin/manifestos.js";
6
+ /** As três saídas oferecidas quando há modificação local. */
7
+ export const OPCOES_DE_DECISAO = [
8
+ { id: "manter", rotulo: "manter o local e nao atualizar esta skill" },
9
+ { id: "substituir", rotulo: "substituir pelo novo, descartando a alteracao local" },
10
+ { id: "salvar-ao-lado", rotulo: "salvar o local ao lado antes de substituir" },
11
+ ];
12
+ /** A pasta onde a skill instalada vive dentro do projeto. */
13
+ export function pastaDaSkill(raizProjeto, nome) {
14
+ return join(raizProjeto, ".expx", "marketplace", ORIGEM_DO_PLUGIN, "skills", nome);
15
+ }
16
+ export function verificarModificacaoLocal(raizProjeto, nome) {
17
+ const vazio = { temModificacao: false, alterados: [], removidos: [], novos: [] };
18
+ const l = lerLock(raizProjeto);
19
+ if (!l.ok)
20
+ return { ...vazio, erro: l.erro };
21
+ const travada = l.lock.skills[nome];
22
+ if (travada === undefined)
23
+ return { ...vazio, erro: `${nome} nao esta no lock deste projeto` };
24
+ const pasta = pastaDaSkill(raizProjeto, nome);
25
+ if (!existsSync(pasta)) {
26
+ return { ...vazio, temModificacao: true, erro: `${nome} esta no lock mas nao esta em disco` };
27
+ }
28
+ const d = compararComHashes(pasta, travada.arquivos);
29
+ return {
30
+ temModificacao: !d.limpo,
31
+ alterados: d.alterados,
32
+ removidos: d.removidos,
33
+ novos: d.novos,
34
+ };
35
+ }
36
+ //# sourceMappingURL=modificacao.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modificacao.js","sourceRoot":"","sources":["../../src/update/modificacao.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAY3D,6DAA6D;AAC7D,MAAM,CAAC,MAAM,iBAAiB,GAA4B;IACxD,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,2CAA2C,EAAE;IACrE,EAAE,EAAE,EAAE,YAAY,EAAE,MAAM,EAAE,qDAAqD,EAAE;IACnF,EAAE,EAAE,EAAE,gBAAgB,EAAE,MAAM,EAAE,4CAA4C,EAAE;CACtE,CAAC;AAUX,6DAA6D;AAC7D,MAAM,UAAU,YAAY,CAAC,WAAmB,EAAE,IAAY;IAC5D,OAAO,IAAI,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;AACrF,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,WAAmB,EAAE,IAAY;IACzE,MAAM,KAAK,GAAgB,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAE9F,MAAM,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/B,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAE7C,MAAM,OAAO,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,iCAAiC,EAAE,CAAC;IAE/F,MAAM,KAAK,GAAG,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;IAC9C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,qCAAqC,EAAE,CAAC;IAChG,CAAC;IAED,MAAM,CAAC,GAAG,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACrD,OAAO;QACL,cAAc,EAAE,CAAC,CAAC,CAAC,KAAK;QACxB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,KAAK,EAAE,CAAC,CAAC,KAAK;KACf,CAAC;AACJ,CAAC"}