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.
- package/LICENSE +21 -0
- package/README.md +137 -0
- package/dist/cli/argumentos.d.ts +22 -0
- package/dist/cli/argumentos.js +85 -0
- package/dist/cli/argumentos.js.map +1 -0
- package/dist/cli/expx-bin.d.ts +2 -0
- package/dist/cli/expx-bin.js +40 -0
- package/dist/cli/expx-bin.js.map +1 -0
- package/dist/cli/expx.d.ts +13 -0
- package/dist/cli/expx.js +123 -0
- package/dist/cli/expx.js.map +1 -0
- package/dist/cli/init-flags.d.ts +34 -0
- package/dist/cli/init-flags.js +83 -0
- package/dist/cli/init-flags.js.map +1 -0
- package/dist/cli/init.d.ts +34 -0
- package/dist/cli/init.js +103 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/principal.d.ts +2 -0
- package/dist/cli/principal.js +107 -0
- package/dist/cli/principal.js.map +1 -0
- package/dist/cli/projeto.d.ts +19 -0
- package/dist/cli/projeto.js +28 -0
- package/dist/cli/projeto.js.map +1 -0
- package/dist/cli/selecao.d.ts +19 -0
- package/dist/cli/selecao.js +28 -0
- package/dist/cli/selecao.js.map +1 -0
- package/dist/cli/selecionar.d.ts +23 -0
- package/dist/cli/selecionar.js +45 -0
- package/dist/cli/selecionar.js.map +1 -0
- package/dist/cli/subcomandos.d.ts +25 -0
- package/dist/cli/subcomandos.js +43 -0
- package/dist/cli/subcomandos.js.map +1 -0
- package/dist/doctor/efeito.d.ts +17 -0
- package/dist/doctor/efeito.js +18 -0
- package/dist/doctor/efeito.js.map +1 -0
- package/dist/doctor/verificadores.d.ts +21 -0
- package/dist/doctor/verificadores.js +158 -0
- package/dist/doctor/verificadores.js.map +1 -0
- package/dist/harness/backup.d.ts +15 -0
- package/dist/harness/backup.js +29 -0
- package/dist/harness/backup.js.map +1 -0
- package/dist/harness/instalar.d.ts +31 -0
- package/dist/harness/instalar.js +43 -0
- package/dist/harness/instalar.js.map +1 -0
- package/dist/harness/opencode.d.ts +18 -0
- package/dist/harness/opencode.js +32 -0
- package/dist/harness/opencode.js.map +1 -0
- package/dist/harness/settings.d.ts +36 -0
- package/dist/harness/settings.js +66 -0
- package/dist/harness/settings.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/nucleo/busca.d.ts +28 -0
- package/dist/nucleo/busca.js +29 -0
- package/dist/nucleo/busca.js.map +1 -0
- package/dist/nucleo/caminhos.d.ts +21 -0
- package/dist/nucleo/caminhos.js +64 -0
- package/dist/nucleo/caminhos.js.map +1 -0
- package/dist/nucleo/catalogo.d.ts +20 -0
- package/dist/nucleo/catalogo.js +50 -0
- package/dist/nucleo/catalogo.js.map +1 -0
- package/dist/nucleo/integridade.d.ts +20 -0
- package/dist/nucleo/integridade.js +75 -0
- package/dist/nucleo/integridade.js.map +1 -0
- package/dist/nucleo/layout.d.ts +23 -0
- package/dist/nucleo/layout.js +73 -0
- package/dist/nucleo/layout.js.map +1 -0
- package/dist/nucleo/lock.d.ts +61 -0
- package/dist/nucleo/lock.js +96 -0
- package/dist/nucleo/lock.js.map +1 -0
- package/dist/nucleo/versao.d.ts +35 -0
- package/dist/nucleo/versao.js +63 -0
- package/dist/nucleo/versao.js.map +1 -0
- package/dist/parser/conformidade/regras.d.ts +41 -0
- package/dist/parser/conformidade/regras.js +209 -0
- package/dist/parser/conformidade/regras.js.map +1 -0
- package/dist/parser/descoberta/trabalhos.d.ts +35 -0
- package/dist/parser/descoberta/trabalhos.js +28 -0
- package/dist/parser/descoberta/trabalhos.js.map +1 -0
- package/dist/parser/descoberta/varredura.d.ts +4 -0
- package/dist/parser/descoberta/varredura.js +79 -0
- package/dist/parser/descoberta/varredura.js.map +1 -0
- package/dist/parser/esquema/cabecalho.d.ts +60 -0
- package/dist/parser/esquema/cabecalho.js +57 -0
- package/dist/parser/esquema/cabecalho.js.map +1 -0
- package/dist/parser/esquema/enums.d.ts +114 -0
- package/dist/parser/esquema/enums.js +64 -0
- package/dist/parser/esquema/enums.js.map +1 -0
- package/dist/parser/esquema/kinds.d.ts +768 -0
- package/dist/parser/esquema/kinds.js +231 -0
- package/dist/parser/esquema/kinds.js.map +1 -0
- package/dist/parser/leitura/arquivo.d.ts +9 -0
- package/dist/parser/leitura/arquivo.js +25 -0
- package/dist/parser/leitura/arquivo.js.map +1 -0
- package/dist/parser/leitura/frontmatter.d.ts +31 -0
- package/dist/parser/leitura/frontmatter.js +77 -0
- package/dist/parser/leitura/frontmatter.js.map +1 -0
- package/dist/parser/leitura/rejeicao.d.ts +43 -0
- package/dist/parser/leitura/rejeicao.js +73 -0
- package/dist/parser/leitura/rejeicao.js.map +1 -0
- package/dist/parser/projeto/montar.d.ts +62 -0
- package/dist/parser/projeto/montar.js +149 -0
- package/dist/parser/projeto/montar.js.map +1 -0
- package/dist/plugin/atomico.d.ts +13 -0
- package/dist/plugin/atomico.js +42 -0
- package/dist/plugin/atomico.js.map +1 -0
- package/dist/plugin/manifestos.d.ts +38 -0
- package/dist/plugin/manifestos.js +57 -0
- package/dist/plugin/manifestos.js.map +1 -0
- package/dist/plugin/montagem.d.ts +22 -0
- package/dist/plugin/montagem.js +30 -0
- package/dist/plugin/montagem.js.map +1 -0
- package/dist/relatorio/markdown.d.ts +22 -0
- package/dist/relatorio/markdown.js +0 -0
- package/dist/relatorio/markdown.js.map +1 -0
- package/dist/relatorio/pagina.d.ts +22 -0
- package/dist/relatorio/pagina.js +338 -0
- package/dist/relatorio/pagina.js.map +1 -0
- package/dist/servidor/estado.d.ts +16 -0
- package/dist/servidor/estado.js +16 -0
- package/dist/servidor/estado.js.map +1 -0
- package/dist/servidor/http.d.ts +22 -0
- package/dist/servidor/http.js +164 -0
- package/dist/servidor/http.js.map +1 -0
- package/dist/servidor/observador.d.ts +12 -0
- package/dist/servidor/observador.js +37 -0
- package/dist/servidor/observador.js.map +1 -0
- package/dist/servidor/painel.d.ts +24 -0
- package/dist/servidor/painel.js +49 -0
- package/dist/servidor/painel.js.map +1 -0
- package/dist/teste/layouts-fixture.d.ts +16 -0
- package/dist/teste/layouts-fixture.js +9 -0
- package/dist/teste/layouts-fixture.js.map +1 -0
- package/dist/teste/projeto-temporario.d.ts +14 -0
- package/dist/teste/projeto-temporario.js +16 -0
- package/dist/teste/projeto-temporario.js.map +1 -0
- package/dist/teste/repo-fixture.d.ts +27 -0
- package/dist/teste/repo-fixture.js +49 -0
- package/dist/teste/repo-fixture.js.map +1 -0
- package/dist/update/comparar.d.ts +33 -0
- package/dist/update/comparar.js +67 -0
- package/dist/update/comparar.js.map +1 -0
- package/dist/update/compatibilidade.d.ts +19 -0
- package/dist/update/compatibilidade.js +36 -0
- package/dist/update/compatibilidade.js.map +1 -0
- package/dist/update/flags.d.ts +47 -0
- package/dist/update/flags.js +123 -0
- package/dist/update/flags.js.map +1 -0
- package/dist/update/modificacao.d.ts +23 -0
- package/dist/update/modificacao.js +36 -0
- package/dist/update/modificacao.js.map +1 -0
- package/package.json +73 -0
- package/ui/dist/assets/index-BmDTogQZ.js +14 -0
- package/ui/dist/assets/index-DUzbt2M7.css +1 -0
- package/ui/dist/index.html +13 -0
package/dist/cli/init.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { rmSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { CATALOGO } from "../nucleo/catalogo.js";
|
|
4
|
+
import { resolverAlvo } from "../nucleo/versao.js";
|
|
5
|
+
import { buscarSkill } from "../nucleo/busca.js";
|
|
6
|
+
import { detectarLayout } from "../nucleo/layout.js";
|
|
7
|
+
import { verificarCaminhos } from "../nucleo/caminhos.js";
|
|
8
|
+
import { hashearPasta } from "../nucleo/integridade.js";
|
|
9
|
+
import { versaoDoCli, VERSAO_LOCK } from "../nucleo/lock.js";
|
|
10
|
+
import { escreverAtomico } from "../plugin/atomico.js";
|
|
11
|
+
import { montarMarketplace } from "../plugin/montagem.js";
|
|
12
|
+
import { materializarOpenCode } from "../harness/opencode.js";
|
|
13
|
+
import { mesclarSettings } from "../harness/settings.js";
|
|
14
|
+
import { ORIGEM_DO_PLUGIN } from "../plugin/manifestos.js";
|
|
15
|
+
function origemDe(nome, origens) {
|
|
16
|
+
return origens?.[nome] ?? CATALOGO.find((s) => s.nome === nome)?.repositorio;
|
|
17
|
+
}
|
|
18
|
+
export async function executarInit(op) {
|
|
19
|
+
const instaladas = [];
|
|
20
|
+
const falhas = [];
|
|
21
|
+
const naoTravadas = [];
|
|
22
|
+
const avisos = [];
|
|
23
|
+
const montaveis = [];
|
|
24
|
+
const travadas = {};
|
|
25
|
+
const temporarios = [];
|
|
26
|
+
for (const nome of op.skills) {
|
|
27
|
+
const repositorio = origemDe(nome, op.origens);
|
|
28
|
+
if (repositorio === undefined) {
|
|
29
|
+
falhas.push({ nome, erro: "skill fora do catalogo" });
|
|
30
|
+
continue;
|
|
31
|
+
}
|
|
32
|
+
const alvo = await resolverAlvo(repositorio, op.referencias?.[nome]);
|
|
33
|
+
if (!alvo.ok) {
|
|
34
|
+
falhas.push({ nome, erro: alvo.erro ?? "nao foi possivel resolver a versao" });
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
if (!alvo.travado)
|
|
38
|
+
naoTravadas.push(nome);
|
|
39
|
+
const busca = await buscarSkill({ nome, repositorio, referencia: alvo.referencia });
|
|
40
|
+
if (!busca.ok) {
|
|
41
|
+
falhas.push({ nome, erro: busca.erro });
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
temporarios.push(busca.caminho);
|
|
45
|
+
const layout = detectarLayout(busca.caminho, nome);
|
|
46
|
+
if (!layout.ok) {
|
|
47
|
+
falhas.push({ nome, erro: layout.erro });
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
// A skill não pode referenciar nada fora da própria pasta: o plugin é
|
|
51
|
+
// copiado para o cache e um `../` deixaria de resolver silenciosamente.
|
|
52
|
+
const fora = verificarCaminhos(layout.raizSkill);
|
|
53
|
+
if (fora.length > 0) {
|
|
54
|
+
const lista = fora.slice(0, 3).map((a) => `${a.arquivo}:${String(a.linha)} → ${a.referencia}`);
|
|
55
|
+
falhas.push({
|
|
56
|
+
nome,
|
|
57
|
+
erro: `a skill referencia caminho fora da propria pasta: ${lista.join("; ")}`,
|
|
58
|
+
});
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
montaveis.push({ nome, raizSkill: layout.raizSkill, comandos: layout.comandos });
|
|
62
|
+
travadas[nome] = {
|
|
63
|
+
repositorio,
|
|
64
|
+
referencia: alvo.referencia,
|
|
65
|
+
travado: alvo.travado,
|
|
66
|
+
commit: busca.commit,
|
|
67
|
+
resolvido_em: new Date().toISOString().slice(0, 10),
|
|
68
|
+
arquivos: hashearPasta(layout.raizSkill),
|
|
69
|
+
};
|
|
70
|
+
instaladas.push(nome);
|
|
71
|
+
}
|
|
72
|
+
if (montaveis.length > 0) {
|
|
73
|
+
const lock = {
|
|
74
|
+
lock_version: VERSAO_LOCK,
|
|
75
|
+
cli_version: versaoDoCli(),
|
|
76
|
+
harness: [...op.harness],
|
|
77
|
+
skills: travadas,
|
|
78
|
+
};
|
|
79
|
+
escreverAtomico(op.raiz, (tmp) => {
|
|
80
|
+
montarMarketplace(join(tmp, "marketplace"), montaveis, versaoDoCli());
|
|
81
|
+
// `tmp` JÁ é o futuro `.expx/`, então o lock vai direto nele — passar por
|
|
82
|
+
// `escreverLock`, que acrescenta `.expx/` ao caminho, gravaria fora da
|
|
83
|
+
// pasta temporária e o arquivo se perderia na troca atômica.
|
|
84
|
+
writeFileSync(join(tmp, "expx-lock.json"), `${JSON.stringify(lock, null, 2)}\n`);
|
|
85
|
+
});
|
|
86
|
+
if (op.harness.includes("claude")) {
|
|
87
|
+
const marketplace = join(op.raiz, ".expx", "marketplace");
|
|
88
|
+
const r = mesclarSettings(op.raiz, marketplace);
|
|
89
|
+
if (!r.ok)
|
|
90
|
+
avisos.push(r.erro);
|
|
91
|
+
}
|
|
92
|
+
if (op.harness.includes("opencode"))
|
|
93
|
+
materializarOpenCode(op.raiz, montaveis);
|
|
94
|
+
}
|
|
95
|
+
for (const t of temporarios)
|
|
96
|
+
rmSync(t, { recursive: true, force: true });
|
|
97
|
+
for (const n of naoTravadas) {
|
|
98
|
+
avisos.push(`${n} nao esta travada em versao publicada: o repositorio nao tem tag`);
|
|
99
|
+
}
|
|
100
|
+
return { ok: instaladas.length > 0, instaladas, falhas, naoTravadas, avisos };
|
|
101
|
+
}
|
|
102
|
+
export { ORIGEM_DO_PLUGIN };
|
|
103
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync, realpathSync } from "node:fs";
|
|
3
|
+
import { resolve, dirname, join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { spawn } from "node:child_process";
|
|
6
|
+
import { interpretar, textoDeAjuda } from "./argumentos.js";
|
|
7
|
+
import { iniciarPainel } from "../servidor/painel.js";
|
|
8
|
+
/** Abre o navegador no sistema em que estamos, sem dependência externa. */
|
|
9
|
+
function abrirNavegador(url) {
|
|
10
|
+
const cmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
11
|
+
try {
|
|
12
|
+
spawn(cmd, [url], { detached: true, stdio: "ignore", shell: process.platform === "win32" }).unref();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// falhar ao abrir o navegador nunca derruba o painel
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** A pasta do build da UI, quando existe no pacote publicado. */
|
|
19
|
+
function pastaEstaticos() {
|
|
20
|
+
const aqui = dirname(fileURLToPath(import.meta.url));
|
|
21
|
+
for (const candidato of [join(aqui, "../../ui/dist"), join(aqui, "../ui")]) {
|
|
22
|
+
if (existsSync(join(candidato, "index.html")))
|
|
23
|
+
return candidato;
|
|
24
|
+
}
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
export async function principal(argv) {
|
|
28
|
+
const r = interpretar(argv);
|
|
29
|
+
if (!r.ok) {
|
|
30
|
+
process.stderr.write(`${r.erro}\n\n${textoDeAjuda()}\n`);
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
if (r.opcoes.ajuda) {
|
|
34
|
+
process.stdout.write(`${textoDeAjuda()}\n`);
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
const raiz = resolve(r.opcoes.dir);
|
|
38
|
+
if (!existsSync(raiz)) {
|
|
39
|
+
process.stderr.write(`a pasta ${r.opcoes.dir} nao existe\n`);
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
const estaticos = pastaEstaticos();
|
|
43
|
+
const painel = await iniciarPainel({
|
|
44
|
+
raiz,
|
|
45
|
+
porta: r.opcoes.porta,
|
|
46
|
+
diasBloqueio: r.opcoes.diasBloqueio,
|
|
47
|
+
...(estaticos !== undefined ? { estaticos } : {}),
|
|
48
|
+
});
|
|
49
|
+
const e = painel.estado();
|
|
50
|
+
const url = painel.url();
|
|
51
|
+
process.stdout.write([
|
|
52
|
+
"",
|
|
53
|
+
` expx-painel ${url}`,
|
|
54
|
+
` observando ${raiz}`,
|
|
55
|
+
` ${String(e.trabalhos.length)} trabalho(s) · ${String(e.violacoes.length)} violacao(oes) · ${String(e.rejeicoes.length)} fora do schema`,
|
|
56
|
+
"",
|
|
57
|
+
" somente leitura — o painel nunca escreve nos arquivos do projeto",
|
|
58
|
+
" Ctrl+C para encerrar",
|
|
59
|
+
"",
|
|
60
|
+
].join("\n"));
|
|
61
|
+
if (r.opcoes.abrir) {
|
|
62
|
+
process.stdout.write(" abrindo o navegador...\n\n");
|
|
63
|
+
abrirNavegador(url);
|
|
64
|
+
}
|
|
65
|
+
const encerrar = () => {
|
|
66
|
+
void painel.parar().then(() => process.exit(0));
|
|
67
|
+
};
|
|
68
|
+
process.on("SIGINT", encerrar);
|
|
69
|
+
process.on("SIGTERM", encerrar);
|
|
70
|
+
return 0;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Este módulo foi executado como programa, e não importado?
|
|
74
|
+
*
|
|
75
|
+
* Comparar `argv[1]` com `import.meta.url` direto NÃO funciona quando o pacote
|
|
76
|
+
* está instalado: o npm cria `node_modules/.bin/expx-painel` como symlink, então
|
|
77
|
+
* `argv[1]` é o link e `import.meta.url` é o arquivo real — a igualdade falha e
|
|
78
|
+
* o CLI não roda, sem erro nenhum. `realpath` resolve os dois para o mesmo
|
|
79
|
+
* caminho e faz a detecção valer nos dois casos.
|
|
80
|
+
*/
|
|
81
|
+
function executadoComoPrograma() {
|
|
82
|
+
const argv = process.argv[1];
|
|
83
|
+
if (argv === undefined)
|
|
84
|
+
return false;
|
|
85
|
+
const real = (p) => {
|
|
86
|
+
try {
|
|
87
|
+
return realpathSync(p);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return resolve(p);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
return real(argv) === real(fileURLToPath(import.meta.url));
|
|
94
|
+
}
|
|
95
|
+
const executadoDireto = executadoComoPrograma();
|
|
96
|
+
if (executadoDireto) {
|
|
97
|
+
principal(process.argv.slice(2))
|
|
98
|
+
.then((codigo) => {
|
|
99
|
+
if (codigo !== 0)
|
|
100
|
+
process.exit(codigo);
|
|
101
|
+
})
|
|
102
|
+
.catch((e) => {
|
|
103
|
+
process.stderr.write(`erro ao subir o painel: ${String(e)}\n`);
|
|
104
|
+
process.exit(1);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=principal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"principal.js","sourceRoot":"","sources":["../../src/cli/principal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* O que o CLI precisa saber sobre o projeto antes de tocar em qualquer coisa.
|
|
3
|
+
*
|
|
4
|
+
* `existe` distingue instalação nova de reconfiguração — e reconfiguração nunca
|
|
5
|
+
* apaga nada sem confirmação explícita.
|
|
6
|
+
*/
|
|
7
|
+
export type Projeto = {
|
|
8
|
+
raiz: string;
|
|
9
|
+
versionado: boolean;
|
|
10
|
+
existe: boolean;
|
|
11
|
+
lock: string;
|
|
12
|
+
};
|
|
13
|
+
export declare function detectarProjeto(raiz: string): Projeto;
|
|
14
|
+
/**
|
|
15
|
+
* O `.expx/` é commitado: as skills viajam com o repositório, e é isso que
|
|
16
|
+
* permite a quem clona trabalhar sem rede. Um `.gitignore` que o ignore quebra
|
|
17
|
+
* a premissa inteira em silêncio, então o CLI verifica.
|
|
18
|
+
*/
|
|
19
|
+
export declare function expxNoGitignore(raiz: string): boolean;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { caminhoDoLock } from "../nucleo/lock.js";
|
|
4
|
+
export function detectarProjeto(raiz) {
|
|
5
|
+
const lock = caminhoDoLock(raiz);
|
|
6
|
+
return {
|
|
7
|
+
raiz,
|
|
8
|
+
versionado: existsSync(join(raiz, ".git")),
|
|
9
|
+
existe: existsSync(join(raiz, ".expx")),
|
|
10
|
+
lock,
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* O `.expx/` é commitado: as skills viajam com o repositório, e é isso que
|
|
15
|
+
* permite a quem clona trabalhar sem rede. Um `.gitignore` que o ignore quebra
|
|
16
|
+
* a premissa inteira em silêncio, então o CLI verifica.
|
|
17
|
+
*/
|
|
18
|
+
export function expxNoGitignore(raiz) {
|
|
19
|
+
const caminho = join(raiz, ".gitignore");
|
|
20
|
+
if (!existsSync(caminho))
|
|
21
|
+
return false;
|
|
22
|
+
return readFileSync(caminho, "utf8")
|
|
23
|
+
.split("\n")
|
|
24
|
+
.map((l) => l.trim())
|
|
25
|
+
.filter((l) => l !== "" && !l.startsWith("#"))
|
|
26
|
+
.some((l) => l === ".expx" || l === ".expx/" || l === "/.expx" || l === "/.expx/");
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=projeto.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"projeto.js","sourceRoot":"","sources":["../../src/cli/projeto.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAgBlD,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IACjC,OAAO;QACL,IAAI;QACJ,UAAU,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,EAAE,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;QACvC,IAAI;KACL,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACzC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC;SACjC,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAC7C,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC;AACvF,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* As regras da seleção de skills, aplicadas na hora — avisando sem impedir.
|
|
3
|
+
*
|
|
4
|
+
* O método é deliberado aqui: uma combinação incomum pode ser exatamente o que
|
|
5
|
+
* a pessoa quer. O CLI explica a consequência e pede confirmação; não decide
|
|
6
|
+
* pela pessoa nem recusa a instalação.
|
|
7
|
+
*
|
|
8
|
+
* Nome fora do catálogo é outra coisa: aí não há o que instalar, e o erro é
|
|
9
|
+
* definitivo.
|
|
10
|
+
*/
|
|
11
|
+
export type Avaliacao = {
|
|
12
|
+
permitido: boolean;
|
|
13
|
+
precisaConfirmar: boolean;
|
|
14
|
+
avisos: string[];
|
|
15
|
+
erros: string[];
|
|
16
|
+
/** Skills cuja integração com as demais selecionadas está disponível. */
|
|
17
|
+
integracoes: string[];
|
|
18
|
+
};
|
|
19
|
+
export declare function avaliarSelecao(selecao: readonly string[]): Avaliacao;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { buscarNoCatalogo, ehCamada } from "../nucleo/catalogo.js";
|
|
2
|
+
const BASES = ["sprintx", "runx"];
|
|
3
|
+
export function avaliarSelecao(selecao) {
|
|
4
|
+
const avisos = [];
|
|
5
|
+
const erros = [];
|
|
6
|
+
const integracoes = [];
|
|
7
|
+
for (const nome of selecao) {
|
|
8
|
+
if (buscarNoCatalogo(nome) === undefined)
|
|
9
|
+
erros.push(`skill desconhecida: ${nome}`);
|
|
10
|
+
}
|
|
11
|
+
if (selecao.length === 0)
|
|
12
|
+
erros.push("nenhuma skill selecionada");
|
|
13
|
+
const temBase = selecao.some((s) => BASES.includes(s));
|
|
14
|
+
const camadas = selecao.filter((s) => ehCamada(s));
|
|
15
|
+
if (camadas.length > 0 && !temBase) {
|
|
16
|
+
avisos.push(`${camadas.join(" e ")} ${camadas.length > 1 ? "sao camadas" : "e camada"}: sozinha${camadas.length > 1 ? "s" : ""} nao faz${camadas.length > 1 ? "em" : ""} nada. Instale sprintx ou runx junto.`);
|
|
17
|
+
}
|
|
18
|
+
if (selecao.includes("mergex") && temBase)
|
|
19
|
+
integracoes.push("mergex");
|
|
20
|
+
return {
|
|
21
|
+
permitido: erros.length === 0,
|
|
22
|
+
precisaConfirmar: avisos.length > 0,
|
|
23
|
+
avisos,
|
|
24
|
+
erros,
|
|
25
|
+
integracoes,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=selecao.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selecao.js","sourceRoot":"","sources":["../../src/cli/selecao.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAsBnE,MAAM,KAAK,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAElC,MAAM,UAAU,cAAc,CAAC,OAA0B;IACvD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,WAAW,GAAa,EAAE,CAAC;IAEjC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,gBAAgB,CAAC,IAAI,CAAC,KAAK,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;IAElE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QACnC,MAAM,CAAC,IAAI,CACT,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,YAAY,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,WAAW,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,uCAAuC,CACnM,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO;QAAE,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAEtE,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,MAAM,KAAK,CAAC;QAC7B,gBAAgB,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC;QACnC,MAAM;QACN,KAAK;QACL,WAAW;KACZ,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type ResultadoInit } from "./init.js";
|
|
2
|
+
/**
|
|
3
|
+
* `add` e `remove`: mudam a seleção e remontam tudo a partir dela.
|
|
4
|
+
*
|
|
5
|
+
* Remontar do zero, em vez de mexer no plugin já montado, mantém uma única
|
|
6
|
+
* rotina responsável pela árvore instalada — o que evita a classe de bug em que
|
|
7
|
+
* uma remoção deixa arquivo órfão que ninguém mais sabe de onde veio.
|
|
8
|
+
*/
|
|
9
|
+
export type OpcoesSelecionar = {
|
|
10
|
+
raiz: string;
|
|
11
|
+
skills: readonly string[];
|
|
12
|
+
origens?: Record<string, string>;
|
|
13
|
+
};
|
|
14
|
+
export type ResultadoSelecionar = {
|
|
15
|
+
ok: true;
|
|
16
|
+
selecao: string[];
|
|
17
|
+
init: ResultadoInit;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
erro: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function adicionarSkills(op: OpcoesSelecionar): Promise<ResultadoSelecionar>;
|
|
23
|
+
export declare function removerSkills(op: OpcoesSelecionar): Promise<ResultadoSelecionar>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { lerLock } from "../nucleo/lock.js";
|
|
2
|
+
import { executarInit } from "./init.js";
|
|
3
|
+
function estadoAtual(raiz) {
|
|
4
|
+
const l = lerLock(raiz);
|
|
5
|
+
if (!l.ok)
|
|
6
|
+
return undefined;
|
|
7
|
+
return { skills: Object.keys(l.lock.skills), harness: l.lock.harness };
|
|
8
|
+
}
|
|
9
|
+
async function remontar(op, selecao, harness) {
|
|
10
|
+
const init = await executarInit({
|
|
11
|
+
raiz: op.raiz,
|
|
12
|
+
skills: selecao,
|
|
13
|
+
harness,
|
|
14
|
+
...(op.origens !== undefined ? { origens: op.origens } : {}),
|
|
15
|
+
});
|
|
16
|
+
return { ok: true, selecao, init };
|
|
17
|
+
}
|
|
18
|
+
export async function adicionarSkills(op) {
|
|
19
|
+
const atual = estadoAtual(op.raiz);
|
|
20
|
+
if (atual === undefined)
|
|
21
|
+
return { ok: false, erro: "nao ha instalacao valida neste projeto: rode expx init" };
|
|
22
|
+
const selecao = [...atual.skills];
|
|
23
|
+
for (const s of op.skills)
|
|
24
|
+
if (!selecao.includes(s))
|
|
25
|
+
selecao.push(s);
|
|
26
|
+
return remontar(op, selecao, atual.harness);
|
|
27
|
+
}
|
|
28
|
+
export async function removerSkills(op) {
|
|
29
|
+
const atual = estadoAtual(op.raiz);
|
|
30
|
+
if (atual === undefined)
|
|
31
|
+
return { ok: false, erro: "nao ha instalacao valida neste projeto: rode expx init" };
|
|
32
|
+
for (const s of op.skills) {
|
|
33
|
+
if (!atual.skills.includes(s))
|
|
34
|
+
return { ok: false, erro: `${s} nao esta instalada neste projeto` };
|
|
35
|
+
}
|
|
36
|
+
const selecao = atual.skills.filter((s) => !op.skills.includes(s));
|
|
37
|
+
if (selecao.length === 0) {
|
|
38
|
+
return {
|
|
39
|
+
ok: false,
|
|
40
|
+
erro: "remover a ultima skill deixaria a instalacao vazia: use um novo expx init para reconfigurar",
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
return remontar(op, selecao, atual.harness);
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=selecionar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selecionar.js","sourceRoot":"","sources":["../../src/cli/selecionar.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAsB,MAAM,WAAW,CAAC;AAoB7D,SAAS,WAAW,CAAC,IAAY;IAC/B,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,CAAC,CAAC,CAAC,EAAE;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;AACzE,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,EAAoB,EACpB,OAAiB,EACjB,OAAiB;IAEjB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC;QAC9B,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,MAAM,EAAE,OAAO;QACf,OAAO;QACP,GAAG,CAAC,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7D,CAAC,CAAC;IACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAoB;IACxD,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,wDAAwD,EAAE,CAAC;IAE9G,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM;QAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrE,OAAO,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,EAAoB;IACtD,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IACnC,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,wDAAwD,EAAE,CAAC;IAE9G,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,CAAC,mCAAmC,EAAE,CAAC;IACrG,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,IAAI,EAAE,6FAA6F;SACpG,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Roteador de subcomando do `expx`.
|
|
3
|
+
*
|
|
4
|
+
* O parser original (`argumentos.ts`) só entende opções: qualquer token solto é
|
|
5
|
+
* erro. O `expx` precisa do contrário — o primeiro token é o subcomando e o
|
|
6
|
+
* resto é repassado para quem sabe interpretá-lo. As duas camadas convivem: o
|
|
7
|
+
* `panel` delega para o parser antigo, que continua sendo o dono das opções do
|
|
8
|
+
* painel.
|
|
9
|
+
*/
|
|
10
|
+
export declare const SUBCOMANDOS: readonly ["init", "panel", "add", "remove", "update", "doctor"];
|
|
11
|
+
export type Subcomando = (typeof SUBCOMANDOS)[number];
|
|
12
|
+
export type Roteamento = {
|
|
13
|
+
ok: true;
|
|
14
|
+
ajuda: true;
|
|
15
|
+
} | {
|
|
16
|
+
ok: true;
|
|
17
|
+
ajuda: false;
|
|
18
|
+
subcomando: Subcomando;
|
|
19
|
+
resto: string[];
|
|
20
|
+
} | {
|
|
21
|
+
ok: false;
|
|
22
|
+
erro: string;
|
|
23
|
+
};
|
|
24
|
+
export declare function ajudaGeral(): string;
|
|
25
|
+
export declare function interpretarSubcomando(argv: readonly string[]): Roteamento;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Roteador de subcomando do `expx`.
|
|
3
|
+
*
|
|
4
|
+
* O parser original (`argumentos.ts`) só entende opções: qualquer token solto é
|
|
5
|
+
* erro. O `expx` precisa do contrário — o primeiro token é o subcomando e o
|
|
6
|
+
* resto é repassado para quem sabe interpretá-lo. As duas camadas convivem: o
|
|
7
|
+
* `panel` delega para o parser antigo, que continua sendo o dono das opções do
|
|
8
|
+
* painel.
|
|
9
|
+
*/
|
|
10
|
+
export const SUBCOMANDOS = ["init", "panel", "add", "remove", "update", "doctor"];
|
|
11
|
+
const AJUDA = `
|
|
12
|
+
expx — CLI do metodo Expx
|
|
13
|
+
|
|
14
|
+
npx expx <subcomando> [opcoes]
|
|
15
|
+
|
|
16
|
+
expx init instala as skills escolhidas neste projeto
|
|
17
|
+
expx panel sobe o painel de operacao lendo o docs/ do projeto
|
|
18
|
+
expx add <skill...> acrescenta skills a selecao
|
|
19
|
+
expx remove <skill...> remove skills da selecao
|
|
20
|
+
expx update [skill...] atualiza as skills instaladas
|
|
21
|
+
expx doctor diagnostica uma instalacao quebrada
|
|
22
|
+
|
|
23
|
+
--ajuda mostra esta ajuda
|
|
24
|
+
|
|
25
|
+
O painel funciona sem init: ele nao precisa de nada instalado.
|
|
26
|
+
`.trim();
|
|
27
|
+
export function ajudaGeral() {
|
|
28
|
+
return AJUDA;
|
|
29
|
+
}
|
|
30
|
+
function ehSubcomando(v) {
|
|
31
|
+
return SUBCOMANDOS.includes(v);
|
|
32
|
+
}
|
|
33
|
+
export function interpretarSubcomando(argv) {
|
|
34
|
+
const primeiro = argv[0];
|
|
35
|
+
if (primeiro === undefined || primeiro === "--ajuda" || primeiro === "--help" || primeiro === "-h") {
|
|
36
|
+
return { ok: true, ajuda: true };
|
|
37
|
+
}
|
|
38
|
+
if (!ehSubcomando(primeiro)) {
|
|
39
|
+
return { ok: false, erro: `subcomando desconhecido: ${primeiro}` };
|
|
40
|
+
}
|
|
41
|
+
return { ok: true, ajuda: false, subcomando: primeiro, resto: [...argv.slice(1)] };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=subcomandos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subcomandos.js","sourceRoot":"","sources":["../../src/cli/subcomandos.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAU,CAAC;AAQ3F,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;CAeb,CAAC,IAAI,EAAE,CAAC;AAET,MAAM,UAAU,UAAU;IACxB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,YAAY,CAAC,CAAS;IAC7B,OAAQ,WAAiC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,IAAuB;IAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACnG,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACnC,CAAC;IACD,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,4BAA4B,QAAQ,EAAE,EAAE,CAAC;IACrE,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colisão de nome de skill entre os diretórios que o OpenCode varre.
|
|
3
|
+
*
|
|
4
|
+
* O OpenCode descobre skills em `.claude/skills/` E em `.opencode/skills/`. Se a
|
|
5
|
+
* mesma `name` aparecer nos dois, a duplicata é resolvida por last-writer-wins
|
|
6
|
+
* e só um aviso no log — ou seja, silenciosamente, e por um critério que a
|
|
7
|
+
* documentação não promete manter.
|
|
8
|
+
*
|
|
9
|
+
* O `init` evita isso instalando as skills apenas em `.claude/skills/`. Este
|
|
10
|
+
* verificador existe para o caso de a cópia extra aparecer por outro caminho
|
|
11
|
+
* (instalador antigo, cópia manual, outra ferramenta).
|
|
12
|
+
*/
|
|
13
|
+
export type Colisao = {
|
|
14
|
+
nome: string;
|
|
15
|
+
caminhos: string[];
|
|
16
|
+
};
|
|
17
|
+
export declare function detectarColisoes(raiz: string, nomes: readonly string[]): Colisao[];
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/** Onde o OpenCode procura skills dentro do projeto. */
|
|
4
|
+
const DIRETORIOS_DE_SKILL = [
|
|
5
|
+
join(".claude", "skills"),
|
|
6
|
+
join(".opencode", "skills"),
|
|
7
|
+
join(".agents", "skills"),
|
|
8
|
+
];
|
|
9
|
+
export function detectarColisoes(raiz, nomes) {
|
|
10
|
+
const saida = [];
|
|
11
|
+
for (const nome of nomes) {
|
|
12
|
+
const caminhos = DIRETORIOS_DE_SKILL.map((d) => join(raiz, d, nome)).filter((c) => existsSync(c));
|
|
13
|
+
if (caminhos.length > 1)
|
|
14
|
+
saida.push({ nome, caminhos });
|
|
15
|
+
}
|
|
16
|
+
return saida;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=efeito.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"efeito.js","sourceRoot":"","sources":["../../src/doctor/efeito.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAoBjC,wDAAwD;AACxD,MAAM,mBAAmB,GAAG;IAC1B,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC;IACzB,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC;IAC3B,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC;CAC1B,CAAC;AAEF,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,KAAwB;IACrE,MAAM,KAAK,GAAc,EAAE,CAAC;IAC5B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,mBAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;QAClG,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;YAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC1D,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Diagnóstico de instalação quebrada.
|
|
3
|
+
*
|
|
4
|
+
* Cada achado traz a correção sugerida, porque um diagnóstico que só diz "está
|
|
5
|
+
* errado" transfere o trabalho de volta para quem pediu ajuda.
|
|
6
|
+
*
|
|
7
|
+
* `erro` impede o funcionamento; `aviso` é situação legítima que a pessoa
|
|
8
|
+
* precisa saber (modificação local, skill não travada em versão publicada).
|
|
9
|
+
*/
|
|
10
|
+
export type Severidade = "erro" | "aviso";
|
|
11
|
+
export type Achado = {
|
|
12
|
+
id: string;
|
|
13
|
+
severidade: Severidade;
|
|
14
|
+
problema: string;
|
|
15
|
+
correcao: string;
|
|
16
|
+
};
|
|
17
|
+
export type Diagnostico = {
|
|
18
|
+
saudavel: boolean;
|
|
19
|
+
achados: Achado[];
|
|
20
|
+
};
|
|
21
|
+
export declare function diagnosticar(raiz: string): Diagnostico;
|