{"_id":"@25xcodes/llmfeed-validator","_rev":"7-6e4010573922bb17e89ed1b179331581","name":"@25xcodes/llmfeed-validator","dist-tags":{"latest":"1.2.0"},"versions":{"1.0.0":{"name":"@25xcodes/llmfeed-validator","version":"1.0.0","keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"author":"","license":"MIT","_id":"@25xcodes/llmfeed-validator@1.0.0","maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"bin":{"llmfeed-validate":"bin/llmfeed-validate.js"},"dist":{"shasum":"4a3e020e75134fe4007b3339031a13c027fd06a9","tarball":"https://registry.npmjs.org/@25xcodes/llmfeed-validator/-/llmfeed-validator-1.0.0.tgz","fileCount":15,"integrity":"sha512-YOMQQjFl0/gFeEH9CGhyZudvYfJyn17otcJT2itUKyWOX8bKEA3rDfT+xmhWP2gb0A9GaUB+qOZrQAXvhnE/1g==","signatures":[{"sig":"MEYCIQCCyPaWe3SS4SPjZ0rPVLsrX5kJRLTjVq1X1Miq5NyB5AIhAJpzYsn9DJu7/M1ZNSrb7eYhTsRO/H+8DVNKQf5GQWN2","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@25xcodes%2fllmfeed-validator@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":307017},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"ab21a5f75c70eeb31f321247c41a15b8b32f2525","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"25xcodes","email":"kiarash@25x.codes"},"repository":{"url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","type":"git","directory":"packages/validator"},"_npmVersion":"10.8.2","description":"LLMFeed validation library with Ed25519 signature verification","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^1.0.0","typescript":"^5.3.0"},"peerDependencies":{"@noble/ed25519":"^2.0.0"},"peerDependenciesMeta":{"@noble/ed25519":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/llmfeed-validator_1.0.0_1764879450970_0.5797289792295619","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@25xcodes/llmfeed-validator","version":"1.1.0","keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"author":"","license":"MIT","_id":"@25xcodes/llmfeed-validator@1.1.0","maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"bin":{"llmfeed-validate":"bin/llmfeed-validate.js"},"dist":{"shasum":"7006f8ac836e13124dd3ca9cbc70cd555d2b52f1","tarball":"https://registry.npmjs.org/@25xcodes/llmfeed-validator/-/llmfeed-validator-1.1.0.tgz","fileCount":15,"integrity":"sha512-F3uS++r+OhH49lp6ua6Ch/r9TtndjpQxXK26RG6h5v/9ccqlu+ajX0H5OJXAWusOYBIazxyzYwWwjUZZQTsrIQ==","signatures":[{"sig":"MEUCIQDCYl2PW3eNSBRvjzb00xz7Vq3TzmciBxz0BWq4TAW5gwIgIz4CE5WqTAZ5gIj/5mTzT/0fk0SaVRO1jxPBcrG4ORA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@25xcodes%2fllmfeed-validator@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":308697},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"47edd7f190dea2f8ba4d5b80fcad7fc4c22dfb8f","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"25xcodes","email":"kiarash@25x.codes"},"repository":{"url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","type":"git","directory":"packages/validator"},"_npmVersion":"10.8.2","description":"LLMFeed validation library with Ed25519 signature verification","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^1.0.0","typescript":"^5.3.0"},"peerDependencies":{"@noble/ed25519":"^2.0.0"},"peerDependenciesMeta":{"@noble/ed25519":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/llmfeed-validator_1.1.0_1764906605217_0.023340628543998987","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@25xcodes/llmfeed-validator","version":"1.1.1","keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"author":"","license":"MIT","_id":"@25xcodes/llmfeed-validator@1.1.1","maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"bin":{"llmfeed-validate":"bin/llmfeed-validate.js"},"dist":{"shasum":"cc4464420329e7cd8a08829c0f6672db4f94b917","tarball":"https://registry.npmjs.org/@25xcodes/llmfeed-validator/-/llmfeed-validator-1.1.1.tgz","fileCount":15,"integrity":"sha512-Q4azyf9y/pUaL7wX53d5KqdN2tpLimIo+9COP7wOvIenCoM6WQd2agvpJDmw3PnambmHualXMg9elrdhNKdMBA==","signatures":[{"sig":"MEQCICZsB5HeuiExoTZ9jTHvzVwoUnL9u43HBnqQA7dMHPHLAiAWVwzaq6plf3B3LD8+Z2XgO562/cCyRjhRdcABAMM7cA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@25xcodes%2fllmfeed-validator@1.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":309429},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"2d4af27f1793e4bafe79e346ebe115f0c4a3d192","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"25xcodes","email":"kiarash@25x.codes"},"repository":{"url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","type":"git","directory":"packages/validator"},"_npmVersion":"10.8.2","description":"LLMFeed validation library with Ed25519 signature verification","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^1.0.0","typescript":"^5.3.0"},"peerDependencies":{"@noble/ed25519":"^2.0.0"},"peerDependenciesMeta":{"@noble/ed25519":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/llmfeed-validator_1.1.1_1764911495091_0.1654838253407076","host":"s3://npm-registry-packages-npm-production"}},"1.1.2":{"name":"@25xcodes/llmfeed-validator","version":"1.1.2","keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"author":"","license":"MIT","_id":"@25xcodes/llmfeed-validator@1.1.2","maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"bin":{"llmfeed-validate":"bin/llmfeed-validate.js"},"dist":{"shasum":"088d0de863771bacb8e5a3d001ad608e7352040f","tarball":"https://registry.npmjs.org/@25xcodes/llmfeed-validator/-/llmfeed-validator-1.1.2.tgz","fileCount":15,"integrity":"sha512-Q+FTfabsKezVK3tDYle8bMVIHdS4t8vwtFmnurxNahIIBVY8DJULyHEvPXBoF8u1A3ChjDN7TNq9be+c3gqIhQ==","signatures":[{"sig":"MEQCIHsTuLzRFr0Q88M/Hud6TKM21PlxXgUNSwimk81ZG2bNAiAwIv/nnXSzd8Qu4XmB/c4equs1tfZ1fK+neDPsxC136Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@25xcodes%2fllmfeed-validator@1.1.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":309429},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"913711bc23cdd5a489c6936c07b186e4b9547b30","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"25xcodes","email":"kiarash@25x.codes"},"repository":{"url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","type":"git","directory":"packages/validator"},"_npmVersion":"10.8.2","description":"LLMFeed validation library with Ed25519 signature verification","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^1.0.0","typescript":"^5.3.0"},"peerDependencies":{"@noble/ed25519":"^2.0.0"},"peerDependenciesMeta":{"@noble/ed25519":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/llmfeed-validator_1.1.2_1764928957789_0.952264945014536","host":"s3://npm-registry-packages-npm-production"}},"1.1.6":{"name":"@25xcodes/llmfeed-validator","version":"1.1.6","keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"author":"","license":"MIT","_id":"@25xcodes/llmfeed-validator@1.1.6","maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"bin":{"llmfeed-validate":"bin/llmfeed-validate.js"},"dist":{"shasum":"40b852619cda6341c7c473d83d29126c4118fb8d","tarball":"https://registry.npmjs.org/@25xcodes/llmfeed-validator/-/llmfeed-validator-1.1.6.tgz","fileCount":15,"integrity":"sha512-xXedCGbGeV3mZBwzo11gRkwU+IJZqTouCtvsGlx4pmZRAq1hFMcj5amNQqj/r8jm4VbvcO/THzy6wus6p0EIUQ==","signatures":[{"sig":"MEYCIQC/+Pt7R/bc/NeKTztifEPw1x7dBrkgNTcNhzIgGvMh+gIhAONWi97yx4ZBpHPLCx1V2Bmg7BEVHJZsbYWtQt1Gd4Cx","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@25xcodes%2fllmfeed-validator@1.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":309466},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"bba5ad6825733882894d97bc2a29df542887ec4f","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"25xcodes","email":"kiarash@25x.codes"},"repository":{"url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","type":"git","directory":"packages/validator"},"_npmVersion":"10.8.2","description":"LLMFeed validation library with Ed25519 signature verification","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^4.0.0","typescript":"^5.3.0","@vitest/coverage-v8":"^4.0.0"},"peerDependencies":{"@noble/ed25519":"^2.0.0"},"peerDependenciesMeta":{"@noble/ed25519":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/llmfeed-validator_1.1.6_1764933187257_0.18019209781984524","host":"s3://npm-registry-packages-npm-production"}},"1.1.7":{"name":"@25xcodes/llmfeed-validator","version":"1.1.7","keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"author":"","license":"MIT","_id":"@25xcodes/llmfeed-validator@1.1.7","maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"bin":{"llmfeed-validate":"bin/llmfeed-validate.js"},"dist":{"shasum":"b922ee9989a0fbd70a98762615eef20d25d39230","tarball":"https://registry.npmjs.org/@25xcodes/llmfeed-validator/-/llmfeed-validator-1.1.7.tgz","fileCount":15,"integrity":"sha512-dL5K7j1R4uwYHAm75xfcE/2JZ+QbfL87qAKOvsjPssEyPAiMQawM4PMLQPONWnwSNNuYxsCqanajFufhLOv1ag==","signatures":[{"sig":"MEQCIBp9UgbQX+NV65Z5HUiXMSW018RwjUDvXCVV6CL78XwsAiAFsa78EHpdYrm3zyAafVCjaIyk69pahDdnP31qAC+PYw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@25xcodes%2fllmfeed-validator@1.1.7","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":309495},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"ce001248d2f1dbaacba3fcb9ce8c52f7aeb41ab4","scripts":{"dev":"tsup --watch","test":"vitest run","build":"tsup","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"25xcodes","email":"kiarash@25x.codes"},"repository":{"url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","type":"git","directory":"packages/validator"},"_npmVersion":"10.8.2","description":"LLMFeed validation library with Ed25519 signature verification","directories":{},"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","vitest":"^4.0.0","typescript":"^5.3.0","@vitest/coverage-v8":"^4.0.0"},"peerDependencies":{"@noble/ed25519":"^2.0.0"},"peerDependenciesMeta":{"@noble/ed25519":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/llmfeed-validator_1.1.7_1764938636434_0.6565186509066976","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@25xcodes/llmfeed-validator","version":"1.2.0","description":"LLMFeed validation library with Ed25519 signature verification","type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"bin":{"llmfeed-validate":"bin/llmfeed-validate.js"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","prepublishOnly":"npm run build"},"keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"author":"","license":"MIT","repository":{"type":"git","url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","directory":"packages/validator"},"devDependencies":{"@vitest/coverage-v8":"^4.0.0","tsup":"^8.0.0","typescript":"^5.3.0","vitest":"^4.0.0"},"peerDependencies":{"@noble/ed25519":"^2.0.0"},"peerDependenciesMeta":{"@noble/ed25519":{"optional":true}},"_id":"@25xcodes/llmfeed-validator@1.2.0","gitHead":"06b246443edf450eb842ec3e38e47b339debb92e","bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-Rm3YHn/yDIG/2BZBKjpa2FD1QvA/dfwF5pAXIt5/eRtuz5Ofd1jdCg4bGIALZTZfglAlsug62eUrU8tVXhkaEA==","shasum":"79652d9269f2616f03db2f135db443f809d50d2c","tarball":"https://registry.npmjs.org/@25xcodes/llmfeed-validator/-/llmfeed-validator-1.2.0.tgz","fileCount":15,"unpackedSize":309495,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@25xcodes%2fllmfeed-validator@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGW0ltUdvtiV07AdsNWBXcBsbMV7HgN5s5EmwkZ0T+OLAiAXZ2XPdsPyxrVA8Ir+9EFvaojNs9tXuI26yvejr9YjqA=="}]},"_npmUser":{"name":"25xcodes","email":"kiarash@25x.codes"},"directories":{},"maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/llmfeed-validator_1.2.0_1764957247827_0.6920651376757172"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-04T20:17:30.879Z","modified":"2025-12-05T17:54:08.325Z","1.0.0":"2025-12-04T20:17:31.111Z","1.1.0":"2025-12-05T03:50:05.389Z","1.1.1":"2025-12-05T05:11:35.252Z","1.1.2":"2025-12-05T10:02:37.934Z","1.1.6":"2025-12-05T11:13:07.416Z","1.1.7":"2025-12-05T12:43:56.596Z","1.2.0":"2025-12-05T17:54:07.972Z"},"bugs":{"url":"https://github.com/kiarashplusplus/webmcp-tooling-suite/issues"},"license":"MIT","homepage":"https://github.com/kiarashplusplus/webmcp-tooling-suite#readme","keywords":["llmfeed","mcp","webmcp","validator","ed25519","ai-agents","model-context-protocol"],"repository":{"type":"git","url":"git+https://github.com/kiarashplusplus/webmcp-tooling-suite.git","directory":"packages/validator"},"description":"LLMFeed validation library with Ed25519 signature verification","maintainers":[{"name":"25xcodes","email":"kiarash@25x.codes"}],"readme":"# @25xcodes/llmfeed-validator\n\nLLMFeed validation library with Ed25519 cryptographic signature verification.\n\n## Features\n\n- ✅ **Structure validation** — Validates required fields (feed_type, metadata, capabilities)\n- ✅ **Schema validation** — Validates capability schemas\n- ✅ **Ed25519 signatures** — Full cryptographic signature verification\n- ✅ **Diagnostics** — Detailed step-by-step verification diagnostics\n- ✅ **Bug detection** — Automatically detects common signing implementation bugs\n- ✅ **CLI included** — Validate feeds from the command line\n- ✅ **Zero dependencies** — Uses native Web Crypto API\n\n## Installation\n\n```bash\nnpm install @25xcodes/llmfeed-validator\n```\n\n## CLI Usage\n\n```bash\n# Validate from URL (auto-discovers .well-known path)\nnpx @25xcodes/llmfeed-validator example.com\n\n# Validate full URL\nnpx @25xcodes/llmfeed-validator https://example.com/.well-known/mcp.llmfeed.json\n\n# Validate local file\nnpx @25xcodes/llmfeed-validator ./my-feed.json\n\n# JSON output (for CI/CD)\nnpx @25xcodes/llmfeed-validator example.com --json\n\n# Skip signature verification\nnpx @25xcodes/llmfeed-validator example.com --skip-signature\n\n# Verbose output\nnpx @25xcodes/llmfeed-validator example.com --verbose\n```\n\n### Exit Codes\n\n| Code | Meaning |\n|------|---------|\n| 0 | Feed is valid |\n| 1 | Feed is invalid (has errors) |\n| 2 | Could not fetch or parse feed |\n\n## Programmatic Usage\n\n```typescript\nimport { validateLLMFeed, fetchLLMFeed } from '@25xcodes/llmfeed-validator'\n\n// Validate from URL\nconst feed = await fetchLLMFeed('https://example.com')\nconst result = await validateLLMFeed(feed)\n\nconsole.log(result.valid)          // true/false\nconsole.log(result.score)          // 0-100\nconsole.log(result.signatureValid) // true/false/undefined\nconsole.log(result.errors)         // ValidationError[]\nconsole.log(result.warnings)       // ValidationWarning[]\n\n// With options\nconst result = await validateLLMFeed(feed, {\n  skipSignatureVerification: true,\n  timeout: 5000\n})\n```\n\n### Signature Diagnostics\n\nWhen signature verification fails, detailed diagnostics are available:\n\n```typescript\nconst result = await validateLLMFeed(feed)\n\nif (!result.signatureValid && result.signatureDiagnostics) {\n  const diag = result.signatureDiagnostics\n  \n  // Step-by-step verification status\n  for (const step of diag.steps) {\n    console.log(`${step.status}: ${step.message}`)\n  }\n  \n  // Detected issues with recommendations\n  for (const issue of diag.detectedIssues) {\n    console.log(`[${issue.code}] ${issue.title}`)\n    console.log(`  Recommendation: ${issue.recommendation}`)\n  }\n  \n  // Canonical payload for debugging\n  console.log('Canonical JSON:', diag.canonicalPayload?.json)\n  console.log('SHA-256:', diag.canonicalPayload?.hash)\n}\n```\n\n### Custom Fetch / Node.js\n\nFor environments without global `fetch` or for testing:\n\n```typescript\nimport { validateLLMFeed } from '@25xcodes/llmfeed-validator'\n\nconst result = await validateLLMFeed(feed, {\n  fetch: customFetchFunction,\n  publicKeyResolver: async (url) => {\n    // Return PEM-encoded public key string\n    return '-----BEGIN PUBLIC KEY-----\\n...'\n  }\n})\n```\n\n## CI/CD Integration\n\n### GitHub Actions\n\n```yaml\nname: Validate LLMFeed\non: [push, pull_request]\n\njobs:\n  validate:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-node@v4\n        with:\n          node-version: '20'\n      - run: npx @25xcodes/llmfeed-validator ./mcp.llmfeed.json --json > validation.json\n      - run: |\n          if [ $(jq '.valid' validation.json) != \"true\" ]; then\n            echo \"Feed validation failed!\"\n            jq '.errors' validation.json\n            exit 1\n          fi\n```\n\n### Pre-commit Hook\n\n```bash\n#!/bin/bash\n# .git/hooks/pre-commit\nnpx @webmcp/validator ./mcp.llmfeed.json --quiet\n```\n\n## API Reference\n\n### `validateLLMFeed(feed, options?)`\n\nValidates an LLMFeed object.\n\n**Parameters:**\n- `feed: unknown` — The feed object to validate\n- `options?: ValidatorOptions`\n  - `fetch?: typeof fetch` — Custom fetch function\n  - `skipSignatureVerification?: boolean` — Skip signature checks\n  - `publicKeyResolver?: (url: string) => Promise<string>` — Custom key resolver\n  - `timeout?: number` — Network timeout in ms\n\n**Returns:** `Promise<ValidationResult>`\n\n### `fetchLLMFeed(input, options?)`\n\nFetches an LLMFeed from a URL.\n\n**Parameters:**\n- `input: string` — URL, domain, or file path\n- `options?: ValidatorOptions`\n\n**Returns:** `Promise<LLMFeed>`\n\n### `verifyEd25519Signature(feed, options?)`\n\nVerifies Ed25519 signature with detailed diagnostics.\n\n**Returns:** `Promise<SignatureVerificationResult>`\n\n## Types\n\n```typescript\ninterface ValidationResult {\n  valid: boolean\n  errors: ValidationError[]\n  warnings: ValidationWarning[]\n  score: number\n  signatureValid?: boolean\n  signatureDiagnostics?: SignatureVerificationResult\n}\n\ninterface ValidationError {\n  type: 'structure' | 'schema' | 'signature' | 'format'\n  field?: string\n  message: string\n  severity: 'error' | 'warning'\n}\n\ninterface SignatureVerificationResult {\n  valid: boolean\n  error?: string\n  steps: SignatureVerificationStep[]\n  canonicalPayload?: { json: string; bytes: number; hash?: string }\n  detectedIssues: SignatureIssue[]\n  // ... more fields\n}\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}