import fs from "node:fs/promises"; import path from "node:path"; import fg from "fast-glob"; import type { VersionFinding } from "./shared"; const FRONTMATTER_RE = /^---\n([\s\S]*?)^---$/m; const ERP_KIT_VERSION_RE = /^\s*erp-kit-version:\s*"([^"]+)"$/m; export async function checkSkillsVersion( cwd: string, installedVersion: string, ): Promise { const skillFiles = await fg([".agents/skills/erp-kit-*/SKILL.md"], { cwd, onlyFiles: true, dot: true, ignore: ["**/node_modules/**"], }); const results = await Promise.all( skillFiles.map(async (relativePath): Promise => { const content = await fs.readFile(path.join(cwd, relativePath), "utf8"); const frontmatterMatch = content.match(FRONTMATTER_RE); const versionMatch = frontmatterMatch?.[1].match(ERP_KIT_VERSION_RE); if (!versionMatch) { return { severity: "error", check: "skills-version", subject: relativePath, message: `metadata.erp-kit-version frontmatter is missing; run \`erp-kit update skills\` to regenerate.`, }; } const recordedVersion = versionMatch[1]; if (recordedVersion === "0.0.0") { return { severity: "info", check: "skills-version", subject: relativePath, message: `recorded erp-kit version ${recordedVersion} is the unpublished placeholder (expected only in the erp-kit dev repo).`, }; } if (recordedVersion === installedVersion) return undefined; return { severity: "error", check: "skills-version", subject: relativePath, message: `generated for erp-kit ${recordedVersion}, but installed erp-kit is ${installedVersion}. Run \`erp-kit update skills\` to refresh.`, }; }), ); return results.filter((f): f is VersionFinding => f !== undefined); }