sabia 1.1.1 → 1.1.3
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/package.json +1 -1
- package/sabia.mjs +20 -9
package/package.json
CHANGED
package/sabia.mjs
CHANGED
|
@@ -427,7 +427,10 @@ export function validarToolkit(pasta, nomeEsperado = null) {
|
|
|
427
427
|
let m;
|
|
428
428
|
try { m = JSON.parse(fs.readFileSync(f, "utf8")); } catch (e) { return [`toolkit.json inválido: ${e.message}`]; }
|
|
429
429
|
const erros = [];
|
|
430
|
-
for (const c of ["nome", "versao", "descricao", "tipos-de-projeto", "skills"]) if (!(c in m)) erros.push(`falta o campo ${c}`);
|
|
430
|
+
for (const c of ["nome", "versao", "descricao", "autor", "tipos-de-projeto", "skills"]) if (!(c in m)) erros.push(`falta o campo ${c}`);
|
|
431
|
+
// quem fez responde pelo toolkit: nome e área aparecem no listar e na setup
|
|
432
|
+
if (m.autor && (typeof m.autor.nome !== "string" || typeof m.autor.area !== "string" || !m.autor.nome.trim() || !m.autor.area.trim()))
|
|
433
|
+
erros.push("autor: precisa de nome e area");
|
|
431
434
|
const nomeOk = (n) => typeof n === "string" && /^[a-z0-9][a-z0-9-]*$/.test(n) && !n.startsWith("sa-");
|
|
432
435
|
if (!nomeOk(m.nome)) erros.push(`nome inválido (kebab-case, sem sa-): ${m.nome}`);
|
|
433
436
|
if (nomeEsperado && m.nome !== nomeEsperado) erros.push(`nome ${m.nome} ≠ ${nomeEsperado} do índice`);
|
|
@@ -463,7 +466,7 @@ export function lerIndice(fonte) {
|
|
|
463
466
|
const m = JSON.parse(fs.readFileSync(path.join(raiz, ".claude-plugin", "marketplace.json"), "utf8"));
|
|
464
467
|
return (m.plugins || []).map((p) => {
|
|
465
468
|
const s = p.source;
|
|
466
|
-
const base = { nome: p.name, versao: p.version, descricao: p.description, indice: fonte };
|
|
469
|
+
const base = { nome: p.name, versao: p.version, descricao: p.description, customiza: p.customiza, autor: p.autor, indice: fonte };
|
|
467
470
|
if (typeof s === "string") return { ...base, url: local ? path.resolve(raiz, dentro(s.replace(/^\.\//, ""), fonte)) : fonte, subpasta: local ? null : s.replace(/^\.\//, "") };
|
|
468
471
|
if (s?.source === "github") return { ...base, url: `https://github.com/${s.repo}.git`, ref: s.ref, sha: s.sha };
|
|
469
472
|
if (s?.source === "url") return { ...base, url: s.url, ref: s.ref, sha: s.sha };
|
|
@@ -581,28 +584,36 @@ export function listarToolkits(opcoes = {}) {
|
|
|
581
584
|
const inv = lerInventario();
|
|
582
585
|
const projeto = path.join(process.cwd(), ".sabia", "config", "agentes.json");
|
|
583
586
|
const doProjeto = fs.existsSync(projeto) ? JSON.parse(fs.readFileSync(projeto, "utf8")).toolkits || {} : {};
|
|
584
|
-
|
|
587
|
+
// autor e customiza: do toolkit baixado (o toolkit.json) ou, sem ele, da entrada do índice
|
|
588
|
+
const manifesto = (n) => { const f = sabia("toolkits", n, "toolkit.json"); return fs.existsSync(f) ? JSON.parse(fs.readFileSync(f, "utf8")) : {}; };
|
|
589
|
+
const linhas = [], doIndice = {};
|
|
585
590
|
for (const i of opcoes.indice ? [opcoes.indice] : indices()) {
|
|
586
591
|
try {
|
|
587
|
-
for (const e of lerIndice(i))
|
|
592
|
+
for (const e of lerIndice(i)) {
|
|
593
|
+
doIndice[e.nome] = e;
|
|
594
|
+
linhas.push([e.nome, "", e.versao || "—", inv.toolkits[e.nome]?.versao || "—", doProjeto[e.nome]?.versao || "—", e.descricao || ""]);
|
|
595
|
+
}
|
|
588
596
|
} catch (err) {
|
|
589
597
|
ctx.log(`índice ${i}: ${err.message}`);
|
|
590
598
|
}
|
|
591
599
|
}
|
|
592
|
-
for (const [n, t] of Object.entries(inv.toolkits)) if (!linhas.some((l) => l[0] === n)) linhas.push([n, "—", t.versao, doProjeto[n]?.versao || "—", "(fora dos índices)"]);
|
|
600
|
+
for (const [n, t] of Object.entries(inv.toolkits)) if (!linhas.some((l) => l[0] === n)) linhas.push([n, "", "—", t.versao, doProjeto[n]?.versao || "—", "(fora dos índices)"]);
|
|
601
|
+
for (const l of linhas) {
|
|
602
|
+
const a = manifesto(l[0]).autor ?? doIndice[l[0]]?.autor;
|
|
603
|
+
l[1] = a ? `${a.nome} (${a.area})` : "—";
|
|
604
|
+
}
|
|
593
605
|
// a customização logo abaixo da base, com ↳ e de onde veio
|
|
594
606
|
for (const l of [...linhas]) {
|
|
595
|
-
const
|
|
596
|
-
const c = fs.existsSync(f) ? JSON.parse(fs.readFileSync(f, "utf8")).customiza : null;
|
|
607
|
+
const c = manifesto(l[0]).customiza ?? doIndice[l[0]]?.customiza;
|
|
597
608
|
if (!c) continue;
|
|
598
609
|
linhas.splice(linhas.indexOf(l), 1);
|
|
599
610
|
const i = linhas.findIndex((b) => b[0] === c.toolkit);
|
|
600
611
|
// só a primeira mudança (quem customizou), como resumo; a lista inteira está no toolkit.json
|
|
601
|
-
l[
|
|
612
|
+
l[5] = `customiza ${c.toolkit} ${c.versao}${c.mudancas?.length ? `: ${c.mudancas[0]}${c.mudancas.length > 1 ? "; …" : ""}` : ""}${l[5] ? " — " + l[5] : ""}`;
|
|
602
613
|
l[0] = `↳ ${l[0]}`;
|
|
603
614
|
linhas.splice(i < 0 ? linhas.length : i + 1, 0, l);
|
|
604
615
|
}
|
|
605
|
-
ctx.log(["| Toolkit | No índice | Instalado | Neste projeto | Descrição |", "
|
|
616
|
+
ctx.log(["| Toolkit | Autor | No índice | Instalado | Neste projeto | Descrição |", "|---|---|---|---|---|---|",
|
|
606
617
|
...linhas.map((l) => `| ${l.join(" | ")} |`)].join("\n"));
|
|
607
618
|
return linhas;
|
|
608
619
|
}
|