mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
feat(setup): verify installed skill catalog identity
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath, pathToFileURL } from "node:url";
|
||||
|
||||
import { ensureGeneratedFile } from "./lib/generated-file.mjs";
|
||||
|
||||
const arguments_ = new Set(process.argv.slice(2));
|
||||
for (const argument of arguments_)
|
||||
if (argument !== "--check")
|
||||
throw new Error(`Unknown skill metadata option: ${argument}`);
|
||||
|
||||
const root = join(dirname(fileURLToPath(import.meta.url)), "..");
|
||||
const path = join(root, "skills/rea-analysis/SKILL.md");
|
||||
const current = await readFile(path, "utf8");
|
||||
const { CATALOG_IDENTITY } = await import(
|
||||
`${pathToFileURL(join(root, "dist/catalogIdentity.js")).href}?${String(Date.now())}`
|
||||
);
|
||||
const withCount = current.replace(
|
||||
/^\s{2}tool_count:\s*\d+\s*$/mu,
|
||||
` tool_count: ${String(CATALOG_IDENTITY.counts.mcp_tools)}`,
|
||||
);
|
||||
const digestLine = ` catalog_digest: "${CATALOG_IDENTITY.digests.combined_sha256}"`;
|
||||
const source = /^\s{2}catalog_digest:/mu.test(withCount)
|
||||
? withCount.replace(
|
||||
/^\s{2}catalog_digest:\s*"[a-f0-9]{64}"\s*$/mu,
|
||||
digestLine,
|
||||
)
|
||||
: withCount.replace(/^(\s{2}tool_count:\s*\d+\s*)$/mu, `$1\n${digestLine}`);
|
||||
|
||||
await ensureGeneratedFile({
|
||||
path,
|
||||
source,
|
||||
check: arguments_.has("--check"),
|
||||
generateCommand: "npm run docs:generate",
|
||||
});
|
||||
+13
-24
@@ -10,26 +10,20 @@ const README_PATHS = [
|
||||
];
|
||||
const familyLabel = (id) => (id === "electron" ? "Electron" : id);
|
||||
|
||||
const tableCounts = (content, path, total) => {
|
||||
const tableCounts = (content, path, expectedCounts) => {
|
||||
const lines = content.split(/\r?\n/u);
|
||||
const headingIndex = lines.findIndex(
|
||||
(line) => line.startsWith("## ") && line.includes(String(total)),
|
||||
);
|
||||
if (headingIndex === -1) {
|
||||
throw new Error(`Missing ${total}-tool heading in ${path}`);
|
||||
}
|
||||
const counts = [];
|
||||
for (const line of lines.slice(headingIndex + 1)) {
|
||||
if (line.startsWith("## ")) break;
|
||||
if (!line.trim().startsWith("|") || /^\|\s*-/u.test(line)) continue;
|
||||
const count = Number(line.split("|")[2]?.trim());
|
||||
if (!Number.isInteger(count)) {
|
||||
if (counts.length === 0) continue;
|
||||
throw new Error(`Non-numeric tool count in ${path}`);
|
||||
for (const [index, line] of lines.entries()) {
|
||||
if (!/^\|\s*-/u.test(line)) continue;
|
||||
const counts = [];
|
||||
for (const row of lines.slice(index + 1)) {
|
||||
if (!row.trim().startsWith("|")) break;
|
||||
const count = Number(row.split("|")[2]?.trim());
|
||||
if (!Number.isInteger(count)) break;
|
||||
counts.push(count);
|
||||
}
|
||||
counts.push(count);
|
||||
if (counts.length === expectedCounts.length) return counts;
|
||||
}
|
||||
return counts;
|
||||
throw new Error(`Missing tool-family inventory table in ${path}`);
|
||||
};
|
||||
|
||||
const requireText = (issues, path, content, expected) => {
|
||||
@@ -42,16 +36,11 @@ export const documentationFactIssues = async (root, catalog) => {
|
||||
const expectedCounts = catalog.tools.families.map(({ count }) => count);
|
||||
for (const path of README_PATHS) {
|
||||
const content = await readFile(join(root, path), "utf8");
|
||||
requireText(
|
||||
issues,
|
||||
path,
|
||||
content,
|
||||
`MCP_tools-${String(catalog.tools.total)}`,
|
||||
);
|
||||
requireText(issues, path, content, "MCP-tool_catalog");
|
||||
for (const client of catalog.setup_clients)
|
||||
requireText(issues, path, content, client.display_name);
|
||||
try {
|
||||
const actualCounts = tableCounts(content, path, catalog.tools.total);
|
||||
const actualCounts = tableCounts(content, path, expectedCounts);
|
||||
if (JSON.stringify(actualCounts) !== JSON.stringify(expectedCounts))
|
||||
issues.push(
|
||||
`${path}: tool family counts ${JSON.stringify(actualCounts)} do not match ${JSON.stringify(expectedCounts)}`,
|
||||
|
||||
Reference in New Issue
Block a user