UNPKG

aura-protocol

Version:

Core TypeScript definitions and JSON Schema for the AURA protocol - making websites machine-readable for AI agents

238 lines (237 loc) 10.1 kB
#!/usr/bin/env node "use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(require("fs")); const path = __importStar(require("path")); const citty_1 = require("citty"); const Ajv = __importStar(require("ajv")); const kleur_1 = require("kleur"); const main = (0, citty_1.defineCommand)({ meta: { name: 'aura-validate', description: 'Validate AURA manifest files against the official schema', version: '1.0.0', }, args: { file: { type: 'positional', description: 'Path to the manifest file (default: .well-known/aura.json)', required: false, }, url: { type: 'string', description: 'Validate manifest from URL', alias: 'u', }, schema: { type: 'string', description: 'Path to custom schema file', alias: 's', }, verbose: { type: 'boolean', description: 'Show detailed validation output', alias: 'v', }, json: { type: 'boolean', description: 'Output machine-readable JSON', alias: 'j', }, }, async run({ args }) { var _a, _b; const result = { valid: false, warnings: [], }; try { // Determine manifest source let manifestData; let manifestSource; if (args.url) { // Fetch from URL - temporarily disabled const error = 'URL validation is temporarily disabled. Please use local file validation.'; if (args.json) { console.log(JSON.stringify({ valid: false, error }, null, 2)); } else { console.error((0, kleur_1.red)(error)); } process.exit(1); } else { // Read from file const manifestPath = args.file || path.join(process.cwd(), '.well-known', 'aura.json'); if (!fs.existsSync(manifestPath)) { const error = `Manifest file not found: ${manifestPath}`; if (args.json) { console.log(JSON.stringify({ valid: false, error }, null, 2)); } else { console.error((0, kleur_1.red)(error)); } process.exit(1); } manifestData = JSON.parse(fs.readFileSync(manifestPath, 'utf-8')); manifestSource = manifestPath; } result.manifest = manifestData; result.source = manifestSource; if (!args.json) { console.log((0, kleur_1.blue)(`Validating manifest from: ${manifestSource}`)); } // Load schema let schema; if (args.schema) { // Custom schema if (!fs.existsSync(args.schema)) { const error = `Schema file not found: ${args.schema}`; if (args.json) { console.log(JSON.stringify({ valid: false, error }, null, 2)); } else { console.error((0, kleur_1.red)(error)); } process.exit(1); } schema = JSON.parse(fs.readFileSync(args.schema, 'utf-8')); } else { // Default schema from dist const schemaPath = path.join(__dirname, '../../dist/aura-v1.0.schema.json'); if (!fs.existsSync(schemaPath)) { const error = 'Default schema not found. Run "npm run build" first.'; if (args.json) { console.log(JSON.stringify({ valid: false, error }, null, 2)); } else { console.error((0, kleur_1.red)(error)); } process.exit(1); } schema = JSON.parse(fs.readFileSync(schemaPath, 'utf-8')); } // Validate const ajv = new Ajv.default({ allErrors: true, verbose: args.verbose, strict: false // Allow additional keywords from TypeScript JSON Schema }); const validate = ajv.compile(schema); const valid = validate(manifestData); result.valid = valid; if (valid) { if (!args.json) { console.log((0, kleur_1.green)('✓ Manifest is valid!')); // Show summary console.log((0, kleur_1.cyan)('\nManifest Summary:')); console.log(` Protocol: ${manifestData.protocol} v${manifestData.version}`); console.log(` Site: ${manifestData.site.name}`); console.log(` Resources: ${Object.keys(manifestData.resources || {}).length}`); console.log(` Capabilities: ${Object.keys(manifestData.capabilities || {}).length}`); if (args.verbose) { console.log((0, kleur_1.cyan)('\nCapabilities:')); Object.entries(manifestData.capabilities || {}).forEach(([id, cap]) => { console.log(` - ${id}: ${cap.description}`); }); } } } else { result.errors = validate.errors; if (!args.json) { console.log((0, kleur_1.red)('✗ Manifest is invalid!')); console.log((0, kleur_1.red)('\nValidation errors:')); (_a = validate.errors) === null || _a === void 0 ? void 0 : _a.forEach((error) => { const instancePath = error.instancePath || '/'; console.log((0, kleur_1.red)(` ${instancePath}: ${error.message}`)); if (error.params && args.verbose) { console.log((0, kleur_1.gray)(` Details: ${JSON.stringify(error.params)}`)); } }); } } // Additional checks if (manifestData.capabilities) { if (!args.json) { console.log((0, kleur_1.cyan)('\nPerforming additional checks...')); } // Check for referenced capabilities in resources const referencedCapabilities = new Set(); Object.values(manifestData.resources || {}).forEach((resource) => { Object.values(resource.operations || {}).forEach((op) => { if (op.capabilityId) { referencedCapabilities.add(op.capabilityId); } }); }); // Check for unreferenced capabilities const definedCapabilities = new Set(Object.keys(manifestData.capabilities)); const unreferenced = Array.from(definedCapabilities).filter(id => !referencedCapabilities.has(id)); if (unreferenced.length > 0) { const warning = `Unreferenced capabilities: ${unreferenced.join(', ')}`; (_b = result.warnings) === null || _b === void 0 ? void 0 : _b.push(warning); if (!args.json) { console.log((0, kleur_1.yellow)(` ⚠ ${warning}`)); } } // Check for undefined capability references const undefined = Array.from(referencedCapabilities).filter(id => !definedCapabilities.has(id)); if (undefined.length > 0) { const error = `Undefined capability references: ${undefined.join(', ')}`; result.errors = result.errors || []; result.errors.push({ message: error }); result.valid = false; if (!args.json) { console.log((0, kleur_1.red)(` ✗ ${error}`)); } } } if (args.json) { console.log(JSON.stringify(result, null, 2)); } else { if (result.valid) { console.log((0, kleur_1.green)('\n✓ All checks passed!')); } } if (!result.valid) { process.exit(1); } } catch (error) { if (args.json) { console.log(JSON.stringify({ valid: false, error: error.message }, null, 2)); } else { console.error((0, kleur_1.red)(`Error: ${error.message}`)); } process.exit(1); } }, }); (0, citty_1.runMain)(main);