expxdev 0.1.1 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +459 -72
- package/dist/cli/expx.d.ts +2 -0
- package/dist/cli/expx.js +55 -6
- package/dist/cli/expx.js.map +1 -1
- package/dist/cli/init.js +6 -2
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/perguntar.d.ts +37 -0
- package/dist/cli/perguntar.js +76 -0
- package/dist/cli/perguntar.js.map +1 -0
- package/dist/cli/wizard.d.ts +21 -0
- package/dist/cli/wizard.js +101 -0
- package/dist/cli/wizard.js.map +1 -0
- package/dist/doctor/verificadores.js +97 -1
- package/dist/doctor/verificadores.js.map +1 -1
- package/dist/harness/hooks.d.ts +27 -0
- package/dist/harness/hooks.js +36 -0
- package/dist/harness/hooks.js.map +1 -0
- package/dist/harness/settings.d.ts +2 -1
- package/dist/harness/settings.js +40 -2
- package/dist/harness/settings.js.map +1 -1
- package/dist/nucleo/caminhos.d.ts +1 -1
- package/dist/nucleo/catalogo.d.ts +1 -1
- package/dist/nucleo/catalogo.js +7 -1
- package/dist/nucleo/catalogo.js.map +1 -1
- package/dist/nucleo/layout.d.ts +3 -2
- package/dist/nucleo/layout.js +37 -1
- package/dist/nucleo/layout.js.map +1 -1
- package/dist/nucleo/versao.d.ts +1 -1
- package/dist/parser/conformidade/regras.d.ts +1 -0
- package/dist/parser/conformidade/regras.js +24 -0
- package/dist/parser/conformidade/regras.js.map +1 -1
- package/dist/parser/esquema/enums.d.ts +19 -0
- package/dist/parser/esquema/enums.js +18 -0
- package/dist/parser/esquema/enums.js.map +1 -1
- package/dist/parser/esquema/evento.d.ts +123 -0
- package/dist/parser/esquema/evento.js +141 -0
- package/dist/parser/esquema/evento.js.map +1 -0
- package/dist/parser/leitura/rejeicao.d.ts +9 -0
- package/dist/parser/leitura/rejeicao.js +56 -0
- package/dist/parser/leitura/rejeicao.js.map +1 -1
- package/dist/parser/memoria/ler.d.ts +38 -0
- package/dist/parser/memoria/ler.js +46 -0
- package/dist/parser/memoria/ler.js.map +1 -0
- package/dist/parser/memoria/projetar.d.ts +3 -0
- package/dist/parser/memoria/projetar.js +132 -0
- package/dist/parser/memoria/projetar.js.map +1 -0
- package/dist/parser/memoria/tipos.d.ts +155 -0
- package/dist/parser/memoria/tipos.js +97 -0
- package/dist/parser/memoria/tipos.js.map +1 -0
- package/dist/parser/projeto/montar.d.ts +17 -0
- package/dist/parser/projeto/montar.js +17 -0
- package/dist/parser/projeto/montar.js.map +1 -1
- package/dist/plugin/montagem.d.ts +7 -0
- package/dist/plugin/montagem.js +22 -2
- package/dist/plugin/montagem.js.map +1 -1
- package/dist/servidor/http.js +5 -0
- package/dist/servidor/http.js.map +1 -1
- package/dist/servidor/observador.js +5 -1
- package/dist/servidor/observador.js.map +1 -1
- package/dist/teste/repo-fixture.d.ts +7 -0
- package/dist/teste/repo-fixture.js +18 -0
- package/dist/teste/repo-fixture.js.map +1 -1
- package/nucleo/README.md +79 -0
- package/nucleo/hooks/expx-rastro.sh +261 -0
- package/package.json +2 -1
- package/ui/dist/assets/index-BNE_RJrV.js +15 -0
- package/ui/dist/index.html +1 -1
- package/ui/dist/assets/index-BmDTogQZ.js +0 -14
package/dist/cli/expx.js
CHANGED
|
@@ -6,8 +6,36 @@ import { adicionarSkills, removerSkills } from "./selecionar.js";
|
|
|
6
6
|
import { interpretarFlagsUpdate, executarUpdate } from "../update/flags.js";
|
|
7
7
|
import { diagnosticar } from "../doctor/verificadores.js";
|
|
8
8
|
import { avaliarSelecao } from "./selecao.js";
|
|
9
|
+
import { executarWizard } from "./wizard.js";
|
|
10
|
+
import { perguntadorDeTerminal } from "./perguntar.js";
|
|
11
|
+
import { NOMES } from "../nucleo/catalogo.js";
|
|
9
12
|
import { instalarPlugin } from "../harness/instalar.js";
|
|
10
13
|
import { join } from "node:path";
|
|
14
|
+
/**
|
|
15
|
+
* Há um humano capaz de responder?
|
|
16
|
+
*
|
|
17
|
+
* Precisa dos DOIS lados: `stdout` sozinho não basta, porque escrever no
|
|
18
|
+
* terminal não prova que existe teclado do outro lado — num `expx init < /dev/null`
|
|
19
|
+
* o `stdout` continua TTY e o wizard travaria esperando uma resposta que não vem.
|
|
20
|
+
* É `stdin` que decide se dá para perguntar.
|
|
21
|
+
*/
|
|
22
|
+
function ehInterativo() {
|
|
23
|
+
return process.stdin.isTTY === true && process.stdout.isTTY === true;
|
|
24
|
+
}
|
|
25
|
+
/** Injetável para o teste trocar o terminal por um roteiro de respostas. */
|
|
26
|
+
let criarPerguntador = () => perguntadorDeTerminal();
|
|
27
|
+
export function usarPerguntador(fabrica) {
|
|
28
|
+
criarPerguntador = fabrica;
|
|
29
|
+
}
|
|
30
|
+
function comoEscolherSkills() {
|
|
31
|
+
return [
|
|
32
|
+
"escolha as skills com --skills, ou rode num terminal para responder na hora:",
|
|
33
|
+
"",
|
|
34
|
+
` npx expxdev init --skills ${NOMES.slice(0, 2).join(",")} --yes`,
|
|
35
|
+
"",
|
|
36
|
+
`disponiveis: ${NOMES.join(", ")}`,
|
|
37
|
+
].join("\n");
|
|
38
|
+
}
|
|
11
39
|
const EXECUTORES = {
|
|
12
40
|
panel: async (resto) => principalPainel(resto),
|
|
13
41
|
init: async (resto, saida) => {
|
|
@@ -16,20 +44,41 @@ const EXECUTORES = {
|
|
|
16
44
|
saida.escreverErro(`${f.erro}\n`);
|
|
17
45
|
return 1;
|
|
18
46
|
}
|
|
19
|
-
|
|
47
|
+
let opcoes = f.opcoes;
|
|
48
|
+
// Faltou o que instalar e há alguém para responder? Pergunta, em vez de
|
|
49
|
+
// sair com "nenhuma skill selecionada" — que era o beco sem saída do
|
|
50
|
+
// `npx expxdev init` puro.
|
|
51
|
+
if (opcoes.skills.length === 0 && ehInterativo()) {
|
|
52
|
+
const p = criarPerguntador();
|
|
53
|
+
try {
|
|
54
|
+
const w = await executarWizard(p, opcoes, process.cwd());
|
|
55
|
+
if (!w.ok) {
|
|
56
|
+
saida.escreverErro(`${w.erro}\n`);
|
|
57
|
+
return 1;
|
|
58
|
+
}
|
|
59
|
+
opcoes = w.opcoes;
|
|
60
|
+
}
|
|
61
|
+
finally {
|
|
62
|
+
p.fechar();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const aval = avaliarSelecao(opcoes.skills);
|
|
20
66
|
if (!aval.permitido) {
|
|
21
67
|
saida.escreverErro(`${aval.erros.join("\n")}\n`);
|
|
68
|
+
// Sem terminal para perguntar, a saída precisa dizer como resolver:
|
|
69
|
+
// o erro sozinho não ensina a próxima ação.
|
|
70
|
+
if (!ehInterativo())
|
|
71
|
+
saida.escreverErro(`\n${comoEscolherSkills()}\n`);
|
|
22
72
|
return 1;
|
|
23
73
|
}
|
|
24
74
|
for (const a of aval.avisos)
|
|
25
75
|
saida.escrever(`aviso: ${a}\n`);
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
saida.escrever(`instalaria: ${f.opcoes.skills.join(", ")}\nuse --yes para aplicar sem perguntar\n`);
|
|
76
|
+
if (!opcoes.sim && !ehInterativo()) {
|
|
77
|
+
saida.escrever(`instalaria: ${opcoes.skills.join(", ")}\nuse --yes para aplicar sem perguntar\n`);
|
|
29
78
|
return 0;
|
|
30
79
|
}
|
|
31
|
-
const harness =
|
|
32
|
-
const r = await executarInit({ raiz: process.cwd(), skills:
|
|
80
|
+
const harness = opcoes.harness.length > 0 ? opcoes.harness : ["claude"];
|
|
81
|
+
const r = await executarInit({ raiz: process.cwd(), skills: opcoes.skills, harness });
|
|
33
82
|
for (const a of r.avisos)
|
|
34
83
|
saida.escrever(`aviso: ${a}\n`);
|
|
35
84
|
for (const x of r.falhas)
|
package/dist/cli/expx.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expx.js","sourceRoot":"","sources":["../../src/cli/expx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,UAAU,EAAmB,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,SAAS,IAAI,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAiBjC,MAAM,UAAU,GAA0C;IACxD,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC;IAE9C,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;YACV,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;YAClC,OAAO,CAAC,CAAC;QACX,CAAC;
|
|
1
|
+
{"version":3,"file":"expx.js","sourceRoot":"","sources":["../../src/cli/expx.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/init.js
CHANGED
|
@@ -11,6 +11,7 @@ import { escreverAtomico } from "../plugin/atomico.js";
|
|
|
11
11
|
import { montarMarketplace } from "../plugin/montagem.js";
|
|
12
12
|
import { materializarOpenCode } from "../harness/opencode.js";
|
|
13
13
|
import { mesclarSettings } from "../harness/settings.js";
|
|
14
|
+
import { instalarHooks } from "../harness/hooks.js";
|
|
14
15
|
import { ORIGEM_DO_PLUGIN } from "../plugin/manifestos.js";
|
|
15
16
|
function origemDe(nome, origens) {
|
|
16
17
|
return origens?.[nome] ?? CATALOGO.find((s) => s.nome === nome)?.repositorio;
|
|
@@ -58,7 +59,7 @@ export async function executarInit(op) {
|
|
|
58
59
|
});
|
|
59
60
|
continue;
|
|
60
61
|
}
|
|
61
|
-
montaveis.push({ nome, raizSkill: layout.raizSkill, comandos: layout.comandos });
|
|
62
|
+
montaveis.push({ nome, raizSkill: layout.raizSkill, comandos: layout.comandos, hooks: layout.hooks });
|
|
62
63
|
travadas[nome] = {
|
|
63
64
|
repositorio,
|
|
64
65
|
referencia: alvo.referencia,
|
|
@@ -83,9 +84,12 @@ export async function executarInit(op) {
|
|
|
83
84
|
// pasta temporária e o arquivo se perderia na troca atômica.
|
|
84
85
|
writeFileSync(join(tmp, "expx-lock.json"), `${JSON.stringify(lock, null, 2)}\n`);
|
|
85
86
|
});
|
|
87
|
+
// A cópia acontece AQUI, antes do `rmSync` dos clones lá embaixo: feita
|
|
88
|
+
// depois, leria pasta já apagada (decisão D-26).
|
|
89
|
+
const hooksInstalados = instalarHooks(op.raiz, montaveis);
|
|
86
90
|
if (op.harness.includes("claude")) {
|
|
87
91
|
const marketplace = join(op.raiz, ".expx", "marketplace");
|
|
88
|
-
const r = mesclarSettings(op.raiz, marketplace);
|
|
92
|
+
const r = mesclarSettings(op.raiz, marketplace, hooksInstalados);
|
|
89
93
|
if (!r.ok)
|
|
90
94
|
avisos.push(r.erro);
|
|
91
95
|
}
|
package/dist/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
2
|
+
/**
|
|
3
|
+
* A camada de pergunta e resposta do terminal — e só ela.
|
|
4
|
+
*
|
|
5
|
+
* O wizard do `init` não fala com `process.stdin` diretamente: recebe um
|
|
6
|
+
* `Perguntador`. É o que torna o fluxo testável sem subprocesso e sem TTY
|
|
7
|
+
* falso, do mesmo jeito que `expx.ts` já injeta a saída para não capturar
|
|
8
|
+
* `process.stdout` global.
|
|
9
|
+
*/
|
|
10
|
+
export type Perguntador = {
|
|
11
|
+
/** Uma linha de texto livre, já sem espaço nas pontas. */
|
|
12
|
+
linha: (rotulo: string) => Promise<string>;
|
|
13
|
+
escrever: (texto: string) => void;
|
|
14
|
+
fechar: () => void;
|
|
15
|
+
};
|
|
16
|
+
export declare function perguntadorDeTerminal(entrada?: Readable, saida?: Writable): Perguntador;
|
|
17
|
+
/**
|
|
18
|
+
* Um perguntador de roteiro, para teste: consome respostas em ordem.
|
|
19
|
+
*
|
|
20
|
+
* Acabaram as respostas do roteiro? Devolve string vazia — que todo passo do
|
|
21
|
+
* wizard trata como "aceito o padrão". Um teste que esquece uma resposta
|
|
22
|
+
* termina com o padrão em vez de travar o processo esperando `stdin`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function perguntadorDeRoteiro(respostas: readonly string[]): Perguntador & {
|
|
25
|
+
escrito: () => string;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Lê uma escolha múltipla por número: `1,3` ou `1 3`.
|
|
29
|
+
*
|
|
30
|
+
* Devolve `undefined` quando algum número está fora da faixa, para o chamador
|
|
31
|
+
* repetir a pergunta em vez de instalar a coisa errada em silêncio. Resposta
|
|
32
|
+
* vazia é escolha vazia — quem decide se isso vale é a regra de seleção, não
|
|
33
|
+
* a leitura.
|
|
34
|
+
*/
|
|
35
|
+
export declare function interpretarEscolhaMultipla(resposta: string, total: number): number[] | undefined;
|
|
36
|
+
/** `sim`/`s`/`y`/`yes` é sim; vazio devolve o padrão; o resto é não. */
|
|
37
|
+
export declare function interpretarSimNao(resposta: string, padrao: boolean): boolean;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createInterface } from "node:readline";
|
|
2
|
+
export function perguntadorDeTerminal(entrada = process.stdin, saida = process.stdout) {
|
|
3
|
+
let rl;
|
|
4
|
+
const obter = () => {
|
|
5
|
+
rl ??= createInterface({ input: entrada, output: saida });
|
|
6
|
+
return rl;
|
|
7
|
+
};
|
|
8
|
+
return {
|
|
9
|
+
linha: async (rotulo) => {
|
|
10
|
+
const resposta = await new Promise((resolver) => {
|
|
11
|
+
obter().question(rotulo, resolver);
|
|
12
|
+
});
|
|
13
|
+
return resposta.trim();
|
|
14
|
+
},
|
|
15
|
+
escrever: (texto) => {
|
|
16
|
+
saida.write(texto);
|
|
17
|
+
},
|
|
18
|
+
fechar: () => {
|
|
19
|
+
rl?.close();
|
|
20
|
+
rl = undefined;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Um perguntador de roteiro, para teste: consome respostas em ordem.
|
|
26
|
+
*
|
|
27
|
+
* Acabaram as respostas do roteiro? Devolve string vazia — que todo passo do
|
|
28
|
+
* wizard trata como "aceito o padrão". Um teste que esquece uma resposta
|
|
29
|
+
* termina com o padrão em vez de travar o processo esperando `stdin`.
|
|
30
|
+
*/
|
|
31
|
+
export function perguntadorDeRoteiro(respostas) {
|
|
32
|
+
const restantes = [...respostas];
|
|
33
|
+
let escrito = "";
|
|
34
|
+
return {
|
|
35
|
+
linha: (rotulo) => {
|
|
36
|
+
escrito += rotulo;
|
|
37
|
+
return Promise.resolve(restantes.shift() ?? "");
|
|
38
|
+
},
|
|
39
|
+
escrever: (texto) => {
|
|
40
|
+
escrito += texto;
|
|
41
|
+
},
|
|
42
|
+
fechar: () => { },
|
|
43
|
+
escrito: () => escrito,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Lê uma escolha múltipla por número: `1,3` ou `1 3`.
|
|
48
|
+
*
|
|
49
|
+
* Devolve `undefined` quando algum número está fora da faixa, para o chamador
|
|
50
|
+
* repetir a pergunta em vez de instalar a coisa errada em silêncio. Resposta
|
|
51
|
+
* vazia é escolha vazia — quem decide se isso vale é a regra de seleção, não
|
|
52
|
+
* a leitura.
|
|
53
|
+
*/
|
|
54
|
+
export function interpretarEscolhaMultipla(resposta, total) {
|
|
55
|
+
if (resposta.trim() === "")
|
|
56
|
+
return [];
|
|
57
|
+
const indices = [];
|
|
58
|
+
for (const parte of resposta.split(/[,\s]+/).filter((p) => p !== "")) {
|
|
59
|
+
if (!/^\d+$/.test(parte))
|
|
60
|
+
return undefined;
|
|
61
|
+
const n = Number(parte);
|
|
62
|
+
if (n < 1 || n > total)
|
|
63
|
+
return undefined;
|
|
64
|
+
if (!indices.includes(n - 1))
|
|
65
|
+
indices.push(n - 1);
|
|
66
|
+
}
|
|
67
|
+
return indices;
|
|
68
|
+
}
|
|
69
|
+
/** `sim`/`s`/`y`/`yes` é sim; vazio devolve o padrão; o resto é não. */
|
|
70
|
+
export function interpretarSimNao(resposta, padrao) {
|
|
71
|
+
const v = resposta.trim().toLowerCase();
|
|
72
|
+
if (v === "")
|
|
73
|
+
return padrao;
|
|
74
|
+
return v === "s" || v === "sim" || v === "y" || v === "yes";
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=perguntar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"perguntar.js","sourceRoot":"","sources":["../../src/cli/perguntar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAkB,MAAM,eAAe,CAAC;AAmBhE,MAAM,UAAU,qBAAqB,CACnC,UAAoB,OAAO,CAAC,KAAK,EACjC,QAAkB,OAAO,CAAC,MAAM;IAEhC,IAAI,EAAyB,CAAC;IAC9B,MAAM,KAAK,GAAG,GAAc,EAAE;QAC5B,EAAE,KAAK,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;QAC1D,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,MAAM,IAAI,OAAO,CAAS,CAAC,QAAQ,EAAE,EAAE;gBACtD,KAAK,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC;QACzB,CAAC;QACD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;YAClB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,MAAM,EAAE,GAAG,EAAE;YACX,EAAE,EAAE,KAAK,EAAE,CAAC;YACZ,EAAE,GAAG,SAAS,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAA4B;IAC/D,MAAM,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC,CAAC;IACjC,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,OAAO;QACL,KAAK,EAAE,CAAC,MAAM,EAAE,EAAE;YAChB,OAAO,IAAI,MAAM,CAAC;YAClB,OAAO,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,CAAC;QACD,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;YAClB,OAAO,IAAI,KAAK,CAAC;QACnB,CAAC;QACD,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;QAChB,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO;KACvB,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,0BAA0B,CAAC,QAAgB,EAAE,KAAa;IACxE,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,CAAC;IAEtC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;QACrE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,KAAK;YAAE,OAAO,SAAS,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,MAAe;IACjE,MAAM,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE;QAAE,OAAO,MAAM,CAAC;IAC5B,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,KAAK,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type OpcoesInitCli } from "./init-flags.js";
|
|
2
|
+
import { type Perguntador } from "./perguntar.js";
|
|
3
|
+
/**
|
|
4
|
+
* As quatro perguntas do `init` interativo (especificação, promptcli1.md:51-68).
|
|
5
|
+
*
|
|
6
|
+
* O wizard não instala nada: ele só transforma "nenhuma flag" em uma seleção
|
|
7
|
+
* completa e devolve. Quem escreve em disco continua sendo `executarInit`, com
|
|
8
|
+
* exatamente o mesmo caminho que as flags percorrem — é o que garante que o
|
|
9
|
+
* modo interativo e o modo `--skills` não divirjam em comportamento.
|
|
10
|
+
*
|
|
11
|
+
* Toda pergunta respeita o que já veio por flag: quem passou `--harness` não é
|
|
12
|
+
* perguntado de novo. Isso permite responder metade por flag e metade na mão.
|
|
13
|
+
*/
|
|
14
|
+
export type ResultadoWizard = {
|
|
15
|
+
ok: true;
|
|
16
|
+
opcoes: OpcoesInitCli;
|
|
17
|
+
} | {
|
|
18
|
+
ok: false;
|
|
19
|
+
erro: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function executarWizard(p: Perguntador, parciais: OpcoesInitCli, raiz: string): Promise<ResultadoWizard>;
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { CATALOGO } from "../nucleo/catalogo.js";
|
|
2
|
+
import { avaliarSelecao } from "./selecao.js";
|
|
3
|
+
import { detectarProjeto } from "./projeto.js";
|
|
4
|
+
import { HARNESS_VALIDOS } from "./init-flags.js";
|
|
5
|
+
import { interpretarEscolhaMultipla, interpretarSimNao } from "./perguntar.js";
|
|
6
|
+
const TENTATIVAS = 3;
|
|
7
|
+
function listarSkills(p) {
|
|
8
|
+
p.escrever("\nQuais skills instalar neste projeto?\n\n");
|
|
9
|
+
CATALOGO.forEach((s, i) => {
|
|
10
|
+
const marca = s.camada ? " (camada)" : "";
|
|
11
|
+
p.escrever(` ${String(i + 1)}. ${s.nome}${marca} — ${s.papel}\n`);
|
|
12
|
+
});
|
|
13
|
+
p.escrever("\nResponda com os numeros separados por virgula (ex.: 1,5).\n");
|
|
14
|
+
}
|
|
15
|
+
async function escolherSkills(p) {
|
|
16
|
+
listarSkills(p);
|
|
17
|
+
for (let tentativa = 0; tentativa < TENTATIVAS; tentativa++) {
|
|
18
|
+
const resposta = await p.linha("skills: ");
|
|
19
|
+
const indices = interpretarEscolhaMultipla(resposta, CATALOGO.length);
|
|
20
|
+
if (indices === undefined) {
|
|
21
|
+
p.escrever(`numero invalido: responda entre 1 e ${String(CATALOGO.length)}\n`);
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
if (indices.length === 0) {
|
|
25
|
+
p.escrever("nenhuma skill escolhida: escolha ao menos uma\n");
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const selecao = indices.map((i) => CATALOGO[i]?.nome ?? "");
|
|
29
|
+
const aval = avaliarSelecao(selecao);
|
|
30
|
+
// Aviso nunca impede: a combinação incomum pode ser exatamente a pedida.
|
|
31
|
+
// O CLI explica a consequência e deixa a pessoa confirmar (selecao.ts).
|
|
32
|
+
if (aval.precisaConfirmar) {
|
|
33
|
+
for (const a of aval.avisos)
|
|
34
|
+
p.escrever(`\naviso: ${a}\n`);
|
|
35
|
+
const segue = interpretarSimNao(await p.linha("seguir assim mesmo? [s/N] "), false);
|
|
36
|
+
if (!segue) {
|
|
37
|
+
p.escrever("\nescolha de novo:\n");
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
for (const i of aval.integracoes) {
|
|
42
|
+
p.escrever(`integracao disponivel: ${i} se conecta com as skills escolhidas\n`);
|
|
43
|
+
}
|
|
44
|
+
return selecao;
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
async function escolherHarness(p) {
|
|
49
|
+
p.escrever("\nQual harness configurar?\n\n");
|
|
50
|
+
p.escrever(" 1. claude — Claude Code\n");
|
|
51
|
+
p.escrever(" 2. opencode — OpenCode\n");
|
|
52
|
+
p.escrever("\nOs dois: 1,2. Vazio usa claude.\n");
|
|
53
|
+
for (let tentativa = 0; tentativa < TENTATIVAS; tentativa++) {
|
|
54
|
+
const resposta = await p.linha("harness [1]: ");
|
|
55
|
+
if (resposta.trim() === "")
|
|
56
|
+
return ["claude"];
|
|
57
|
+
const indices = interpretarEscolhaMultipla(resposta, HARNESS_VALIDOS.length);
|
|
58
|
+
if (indices === undefined || indices.length === 0) {
|
|
59
|
+
p.escrever("responda 1, 2 ou 1,2\n");
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
return indices.map((i) => HARNESS_VALIDOS[i] ?? "claude");
|
|
63
|
+
}
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Reconfiguração nunca apaga sem confirmar (promptcli1.md:51-53).
|
|
68
|
+
*
|
|
69
|
+
* O `.expx/` existente é remontado do zero pelo `init`, então seguir sem
|
|
70
|
+
* perguntar destruiria a seleção anterior em silêncio.
|
|
71
|
+
*/
|
|
72
|
+
async function confirmarReconfiguracao(p, raiz) {
|
|
73
|
+
if (!detectarProjeto(raiz).existe)
|
|
74
|
+
return true;
|
|
75
|
+
p.escrever("\nEste projeto ja tem um .expx/ instalado.\n");
|
|
76
|
+
p.escrever("Seguir remonta a instalacao a partir da nova selecao, substituindo a atual.\n");
|
|
77
|
+
return interpretarSimNao(await p.linha("reconfigurar? [s/N] "), false);
|
|
78
|
+
}
|
|
79
|
+
export async function executarWizard(p, parciais, raiz) {
|
|
80
|
+
if (!(await confirmarReconfiguracao(p, raiz))) {
|
|
81
|
+
return { ok: false, erro: "reconfiguracao cancelada: nada foi alterado" };
|
|
82
|
+
}
|
|
83
|
+
const skills = parciais.skills.length > 0 ? parciais.skills : await escolherSkills(p);
|
|
84
|
+
if (skills === undefined)
|
|
85
|
+
return { ok: false, erro: "selecao de skills invalida apos varias tentativas" };
|
|
86
|
+
const harness = parciais.harness.length > 0 ? parciais.harness : await escolherHarness(p);
|
|
87
|
+
if (harness === undefined)
|
|
88
|
+
return { ok: false, erro: "harness invalido apos varias tentativas" };
|
|
89
|
+
const painel = parciais.painel
|
|
90
|
+
? true
|
|
91
|
+
: interpretarSimNao(await p.linha("\nInstalar o painel como devDependency? [s/N] "), false);
|
|
92
|
+
p.escrever(`\nvai instalar: ${skills.join(", ")}\n`);
|
|
93
|
+
p.escrever(`harness: ${harness.join(", ")}\n`);
|
|
94
|
+
if (painel)
|
|
95
|
+
p.escrever("painel: sim\n");
|
|
96
|
+
if (!interpretarSimNao(await p.linha("\nconfirmar? [S/n] "), true)) {
|
|
97
|
+
return { ok: false, erro: "cancelado: nada foi alterado" };
|
|
98
|
+
}
|
|
99
|
+
return { ok: true, opcoes: { skills: [...skills], harness: [...harness], painel, sim: true, simular: parciais.simular } };
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=wizard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wizard.js","sourceRoot":"","sources":["../../src/cli/wizard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from "node:fs";
|
|
1
|
+
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { lerLock } from "../nucleo/lock.js";
|
|
4
|
+
import { validarRastro } from "../parser/esquema/evento.js";
|
|
4
5
|
import { verificarCaminhos } from "../nucleo/caminhos.js";
|
|
5
6
|
import { expxNoGitignore } from "../cli/projeto.js";
|
|
6
7
|
import { verificarModificacaoLocal, pastaDaSkill } from "../update/modificacao.js";
|
|
@@ -153,6 +154,101 @@ export function diagnosticar(raiz) {
|
|
|
153
154
|
});
|
|
154
155
|
}
|
|
155
156
|
}
|
|
157
|
+
verificarHooks(raiz, push);
|
|
158
|
+
verificarRastro(raiz, push);
|
|
156
159
|
return { saudavel: achados.filter((a) => a.severidade === "erro").length === 0, achados };
|
|
157
160
|
}
|
|
161
|
+
/**
|
|
162
|
+
* O rastro de eventos obedece ao contrato `expx-eventos`?
|
|
163
|
+
*
|
|
164
|
+
* Aviso, nunca erro: rastro malformado não impede o método de funcionar, e um
|
|
165
|
+
* `doctor` que reprova a instalação por causa de linha antiga em disco é um
|
|
166
|
+
* doctor que as pessoas param de rodar. As quatro skills que escrevem o rastro
|
|
167
|
+
* têm implementações independentes — é justamente onde a divergência aparece.
|
|
168
|
+
*/
|
|
169
|
+
function verificarRastro(raiz, push) {
|
|
170
|
+
const dir = join(raiz, "docs", "eventos");
|
|
171
|
+
if (!existsSync(dir))
|
|
172
|
+
return;
|
|
173
|
+
let arquivos;
|
|
174
|
+
try {
|
|
175
|
+
arquivos = readdirSync(dir).filter((f) => f.endsWith(".jsonl"));
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
for (const nome of arquivos) {
|
|
181
|
+
let conteudo;
|
|
182
|
+
try {
|
|
183
|
+
conteudo = readFileSync(join(dir, nome), "utf8");
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
const r = validarRastro(conteudo);
|
|
189
|
+
if (r.defeitos.length > 0) {
|
|
190
|
+
const primeiro = r.defeitos[0];
|
|
191
|
+
const resto = r.defeitos.length - 1;
|
|
192
|
+
push({
|
|
193
|
+
id: "rastro-fora-do-contrato",
|
|
194
|
+
severidade: "aviso",
|
|
195
|
+
problema: `docs/eventos/${nome}: ${r.defeitos.length} de ${r.linhas} linhas fora do ` +
|
|
196
|
+
`contrato expx-eventos (L${primeiro?.linha}: ${primeiro?.motivo}` +
|
|
197
|
+
`${resto > 0 ? `, e mais ${resto}` : ""})`,
|
|
198
|
+
correcao: "o rastro e append-only e nao se edita a mao: corrija quem grava (o hook da skill) " +
|
|
199
|
+
"e deixe as linhas antigas onde estao",
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (r.desconhecidas.length > 0) {
|
|
203
|
+
push({
|
|
204
|
+
id: "rastro-chave-nao-declarada",
|
|
205
|
+
severidade: "aviso",
|
|
206
|
+
problema: `docs/eventos/${nome}: chaves fora do contrato: ${r.desconhecidas.join(", ")}`,
|
|
207
|
+
correcao: "chave extra e permitida, mas precisa ser declarada em CONTRATO-expx-eventos.md " +
|
|
208
|
+
"e vir depois das doze obrigatorias",
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Hook instalado sem o motor ao lado.
|
|
215
|
+
*
|
|
216
|
+
* Todo caminho de erro dos hooks do memox termina em `exit 0`, de propósito:
|
|
217
|
+
* falha aberta nunca trava o prompt de quem está trabalhando. O preço é que
|
|
218
|
+
* uma instalação quebrada fica indistinguível de um projeto sem artefatos —
|
|
219
|
+
* silêncio dos dois lados. Este verificador é o único lugar onde a diferença
|
|
220
|
+
* aparece (decisão D-17).
|
|
221
|
+
*
|
|
222
|
+
* O caminho conferido é exatamente o que o hook resolve por conta própria:
|
|
223
|
+
* `DIR_HOOK/../skills/<skill>/assets/`.
|
|
224
|
+
*/
|
|
225
|
+
function verificarHooks(raiz, push) {
|
|
226
|
+
const dirHooks = join(raiz, ".claude", "hooks");
|
|
227
|
+
if (!existsSync(dirHooks))
|
|
228
|
+
return;
|
|
229
|
+
let arquivos;
|
|
230
|
+
try {
|
|
231
|
+
arquivos = readdirSync(dirHooks);
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
// uma entrada por skill dona de hook, para não repetir o achado por arquivo
|
|
237
|
+
const skills = new Set(arquivos
|
|
238
|
+
.filter((a) => a.endsWith(".sh"))
|
|
239
|
+
.map((a) => a.split("-")[0] ?? "")
|
|
240
|
+
.filter((n) => n !== ""));
|
|
241
|
+
for (const skill of skills) {
|
|
242
|
+
const motor = join(raiz, ".claude", "skills", skill, "assets");
|
|
243
|
+
if (existsSync(motor))
|
|
244
|
+
continue;
|
|
245
|
+
push({
|
|
246
|
+
id: `${skill}-sem-motor`,
|
|
247
|
+
severidade: "erro",
|
|
248
|
+
problema: `o hook de ${skill} esta em .claude/hooks mas o motor nao esta em ` +
|
|
249
|
+
`.claude/skills/${skill}/assets: o hook sai 0 em silencio e nao faz nada`,
|
|
250
|
+
correcao: `rode \`expx init\` incluindo ${skill}: o hook e a skill precisam ser instalados juntos`,
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
}
|
|
158
254
|
//# sourceMappingURL=verificadores.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verificadores.js","sourceRoot":"","sources":["../../src/doctor/verificadores.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"verificadores.js","sourceRoot":"","sources":["../../src/doctor/verificadores.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { SkillMontavel } from "../plugin/montagem.js";
|
|
2
|
+
/**
|
|
3
|
+
* Materializa hooks de skill em `.claude/hooks/`, com a skill ao lado em
|
|
4
|
+
* `.claude/skills/`.
|
|
5
|
+
*
|
|
6
|
+
* Os dois andam juntos por imposição do próprio hook: o do memox resolve o
|
|
7
|
+
* motor como `DIR_HOOK/../skills/<nome>/assets/...`. Copiar o hook sem copiar a
|
|
8
|
+
* skill produz um hook que sai `0` em silêncio — e como TODO caminho de erro
|
|
9
|
+
* dele sai `0`, a instalação quebrada fica indistinguível de um projeto sem
|
|
10
|
+
* artefatos. É por isso que a cópia da skill aqui é incondicional, e não
|
|
11
|
+
* depende de o harness incluir `opencode` (decisões D-14 e D-15).
|
|
12
|
+
*
|
|
13
|
+
* Hooks são mecanismo do Claude Code. No OpenCode isso é lacuna declarada, não
|
|
14
|
+
* paridade garantida.
|
|
15
|
+
*/
|
|
16
|
+
export type HookInstalado = {
|
|
17
|
+
skill: string;
|
|
18
|
+
/** Caminho do hook relativo à raiz do projeto, como vai para o settings.json. */
|
|
19
|
+
relativo: string;
|
|
20
|
+
};
|
|
21
|
+
/** As skills que trazem hook. Sem nenhuma, nada é criado — nem a pasta. */
|
|
22
|
+
export declare function comHooks(skills: readonly SkillMontavel[]): SkillMontavel[];
|
|
23
|
+
/**
|
|
24
|
+
* Copia hooks e skills para `.claude/`. Devolve os hooks instalados, na ordem,
|
|
25
|
+
* para quem for registrá-los no `settings.json`.
|
|
26
|
+
*/
|
|
27
|
+
export declare function instalarHooks(raizProjeto: string, skills: readonly SkillMontavel[]): HookInstalado[];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { chmodSync, cpSync, existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
/** As skills que trazem hook. Sem nenhuma, nada é criado — nem a pasta. */
|
|
4
|
+
export function comHooks(skills) {
|
|
5
|
+
return skills.filter((s) => (s.hooks?.length ?? 0) > 0);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Copia hooks e skills para `.claude/`. Devolve os hooks instalados, na ordem,
|
|
9
|
+
* para quem for registrá-los no `settings.json`.
|
|
10
|
+
*/
|
|
11
|
+
export function instalarHooks(raizProjeto, skills) {
|
|
12
|
+
const alvos = comHooks(skills);
|
|
13
|
+
if (alvos.length === 0)
|
|
14
|
+
return [];
|
|
15
|
+
const dirHooks = join(raizProjeto, ".claude", "hooks");
|
|
16
|
+
const dirSkills = join(raizProjeto, ".claude", "skills");
|
|
17
|
+
mkdirSync(dirHooks, { recursive: true });
|
|
18
|
+
mkdirSync(dirSkills, { recursive: true });
|
|
19
|
+
const instalados = [];
|
|
20
|
+
for (const s of alvos) {
|
|
21
|
+
// a skill vai junto: é o que o hook procura ao lado de si mesmo
|
|
22
|
+
cpSync(s.raizSkill, join(dirSkills, s.nome), { recursive: true });
|
|
23
|
+
for (const origem of s.hooks ?? []) {
|
|
24
|
+
if (!existsSync(origem))
|
|
25
|
+
continue;
|
|
26
|
+
const nome = basename(origem);
|
|
27
|
+
const destino = join(dirHooks, nome);
|
|
28
|
+
cpSync(origem, destino);
|
|
29
|
+
// o bit de execução não é detalhe: sem ele o hook não roda, e não avisa
|
|
30
|
+
chmodSync(destino, 0o755);
|
|
31
|
+
instalados.push({ skill: s.nome, relativo: `.claude/hooks/${nome}` });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return instalados;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/harness/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAwB3C,2EAA2E;AAC3E,MAAM,UAAU,QAAQ,CAAC,MAAgC;IACvD,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB,EAAE,MAAgC;IACjF,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IACvD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzD,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACzC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,MAAM,UAAU,GAAoB,EAAE,CAAC;IACvC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,gEAAgE;QAChE,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAElE,KAAK,MAAM,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE,CAAC;YACnC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;gBAAE,SAAS;YAClC,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC9B,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACrC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YACxB,wEAAwE;YACxE,SAAS,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC1B,UAAU,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC,CAAC;QACxE,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|