JSPM

@a2a-compliance/core

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 32
  • Score
    100M100P100Q58185F
  • License MIT

Assertion engine and reporters (JSON, JUnit, badge SVG) for A2A protocol compliance testing

Package Exports

  • @a2a-compliance/core

Readme

@a2a-compliance/core

Programmatic compliance engine for A2A (Agent2Agent) protocol endpoints. Drop it into your own server, test harness, or CI wrapper when the @a2a-compliance/cli doesn't fit.

npm i @a2a-compliance/core

Quick start

import { runFullChecks } from '@a2a-compliance/core';

const report = await runFullChecks('https://agent.example.com');

console.log(report.summary);
// → { total: 15, pass: 11, fail: 2, warn: 1, skip: 1 }

for (const check of report.checks) {
  if (check.status === 'fail') {
    console.warn(`${check.id}: ${check.message}`);
  }
}

Card-only, faster

import { runCardChecks } from '@a2a-compliance/core';
const report = await runCardChecks('https://agent.example.com');

Reporters

import { toBadgeSvg, toJUnitXml } from '@a2a-compliance/core';
import { writeFileSync } from 'node:fs';

writeFileSync('./report.junit.xml', toJUnitXml(report));
writeFileSync('./badge.svg', toBadgeSvg(report));

Snapshot regression detection

import { toSnapshot, diffSnapshot, hasRegressions, parseSnapshot } from '@a2a-compliance/core';
import { readFileSync, writeFileSync } from 'node:fs';

// Capture a baseline
writeFileSync('./baseline.json', JSON.stringify(toSnapshot(report)));

// Later: compare
const base = parseSnapshot(JSON.parse(readFileSync('./baseline.json', 'utf8')));
if (base) {
  const diff = diffSnapshot(base, newReport);
  if (hasRegressions(diff)) process.exit(1);
}

SSRF guard for your own service

import { ssrfCheckForUrl } from '@a2a-compliance/core';

const safety = await ssrfCheckForUrl(userSuppliedUrl);
if (!safety.ok) throw new Error(`refusing to probe: ${safety.reason}`);

The guard rejects loopback, RFC 1918, link-local (incl. 169.254.169.254 cloud metadata), carrier-NAT, and IPv4-mapped / IPv4-compat / NAT64 IPv6 forms of all the above.

Check taxonomy

Every check returns:

interface CheckResult {
  id: string;                        // stable dotted id, e.g. 'sec.ssrf'
  title: string;
  severity: 'must' | 'should' | 'info';
  status: 'pass' | 'fail' | 'warn' | 'skip';
  message?: string;
  evidence?: unknown;
  durationMs: number;
}

The full assertion list is in docs/ARCHITECTURE.md on the repo.

Spec version adaptation

runFullChecks reads protocolVersion from the agent card and swaps the JSON-RPC method names accordingly (A2A v0.3 tasks/send ↔ v1.0 message/send, etc.). Unknown versions fall back to v1.0 with a warning.

Safety limits

  • 10 s per outbound HTTP call (configurable via internal constants)
  • 2 MB response body cap (ResponseTooLargeError on overrun)
  • Timeouts are per-request, not per-run — no cumulative budget yet

License

MIT.