Buckets:
| import fs from "node:fs"; | |
| import path from "node:path"; | |
| import { fileURLToPath } from "node:url"; | |
| const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), ".."); | |
| const registryPath = path.join(root, "registry", "skills.index.json"); | |
| const schemaPath = path.join(root, "schemas", "universal-skill.schema.json"); | |
| const readJson = (filePath) => JSON.parse(fs.readFileSync(filePath, "utf8")); | |
| const errors = []; | |
| const warnings = []; | |
| function exists(relativePath) { | |
| return fs.existsSync(path.join(root, relativePath)); | |
| } | |
| function validateRegistry() { | |
| const registry = readJson(registryPath); | |
| if (!Array.isArray(registry.skills)) { | |
| errors.push("registry/skills.index.json: `skills` must be an array"); | |
| return; | |
| } | |
| const seen = new Set(); | |
| for (const entry of registry.skills) { | |
| if (!entry.id) errors.push("registry entry missing `id`"); | |
| if (seen.has(entry.id)) errors.push(`duplicate registry id: ${entry.id}`); | |
| seen.add(entry.id); | |
| if (!entry.path) { | |
| errors.push(`${entry.id}: missing path`); | |
| } else if (!exists(entry.path)) { | |
| errors.push(`${entry.id}: path does not exist: ${entry.path}`); | |
| } | |
| } | |
| } | |
| function validateUcaFile(relativePath, schema) { | |
| const data = readJson(path.join(root, relativePath)); | |
| for (const field of schema.required || []) { | |
| if (!(field in data)) { | |
| errors.push(`${relativePath}: missing required field: ${field}`); | |
| } | |
| } | |
| const statusEnum = schema.properties?.status?.enum || []; | |
| if (data.status && !statusEnum.includes(data.status)) { | |
| errors.push(`${relativePath}: invalid status: ${data.status}`); | |
| } | |
| const queueEnum = schema.properties?.queue_state?.enum || []; | |
| if (data.queue_state && !queueEnum.includes(data.queue_state)) { | |
| errors.push(`${relativePath}: invalid queue_state: ${data.queue_state}`); | |
| } | |
| if (data.steps && !Array.isArray(data.steps)) { | |
| errors.push(`${relativePath}: steps must be an array`); | |
| } | |
| } | |
| function validateUcaFiles() { | |
| const schema = readJson(schemaPath); | |
| const candidates = [ | |
| "skills/create-skill/skill.json", | |
| "skills/luuna-capability-radar/skill.json", | |
| "examples/luuna-capability-radar.example.json", | |
| ]; | |
| for (const relativePath of candidates) { | |
| if (!exists(relativePath)) { | |
| warnings.push(`skipped missing UCA file: ${relativePath}`); | |
| continue; | |
| } | |
| validateUcaFile(relativePath, schema); | |
| } | |
| } | |
| function validateLegacyNames() { | |
| for (const legacy of ["arhidecture", "capibility-radar", "files"]) { | |
| if (exists(legacy)) errors.push(`legacy folder still exists: ${legacy}`); | |
| } | |
| } | |
| validateRegistry(); | |
| validateUcaFiles(); | |
| validateLegacyNames(); | |
| if (warnings.length) { | |
| console.log("Warnings:"); | |
| for (const warning of warnings) console.log(`- ${warning}`); | |
| } | |
| if (errors.length) { | |
| console.error("Validation failed:"); | |
| for (const error of errors) console.error(`- ${error}`); | |
| process.exit(1); | |
| } | |
| console.log("SKILLGENERATOR validation OK"); | |
Xet Storage Details
- Size:
- 2.98 kB
- Xet hash:
- ddb6e63b0689290d78b587def9d0952f8667293452bfb48b16495d815bcfea29
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.