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
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { basename, dirname, join } from "node:path";
|
|
2
|
+
import { descobrirTrabalhos } from "../descoberta/trabalhos.js";
|
|
3
|
+
/** Frontmatter mais a prosa, que é o que o painel renderiza no relatório. */
|
|
4
|
+
function comCorpo(a) {
|
|
5
|
+
return a ? { ...a.dados, _corpo: a.corpo } : null;
|
|
6
|
+
}
|
|
7
|
+
function porPasta(aceitos) {
|
|
8
|
+
const m = new Map();
|
|
9
|
+
for (const a of aceitos) {
|
|
10
|
+
const d = dirname(a.arquivo);
|
|
11
|
+
const lista = m.get(d);
|
|
12
|
+
if (lista)
|
|
13
|
+
lista.push(a);
|
|
14
|
+
else
|
|
15
|
+
m.set(d, [a]);
|
|
16
|
+
}
|
|
17
|
+
return m;
|
|
18
|
+
}
|
|
19
|
+
/** Progresso = fração de tasks concluídas. Sem tasks, 0 — nunca divide por zero. */
|
|
20
|
+
function progressoDe(tasks) {
|
|
21
|
+
if (tasks.length === 0)
|
|
22
|
+
return 0;
|
|
23
|
+
return tasks.filter((t) => t.status === "concluida").length / tasks.length;
|
|
24
|
+
}
|
|
25
|
+
function montarSprints(trabalho, mapa) {
|
|
26
|
+
const sprints = [];
|
|
27
|
+
// Sprints são descobertas varrendo as pastas do disco (decisão D-14):
|
|
28
|
+
// uma pasta sprint-NN ausente da lista do orquestrador ainda é real.
|
|
29
|
+
const pastas = [...mapa.keys()]
|
|
30
|
+
.filter((p) => dirname(p) === trabalho.pasta && /^sprint-\d+$/.test(basename(p)))
|
|
31
|
+
.sort();
|
|
32
|
+
for (const pasta of pastas) {
|
|
33
|
+
const arquivos = mapa.get(pasta) ?? [];
|
|
34
|
+
const aSprint = arquivos.find((a) => a.kind === "sprint");
|
|
35
|
+
const aFases = arquivos.find((a) => a.kind === "fases");
|
|
36
|
+
const aTasks = arquivos.find((a) => a.kind === "tasks");
|
|
37
|
+
const tasksBrutas = aTasks?.dados["tasks"] ?? [];
|
|
38
|
+
const tasks = tasksBrutas.map((t, i) => ({
|
|
39
|
+
...t,
|
|
40
|
+
arquivo: aTasks?.arquivo ?? join(pasta, "tasks.md"),
|
|
41
|
+
linha: aTasks?.linhas.get(`tasks.${i}`) ?? null,
|
|
42
|
+
trabalho_id: trabalho.trabalho_id,
|
|
43
|
+
sprint_id: basename(pasta),
|
|
44
|
+
}));
|
|
45
|
+
const fasesBrutas = aFases?.dados["fases"] ?? [];
|
|
46
|
+
const fases = fasesBrutas.map((f, i) => {
|
|
47
|
+
// o vínculo autoritativo é o campo `fase` da task (decisão D-13)
|
|
48
|
+
const minhas = tasks.filter((t) => t.fase === f.id);
|
|
49
|
+
return {
|
|
50
|
+
...f,
|
|
51
|
+
tasks: minhas,
|
|
52
|
+
progresso: progressoDe(minhas),
|
|
53
|
+
arquivo: aFases?.arquivo ?? join(pasta, "fases.md"),
|
|
54
|
+
linha: aFases?.linhas.get(`fases.${i}`) ?? null,
|
|
55
|
+
};
|
|
56
|
+
});
|
|
57
|
+
sprints.push({
|
|
58
|
+
sprint_id: aSprint?.dados["sprint_id"] ?? basename(pasta),
|
|
59
|
+
titulo: aSprint?.dados["titulo"] ?? basename(pasta),
|
|
60
|
+
status: aSprint?.dados["status"] ?? "nao_iniciado",
|
|
61
|
+
criterio_saida: aSprint?.dados["criterio_saida"] ?? null,
|
|
62
|
+
riscos: aSprint?.dados["riscos"] ?? [],
|
|
63
|
+
fases,
|
|
64
|
+
tasks,
|
|
65
|
+
progresso: progressoDe(tasks),
|
|
66
|
+
arquivo: aSprint?.arquivo ?? null,
|
|
67
|
+
linha: aSprint?.linhas.get("criterio_saida") ?? aSprint?.linhas.get("kind") ?? null,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
return sprints;
|
|
71
|
+
}
|
|
72
|
+
function montarBloqueios(trabalho, mapa) {
|
|
73
|
+
const arquivos = mapa.get(trabalho.pasta) ?? [];
|
|
74
|
+
const a = arquivos.find((x) => x.kind === "bloqueios");
|
|
75
|
+
if (!a)
|
|
76
|
+
return [];
|
|
77
|
+
const lista = a.dados["bloqueios"] ?? [];
|
|
78
|
+
return lista.map((b, i) => ({
|
|
79
|
+
...b,
|
|
80
|
+
// um bloqueio está aberto quando resolvido_em é null — única definição disponível
|
|
81
|
+
aberto: b.resolvido_em === null || b.resolvido_em === undefined,
|
|
82
|
+
trabalho_id: trabalho.trabalho_id,
|
|
83
|
+
arquivo: a.arquivo,
|
|
84
|
+
linha: a.linhas.get(`bloqueios.${i}`) ?? null,
|
|
85
|
+
}));
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* O histórico é montado varrendo as pastas de `docs/relatorios/` (decisão D-18).
|
|
89
|
+
* O INDICE.md não é fonte: uma pasta sem entrada no índice ficaria invisível,
|
|
90
|
+
* e o índice é mantido à mão pela skill, podendo ficar defasado.
|
|
91
|
+
*/
|
|
92
|
+
function montarHistorico(aceitos) {
|
|
93
|
+
const porPastaRel = new Map();
|
|
94
|
+
for (const a of aceitos) {
|
|
95
|
+
if (a.kind !== "relatorio_tecnico" && a.kind !== "relatorio_uso")
|
|
96
|
+
continue;
|
|
97
|
+
const pasta = dirname(a.arquivo);
|
|
98
|
+
const atual = porPastaRel.get(pasta) ?? {};
|
|
99
|
+
if (a.kind === "relatorio_tecnico")
|
|
100
|
+
atual.tecnico = a;
|
|
101
|
+
else
|
|
102
|
+
atual.uso = a;
|
|
103
|
+
porPastaRel.set(pasta, atual);
|
|
104
|
+
}
|
|
105
|
+
const entradas = [];
|
|
106
|
+
for (const [pasta, { tecnico, uso }] of porPastaRel) {
|
|
107
|
+
const fonte = tecnico ?? uso;
|
|
108
|
+
if (!fonte)
|
|
109
|
+
continue;
|
|
110
|
+
const d = fonte.dados;
|
|
111
|
+
entradas.push({
|
|
112
|
+
oc_id: d["trabalho_id"] ?? basename(pasta),
|
|
113
|
+
titulo: d["titulo"] ?? "",
|
|
114
|
+
tipo_ocorrencia: d["tipo_ocorrencia"] ?? "outro",
|
|
115
|
+
fechado_em: d["fechado_em"] ?? "",
|
|
116
|
+
modulo_afetado: d["modulo_afetado"] ?? [],
|
|
117
|
+
pasta,
|
|
118
|
+
tecnico: comCorpo(tecnico),
|
|
119
|
+
uso: comCorpo(uso),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// ordenado por data de fechamento, mais recente primeiro
|
|
123
|
+
entradas.sort((a, b) => b.fechado_em.localeCompare(a.fechado_em));
|
|
124
|
+
return entradas;
|
|
125
|
+
}
|
|
126
|
+
export function montarProjeto(raiz, agora = new Date()) {
|
|
127
|
+
const { trabalhos, rejeicoes, aceitos } = descobrirTrabalhos(raiz);
|
|
128
|
+
const mapa = porPasta(aceitos);
|
|
129
|
+
const montados = trabalhos.map((t) => {
|
|
130
|
+
const sprints = montarSprints(t, mapa);
|
|
131
|
+
const todas = sprints.flatMap((s) => s.tasks);
|
|
132
|
+
return {
|
|
133
|
+
...t,
|
|
134
|
+
sprints,
|
|
135
|
+
sprints_declaradas: t.sprints,
|
|
136
|
+
progresso: progressoDe(todas),
|
|
137
|
+
bloqueios: montarBloqueios(t, mapa),
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
return {
|
|
141
|
+
raiz,
|
|
142
|
+
trabalhos: montados,
|
|
143
|
+
bloqueios: montados.flatMap((t) => t.bloqueios),
|
|
144
|
+
historico: montarHistorico(aceitos),
|
|
145
|
+
rejeicoes,
|
|
146
|
+
lido_em: agora.toISOString(),
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=montar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"montar.js","sourceRoot":"","sources":["../../../src/parser/projeto/montar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Troca o `.expx/` inteiro de uma vez, ou não troca nada.
|
|
3
|
+
*
|
|
4
|
+
* Montar direto no destino final deixa `.expx/` pela metade se a busca de uma
|
|
5
|
+
* skill falhar no meio — e um `.expx/` pela metade é pior que nenhum, porque o
|
|
6
|
+
* harness carrega um plugin incompleto sem avisar. Montar ao lado e trocar por
|
|
7
|
+
* `rename` mantém a instalação anterior válida até o último instante.
|
|
8
|
+
*
|
|
9
|
+
* O `rename` é a operação que dá a atomicidade, e ele só é atômico dentro do
|
|
10
|
+
* mesmo sistema de arquivos: por isso a pasta temporária fica ao lado do
|
|
11
|
+
* destino, na raiz do projeto, e não em `/tmp`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function escreverAtomico(raizProjeto: string, montar: (pastaTemporaria: string) => void): void;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, renameSync, rmSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* Troca o `.expx/` inteiro de uma vez, ou não troca nada.
|
|
5
|
+
*
|
|
6
|
+
* Montar direto no destino final deixa `.expx/` pela metade se a busca de uma
|
|
7
|
+
* skill falhar no meio — e um `.expx/` pela metade é pior que nenhum, porque o
|
|
8
|
+
* harness carrega um plugin incompleto sem avisar. Montar ao lado e trocar por
|
|
9
|
+
* `rename` mantém a instalação anterior válida até o último instante.
|
|
10
|
+
*
|
|
11
|
+
* O `rename` é a operação que dá a atomicidade, e ele só é atômico dentro do
|
|
12
|
+
* mesmo sistema de arquivos: por isso a pasta temporária fica ao lado do
|
|
13
|
+
* destino, na raiz do projeto, e não em `/tmp`.
|
|
14
|
+
*/
|
|
15
|
+
export function escreverAtomico(raizProjeto, montar) {
|
|
16
|
+
const destino = join(raizProjeto, ".expx");
|
|
17
|
+
const temporaria = join(raizProjeto, `.expx.tmp-${String(process.pid)}-${String(Date.now())}`);
|
|
18
|
+
const anterior = `${temporaria}-anterior`;
|
|
19
|
+
mkdirSync(temporaria, { recursive: true });
|
|
20
|
+
try {
|
|
21
|
+
montar(temporaria);
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
rmSync(temporaria, { recursive: true, force: true });
|
|
25
|
+
throw e;
|
|
26
|
+
}
|
|
27
|
+
const tinhaAnterior = existsSync(destino);
|
|
28
|
+
if (tinhaAnterior)
|
|
29
|
+
renameSync(destino, anterior);
|
|
30
|
+
try {
|
|
31
|
+
renameSync(temporaria, destino);
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
// não conseguiu publicar o novo: devolve o antigo ao lugar
|
|
35
|
+
if (tinhaAnterior)
|
|
36
|
+
renameSync(anterior, destino);
|
|
37
|
+
rmSync(temporaria, { recursive: true, force: true });
|
|
38
|
+
throw e;
|
|
39
|
+
}
|
|
40
|
+
rmSync(anterior, { recursive: true, force: true });
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=atomico.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"atomico.js","sourceRoot":"","sources":["../../src/plugin/atomico.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACpE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,WAAmB,EAAE,MAAyC;IAC5F,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,aAAa,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;IAC/F,MAAM,QAAQ,GAAG,GAAG,UAAU,WAAW,CAAC;IAE1C,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3C,IAAI,CAAC;QACH,MAAM,CAAC,UAAU,CAAC,CAAC;IACrB,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,MAAM,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,CAAC;IACV,CAAC;IAED,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,aAAa;QAAE,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACjD,IAAI,CAAC;QACH,UAAU,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,2DAA2D;QAC3D,IAAI,aAAa;YAAE,UAAU,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,MAAM,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,CAAC;IACV,CAAC;IACD,MAAM,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Os dois manifestos do plugin local.
|
|
4
|
+
*
|
|
5
|
+
* O nome do plugin é o que dá namespace aos comandos: com `name: "expx"`, a
|
|
6
|
+
* skill `sprintx` fica disponível como `/expx:sprintx`. Isso foi verificado em
|
|
7
|
+
* execução, não só na documentação — ver
|
|
8
|
+
* `docs/expx-cli/base/09-validacao-marketplace-local.md`.
|
|
9
|
+
*
|
|
10
|
+
* O `source` do marketplace aponta para uma pasta DENTRO da árvore do próprio
|
|
11
|
+
* marketplace. Um `source` que sobe de diretório (`../plugin`) é rejeitado pelo
|
|
12
|
+
* Claude Code com `source: Invalid input` — medido, não suposto. Por isso o
|
|
13
|
+
* plugin mora em `marketplace/plugins/expx/`, e não como irmão do marketplace.
|
|
14
|
+
*/
|
|
15
|
+
export declare const NOME_DO_PLUGIN = "expx";
|
|
16
|
+
export declare const NOME_DO_MARKETPLACE = "expx-local";
|
|
17
|
+
/** Relativo à raiz do marketplace. Nunca pode conter `..`. */
|
|
18
|
+
export declare const ORIGEM_DO_PLUGIN = "./plugins/expx";
|
|
19
|
+
export declare const PluginJson: z.ZodObject<{
|
|
20
|
+
name: z.ZodLiteral<"expx">;
|
|
21
|
+
description: z.ZodString;
|
|
22
|
+
version: z.ZodString;
|
|
23
|
+
}, z.core.$strip>;
|
|
24
|
+
export type PluginJson = z.infer<typeof PluginJson>;
|
|
25
|
+
export declare const MarketplaceJson: z.ZodObject<{
|
|
26
|
+
name: z.ZodLiteral<"expx-local">;
|
|
27
|
+
owner: z.ZodObject<{
|
|
28
|
+
name: z.ZodString;
|
|
29
|
+
}, z.core.$strip>;
|
|
30
|
+
plugins: z.ZodArray<z.ZodObject<{
|
|
31
|
+
name: z.ZodLiteral<"expx">;
|
|
32
|
+
source: z.ZodString;
|
|
33
|
+
description: z.ZodString;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
}, z.core.$strip>;
|
|
36
|
+
export type MarketplaceJson = z.infer<typeof MarketplaceJson>;
|
|
37
|
+
export declare function montarPluginJson(versao: string): PluginJson;
|
|
38
|
+
export declare function montarMarketplaceJson(): MarketplaceJson;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Os dois manifestos do plugin local.
|
|
4
|
+
*
|
|
5
|
+
* O nome do plugin é o que dá namespace aos comandos: com `name: "expx"`, a
|
|
6
|
+
* skill `sprintx` fica disponível como `/expx:sprintx`. Isso foi verificado em
|
|
7
|
+
* execução, não só na documentação — ver
|
|
8
|
+
* `docs/expx-cli/base/09-validacao-marketplace-local.md`.
|
|
9
|
+
*
|
|
10
|
+
* O `source` do marketplace aponta para uma pasta DENTRO da árvore do próprio
|
|
11
|
+
* marketplace. Um `source` que sobe de diretório (`../plugin`) é rejeitado pelo
|
|
12
|
+
* Claude Code com `source: Invalid input` — medido, não suposto. Por isso o
|
|
13
|
+
* plugin mora em `marketplace/plugins/expx/`, e não como irmão do marketplace.
|
|
14
|
+
*/
|
|
15
|
+
export const NOME_DO_PLUGIN = "expx";
|
|
16
|
+
export const NOME_DO_MARKETPLACE = "expx-local";
|
|
17
|
+
/** Relativo à raiz do marketplace. Nunca pode conter `..`. */
|
|
18
|
+
export const ORIGEM_DO_PLUGIN = "./plugins/expx";
|
|
19
|
+
export const PluginJson = z.object({
|
|
20
|
+
name: z.literal(NOME_DO_PLUGIN),
|
|
21
|
+
description: z.string().min(1),
|
|
22
|
+
version: z.string().min(1),
|
|
23
|
+
});
|
|
24
|
+
export const MarketplaceJson = z.object({
|
|
25
|
+
name: z.literal(NOME_DO_MARKETPLACE),
|
|
26
|
+
owner: z.object({ name: z.string().min(1) }),
|
|
27
|
+
plugins: z
|
|
28
|
+
.array(z.object({
|
|
29
|
+
name: z.literal(NOME_DO_PLUGIN),
|
|
30
|
+
source: z.string().refine((s) => !s.includes(".."), {
|
|
31
|
+
message: "source do marketplace nao pode subir de diretorio",
|
|
32
|
+
}),
|
|
33
|
+
description: z.string().min(1),
|
|
34
|
+
}))
|
|
35
|
+
.length(1),
|
|
36
|
+
});
|
|
37
|
+
export function montarPluginJson(versao) {
|
|
38
|
+
return {
|
|
39
|
+
name: NOME_DO_PLUGIN,
|
|
40
|
+
description: "Skills do metodo Expx instaladas neste projeto",
|
|
41
|
+
version: versao,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export function montarMarketplaceJson() {
|
|
45
|
+
return {
|
|
46
|
+
name: NOME_DO_MARKETPLACE,
|
|
47
|
+
owner: { name: "Expx" },
|
|
48
|
+
plugins: [
|
|
49
|
+
{
|
|
50
|
+
name: NOME_DO_PLUGIN,
|
|
51
|
+
source: ORIGEM_DO_PLUGIN,
|
|
52
|
+
description: "Skills do metodo Expx instaladas neste projeto",
|
|
53
|
+
},
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=manifestos.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifestos.js","sourceRoot":"","sources":["../../src/plugin/manifestos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;GAYG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,mBAAmB,GAAG,YAAY,CAAC;AAChD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,gBAAgB,GAAG,gBAAgB,CAAC;AAEjD,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,CAAC;IACjC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;IAC/B,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC9B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;CAC3B,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,mBAAmB,CAAC;IACpC,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5C,OAAO,EAAE,CAAC;SACP,KAAK,CACJ,CAAC,CAAC,MAAM,CAAC;QACP,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,cAAc,CAAC;QAC/B,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAClD,OAAO,EAAE,mDAAmD;SAC7D,CAAC;QACF,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;KAC/B,CAAC,CACH;SACA,MAAM,CAAC,CAAC,CAAC;CACb,CAAC,CAAC;AAGH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,OAAO;QACL,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,gDAAgD;QAC7D,OAAO,EAAE,MAAM;KAChB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO;QACL,IAAI,EAAE,mBAAmB;QACzB,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;QACvB,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,cAAc;gBACpB,MAAM,EAAE,gBAAgB;gBACxB,WAAW,EAAE,gDAAgD;aAC9D;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monta a árvore do plugin local com as skills selecionadas.
|
|
3
|
+
*
|
|
4
|
+
* A estrutura respeita a regra da documentação de que apenas `plugin.json` fica
|
|
5
|
+
* dentro de `.claude-plugin/`; `skills/` e `commands/` ficam na raiz do plugin.
|
|
6
|
+
*/
|
|
7
|
+
export type SkillMontavel = {
|
|
8
|
+
nome: string;
|
|
9
|
+
/** Pasta que contém o `SKILL.md`, já normalizada pelo detector de layout. */
|
|
10
|
+
raizSkill: string;
|
|
11
|
+
/** Arquivos de comando da skill, no repositório de origem. */
|
|
12
|
+
comandos: readonly string[];
|
|
13
|
+
};
|
|
14
|
+
/** Monta só o plugin, em `destino`. */
|
|
15
|
+
export declare function montarPlugin(destino: string, skills: readonly SkillMontavel[], versao: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* Monta marketplace e plugin, com o plugin DENTRO do marketplace.
|
|
18
|
+
*
|
|
19
|
+
* A hierarquia não é estética: um `source` relativo que sobe de diretório é
|
|
20
|
+
* rejeitado na instalação (ver `manifestos.ts`).
|
|
21
|
+
*/
|
|
22
|
+
export declare function montarMarketplace(raizMarketplace: string, skills: readonly SkillMontavel[], versao: string): void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { cpSync, mkdirSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { basename, join } from "node:path";
|
|
3
|
+
import { montarPluginJson, montarMarketplaceJson, ORIGEM_DO_PLUGIN } from "./manifestos.js";
|
|
4
|
+
/** Monta só o plugin, em `destino`. */
|
|
5
|
+
export function montarPlugin(destino, skills, versao) {
|
|
6
|
+
mkdirSync(join(destino, ".claude-plugin"), { recursive: true });
|
|
7
|
+
mkdirSync(join(destino, "skills"), { recursive: true });
|
|
8
|
+
mkdirSync(join(destino, "commands"), { recursive: true });
|
|
9
|
+
writeFileSync(join(destino, ".claude-plugin", "plugin.json"), `${JSON.stringify(montarPluginJson(versao), null, 2)}\n`);
|
|
10
|
+
for (const s of skills) {
|
|
11
|
+
// O nome da pasta tem que continuar igual ao `name` do frontmatter: o
|
|
12
|
+
// OpenCode exige isso para descobrir a skill.
|
|
13
|
+
cpSync(s.raizSkill, join(destino, "skills", s.nome), { recursive: true });
|
|
14
|
+
for (const c of s.comandos) {
|
|
15
|
+
cpSync(c, join(destino, "commands", basename(c)));
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Monta marketplace e plugin, com o plugin DENTRO do marketplace.
|
|
21
|
+
*
|
|
22
|
+
* A hierarquia não é estética: um `source` relativo que sobe de diretório é
|
|
23
|
+
* rejeitado na instalação (ver `manifestos.ts`).
|
|
24
|
+
*/
|
|
25
|
+
export function montarMarketplace(raizMarketplace, skills, versao) {
|
|
26
|
+
mkdirSync(join(raizMarketplace, ".claude-plugin"), { recursive: true });
|
|
27
|
+
writeFileSync(join(raizMarketplace, ".claude-plugin", "marketplace.json"), `${JSON.stringify(montarMarketplaceJson(), null, 2)}\n`);
|
|
28
|
+
montarPlugin(join(raizMarketplace, ORIGEM_DO_PLUGIN), skills, versao);
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=montagem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"montagem.js","sourceRoot":"","sources":["../../src/plugin/montagem.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAiB5F,uCAAuC;AACvC,MAAM,UAAU,YAAY,CAC1B,OAAe,EACf,MAAgC,EAChC,MAAc;IAEd,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChE,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1D,aAAa,CACX,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,aAAa,CAAC,EAC9C,GAAG,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACzD,CAAC;IAEF,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,sEAAsE;QACtE,8CAA8C;QAC9C,MAAM,CAAC,CAAC,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3B,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,eAAuB,EACvB,MAAgC,EAChC,MAAc;IAEd,SAAS,CAAC,IAAI,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxE,aAAa,CACX,IAAI,CAAC,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,CAAC,EAC3D,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACxD,CAAC;IACF,YAAY,CAAC,IAAI,CAAC,eAAe,EAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderizador de Markdown para os relatórios.
|
|
3
|
+
*
|
|
4
|
+
* Escrito à mão de propósito, em vez de uma dependência: os relatórios das
|
|
5
|
+
* skills usam um subconjunto previsível (títulos, listas, tabelas, código,
|
|
6
|
+
* ênfase, citação), e escrever o próprio renderizador nos dá o controle do
|
|
7
|
+
* ESCAPE — o conteúdo vem de arquivo do usuário e nunca pode virar HTML ativo.
|
|
8
|
+
*
|
|
9
|
+
* Regra dura: todo texto passa por `escapar()` ANTES de qualquer tag ser
|
|
10
|
+
* inserida. Nenhum caminho do código emite HTML vindo do arquivo.
|
|
11
|
+
*/
|
|
12
|
+
export declare function escapar(s: string): string;
|
|
13
|
+
export type ItemSumario = {
|
|
14
|
+
nivel: number;
|
|
15
|
+
texto: string;
|
|
16
|
+
id: string;
|
|
17
|
+
};
|
|
18
|
+
/** Converte Markdown em HTML. O `id` dos títulos alimenta o sumário. */
|
|
19
|
+
export declare function renderizar(md: string): {
|
|
20
|
+
html: string;
|
|
21
|
+
sumario: ItemSumario[];
|
|
22
|
+
};
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/relatorio/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documento HTML de um relatório, servido em aba própria.
|
|
3
|
+
*
|
|
4
|
+
* É uma página autocontida: nada de CDN, nada de fetch. O usuário imprime,
|
|
5
|
+
* salva em PDF ou baixa o .md sem depender do painel continuar no ar — e o
|
|
6
|
+
* `@media print` é o que faz o "Salvar como PDF" do navegador sair com cara
|
|
7
|
+
* de documento, não de captura de tela.
|
|
8
|
+
*/
|
|
9
|
+
export type DadosRelatorio = {
|
|
10
|
+
tipo: "tecnico" | "uso";
|
|
11
|
+
titulo: string;
|
|
12
|
+
oc_id: string;
|
|
13
|
+
tipo_ocorrencia: string;
|
|
14
|
+
fechado_em: string;
|
|
15
|
+
modulo_afetado: string[];
|
|
16
|
+
arquivos_alterados?: string[];
|
|
17
|
+
testes_adicionados?: number | null;
|
|
18
|
+
corpo: string;
|
|
19
|
+
/** Nome sugerido do arquivo ao baixar o .md. */
|
|
20
|
+
nomeArquivo: string;
|
|
21
|
+
};
|
|
22
|
+
export declare function paginaRelatorio(d: DadosRelatorio): string;
|